mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add visualization for Chrome configuration changes (fixes #3892)
- Add new API to retrieve/observe configuration values. - cefclient: Add https://tests/config to inspect configuration values in real time.
This commit is contained in:
@@ -12,10 +12,12 @@
|
||||
#include "base/task/current_thread.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "cef/libcef/browser/browser_info_manager.h"
|
||||
#include "cef/libcef/browser/prefs/pref_helper.h"
|
||||
#include "cef/libcef/browser/request_context_impl.h"
|
||||
#include "cef/libcef/browser/thread_util.h"
|
||||
#include "cef/libcef/browser/trace_subscriber.h"
|
||||
#include "cef/libcef/common/cef_switches.h"
|
||||
#include "chrome/browser/browser_process_impl.h"
|
||||
#include "components/network_session_configurator/common/network_switches.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
|
||||
@@ -570,12 +572,24 @@ CefTraceSubscriber* CefContext::GetTraceSubscriber() {
|
||||
if (shutting_down_) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!trace_subscriber_.get()) {
|
||||
if (!trace_subscriber_) {
|
||||
trace_subscriber_ = std::make_unique<CefTraceSubscriber>();
|
||||
}
|
||||
return trace_subscriber_.get();
|
||||
}
|
||||
|
||||
pref_helper::Registrar* CefContext::GetPrefRegistrar() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (shutting_down_) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!pref_registrar_) {
|
||||
pref_registrar_ = std::make_unique<pref_helper::Registrar>();
|
||||
pref_registrar_->Init(g_browser_process->local_state());
|
||||
}
|
||||
return pref_registrar_.get();
|
||||
}
|
||||
|
||||
void CefContext::PopulateGlobalRequestContextSettings(
|
||||
CefRequestContextSettings* settings) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
@@ -645,12 +659,15 @@ void CefContext::ShutdownOnUIThread() {
|
||||
observer.OnContextDestroyed();
|
||||
}
|
||||
|
||||
if (trace_subscriber_.get()) {
|
||||
trace_subscriber_.reset(nullptr);
|
||||
if (trace_subscriber_) {
|
||||
trace_subscriber_.reset();
|
||||
}
|
||||
if (pref_registrar_) {
|
||||
pref_registrar_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CefContext::FinalizeShutdown() {
|
||||
browser_info_manager_.reset(nullptr);
|
||||
browser_info_manager_.reset();
|
||||
application_ = nullptr;
|
||||
}
|
||||
|
@@ -16,6 +16,10 @@
|
||||
#include "cef/libcef/browser/main_runner.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
|
||||
namespace pref_helper {
|
||||
class Registrar;
|
||||
}
|
||||
|
||||
class CefBrowserInfoManager;
|
||||
class CefTraceSubscriber;
|
||||
|
||||
@@ -73,6 +77,7 @@ class CefContext {
|
||||
cef_state_t windowless_state) const;
|
||||
|
||||
CefTraceSubscriber* GetTraceSubscriber();
|
||||
pref_helper::Registrar* GetPrefRegistrar();
|
||||
|
||||
// Populate request context settings for the global system context based on
|
||||
// CefSettings and command-line flags.
|
||||
@@ -112,6 +117,7 @@ class CefContext {
|
||||
|
||||
std::unique_ptr<CefMainRunner> main_runner_;
|
||||
std::unique_ptr<CefTraceSubscriber> trace_subscriber_;
|
||||
std::unique_ptr<pref_helper::Registrar> pref_registrar_;
|
||||
std::unique_ptr<CefBrowserInfoManager> browser_info_manager_;
|
||||
|
||||
// Observers that want to be notified of changes to this object.
|
||||
|
@@ -4,10 +4,28 @@
|
||||
|
||||
#include "cef/libcef/browser/global_preference_manager_impl.h"
|
||||
|
||||
#include "base/metrics/field_trial_list_including_low_anonymity.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "cef/libcef/browser/context.h"
|
||||
#include "cef/libcef/browser/prefs/pref_helper.h"
|
||||
#include "cef/libcef/browser/thread_util.h"
|
||||
#include "cef/libcef/common/api_version_util.h"
|
||||
#include "chrome/browser/about_flags.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "components/flags_ui/pref_service_flags_storage.h"
|
||||
#include "components/variations/synthetic_trials_active_group_id_provider.h"
|
||||
|
||||
namespace {
|
||||
|
||||
std::string GetActiveGroupNameAsString(
|
||||
const base::FieldTrial::ActiveGroup& group) {
|
||||
constexpr std::string_view kNonBreakingHyphenUTF8 = "\xE2\x80\x91";
|
||||
std::string result = group.trial_name + ":" + group.group_name;
|
||||
base::ReplaceChars(result, "-", kNonBreakingHyphenUTF8, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool CefGlobalPreferenceManagerImpl::HasPreference(const CefString& name) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
@@ -40,6 +58,77 @@ bool CefGlobalPreferenceManagerImpl::SetPreference(const CefString& name,
|
||||
value, error);
|
||||
}
|
||||
|
||||
CefRefPtr<CefRegistration>
|
||||
CefGlobalPreferenceManagerImpl::AddPreferenceObserver(
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer) {
|
||||
CEF_API_REQUIRE_ADDED(CEF_NEXT);
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
return CefContext::Get()->GetPrefRegistrar()->AddObserver(name, observer);
|
||||
}
|
||||
|
||||
// static
|
||||
void CefPreferenceManager::GetChromeVariationsAsSwitches(
|
||||
std::vector<CefString>& switches) {
|
||||
CEF_API_REQUIRE_ADDED(CEF_NEXT);
|
||||
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
DCHECK(false) << "context not valid";
|
||||
return;
|
||||
}
|
||||
|
||||
switches.clear();
|
||||
|
||||
// Based on ChromeFeatureListCreator::ConvertFlagsToSwitches().
|
||||
|
||||
flags_ui::PrefServiceFlagsStorage flags_storage(
|
||||
g_browser_process->local_state());
|
||||
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
|
||||
about_flags::ConvertFlagsToSwitches(&flags_storage, &command_line,
|
||||
flags_ui::kNoSentinels);
|
||||
|
||||
for (const auto& arg : command_line.argv()) {
|
||||
if (!arg.empty()) {
|
||||
switches.push_back(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void CefPreferenceManager::GetChromeVariationsAsStrings(
|
||||
std::vector<CefString>& strings) {
|
||||
CEF_API_REQUIRE_ADDED(CEF_NEXT);
|
||||
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
DCHECK(false) << "context not valid";
|
||||
return;
|
||||
}
|
||||
|
||||
strings.clear();
|
||||
|
||||
// Based on components/webui/version/version_handler_helper.cc
|
||||
// GetVariationsList().
|
||||
|
||||
base::FieldTrial::ActiveGroups active_groups;
|
||||
// Include low anonymity trial groups in the version string, as it is only
|
||||
// displayed locally (and is useful for diagnostics purposes).
|
||||
base::FieldTrialListIncludingLowAnonymity::
|
||||
GetActiveFieldTrialGroupsForTesting(&active_groups);
|
||||
|
||||
for (const auto& group : active_groups) {
|
||||
strings.push_back(GetActiveGroupNameAsString(group));
|
||||
}
|
||||
|
||||
// Synthetic field trials.
|
||||
for (const auto& group :
|
||||
variations::SyntheticTrialsActiveGroupIdProvider::GetInstance()
|
||||
->GetGroups()) {
|
||||
strings.push_back(GetActiveGroupNameAsString(group.active_group()));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefPreferenceManager>
|
||||
CefPreferenceManager::GetGlobalPreferenceManager() {
|
||||
|
@@ -27,6 +27,9 @@ class CefGlobalPreferenceManagerImpl : public CefPreferenceManager {
|
||||
bool SetPreference(const CefString& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
CefString& error) override;
|
||||
CefRefPtr<CefRegistration> AddPreferenceObserver(
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer) override;
|
||||
|
||||
private:
|
||||
IMPLEMENT_REFCOUNTING(CefGlobalPreferenceManagerImpl);
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "base/notreached.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "cef/include/cef_preference.h"
|
||||
#include "cef/libcef/browser/thread_util.h"
|
||||
#include "cef/libcef/common/values_impl.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
@@ -118,4 +119,145 @@ bool SetPreference(PrefService* pref_service,
|
||||
return true;
|
||||
}
|
||||
|
||||
class RegistrationImpl final : public Registration, public CefRegistration {
|
||||
public:
|
||||
RegistrationImpl(Registrar* registrar,
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer)
|
||||
: registrar_(registrar), name_(name), observer_(observer) {
|
||||
DCHECK(registrar_);
|
||||
DCHECK(observer_);
|
||||
}
|
||||
|
||||
RegistrationImpl(const RegistrationImpl&) = delete;
|
||||
RegistrationImpl& operator=(const RegistrationImpl&) = delete;
|
||||
|
||||
~RegistrationImpl() override {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (registrar_) {
|
||||
registrar_->RemoveObserver(name_.ToString(), this);
|
||||
}
|
||||
}
|
||||
|
||||
void Detach() override {
|
||||
registrar_ = nullptr;
|
||||
observer_ = nullptr;
|
||||
}
|
||||
|
||||
void RunCallback() const override { RunCallback(name_); }
|
||||
|
||||
void RunCallback(const CefString& name) const override {
|
||||
observer_->OnPreferenceChanged(name);
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<Registrar> registrar_;
|
||||
CefString name_;
|
||||
CefRefPtr<CefPreferenceObserver> observer_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(RegistrationImpl);
|
||||
};
|
||||
|
||||
Registrar::~Registrar() {
|
||||
RemoveAll();
|
||||
}
|
||||
|
||||
void Registrar::Init(PrefService* service) {
|
||||
DCHECK(service);
|
||||
DCHECK(IsEmpty() || service_ == service);
|
||||
service_ = service;
|
||||
}
|
||||
|
||||
void Registrar::Reset() {
|
||||
RemoveAll();
|
||||
service_ = nullptr;
|
||||
}
|
||||
|
||||
void Registrar::RemoveAll() {
|
||||
if (!name_observers_.empty()) {
|
||||
for (auto& [name, registrations] : name_observers_) {
|
||||
service_->RemovePrefObserver(name, this);
|
||||
for (auto& registration : registrations) {
|
||||
registration.Detach();
|
||||
}
|
||||
}
|
||||
name_observers_.clear();
|
||||
}
|
||||
|
||||
if (!all_observers_.empty()) {
|
||||
service_->RemovePrefObserverAllPrefs(this);
|
||||
for (auto& registration : all_observers_) {
|
||||
registration.Detach();
|
||||
}
|
||||
all_observers_.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool Registrar::IsEmpty() const {
|
||||
return name_observers_.empty() && all_observers_.empty();
|
||||
}
|
||||
|
||||
CefRefPtr<CefRegistration> Registrar::AddObserver(
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer) {
|
||||
CHECK(service_);
|
||||
|
||||
RegistrationImpl* impl = new RegistrationImpl(this, name, observer);
|
||||
|
||||
if (name.empty()) {
|
||||
if (all_observers_.empty()) {
|
||||
service_->AddPrefObserverAllPrefs(this);
|
||||
}
|
||||
all_observers_.AddObserver(impl);
|
||||
} else {
|
||||
const std::string& name_str = name.ToString();
|
||||
if (!name_observers_.contains(name_str)) {
|
||||
service_->AddPrefObserver(name_str, this);
|
||||
}
|
||||
name_observers_[name_str].AddObserver(impl);
|
||||
}
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
void Registrar::RemoveObserver(std::string_view name,
|
||||
Registration* registration) {
|
||||
CHECK(service_);
|
||||
|
||||
if (name.empty()) {
|
||||
all_observers_.RemoveObserver(registration);
|
||||
if (all_observers_.empty()) {
|
||||
service_->RemovePrefObserverAllPrefs(this);
|
||||
}
|
||||
} else {
|
||||
auto it = name_observers_.find(std::string(name));
|
||||
DCHECK(it != name_observers_.end());
|
||||
it->second.RemoveObserver(registration);
|
||||
if (it->second.empty()) {
|
||||
name_observers_.erase(it);
|
||||
service_->RemovePrefObserver(name, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Registrar::OnPreferenceChanged(PrefService* service,
|
||||
std::string_view pref_name) {
|
||||
std::string pref_name_str(pref_name);
|
||||
if (!name_observers_.empty()) {
|
||||
auto it = name_observers_.find(pref_name_str);
|
||||
if (it != name_observers_.end()) {
|
||||
for (Registration& registration : it->second) {
|
||||
registration.RunCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!all_observers_.empty()) {
|
||||
CefString name_str(pref_name_str);
|
||||
for (Registration& registration : all_observers_) {
|
||||
registration.RunCallback(name_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pref_helper
|
||||
|
@@ -5,8 +5,16 @@
|
||||
#ifndef CEF_LIBCEF_BROWSER_PREFS_PREF_HELPER_H_
|
||||
#define CEF_LIBCEF_BROWSER_PREFS_PREF_HELPER_H_
|
||||
|
||||
#include "cef/include/cef_values.h"
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "cef/include/cef_registration.h"
|
||||
#include "cef/include/cef_values.h"
|
||||
#include "components/prefs/pref_observer.h"
|
||||
|
||||
class CefPreferenceObserver;
|
||||
class CefRegistration;
|
||||
class PrefService;
|
||||
|
||||
namespace pref_helper {
|
||||
@@ -28,6 +36,69 @@ bool SetPreference(PrefService* pref_service,
|
||||
CefRefPtr<CefValue> value,
|
||||
CefString& error);
|
||||
|
||||
class Registration : public base::CheckedObserver {
|
||||
public:
|
||||
virtual void Detach() = 0;
|
||||
virtual void RunCallback() const = 0;
|
||||
virtual void RunCallback(const CefString& name) const = 0;
|
||||
};
|
||||
|
||||
class RegistrationImpl;
|
||||
|
||||
// Automatically manages the registration of one or more CefPreferenceObserver
|
||||
// objects with a PrefService. When the Registrar is destroyed, all registered
|
||||
// observers are automatically unregistered with the PrefService. Loosely based
|
||||
// on PrefChangeRegistrar.
|
||||
class Registrar final : public PrefObserver {
|
||||
public:
|
||||
Registrar() = default;
|
||||
|
||||
Registrar(const Registrar&) = delete;
|
||||
Registrar& operator=(const Registrar&) = delete;
|
||||
|
||||
~Registrar();
|
||||
|
||||
// Must be called before adding or removing observers. Can be called more
|
||||
// than once as long as the value of |service| doesn't change.
|
||||
void Init(PrefService* service);
|
||||
|
||||
// Removes all observers and clears the reference to the PrefService.
|
||||
// `Init` must be called before adding or removing any observers.
|
||||
void Reset();
|
||||
|
||||
// Removes all observers that have been previously added with a call to Add.
|
||||
void RemoveAll();
|
||||
|
||||
// Returns true if no observers are registered.
|
||||
bool IsEmpty() const;
|
||||
|
||||
// Adds a pref |observer| for the specified pref |name|. All registered
|
||||
// observers will be automatically unregistered and detached when the
|
||||
// Registrar's destructor is called.
|
||||
CefRefPtr<CefRegistration> AddObserver(
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer);
|
||||
|
||||
private:
|
||||
friend class RegistrationImpl;
|
||||
|
||||
void RemoveObserver(std::string_view name, Registration* registration);
|
||||
|
||||
// PrefObserver:
|
||||
void OnPreferenceChanged(PrefService* service,
|
||||
std::string_view pref_name) override;
|
||||
|
||||
raw_ptr<PrefService, AcrossTasksDanglingUntriaged> service_ = nullptr;
|
||||
|
||||
// Observers registered for a preference by name.
|
||||
using ObserverMap =
|
||||
std::unordered_map<std::string, base::ObserverList<Registration>>;
|
||||
ObserverMap name_observers_;
|
||||
|
||||
// Observers registered for all preferences.
|
||||
base::ObserverList<Registration> all_observers_;
|
||||
};
|
||||
|
||||
} // namespace pref_helper
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_PREFS_PREF_HELPER_H_
|
||||
|
@@ -10,7 +10,9 @@
|
||||
#include "cef/libcef/browser/browser_context.h"
|
||||
#include "cef/libcef/browser/context.h"
|
||||
#include "cef/libcef/browser/prefs/pref_helper.h"
|
||||
#include "cef/libcef/browser/setting_helper.h"
|
||||
#include "cef/libcef/browser/thread_util.h"
|
||||
#include "cef/libcef/common/api_version_util.h"
|
||||
#include "cef/libcef/common/app_manager.h"
|
||||
#include "cef/libcef/common/task_runner_impl.h"
|
||||
#include "cef/libcef/common/values_impl.h"
|
||||
@@ -459,6 +461,22 @@ bool CefRequestContextImpl::SetPreference(const CefString& name,
|
||||
return pref_helper::SetPreference(pref_service, name, value, error);
|
||||
}
|
||||
|
||||
CefRefPtr<CefRegistration> CefRequestContextImpl::AddPreferenceObserver(
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer) {
|
||||
CEF_API_REQUIRE_ADDED(CEF_NEXT);
|
||||
if (!VerifyBrowserContext()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!pref_registrar_) {
|
||||
pref_registrar_ = std::make_unique<pref_helper::Registrar>();
|
||||
pref_registrar_->Init(browser_context()->AsProfile()->GetPrefs());
|
||||
}
|
||||
|
||||
return pref_registrar_->AddObserver(name, observer);
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::ClearCertificateExceptions(
|
||||
CefRefPtr<CefCompletionCallback> callback) {
|
||||
GetBrowserContext(
|
||||
@@ -588,6 +606,26 @@ void CefRequestContextImpl::SetContentSetting(
|
||||
requesting_url, top_level_url, content_type, value));
|
||||
}
|
||||
|
||||
CefRefPtr<CefRegistration> CefRequestContextImpl::AddSettingObserver(
|
||||
CefRefPtr<CefSettingObserver> observer) {
|
||||
CEF_API_REQUIRE_ADDED(CEF_NEXT);
|
||||
if (!VerifyBrowserContext()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!setting_registrar_) {
|
||||
auto* settings_map = HostContentSettingsMapFactory::GetForProfile(
|
||||
browser_context()->AsProfile());
|
||||
if (!settings_map) {
|
||||
return nullptr;
|
||||
}
|
||||
setting_registrar_ = std::make_unique<setting_helper::Registrar>();
|
||||
setting_registrar_->Init(settings_map);
|
||||
}
|
||||
|
||||
return setting_registrar_->AddObserver(observer);
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::SetChromeColorScheme(cef_color_variant_t variant,
|
||||
cef_color_t user_color) {
|
||||
GetBrowserContext(
|
||||
|
@@ -17,6 +17,14 @@ namespace content {
|
||||
struct GlobalRenderFrameHostId;
|
||||
}
|
||||
|
||||
namespace pref_helper {
|
||||
class Registrar;
|
||||
}
|
||||
|
||||
namespace setting_helper {
|
||||
class Registrar;
|
||||
}
|
||||
|
||||
class CefBrowserContext;
|
||||
|
||||
// Implementation of the CefRequestContext interface. All methods are thread-
|
||||
@@ -80,6 +88,20 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
BrowserContextCallback callback);
|
||||
|
||||
// CefPreferenceManager methods.
|
||||
bool HasPreference(const CefString& name) override;
|
||||
CefRefPtr<CefValue> GetPreference(const CefString& name) override;
|
||||
CefRefPtr<CefDictionaryValue> GetAllPreferences(
|
||||
bool include_defaults) override;
|
||||
bool CanSetPreference(const CefString& name) override;
|
||||
bool SetPreference(const CefString& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
CefString& error) override;
|
||||
CefRefPtr<CefRegistration> AddPreferenceObserver(
|
||||
const CefString& name,
|
||||
CefRefPtr<CefPreferenceObserver> observer) override;
|
||||
|
||||
// CefRequestContext methods.
|
||||
bool IsSame(CefRefPtr<CefRequestContext> other) override;
|
||||
bool IsSharingWith(CefRefPtr<CefRequestContext> other) override;
|
||||
bool IsGlobal() override;
|
||||
@@ -92,14 +114,6 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
const CefString& domain_name,
|
||||
CefRefPtr<CefSchemeHandlerFactory> factory) override;
|
||||
bool ClearSchemeHandlerFactories() override;
|
||||
bool HasPreference(const CefString& name) override;
|
||||
CefRefPtr<CefValue> GetPreference(const CefString& name) override;
|
||||
CefRefPtr<CefDictionaryValue> GetAllPreferences(
|
||||
bool include_defaults) override;
|
||||
bool CanSetPreference(const CefString& name) override;
|
||||
bool SetPreference(const CefString& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
CefString& error) override;
|
||||
void ClearCertificateExceptions(
|
||||
CefRefPtr<CefCompletionCallback> callback) override;
|
||||
void ClearHttpAuthCredentials(
|
||||
@@ -125,6 +139,8 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
const CefString& top_level_url,
|
||||
cef_content_setting_types_t content_type,
|
||||
cef_content_setting_values_t value) override;
|
||||
CefRefPtr<CefRegistration> AddSettingObserver(
|
||||
CefRefPtr<CefSettingObserver> observer) override;
|
||||
void SetChromeColorScheme(cef_color_variant_t variant,
|
||||
cef_color_t user_color) override;
|
||||
cef_color_variant_t GetChromeColorSchemeMode() override;
|
||||
@@ -218,6 +234,9 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
|
||||
Config config_;
|
||||
|
||||
std::unique_ptr<pref_helper::Registrar> pref_registrar_;
|
||||
std::unique_ptr<setting_helper::Registrar> setting_registrar_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefRequestContextImpl);
|
||||
};
|
||||
|
||||
|
118
libcef/browser/setting_helper.cc
Normal file
118
libcef/browser/setting_helper.cc
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#include "cef/libcef/browser/setting_helper.h"
|
||||
|
||||
#include "cef/include/cef_request_context.h"
|
||||
#include "cef/libcef/browser/thread_util.h"
|
||||
#include "components/content_settings/core/browser/host_content_settings_map.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace setting_helper {
|
||||
|
||||
class RegistrationImpl final : public Registration, public CefRegistration {
|
||||
public:
|
||||
RegistrationImpl(Registrar* registrar, CefRefPtr<CefSettingObserver> observer)
|
||||
: registrar_(registrar), observer_(observer) {
|
||||
DCHECK(registrar_);
|
||||
DCHECK(observer_);
|
||||
}
|
||||
|
||||
RegistrationImpl(const RegistrationImpl&) = delete;
|
||||
RegistrationImpl& operator=(const RegistrationImpl&) = delete;
|
||||
|
||||
~RegistrationImpl() override {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (registrar_) {
|
||||
registrar_->RemoveObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Detach() override {
|
||||
registrar_ = nullptr;
|
||||
observer_ = nullptr;
|
||||
}
|
||||
|
||||
void RunCallback(const CefString& requesting_url,
|
||||
const CefString& top_level_url,
|
||||
cef_content_setting_types_t content_type) const override {
|
||||
observer_->OnSettingChanged(requesting_url, top_level_url, content_type);
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<Registrar> registrar_;
|
||||
CefRefPtr<CefSettingObserver> observer_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(RegistrationImpl);
|
||||
};
|
||||
|
||||
Registrar::~Registrar() {
|
||||
RemoveAll();
|
||||
}
|
||||
|
||||
void Registrar::Init(HostContentSettingsMap* settings) {
|
||||
DCHECK(settings);
|
||||
DCHECK(IsEmpty() || settings_ == settings);
|
||||
settings_ = settings;
|
||||
}
|
||||
|
||||
void Registrar::Reset() {
|
||||
RemoveAll();
|
||||
settings_ = nullptr;
|
||||
}
|
||||
|
||||
void Registrar::RemoveAll() {
|
||||
if (!observers_.empty()) {
|
||||
settings_->RemoveObserver(this);
|
||||
for (auto& registration : observers_) {
|
||||
registration.Detach();
|
||||
}
|
||||
observers_.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool Registrar::IsEmpty() const {
|
||||
return observers_.empty();
|
||||
}
|
||||
|
||||
CefRefPtr<CefRegistration> Registrar::AddObserver(
|
||||
CefRefPtr<CefSettingObserver> observer) {
|
||||
CHECK(settings_);
|
||||
|
||||
RegistrationImpl* impl = new RegistrationImpl(this, observer);
|
||||
|
||||
if (observers_.empty()) {
|
||||
settings_->AddObserver(this);
|
||||
}
|
||||
observers_.AddObserver(impl);
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
void Registrar::RemoveObserver(Registration* registration) {
|
||||
CHECK(settings_);
|
||||
|
||||
observers_.RemoveObserver(registration);
|
||||
if (observers_.empty()) {
|
||||
settings_->RemoveObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Registrar::OnContentSettingChanged(
|
||||
const ContentSettingsPattern& primary_pattern,
|
||||
const ContentSettingsPattern& secondary_pattern,
|
||||
ContentSettingsTypeSet content_type_set) {
|
||||
DCHECK(!IsEmpty());
|
||||
|
||||
const CefString requesting_url(primary_pattern.ToRepresentativeUrl().spec());
|
||||
const CefString top_level_url(secondary_pattern.ToRepresentativeUrl().spec());
|
||||
const auto content_type =
|
||||
static_cast<cef_content_setting_types_t>(content_type_set.GetType());
|
||||
|
||||
for (Registration& registration : observers_) {
|
||||
registration.RunCallback(requesting_url, top_level_url, content_type);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace setting_helper
|
81
libcef/browser/setting_helper.h
Normal file
81
libcef/browser/setting_helper.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_SETTING_HELPER_H_
|
||||
#define CEF_LIBCEF_BROWSER_SETTING_HELPER_H_
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "cef/include/cef_registration.h"
|
||||
#include "components/content_settings/core/browser/content_settings_observer.h"
|
||||
|
||||
class CefSettingObserver;
|
||||
class CefRegistration;
|
||||
class HostContentSettingsMap;
|
||||
|
||||
namespace setting_helper {
|
||||
|
||||
class Registration : public base::CheckedObserver {
|
||||
public:
|
||||
virtual void Detach() = 0;
|
||||
virtual void RunCallback(const CefString& requesting_url,
|
||||
const CefString& top_level_url,
|
||||
cef_content_setting_types_t content_type) const = 0;
|
||||
};
|
||||
|
||||
class RegistrationImpl;
|
||||
|
||||
// Automatically manages the registration of one or more CefSettingObserver
|
||||
// objects with a HostContentSettingsMap. When the Registrar is destroyed, all
|
||||
// registered observers are automatically unregistered with the
|
||||
// HostContentSettingsMap. Loosely based on PrefChangeRegistrar.
|
||||
class Registrar final : public content_settings::Observer {
|
||||
public:
|
||||
Registrar() = default;
|
||||
|
||||
Registrar(const Registrar&) = delete;
|
||||
Registrar& operator=(const Registrar&) = delete;
|
||||
|
||||
~Registrar();
|
||||
|
||||
// Must be called before adding or removing observers. Can be called more
|
||||
// than once as long as the value of |settings| doesn't change.
|
||||
void Init(HostContentSettingsMap* settings);
|
||||
|
||||
// Removes all observers and clears the reference to the
|
||||
// HostContentSettingsMap. `Init` must be called before adding or removing any
|
||||
// observers.
|
||||
void Reset();
|
||||
|
||||
// Removes all observers that have been previously added with a call to Add.
|
||||
void RemoveAll();
|
||||
|
||||
// Returns true if no observers are registered.
|
||||
bool IsEmpty() const;
|
||||
|
||||
// Adds a setting observer. All registered observers will be automatically
|
||||
// unregistered and detached when the Registrar's destructor is called.
|
||||
CefRefPtr<CefRegistration> AddObserver(
|
||||
CefRefPtr<CefSettingObserver> observer);
|
||||
|
||||
private:
|
||||
friend class RegistrationImpl;
|
||||
|
||||
void RemoveObserver(Registration* registration);
|
||||
|
||||
// content_settings::Observer:
|
||||
void OnContentSettingChanged(
|
||||
const ContentSettingsPattern& primary_pattern,
|
||||
const ContentSettingsPattern& secondary_pattern,
|
||||
ContentSettingsTypeSet content_type_set) override;
|
||||
|
||||
raw_ptr<HostContentSettingsMap, AcrossTasksDanglingUntriaged> settings_ =
|
||||
nullptr;
|
||||
|
||||
base::ObserverList<Registration> observers_;
|
||||
};
|
||||
|
||||
} // namespace setting_helper
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_SETTING_HELPER_H_
|
Reference in New Issue
Block a user