Stateless system permission retrieval
Making the design more flexible, so that each platform can implement
stateless or statefull permission retrieval.
Accesses are now done via a static api.
Bug: b/331784136
Change-Id: I3d14c58f6d9f914948231723e5efd47e8db37529
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5638632
Code-Coverage: [email protected] <[email protected]>
Reviewed-by: Greg Thompson <[email protected]>
Commit-Queue: Jan Láník <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1332921}
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index f0b98065..395f65b 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -78,7 +78,6 @@
#include "chrome/browser/metrics/shutdown_watcher_helper.h"
#include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
#include "chrome/browser/net/system_network_context_manager.h"
-#include "chrome/browser/permissions/system/system_permission_settings.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/policy/messaging_layer/public/report_client.h"
#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
@@ -1398,8 +1397,6 @@
headless::ReportHeadlessActionMetrics();
}
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-
- SystemPermissionSettings::Create(profile);
}
void ChromeBrowserMainParts::PreBrowserStart() {
diff --git a/chrome/browser/global_features.cc b/chrome/browser/global_features.cc
index 75369d9f..3a36ca1 100644
--- a/chrome/browser/global_features.cc
+++ b/chrome/browser/global_features.cc
@@ -8,6 +8,7 @@
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "build/build_config.h"
+#include "chrome/browser/permissions/system/platform_handle.h"
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
// This causes a gn error on Android builds, because gn does not understand
@@ -47,6 +48,7 @@
}
void GlobalFeatures::Init() {
+ system_permissions_platform_handle_ = CreateSystemPermissionsPlatformHandle();
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
if (user_education::features::IsWhatsNewV2()) {
whats_new_registry_ = CreateWhatsNewRegistry();
@@ -54,6 +56,11 @@
#endif
}
+std::unique_ptr<system_permission_settings::PlatformHandle>
+GlobalFeatures::CreateSystemPermissionsPlatformHandle() {
+ return system_permission_settings::PlatformHandle::Create();
+}
+
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
std::unique_ptr<whats_new::WhatsNewRegistry>
GlobalFeatures::CreateWhatsNewRegistry() {
diff --git a/chrome/browser/global_features.h b/chrome/browser/global_features.h
index d91ece6..dd5e550 100644
--- a/chrome/browser/global_features.h
+++ b/chrome/browser/global_features.h
@@ -5,9 +5,14 @@
#ifndef CHROME_BROWSER_GLOBAL_FEATURES_H_
#define CHROME_BROWSER_GLOBAL_FEATURES_H_
+#include <memory.h>
+
#include "base/functional/callback.h"
#include "build/build_config.h"
+namespace system_permission_settings {
+class PlatformHandle;
+} // namespace system_permission_settings
namespace whats_new {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
class WhatsNewRegistry;
@@ -36,6 +41,10 @@
// Public accessors for features, e.g.
// FooFeature* foo_feature() { return foo_feature_.get(); }
+ system_permission_settings::PlatformHandle*
+ system_permissions_platform_handle() {
+ return system_permissions_platform_handle_.get();
+ }
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
whats_new::WhatsNewRegistry* whats_new_registry() {
return whats_new_registry_.get();
@@ -49,6 +58,8 @@
// testing. e.g.
// virtual std::unique_ptr<FooFeature> CreateFooFeature();
+ virtual std::unique_ptr<system_permission_settings::PlatformHandle>
+ CreateSystemPermissionsPlatformHandle();
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
virtual std::unique_ptr<whats_new::WhatsNewRegistry> CreateWhatsNewRegistry();
#endif
@@ -57,6 +68,8 @@
// Features will each have a controller. e.g.
// std::unique_ptr<FooFeature> foo_feature_;
+ std::unique_ptr<system_permission_settings::PlatformHandle>
+ system_permissions_platform_handle_;
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
std::unique_ptr<whats_new::WhatsNewRegistry> whats_new_registry_;
#endif
diff --git a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h
index ce0f97d..20aaa17 100644
--- a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h
+++ b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h
@@ -241,9 +241,6 @@
// Handles receiving requests from the Media App (which is in ash).
std::unique_ptr<crosapi::MediaAppLacros> media_app_;
-
- // Retrieves and caces the state of the system permissions on the device.
- std::unique_ptr<SystemPermissionSettings> system_permission_settings_;
};
#endif // CHROME_BROWSER_LACROS_CHROME_BROWSER_MAIN_EXTRA_PARTS_LACROS_H_
diff --git a/chrome/browser/permissions/BUILD.gn b/chrome/browser/permissions/BUILD.gn
index 856028e4a..6f50683e 100644
--- a/chrome/browser/permissions/BUILD.gn
+++ b/chrome/browser/permissions/BUILD.gn
@@ -53,6 +53,7 @@
"quiet_notification_permission_ui_config.h",
"quiet_notification_permission_ui_state.cc",
"quiet_notification_permission_ui_state.h",
+ "system/platform_handle.h",
"system/system_permission_settings.cc",
"system/system_permission_settings.h",
]
diff --git a/chrome/browser/permissions/system/platform_handle.h b/chrome/browser/permissions/system/platform_handle.h
new file mode 100644
index 0000000..e85b5d32
--- /dev/null
+++ b/chrome/browser/permissions/system/platform_handle.h
@@ -0,0 +1,56 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PERMISSIONS_SYSTEM_PLATFORM_HANDLE_H_
+#define CHROME_BROWSER_PERMISSIONS_SYSTEM_PLATFORM_HANDLE_H_
+
+#include <memory>
+
+#include "chrome/browser/permissions/system/system_permission_settings.h"
+#include "components/content_settings/core/common/content_settings_types.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace system_permission_settings {
+
+// A class that abstracts the access to the system-level permission settings.
+// This class is to be implemented separately for each platform.
+// A single instance is created at a startup and is accessible via
+// GlobalFeatures within the BrowserProcess.
+class PlatformHandle {
+ public:
+ virtual ~PlatformHandle() = default;
+
+ // Returns a new instance of the platform-specific implementation.
+ static std::unique_ptr<PlatformHandle> Create();
+
+ // Returns `true` if Chrome can request system-level permission. Returns
+ // `false` otherwise.
+ virtual bool CanPrompt(ContentSettingsType type) = 0;
+
+ // Returns true if the system blocks the access to the specified content type
+ // permission.
+
+ virtual bool IsDenied(ContentSettingsType type) = 0;
+ // Returns true if the system blocks the access to the specified content type
+ // permission.
+
+ virtual bool IsAllowed(ContentSettingsType type) = 0;
+
+ // Opens the OS page where the user can change the permission settings.
+ // Implementation is OS specific.
+ virtual void OpenSystemSettings(content::WebContents* web_contents,
+ ContentSettingsType type) = 0;
+
+ // Initiates a system permission request and invokes the provided callback
+ // once the user's decision is made.
+ virtual void Request(ContentSettingsType type,
+ SystemPermissionResponseCallback callback) = 0;
+};
+
+} // namespace system_permission_settings
+
+#endif // CHROME_BROWSER_PERMISSIONS_SYSTEM_PLATFORM_HANDLE_H_
diff --git a/chrome/browser/permissions/system/system_permission_settings.cc b/chrome/browser/permissions/system/system_permission_settings.cc
index 15bd096..29ec1d7 100644
--- a/chrome/browser/permissions/system/system_permission_settings.cc
+++ b/chrome/browser/permissions/system/system_permission_settings.cc
@@ -6,11 +6,16 @@
#include <map>
#include <memory>
+#include <utility>
-#include "base/supports_user_data.h"
+#include "base/check.h"
+#include "base/check_deref.h"
+#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/global_features.h"
+#include "chrome/browser/permissions/system/platform_handle.h"
+
+namespace system_permission_settings {
namespace {
std::map<ContentSettingsType, bool>& GlobalTestingBlockOverrides() {
@@ -18,53 +23,62 @@
return g_testing_block_overrides;
}
-const void* const kSystemPermissionSettingsKey = &kSystemPermissionSettingsKey;
+PlatformHandle* GetPlatformHandle() {
+#if !BUILDFLAG(IS_ANDROID)
+ return CHECK_DEREF(CHECK_DEREF(g_browser_process).GetFeatures())
+ .system_permissions_platform_handle();
+#else
+ return nullptr;
+#endif
+}
} // namespace
-std::unique_ptr<base::SupportsUserData::Data>
-SystemPermissionSettings::Clone() {
- return nullptr;
+// static
+bool CanPrompt(ContentSettingsType type) {
+ return GetPlatformHandle()->CanPrompt(type);
}
-void SystemPermissionSettings::Create(Profile* profile) {
- CHECK(profile);
- profile->SetUserData(kSystemPermissionSettingsKey, CreateImpl());
-}
-
-SystemPermissionSettings* SystemPermissionSettings::GetInstance() {
- Profile* profile = g_browser_process->profile_manager()->GetLastUsedProfile();
- CHECK(profile);
- return static_cast<SystemPermissionSettings*>(
- profile->GetUserData(kSystemPermissionSettingsKey));
-}
-
-bool SystemPermissionSettings::IsDenied(ContentSettingsType type) const {
+// static
+bool IsDenied(ContentSettingsType type) {
if (GlobalTestingBlockOverrides().find(type) !=
GlobalTestingBlockOverrides().end()) {
return GlobalTestingBlockOverrides().at(type);
}
- return IsDeniedImpl(type);
+ return GetPlatformHandle()->IsDenied(type);
}
-bool SystemPermissionSettings::IsAllowed(ContentSettingsType type) const {
+// static
+bool IsAllowed(ContentSettingsType type) {
if (GlobalTestingBlockOverrides().find(type) !=
GlobalTestingBlockOverrides().end()) {
- return GlobalTestingBlockOverrides().at(type);
+ return !GlobalTestingBlockOverrides().at(type);
}
- return IsAllowedImpl(type);
+ return GetPlatformHandle()->IsAllowed(type);
}
-ScopedSystemPermissionSettingsForTesting::
- ScopedSystemPermissionSettingsForTesting(ContentSettingsType type,
- bool blocked)
+// static
+void OpenSystemSettings(content::WebContents* web_contents,
+ ContentSettingsType type) {
+ GetPlatformHandle()->OpenSystemSettings(web_contents, type);
+}
+
+// static
+void Request(ContentSettingsType type,
+ SystemPermissionResponseCallback callback) {
+ GetPlatformHandle()->Request(type, std::move(callback));
+}
+
+ScopedSettingsForTesting::ScopedSettingsForTesting(ContentSettingsType type,
+ bool blocked)
: type_(type) {
CHECK(GlobalTestingBlockOverrides().find(type) ==
GlobalTestingBlockOverrides().end());
GlobalTestingBlockOverrides()[type] = blocked;
}
-ScopedSystemPermissionSettingsForTesting::
- ~ScopedSystemPermissionSettingsForTesting() {
+ScopedSettingsForTesting::~ScopedSettingsForTesting() {
GlobalTestingBlockOverrides().erase(type_);
}
+
+} // namespace system_permission_settings
diff --git a/chrome/browser/permissions/system/system_permission_settings.h b/chrome/browser/permissions/system/system_permission_settings.h
index 988e8d94..2159e962 100644
--- a/chrome/browser/permissions/system/system_permission_settings.h
+++ b/chrome/browser/permissions/system/system_permission_settings.h
@@ -5,69 +5,49 @@
#ifndef CHROME_BROWSER_PERMISSIONS_SYSTEM_SYSTEM_PERMISSION_SETTINGS_H_
#define CHROME_BROWSER_PERMISSIONS_SYSTEM_SYSTEM_PERMISSION_SETTINGS_H_
-#include <memory>
-
-#include "base/supports_user_data.h"
-#include "chrome/browser/profiles/profile.h"
#include "components/content_settings/core/common/content_settings_types.h"
-#include "content/public/browser/web_contents.h"
-// A class that abstracts the access to the system-level permission settings.
-//
-// There is a certain overlap with
-// https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/permissions/system_permission_delegate.h
-// this is intentional as explained in
-// https://chromium-review.googlesource.com/c/chromium/src/+/5424111/comment/5e007f7b_c2b9ff9f
-class SystemPermissionSettings : public base::SupportsUserData::Data {
+namespace content {
+class WebContents;
+}
+
+namespace system_permission_settings {
+
+using SystemPermissionResponseCallback = base::OnceCallback<void()>;
+
+// Returns `true` if Chrome can request system-level permission. Returns
+// `false` otherwise.
+bool CanPrompt(ContentSettingsType type);
+
+// Check whether the system blocks the access to the specified content type /
+// permission.
+bool IsDenied(ContentSettingsType type);
+
+// Check whether the system allows the access to the specified content type /
+// permission.
+// On some platforms, both IsDenied and IsAllowed may return false for the
+// same permission.
+bool IsAllowed(ContentSettingsType type);
+
+// Opens the OS page where the user can change the permission settings.
+// Implementation is OS specific.
+void OpenSystemSettings(content::WebContents* web_contents,
+ ContentSettingsType type);
+
+// Initiates a system permission request and invokes the provided callback
+// once the user's decision is made.
+void Request(ContentSettingsType type,
+ SystemPermissionResponseCallback callback);
+
+class ScopedSettingsForTesting {
public:
- using SystemPermissionResponseCallback = base::OnceCallback<void()>;
-
- // base::SupportsUserData::Data:
- std::unique_ptr<base::SupportsUserData::Data> Clone() override;
-
- // Creates a new instance of SystemPermissionSettings that is OS-specific and
- // saves it within the profile. Should be only used when initializing the
- // Profile.
- static void Create(Profile*);
-
- // Gets a cached instance of SystemPermissionSettings from Profile.
- static SystemPermissionSettings* GetInstance();
-
- // Returns `true` if Chrome can request system-level permission. Returns
- // `false` otherwise.
- virtual bool CanPrompt(ContentSettingsType type) const = 0;
-
- // Check whether the system blocks the access to the specified content type /
- // permission.
- bool IsDenied(ContentSettingsType type) const;
- // Check whether the system allows the access to the specified content type /
- // permission.
- bool IsAllowed(ContentSettingsType type) const;
-
- // Opens the OS page where the user can change the permission settings.
- // Implementation is OS specific.
- virtual void OpenSystemSettings(content::WebContents* web_contents,
- ContentSettingsType type) const = 0;
-
- // Initiates a system permission request and invokes the provided callback
- // once the user's decision is made.
- virtual void Request(ContentSettingsType type,
- SystemPermissionResponseCallback callback) = 0;
-
- private:
- virtual bool IsDeniedImpl(ContentSettingsType type) const = 0;
- virtual bool IsAllowedImpl(ContentSettingsType type) const = 0;
- static std::unique_ptr<SystemPermissionSettings> CreateImpl();
-};
-
-class ScopedSystemPermissionSettingsForTesting {
- public:
- ScopedSystemPermissionSettingsForTesting(ContentSettingsType type,
- bool blocked);
- ~ScopedSystemPermissionSettingsForTesting();
+ ScopedSettingsForTesting(ContentSettingsType type, bool blocked);
+ ~ScopedSettingsForTesting();
private:
ContentSettingsType type_;
};
+} // namespace system_permission_settings
+
#endif // CHROME_BROWSER_PERMISSIONS_SYSTEM_SYSTEM_PERMISSION_SETTINGS_H_
diff --git a/chrome/browser/permissions/system/system_permission_settings_chromeos.cc b/chrome/browser/permissions/system/system_permission_settings_chromeos.cc
index 607b250..1bc848fc 100644
--- a/chrome/browser/permissions/system/system_permission_settings_chromeos.cc
+++ b/chrome/browser/permissions/system/system_permission_settings_chromeos.cc
@@ -4,16 +4,23 @@
#include "chrome/browser/permissions/system/system_permission_settings.h"
+#include <utility>
+
#include "base/feature_list.h"
#include "chrome/browser/ash/privacy_hub/privacy_hub_util.h"
+#include "chrome/browser/permissions/system/platform_handle.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/features.h"
-class SystemPermissionSettingsImpl : public SystemPermissionSettings {
- bool CanPrompt(ContentSettingsType type) const override { return false; }
+namespace system_permission_settings {
- bool IsDeniedImpl(ContentSettingsType type) const override {
+namespace {
+
+class PlatformHandleImpl : public PlatformHandle {
+ bool CanPrompt(ContentSettingsType type) override { return false; }
+
+ bool IsDenied(ContentSettingsType type) override {
if (base::FeatureList::IsEnabled(
content_settings::features::
kCrosSystemLevelPermissionBlockedWarnings)) {
@@ -22,12 +29,10 @@
return false;
}
- bool IsAllowedImpl(ContentSettingsType type) const override {
- return !IsDeniedImpl(type);
- }
+ bool IsAllowed(ContentSettingsType type) override { return !IsDenied(type); }
void OpenSystemSettings(content::WebContents*,
- ContentSettingsType type) const override {
+ ContentSettingsType type) override {
if (base::FeatureList::IsEnabled(
content_settings::features::
kCrosSystemLevelPermissionBlockedWarnings)) {
@@ -43,7 +48,11 @@
}
};
-std::unique_ptr<SystemPermissionSettings>
-SystemPermissionSettings::CreateImpl() {
- return std::make_unique<SystemPermissionSettingsImpl>();
+} // namespace
+
+// static
+std::unique_ptr<PlatformHandle> PlatformHandle::Create() {
+ return std::make_unique<PlatformHandleImpl>();
}
+
+} // namespace system_permission_settings
diff --git a/chrome/browser/permissions/system/system_permission_settings_default.cc b/chrome/browser/permissions/system/system_permission_settings_default.cc
index d280fb8..44c2eac 100644
--- a/chrome/browser/permissions/system/system_permission_settings_default.cc
+++ b/chrome/browser/permissions/system/system_permission_settings_default.cc
@@ -2,20 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "build/buildflag.h"
+#include "chrome/browser/permissions/system/platform_handle.h"
#include "chrome/browser/permissions/system/system_permission_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
static_assert(!BUILDFLAG(IS_CHROMEOS_ASH));
static_assert(!BUILDFLAG(IS_MAC));
-class SystemPermissionSettingsImpl : public SystemPermissionSettings {
- bool CanPrompt(ContentSettingsType type) const override { return false; }
- bool IsDeniedImpl(ContentSettingsType type) const override { return false; }
- bool IsAllowedImpl(ContentSettingsType type) const override { return true; }
+namespace system_permission_settings {
+
+namespace {
+
+class PlatformHandleImpl : public PlatformHandle {
+ bool CanPrompt(ContentSettingsType type) override { return false; }
+
+ bool IsDenied(ContentSettingsType type) override { return false; }
+
+ bool IsAllowed(ContentSettingsType type) override { return true; }
void OpenSystemSettings(content::WebContents*,
- ContentSettingsType type) const override {
+ ContentSettingsType type) override {
// no-op
NOTREACHED();
}
@@ -27,7 +36,11 @@
}
};
-std::unique_ptr<SystemPermissionSettings>
-SystemPermissionSettings::CreateImpl() {
- return std::make_unique<SystemPermissionSettingsImpl>();
+} // namespace
+
+// static
+std::unique_ptr<PlatformHandle> PlatformHandle::Create() {
+ return std::make_unique<PlatformHandleImpl>();
}
+
+} // namespace system_permission_settings
diff --git a/chrome/browser/permissions/system/system_permission_settings_mac.cc b/chrome/browser/permissions/system/system_permission_settings_mac.cc
index 296397f..8e491e38 100644
--- a/chrome/browser/permissions/system/system_permission_settings_mac.cc
+++ b/chrome/browser/permissions/system/system_permission_settings_mac.cc
@@ -5,11 +5,14 @@
#include "chrome/browser/permissions/system/system_permission_settings.h"
#include <memory>
+#include <utility>
+#include <vector>
#include "base/mac/mac_util.h"
#include "base/notreached.h"
#include "base/scoped_observation.h"
#include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
+#include "chrome/browser/permissions/system/platform_handle.h"
#include "chrome/browser/web_applications/os_integration/mac/app_shim_registry.h"
#include "chrome/browser/web_applications/os_integration/mac/web_app_shortcut_mac.h"
#include "chrome/browser/web_applications/web_app_tab_helper.h"
@@ -20,6 +23,8 @@
static_assert(BUILDFLAG(IS_MAC));
+namespace system_permission_settings {
+
namespace {
bool denied(system_media_permissions::SystemPermission permission) {
return system_media_permissions::SystemPermission::kDenied == permission;
@@ -29,31 +34,16 @@
return system_media_permissions::SystemPermission::kNotDetermined ==
permission;
}
-
bool allowed(system_media_permissions::SystemPermission permission) {
return system_media_permissions::SystemPermission::kAllowed == permission;
}
-} // namespace
-
-class SystemPermissionSettingsImpl
- : public SystemPermissionSettings,
+class PlatformHandleImpl
+ : public PlatformHandle,
public device::GeolocationSystemPermissionManager::PermissionObserver {
public:
- SystemPermissionSettingsImpl() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- auto* geolocation_system_permission_manager =
- device::GeolocationSystemPermissionManager::GetInstance();
- CHECK(geolocation_system_permission_manager);
- observation_.Observe(geolocation_system_permission_manager);
- }
-
- ~SystemPermissionSettingsImpl() override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- FlushGeolocationCallbacks();
- }
-
- bool CanPrompt(ContentSettingsType type) const override {
+ // PlatformHandle:
+ bool CanPrompt(ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::MEDIASTREAM_CAMERA:
return prompt(
@@ -70,7 +60,7 @@
}
}
- bool IsDeniedImpl(ContentSettingsType type) const override {
+ bool IsDenied(ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::MEDIASTREAM_CAMERA:
return denied(
@@ -87,7 +77,7 @@
}
}
- bool IsAllowedImpl(ContentSettingsType type) const override {
+ bool IsAllowed(ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::MEDIASTREAM_CAMERA:
return allowed(
@@ -105,7 +95,7 @@
}
void OpenSystemSettings(content::WebContents* web_contents,
- ContentSettingsType type) const override {
+ ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::NOTIFICATIONS: {
const webapps::AppId* app_id =
@@ -152,12 +142,18 @@
return;
}
case ContentSettingsType::GEOLOCATION: {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
geolocation_callbacks_.push_back(std::move(callback));
// The system permission prompt is modal and requires a user decision
// (Allow or Deny) before it can be dismissed.
if (geolocation_callbacks_.size() == 1u) {
- device::GeolocationSystemPermissionManager::GetInstance()
- ->RequestSystemPermission();
+ auto* geolocation_system_permission_manager =
+ device::GeolocationSystemPermissionManager::GetInstance();
+ CHECK(geolocation_system_permission_manager);
+ CHECK(!observation_.IsObserving());
+ // Lazily setup geolocation status observation
+ observation_.Observe(geolocation_system_permission_manager);
+ geolocation_system_permission_manager->RequestSystemPermission();
}
return;
}
@@ -167,10 +163,12 @@
}
}
- // device::GeolocationSystemPermissionManager::PermissionObserver
- // implementation.
+ // device::GeolocationSystemPermissionManager::PermissionObserver:
void OnSystemPermissionUpdated(
device::LocationSystemPermissionStatus new_status) override {
+ // No further observation needed as all the current requests will now be
+ // resolved
+ observation_.Reset();
FlushGeolocationCallbacks();
}
@@ -189,7 +187,11 @@
observation_{this};
};
-std::unique_ptr<SystemPermissionSettings>
-SystemPermissionSettings::CreateImpl() {
- return std::make_unique<SystemPermissionSettingsImpl>();
+} // namespace
+
+// static
+std::unique_ptr<PlatformHandle> PlatformHandle::Create() {
+ return std::make_unique<PlatformHandleImpl>();
}
+
+} // namespace system_permission_settings
diff --git a/chrome/browser/permissions/system/system_permission_settings_win.cc b/chrome/browser/permissions/system/system_permission_settings_win.cc
index ac5f9e4..09338c4 100644
--- a/chrome/browser/permissions/system/system_permission_settings_win.cc
+++ b/chrome/browser/permissions/system/system_permission_settings_win.cc
@@ -8,6 +8,7 @@
#include "base/notreached.h"
#include "base/scoped_observation.h"
+#include "chrome/browser/permissions/system/platform_handle.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "services/device/public/cpp/device_features.h"
@@ -16,30 +17,16 @@
static_assert(BUILDFLAG(IS_WIN));
-class SystemPermissionSettingsWin
- : public SystemPermissionSettings,
+namespace system_permission_settings {
+
+namespace {
+
+class PlatformHandleImpl
+ : public PlatformHandle,
public device::GeolocationSystemPermissionManager::PermissionObserver {
public:
- SystemPermissionSettingsWin() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- // Initialize system permission settings for geolocation based on the
- // feature flag.
- if (base::FeatureList::IsEnabled(features::kWinSystemLocationPermission)) {
- // If the feature is enabled, retrieve and observe the system permission
- // status.
- auto* geolocation_system_permission_manager =
- device::GeolocationSystemPermissionManager::GetInstance();
- CHECK(geolocation_system_permission_manager);
- observation_.Observe(geolocation_system_permission_manager);
- }
- }
-
- ~SystemPermissionSettingsWin() override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- FlushGeolocationCallbacks();
- }
-
- bool CanPrompt(ContentSettingsType type) const override {
+ // PlatformHandle:
+ bool CanPrompt(ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::GEOLOCATION: {
if (base::FeatureList::IsEnabled(
@@ -56,7 +43,7 @@
}
}
- bool IsDeniedImpl(ContentSettingsType type) const override {
+ bool IsDenied(ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::GEOLOCATION:
if (base::FeatureList::IsEnabled(
@@ -72,7 +59,7 @@
}
}
- bool IsAllowedImpl(ContentSettingsType type) const override {
+ bool IsAllowed(ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::GEOLOCATION:
if (base::FeatureList::IsEnabled(
@@ -89,7 +76,7 @@
}
void OpenSystemSettings(content::WebContents* web_contents,
- ContentSettingsType type) const override {
+ ContentSettingsType type) override {
switch (type) {
case ContentSettingsType::GEOLOCATION: {
if (base::FeatureList::IsEnabled(
@@ -108,14 +95,22 @@
SystemPermissionResponseCallback callback) override {
switch (type) {
case ContentSettingsType::GEOLOCATION: {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!base::FeatureList::IsEnabled(
+ features::kWinSystemLocationPermission)) {
+ return;
+ }
geolocation_callbacks_.push_back(std::move(callback));
// The system permission prompt is modal and requires a user decision
// (Allow or Deny) before it can be dismissed.
- if (geolocation_callbacks_.size() == 1u &&
- base::FeatureList::IsEnabled(
- features::kWinSystemLocationPermission)) {
- device::GeolocationSystemPermissionManager::GetInstance()
- ->RequestSystemPermission();
+ if (geolocation_callbacks_.size() == 1u) {
+ auto* geolocation_system_permission_manager =
+ device::GeolocationSystemPermissionManager::GetInstance();
+ CHECK(geolocation_system_permission_manager);
+ CHECK(!observation_.IsObserving());
+ // Lazily setup geolocation status observation
+ observation_.Observe(geolocation_system_permission_manager);
+ geolocation_system_permission_manager->RequestSystemPermission();
}
return;
}
@@ -129,6 +124,7 @@
// implementation.
void OnSystemPermissionUpdated(
device::LocationSystemPermissionStatus new_status) override {
+ observation_.Reset();
FlushGeolocationCallbacks();
}
@@ -147,8 +143,11 @@
observation_{this};
};
+} // namespace
+
// static
-std::unique_ptr<SystemPermissionSettings>
-SystemPermissionSettings::CreateImpl() {
- return std::make_unique<SystemPermissionSettingsWin>();
+std::unique_ptr<PlatformHandle> PlatformHandle::Create() {
+ return std::make_unique<PlatformHandleImpl>();
}
+
+} // namespace system_permission_settings
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
index e90beac..7a830cc 100644
--- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
+++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
@@ -262,8 +262,7 @@
case ContentSettingsType::MEDIASTREAM_CAMERA:
if (base::FeatureList::IsEnabled(
content_settings::features::kLeftHandSideActivityIndicators) &&
- SystemPermissionSettings::GetInstance() &&
- SystemPermissionSettings::GetInstance()->IsDenied(type)) {
+ system_permission_settings::IsDenied(type)) {
*text_id = IDS_PAGE_INFO_CAMERA_SYSTEM_SETTINGS_DESCRIPTION;
*link_id = IDS_PAGE_INFO_SETTINGS_OF_A_SYSTEM_LINK;
return true;
@@ -272,8 +271,7 @@
case ContentSettingsType::MEDIASTREAM_MIC:
if (base::FeatureList::IsEnabled(
content_settings::features::kLeftHandSideActivityIndicators) &&
- SystemPermissionSettings::GetInstance() &&
- SystemPermissionSettings::GetInstance()->IsDenied(type)) {
+ system_permission_settings::IsDenied(type)) {
*text_id = IDS_PAGE_INFO_MICROPHONE_SYSTEM_SETTINGS_DESCRIPTION;
*link_id = IDS_PAGE_INFO_SETTINGS_OF_A_SYSTEM_LINK;
return true;
@@ -285,8 +283,7 @@
}
void ChromePageInfoUiDelegate::SettingsLinkClicked(ContentSettingsType type) {
- SystemPermissionSettings::GetInstance()->OpenSystemSettings(web_contents_,
- type);
+ system_permission_settings::OpenSystemSettings(web_contents_, type);
}
bool ChromePageInfoUiDelegate::IsBlockAutoPlayEnabled() {
diff --git a/chrome/browser/ui/views/permissions/chip/LHS_indicators_browsertest.cc b/chrome/browser/ui/views/permissions/chip/LHS_indicators_browsertest.cc
index fce8ef2b..f646a2fc 100644
--- a/chrome/browser/ui/views/permissions/chip/LHS_indicators_browsertest.cc
+++ b/chrome/browser/ui/views/permissions/chip/LHS_indicators_browsertest.cc
@@ -489,7 +489,7 @@
InvokeUi_PageInfo_camera_blocked_on_system_level) {
SetPermission(ContentSettingsType::MEDIASTREAM_CAMERA,
ContentSetting::CONTENT_SETTING_ALLOW);
- ScopedSystemPermissionSettingsForTesting scoped_system_permission(
+ system_permission_settings::ScopedSettingsForTesting scoped_system_permission(
ContentSettingsType::MEDIASTREAM_CAMERA, /*blocked=*/true);
UpdatePageInfo();
@@ -502,7 +502,7 @@
SetPermission(ContentSettingsType::MEDIASTREAM_MIC,
ContentSetting::CONTENT_SETTING_ALLOW);
- ScopedSystemPermissionSettingsForTesting scoped_system_permission(
+ system_permission_settings::ScopedSettingsForTesting scoped_system_permission(
ContentSettingsType::MEDIASTREAM_MIC, /*blocked=*/true);
UpdatePageInfo();
@@ -518,10 +518,12 @@
SetPermission(ContentSettingsType::MEDIASTREAM_MIC,
ContentSetting::CONTENT_SETTING_ALLOW);
- ScopedSystemPermissionSettingsForTesting scoped_system_permission_camera(
- ContentSettingsType::MEDIASTREAM_CAMERA, /*blocked=*/true);
- ScopedSystemPermissionSettingsForTesting scoped_system_permission_mic(
- ContentSettingsType::MEDIASTREAM_MIC, /*blocked=*/true);
+ system_permission_settings::ScopedSettingsForTesting
+ scoped_system_permission_camera(ContentSettingsType::MEDIASTREAM_CAMERA,
+ /*blocked=*/true);
+ system_permission_settings::ScopedSettingsForTesting
+ scoped_system_permission_mic(ContentSettingsType::MEDIASTREAM_MIC,
+ /*blocked=*/true);
UpdatePageInfo();
diff --git a/chrome/browser/ui/views/permissions/chip/dashboard_kombucha_interactive_uitest.cc b/chrome/browser/ui/views/permissions/chip/dashboard_kombucha_interactive_uitest.cc
index 4ffb8c7..82273d5 100644
--- a/chrome/browser/ui/views/permissions/chip/dashboard_kombucha_interactive_uitest.cc
+++ b/chrome/browser/ui/views/permissions/chip/dashboard_kombucha_interactive_uitest.cc
@@ -169,7 +169,7 @@
CameraUsingTestWithSystemBlock) {
SetPermission(ContentSettingsType::MEDIASTREAM_CAMERA, CONTENT_SETTING_ALLOW);
- ScopedSystemPermissionSettingsForTesting scoped_system_permission(
+ system_permission_settings::ScopedSettingsForTesting scoped_system_permission(
ContentSettingsType::MEDIASTREAM_CAMERA, true);
RunTestSequence(
@@ -250,7 +250,7 @@
MicrophoneUsingTestWithSystemBlock) {
SetPermission(ContentSettingsType::MEDIASTREAM_MIC, CONTENT_SETTING_ALLOW);
- ScopedSystemPermissionSettingsForTesting scoped_system_permission(
+ system_permission_settings::ScopedSettingsForTesting scoped_system_permission(
ContentSettingsType::MEDIASTREAM_MIC, true);
RunTestSequence(
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt.cc b/chrome/browser/ui/views/permissions/embedded_permission_prompt.cc
index d320770..3380e553 100644
--- a/chrome/browser/ui/views/permissions/embedded_permission_prompt.cc
+++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt.cc
@@ -179,12 +179,12 @@
// whereas the "OS Prompt" view is only higher priority then the views that
// are associated with a site-level allowed state.
// TODO(crbug.com/40275129): Handle going to Windows settings.
- if (SystemPermissionSettings::GetInstance()->IsDenied(type)) {
+ if (system_permission_settings::IsDenied(type)) {
return Variant::kOsSystemSettings;
}
if (setting == CONTENT_SETTING_ALLOW &&
- SystemPermissionSettings::GetInstance()->CanPrompt(type)) {
+ system_permission_settings::CanPrompt(type)) {
return Variant::kOsPrompt;
}
@@ -376,7 +376,7 @@
if (os_prompt_variant_ == Variant::kUninitialized) {
for (const auto& request : delegate()->Requests()) {
- if (SystemPermissionSettings::GetInstance()->CanPrompt(
+ if (system_permission_settings::CanPrompt(
request->GetContentSettingsType())) {
os_prompt_variant_ = Variant::kOsPrompt;
break;
@@ -386,7 +386,7 @@
if (os_system_settings_variant_ == Variant::kUninitialized) {
for (const auto& request : delegate()->Requests()) {
- if (SystemPermissionSettings::GetInstance()->IsDenied(
+ if (system_permission_settings::IsDenied(
request->GetContentSettingsType())) {
os_system_settings_variant_ = Variant::kOsSystemSettings;
break;
@@ -481,7 +481,7 @@
RecordOsMetrics(permissions::OsScreenAction::SYSTEM_SETTINGS);
RecordPermissionActionUKM(
permissions::ElementAnchoredBubbleAction::kSystemSettings);
- SystemPermissionSettings::GetInstance()->OpenSystemSettings(
+ system_permission_settings::OpenSystemSettings(
delegate()->GetAssociatedWebContents(),
requests_[0]->GetContentSettingsType());
}
@@ -516,7 +516,7 @@
prompt_types_.end());
for (unsigned int idx = 0; idx < types.size(); idx++) {
- SystemPermissionSettings::GetInstance()->Request(
+ system_permission_settings::Request(
types[idx],
base::BindOnce(
&EmbeddedPermissionPrompt::OnRequestSystemPermissionResponse,
@@ -531,14 +531,14 @@
const ContentSettingsType request_type,
const ContentSettingsType other_request_type) {
bool permission_determined =
- !SystemPermissionSettings::GetInstance()->CanPrompt(request_type);
+ !system_permission_settings::CanPrompt(request_type);
// `other_permission_determined` is left with true in non-grouped scenario,
// which would make the final logic fully rely on `permission_determined`.
auto other_permission_determined = true;
if (other_request_type != ContentSettingsType::DEFAULT) {
other_permission_determined =
- !SystemPermissionSettings::GetInstance()->CanPrompt(other_request_type);
+ !system_permission_settings::CanPrompt(other_request_type);
}
if (permission_determined) {