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:
@@ -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_
|
||||
|
Reference in New Issue
Block a user