mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-16 20:20:51 +01:00
Support configuration of preferences during runtime (issue #1709)
- Preferences are now associated with a CefRequestContext instead of being stored globally. - Add methods to CefRequestContext for getting/setting preferences.
This commit is contained in:
parent
2328b9be39
commit
5780ea8baa
2
cef.gyp
2
cef.gyp
@ -428,6 +428,7 @@
|
||||
'tests/unittests/os_rendering_unittest.cc',
|
||||
'tests/unittests/parser_unittest.cc',
|
||||
'tests/unittests/plugin_unittest.cc',
|
||||
'tests/unittests/preference_unittest.cc',
|
||||
'tests/unittests/print_unittest.cc',
|
||||
'tests/unittests/process_message_unittest.cc',
|
||||
'tests/unittests/request_context_unittest.cc',
|
||||
@ -1798,6 +1799,7 @@
|
||||
'tests/unittests/message_router_unittest.cc',
|
||||
'tests/unittests/navigation_unittest.cc',
|
||||
'tests/unittests/plugin_unittest.cc',
|
||||
'tests/unittests/preference_unittest.cc',
|
||||
'tests/unittests/process_message_unittest.cc',
|
||||
'tests/unittests/request_handler_unittest.cc',
|
||||
'tests/unittests/request_unittest.cc',
|
||||
|
@ -171,6 +171,8 @@
|
||||
'tests/cefclient/browser/osr_dragdrop_events.h',
|
||||
'tests/cefclient/browser/osr_renderer.h',
|
||||
'tests/cefclient/browser/osr_renderer.cc',
|
||||
'tests/cefclient/browser/preferences_test.cc',
|
||||
'tests/cefclient/browser/preferences_test.h',
|
||||
'tests/cefclient/browser/resource.h',
|
||||
'tests/cefclient/browser/resource_util.h',
|
||||
'tests/cefclient/browser/root_window.cc',
|
||||
@ -220,6 +222,7 @@
|
||||
'tests/cefclient/resources/pdf.pdf',
|
||||
'tests/cefclient/resources/performance.html',
|
||||
'tests/cefclient/resources/performance2.html',
|
||||
'tests/cefclient/resources/preferences.html',
|
||||
'tests/cefclient/resources/transparency.html',
|
||||
'tests/cefclient/resources/urlrequest.html',
|
||||
'tests/cefclient/resources/window.html',
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "include/capi/cef_cookie_capi.h"
|
||||
#include "include/capi/cef_request_context_handler_capi.h"
|
||||
#include "include/capi/cef_values_capi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -150,6 +151,54 @@ typedef struct _cef_request_context_t {
|
||||
///
|
||||
void (CEF_CALLBACK *purge_plugin_list_cache)(
|
||||
struct _cef_request_context_t* self, int reload_pages);
|
||||
|
||||
///
|
||||
// Returns true (1) if a preference with the specified |name| exists. This
|
||||
// function must be called on the browser process UI thread.
|
||||
///
|
||||
int (CEF_CALLBACK *has_preference)(struct _cef_request_context_t* self,
|
||||
const cef_string_t* name);
|
||||
|
||||
///
|
||||
// Returns the value for the preference with the specified |name|. Returns
|
||||
// NULL if the preference does not exist. The returned object contains a copy
|
||||
// of the underlying preference value and modifications to the returned object
|
||||
// will not modify the underlying preference value. This function must be
|
||||
// called on the browser process UI thread.
|
||||
///
|
||||
struct _cef_value_t* (CEF_CALLBACK *get_preference)(
|
||||
struct _cef_request_context_t* self, const cef_string_t* name);
|
||||
|
||||
///
|
||||
// Returns all preferences as a dictionary. If |include_defaults| is true (1)
|
||||
// then preferences currently at their default value will be included. The
|
||||
// returned object contains a copy of the underlying preference values and
|
||||
// modifications to the returned object will not modify the underlying
|
||||
// preference values. This function must be called on the browser process UI
|
||||
// thread.
|
||||
///
|
||||
struct _cef_dictionary_value_t* (CEF_CALLBACK *get_all_preferences)(
|
||||
struct _cef_request_context_t* self, int include_defaults);
|
||||
|
||||
///
|
||||
// Returns true (1) if the preference with the specified |name| can be
|
||||
// modified using SetPreference. As one example preferences set via the
|
||||
// command-line usually cannot be modified. This function must be called on
|
||||
// the browser process UI thread.
|
||||
///
|
||||
int (CEF_CALLBACK *can_set_preference)(struct _cef_request_context_t* self,
|
||||
const cef_string_t* name);
|
||||
|
||||
///
|
||||
// Set the |value| associated with preference |name|. Returns true (1) if the
|
||||
// value is set successfully and false (0) otherwise. If |value| is NULL the
|
||||
// preference will be restored to its default value. If setting the preference
|
||||
// fails then |error| will be populated with a detailed description of the
|
||||
// problem. This function must be called on the browser process UI thread.
|
||||
///
|
||||
int (CEF_CALLBACK *set_preference)(struct _cef_request_context_t* self,
|
||||
const cef_string_t* name, struct _cef_value_t* value,
|
||||
cef_string_t* error);
|
||||
} cef_request_context_t;
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "include/cef_cookie.h"
|
||||
#include "include/cef_request_context_handler.h"
|
||||
#include "include/cef_values.h"
|
||||
|
||||
class CefSchemeHandlerFactory;
|
||||
|
||||
@ -166,6 +167,56 @@ class CefRequestContext : public virtual CefBase {
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void PurgePluginListCache(bool reload_pages) =0;
|
||||
|
||||
///
|
||||
// Returns true if a preference with the specified |name| exists. This method
|
||||
// must be called on the browser process UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool HasPreference(const CefString& name) =0;
|
||||
|
||||
///
|
||||
// Returns the value for the preference with the specified |name|. Returns
|
||||
// NULL if the preference does not exist. The returned object contains a copy
|
||||
// of the underlying preference value and modifications to the returned object
|
||||
// will not modify the underlying preference value. This method must be called
|
||||
// on the browser process UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual CefRefPtr<CefValue> GetPreference(const CefString& name) =0;
|
||||
|
||||
///
|
||||
// Returns all preferences as a dictionary. If |include_defaults| is true then
|
||||
// preferences currently at their default value will be included. The returned
|
||||
// object contains a copy of the underlying preference values and
|
||||
// modifications to the returned object will not modify the underlying
|
||||
// preference values. This method must be called on the browser process UI
|
||||
// thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual CefRefPtr<CefDictionaryValue> GetAllPreferences(
|
||||
bool include_defaults) =0;
|
||||
|
||||
///
|
||||
// Returns true if the preference with the specified |name| can be modified
|
||||
// using SetPreference. As one example preferences set via the command-line
|
||||
// usually cannot be modified. This method must be called on the browser
|
||||
// process UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool CanSetPreference(const CefString& name) =0;
|
||||
|
||||
///
|
||||
// Set the |value| associated with preference |name|. Returns true if the
|
||||
// value is set successfully and false otherwise. If |value| is NULL the
|
||||
// preference will be restored to its default value. If setting the preference
|
||||
// fails then |error| will be populated with a detailed description of the
|
||||
// problem. This method must be called on the browser process UI thread.
|
||||
///
|
||||
/*--cef(optional_param=value)--*/
|
||||
virtual bool SetPreference(const CefString& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
CefString& error) =0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <map>
|
||||
|
||||
#include "libcef/browser/browser_context_proxy.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/download_manager_delegate.h"
|
||||
#include "libcef/browser/permission_manager.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/net/proxy_service_factory.h"
|
||||
@ -166,6 +166,11 @@ void CefBrowserContextImpl::Initialize() {
|
||||
CefString(&CefContext::Get()->settings().accept_language_list);
|
||||
}
|
||||
|
||||
// Initialize user preferences.
|
||||
pref_store_ = new CefBrowserPrefStore();
|
||||
pref_store_->SetInitializationCompleted();
|
||||
pref_service_ = pref_store_->CreateService().Pass();
|
||||
|
||||
CefBrowserContext::Initialize();
|
||||
|
||||
// Initialize proxy configuration tracker.
|
||||
@ -378,6 +383,5 @@ HostContentSettingsMap* CefBrowserContextImpl::GetHostContentSettingsMap() {
|
||||
}
|
||||
|
||||
PrefService* CefBrowserContextImpl::GetPrefs() {
|
||||
// TODO(cef): Perhaps use per-context settings.
|
||||
return CefContentBrowserClient::Get()->pref_service();
|
||||
return pref_service_.get();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "libcef/browser/browser_context.h"
|
||||
|
||||
#include "libcef/browser/browser_pref_store.h"
|
||||
#include "libcef/browser/url_request_context_getter_impl.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
@ -111,6 +112,8 @@ class CefBrowserContextImpl : public CefBrowserContext {
|
||||
typedef std::vector<const CefBrowserContextProxy*> ProxyList;
|
||||
ProxyList proxy_list_;
|
||||
|
||||
scoped_refptr<CefBrowserPrefStore> pref_store_;
|
||||
scoped_ptr<PrefService> pref_service_;
|
||||
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
|
||||
|
||||
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
|
||||
|
@ -122,11 +122,6 @@ int CefBrowserMainParts::PreCreateThreads() {
|
||||
views::CreateDesktopScreen());
|
||||
#endif
|
||||
|
||||
// Initialize user preferences.
|
||||
pref_store_ = new CefBrowserPrefStore();
|
||||
pref_store_->SetInitializationCompleted();
|
||||
pref_service_ = pref_store_->CreateService().Pass();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define CEF_LIBCEF_BROWSER_BROWSER_MAIN_H_
|
||||
#pragma once
|
||||
|
||||
#include "libcef/browser/browser_pref_store.h"
|
||||
#include "libcef/browser/browser_context_impl.h"
|
||||
#include "libcef/browser/url_request_context_getter_impl.h"
|
||||
|
||||
@ -54,7 +53,6 @@ class CefBrowserMainParts : public content::BrowserMainParts {
|
||||
CefDevToolsDelegate* devtools_delegate() const {
|
||||
return devtools_delegate_;
|
||||
}
|
||||
PrefService* pref_service() const { return pref_service_.get(); }
|
||||
|
||||
private:
|
||||
#if defined(OS_WIN)
|
||||
@ -65,8 +63,6 @@ class CefBrowserMainParts : public content::BrowserMainParts {
|
||||
scoped_refptr<CefBrowserContextImpl> global_browser_context_;
|
||||
CefDevToolsDelegate* devtools_delegate_; // Deletes itself.
|
||||
scoped_ptr<base::MessageLoop> message_loop_;
|
||||
scoped_refptr<CefBrowserPrefStore> pref_store_;
|
||||
scoped_ptr<PrefService> pref_service_;
|
||||
|
||||
scoped_ptr<extensions::ExtensionsClient> extensions_client_;
|
||||
scoped_ptr<extensions::ExtensionsBrowserClient> extensions_browser_client_;
|
||||
|
@ -129,6 +129,16 @@ scoped_ptr<PrefService> CefBrowserPrefStore::CreateService() {
|
||||
registry->RegisterBooleanPref(prefs::kPluginsAllowOutdated, false);
|
||||
registry->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize, false);
|
||||
|
||||
if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) {
|
||||
// Register preferences used with unit tests.
|
||||
registry->RegisterBooleanPref("test.bool", true);
|
||||
registry->RegisterIntegerPref("test.int", 2);
|
||||
registry->RegisterDoublePref("test.double", 5.0);
|
||||
registry->RegisterStringPref("test.string", "default");
|
||||
registry->RegisterListPref("test.list");
|
||||
registry->RegisterDictionaryPref("test.dict");
|
||||
}
|
||||
|
||||
return factory.Create(registry.get());
|
||||
}
|
||||
|
||||
|
@ -1034,10 +1034,6 @@ CefDevToolsDelegate* CefContentBrowserClient::devtools_delegate() const {
|
||||
return browser_main_parts_->devtools_delegate();
|
||||
}
|
||||
|
||||
PrefService* CefContentBrowserClient::pref_service() const {
|
||||
return browser_main_parts_->pref_service();
|
||||
}
|
||||
|
||||
// static
|
||||
SkColor CefContentBrowserClient::GetBaseBackgroundColor(
|
||||
CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
|
@ -29,7 +29,6 @@ class CefBrowserInfo;
|
||||
class CefBrowserMainParts;
|
||||
class CefDevToolsDelegate;
|
||||
class CefResourceDispatcherHostDelegate;
|
||||
class PrefService;
|
||||
|
||||
namespace content {
|
||||
class PluginServiceFilter;
|
||||
@ -167,7 +166,6 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
||||
|
||||
scoped_refptr<CefBrowserContextImpl> browser_context() const;
|
||||
CefDevToolsDelegate* devtools_delegate() const;
|
||||
PrefService* pref_service() const;
|
||||
|
||||
private:
|
||||
static SkColor GetBaseBackgroundColor(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
|
@ -124,7 +124,7 @@ bool CefExtensionsBrowserClient::AllowCrossRendererResourceLoad(
|
||||
|
||||
PrefService* CefExtensionsBrowserClient::GetPrefServiceForContext(
|
||||
BrowserContext* context) {
|
||||
return CefBrowserContextImpl::GetForContext(context)->GetPrefs();
|
||||
return static_cast<CefBrowserContext*>(context)->GetPrefs();
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::GetEarlyExtensionPrefsObservers(
|
||||
|
@ -182,8 +182,8 @@ CefPluginInfoMessageFilter::CefPluginInfoMessageFilter(
|
||||
int render_process_id,
|
||||
CefBrowserContext* profile)
|
||||
: BrowserMessageFilter(ExtensionMsgStart),
|
||||
context_(render_process_id, profile),
|
||||
browser_context_(profile),
|
||||
context_(render_process_id, profile),
|
||||
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
||||
weak_ptr_factory_(this) {
|
||||
}
|
||||
|
@ -121,8 +121,12 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter {
|
||||
std::vector<base::string16>* additional_param_values);
|
||||
#endif
|
||||
|
||||
scoped_refptr<CefBrowserContext> browser_context_;
|
||||
|
||||
// Members will be destroyed in reverse order of declaration. Due to Context
|
||||
// depending on the PrefService owned by CefBrowserContext the Context object
|
||||
// must be destroyed before the CefBrowserContext object.
|
||||
Context context_;
|
||||
CefBrowserContext* browser_context_;
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
|
||||
base::WeakPtrFactory<CefPluginInfoMessageFilter> weak_ptr_factory_;
|
||||
|
@ -47,9 +47,12 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
||||
#if !defined(OS_MACOSX)
|
||||
expecting_first_page_ = true;
|
||||
#endif // OS_MACOSX
|
||||
PrefService* pref_service =
|
||||
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext())->
|
||||
GetPrefs();
|
||||
printing_enabled_.Init(
|
||||
prefs::kPrintingEnabled,
|
||||
CefContentBrowserClient::Get()->pref_service(),
|
||||
pref_service,
|
||||
base::Bind(&PrintViewManagerBase::UpdateScriptedPrintingBlocked,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
@ -9,9 +9,12 @@
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/cookie_manager_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/values_impl.h"
|
||||
|
||||
#include "base/atomic_sequence_num.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
@ -20,6 +23,30 @@ namespace {
|
||||
|
||||
base::StaticAtomicSequenceNumber g_next_id;
|
||||
|
||||
const char* GetTypeString(base::Value::Type type) {
|
||||
switch (type) {
|
||||
case base::Value::TYPE_NULL:
|
||||
return "NULL";
|
||||
case base::Value::TYPE_BOOLEAN:
|
||||
return "BOOLEAN";
|
||||
case base::Value::TYPE_INTEGER:
|
||||
return "INTEGER";
|
||||
case base::Value::TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case base::Value::TYPE_STRING:
|
||||
return "STRING";
|
||||
case base::Value::TYPE_BINARY:
|
||||
return "BINARY";
|
||||
case base::Value::TYPE_DICTIONARY:
|
||||
return "DICTIONARY";
|
||||
case base::Value::TYPE_LIST:
|
||||
return "LIST";
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -292,6 +319,131 @@ void CefRequestContextImpl::PurgePluginListCache(bool reload_pages) {
|
||||
this, reload_pages));
|
||||
}
|
||||
|
||||
bool CefRequestContextImpl::HasPreference(const CefString& name) {
|
||||
// Verify that this method is being called on the UI thread.
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the browser context exists.
|
||||
EnsureBrowserContext();
|
||||
|
||||
PrefService* pref_service = browser_context_->GetPrefs();
|
||||
return (pref_service->FindPreference(name) != NULL);
|
||||
}
|
||||
|
||||
CefRefPtr<CefValue> CefRequestContextImpl::GetPreference(
|
||||
const CefString& name) {
|
||||
// Verify that this method is being called on the UI thread.
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure the browser context exists.
|
||||
EnsureBrowserContext();
|
||||
|
||||
PrefService* pref_service = browser_context_->GetPrefs();
|
||||
const PrefService::Preference* pref = pref_service->FindPreference(name);
|
||||
if (!pref)
|
||||
return NULL;
|
||||
return new CefValueImpl(pref->GetValue()->DeepCopy());
|
||||
}
|
||||
|
||||
CefRefPtr<CefDictionaryValue> CefRequestContextImpl::GetAllPreferences(
|
||||
bool include_defaults) {
|
||||
// Verify that this method is being called on the UI thread.
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure the browser context exists.
|
||||
EnsureBrowserContext();
|
||||
|
||||
PrefService* pref_service = browser_context_->GetPrefs();
|
||||
|
||||
scoped_ptr<base::DictionaryValue> values;
|
||||
if (include_defaults)
|
||||
values = pref_service->GetPreferenceValues();
|
||||
else
|
||||
values = pref_service->GetPreferenceValuesOmitDefaults();
|
||||
|
||||
// CefDictionaryValueImpl takes ownership of |values|.
|
||||
return new CefDictionaryValueImpl(values.release(), true, false);
|
||||
}
|
||||
|
||||
bool CefRequestContextImpl::CanSetPreference(const CefString& name) {
|
||||
// Verify that this method is being called on the UI thread.
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the browser context exists.
|
||||
EnsureBrowserContext();
|
||||
|
||||
PrefService* pref_service = browser_context_->GetPrefs();
|
||||
const PrefService::Preference* pref = pref_service->FindPreference(name);
|
||||
return (pref && pref->IsUserModifiable());
|
||||
}
|
||||
|
||||
bool CefRequestContextImpl::SetPreference(const CefString& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
CefString& error) {
|
||||
// Verify that this method is being called on the UI thread.
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the browser context exists.
|
||||
EnsureBrowserContext();
|
||||
|
||||
PrefService* pref_service = browser_context_->GetPrefs();
|
||||
|
||||
// The below validation logic should match PrefService::SetUserPrefValue.
|
||||
|
||||
const PrefService::Preference* pref = pref_service->FindPreference(name);
|
||||
if (!pref) {
|
||||
error = "Trying to modify an unregistered preference";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pref->IsUserModifiable()) {
|
||||
error = "Trying to modify a preference that is not user modifiable";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!value.get()) {
|
||||
// Reset the preference to its default value.
|
||||
pref_service->ClearPref(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!value->IsValid()) {
|
||||
error = "A valid value is required";
|
||||
return false;
|
||||
}
|
||||
|
||||
CefValueImpl* impl = static_cast<CefValueImpl*>(value.get());
|
||||
|
||||
CefValueImpl::ScopedLockedValue scoped_locked_value(impl);
|
||||
base::Value* impl_value = impl->GetValueUnsafe();
|
||||
|
||||
if (pref->GetType() != impl_value->GetType()) {
|
||||
error = base::StringPrintf(
|
||||
"Trying to set a preference of type %s to value of type %s",
|
||||
GetTypeString(pref->GetType()), GetTypeString(impl_value->GetType()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// PrefService will make a DeepCopy of |impl_value|.
|
||||
pref_service->Set(name, *impl_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
CefRequestContextImpl::CefRequestContextImpl(
|
||||
scoped_refptr<CefBrowserContext> browser_context)
|
||||
: browser_context_(browser_context),
|
||||
@ -319,6 +471,12 @@ CefRequestContextImpl::CefRequestContextImpl(
|
||||
request_context_impl_(NULL) {
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::EnsureBrowserContext() {
|
||||
GetBrowserContext();
|
||||
DCHECK(browser_context_.get());
|
||||
DCHECK(request_context_impl_);
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::GetBrowserContextOnUIThread(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
const BrowserContextCallback& callback) {
|
||||
@ -330,9 +488,7 @@ void CefRequestContextImpl::GetBrowserContextOnUIThread(
|
||||
}
|
||||
|
||||
// Make sure the browser context exists.
|
||||
GetBrowserContext();
|
||||
DCHECK(browser_context_.get());
|
||||
DCHECK(request_context_impl_);
|
||||
EnsureBrowserContext();
|
||||
|
||||
if (task_runner->BelongsToCurrentThread()) {
|
||||
// Execute the callback immediately.
|
||||
|
@ -61,6 +61,14 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
CefRefPtr<CefSchemeHandlerFactory> factory) override;
|
||||
bool ClearSchemeHandlerFactories() override;
|
||||
void PurgePluginListCache(bool reload_pages) 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;
|
||||
|
||||
const CefRequestContextSettings& settings() const { return settings_; }
|
||||
|
||||
@ -74,6 +82,9 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
CefRequestContextImpl(CefRefPtr<CefRequestContextImpl> other,
|
||||
CefRefPtr<CefRequestContextHandler> handler);
|
||||
|
||||
// Make sure the browser context exists. Only called on the UI thread.
|
||||
void EnsureBrowserContext();
|
||||
|
||||
void GetBrowserContextOnUIThread(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
const BrowserContextCallback& callback);
|
||||
|
@ -126,4 +126,7 @@ const char kPluginPolicy_Detect[] = "detect";
|
||||
// Block the content. The user can manually load blocked content.
|
||||
const char kPluginPolicy_Block[] = "block";
|
||||
|
||||
// Expose preferences used only by unit tests.
|
||||
const char kEnablePreferenceTesting[] = "enable-preference-testing";
|
||||
|
||||
} // namespace switches
|
||||
|
@ -52,6 +52,7 @@ extern const char kPluginPolicy[];
|
||||
extern const char kPluginPolicy_Allow[];
|
||||
extern const char kPluginPolicy_Detect[];
|
||||
extern const char kPluginPolicy_Block[];
|
||||
extern const char kEnablePreferenceTesting[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
|
@ -49,6 +49,10 @@ class CefValueImpl : public CefValue {
|
||||
bool new_read_only,
|
||||
CefValueController* new_controller);
|
||||
|
||||
// Returns a reference to the underlying data. Access must be protected by
|
||||
// calling AcquireLock/ReleaseLock.
|
||||
base::Value* GetValueUnsafe() const;
|
||||
|
||||
// CefValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
@ -104,10 +108,6 @@ class CefValueImpl : public CefValue {
|
||||
void AcquireLock();
|
||||
void ReleaseLock();
|
||||
|
||||
// Returns a reference to the underlying data. Access must be protected by
|
||||
// calling AcquireLock/ReleaseLock.
|
||||
base::Value* GetValueUnsafe() const;
|
||||
|
||||
// Access to all members must be protected by |lock_|.
|
||||
base::Lock lock_;
|
||||
|
||||
|
@ -11,7 +11,9 @@
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/cookie_manager_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/dictionary_value_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/value_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/completion_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/request_context_handler_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h"
|
||||
@ -239,6 +241,115 @@ void CEF_CALLBACK request_context_purge_plugin_list_cache(
|
||||
reload_pages?true:false);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK request_context_has_preference(
|
||||
struct _cef_request_context_t* self, const cef_string_t* name) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(name);
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefRequestContextCppToC::Get(self)->HasPreference(
|
||||
CefString(name));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
struct _cef_value_t* CEF_CALLBACK request_context_get_preference(
|
||||
struct _cef_request_context_t* self, const cef_string_t* name) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return NULL;
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(name);
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefValue> _retval = CefRequestContextCppToC::Get(
|
||||
self)->GetPreference(
|
||||
CefString(name));
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
struct _cef_dictionary_value_t* CEF_CALLBACK request_context_get_all_preferences(
|
||||
struct _cef_request_context_t* self, int include_defaults) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefDictionaryValue> _retval = CefRequestContextCppToC::Get(
|
||||
self)->GetAllPreferences(
|
||||
include_defaults?true:false);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefDictionaryValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK request_context_can_set_preference(
|
||||
struct _cef_request_context_t* self, const cef_string_t* name) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(name);
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefRequestContextCppToC::Get(self)->CanSetPreference(
|
||||
CefString(name));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK request_context_set_preference(
|
||||
struct _cef_request_context_t* self, const cef_string_t* name,
|
||||
struct _cef_value_t* value, cef_string_t* error) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(name);
|
||||
if (!name)
|
||||
return 0;
|
||||
// Verify param: error; type: string_byref
|
||||
DCHECK(error);
|
||||
if (!error)
|
||||
return 0;
|
||||
// Unverified params: value
|
||||
|
||||
// Translate param: error; type: string_byref
|
||||
CefString errorStr(error);
|
||||
|
||||
// Execute
|
||||
bool _retval = CefRequestContextCppToC::Get(self)->SetPreference(
|
||||
CefString(name),
|
||||
CefValueCppToC::Unwrap(value),
|
||||
errorStr);
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -258,6 +369,11 @@ CefRequestContextCppToC::CefRequestContextCppToC() {
|
||||
request_context_clear_scheme_handler_factories;
|
||||
GetStruct()->purge_plugin_list_cache =
|
||||
request_context_purge_plugin_list_cache;
|
||||
GetStruct()->has_preference = request_context_has_preference;
|
||||
GetStruct()->get_preference = request_context_get_preference;
|
||||
GetStruct()->get_all_preferences = request_context_get_all_preferences;
|
||||
GetStruct()->can_set_preference = request_context_can_set_preference;
|
||||
GetStruct()->set_preference = request_context_set_preference;
|
||||
}
|
||||
|
||||
template<> CefRefPtr<CefRequestContext> CefCppToC<CefRequestContextCppToC,
|
||||
|
@ -14,7 +14,9 @@
|
||||
#include "libcef_dll/cpptoc/request_context_handler_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/cookie_manager_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/dictionary_value_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/value_ctocpp.h"
|
||||
|
||||
|
||||
// STATIC METHODS - Body may be edited by hand.
|
||||
@ -222,6 +224,107 @@ void CefRequestContextCToCpp::PurgePluginListCache(bool reload_pages) {
|
||||
reload_pages);
|
||||
}
|
||||
|
||||
bool CefRequestContextCToCpp::HasPreference(const CefString& name) {
|
||||
cef_request_context_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, has_preference))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->has_preference(_struct,
|
||||
name.GetStruct());
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefValue> CefRequestContextCToCpp::GetPreference(
|
||||
const CefString& name) {
|
||||
cef_request_context_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_preference))
|
||||
return NULL;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
cef_value_t* _retval = _struct->get_preference(_struct,
|
||||
name.GetStruct());
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
CefRefPtr<CefDictionaryValue> CefRequestContextCToCpp::GetAllPreferences(
|
||||
bool include_defaults) {
|
||||
cef_request_context_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_all_preferences))
|
||||
return NULL;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_dictionary_value_t* _retval = _struct->get_all_preferences(_struct,
|
||||
include_defaults);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefDictionaryValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
bool CefRequestContextCToCpp::CanSetPreference(const CefString& name) {
|
||||
cef_request_context_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, can_set_preference))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->can_set_preference(_struct,
|
||||
name.GetStruct());
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
bool CefRequestContextCToCpp::SetPreference(const CefString& name,
|
||||
CefRefPtr<CefValue> value, CefString& error) {
|
||||
cef_request_context_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, set_preference))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: name; type: string_byref_const
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return false;
|
||||
// Unverified params: value
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->set_preference(_struct,
|
||||
name.GetStruct(),
|
||||
CefValueCToCpp::Unwrap(value),
|
||||
error.GetWritableStruct());
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
|
@ -45,6 +45,13 @@ class CefRequestContextCToCpp
|
||||
CefRefPtr<CefSchemeHandlerFactory> factory) OVERRIDE;
|
||||
bool ClearSchemeHandlerFactories() OVERRIDE;
|
||||
void PurgePluginListCache(bool reload_pages) 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;
|
||||
};
|
||||
|
||||
#endif // USING_CEF_SHARED
|
||||
|
332
tests/cefclient/browser/preferences_test.cc
Normal file
332
tests/cefclient/browser/preferences_test.cc
Normal file
@ -0,0 +1,332 @@
|
||||
// Copyright (c) 2015 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 "cefclient/browser/preferences_test.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "include/cef_parser.h"
|
||||
|
||||
namespace client {
|
||||
namespace preferences_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/preferences";
|
||||
|
||||
// Application-specific error codes.
|
||||
const int kMessageFormatError = 1;
|
||||
const int kPreferenceApplicationError = 1;
|
||||
|
||||
// Common to all messages.
|
||||
const char kNameKey[] = "name";
|
||||
const char kNameValueGet[] = "preferences_get";
|
||||
const char kNameValueSet[] = "preferences_set";
|
||||
const char kNameValueState[] = "preferences_state";
|
||||
|
||||
// Used with "preferences_get" messages.
|
||||
const char kIncludeDefaultsKey[] = "include_defaults";
|
||||
|
||||
// Used with "preferences_set" messages.
|
||||
const char kPreferencesKey[] = "preferences";
|
||||
|
||||
// Handle messages in the browser process. Only accessed on the UI thread.
|
||||
class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
public:
|
||||
typedef std::vector<std::string> NameVector;
|
||||
|
||||
Handler() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
}
|
||||
|
||||
// Called due to cefQuery execution in preferences.html.
|
||||
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64 query_id,
|
||||
const CefString& request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) OVERRIDE {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Only handle messages from the test URL.
|
||||
std::string url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
return false;
|
||||
|
||||
// Parse |request| as a JSON dictionary.
|
||||
CefRefPtr<CefDictionaryValue> request_dict = ParseJSON(request);
|
||||
if (!request_dict) {
|
||||
callback->Failure(kMessageFormatError, "Incorrect message format");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verify the "name" key.
|
||||
if (!VerifyKey(request_dict, kNameKey, VTYPE_STRING, callback))
|
||||
return true;
|
||||
|
||||
const std::string& message_name = request_dict->GetString(kNameKey);
|
||||
if (message_name == kNameValueGet) {
|
||||
// JavaScript is requesting a JSON representation of the preferences tree.
|
||||
|
||||
// Verify the "include_defaults" key.
|
||||
if (!VerifyKey(request_dict, kIncludeDefaultsKey, VTYPE_BOOL, callback))
|
||||
return true;
|
||||
|
||||
const bool include_defaults = request_dict->GetBool(kIncludeDefaultsKey);
|
||||
|
||||
OnPreferencesGet(browser, include_defaults, callback);
|
||||
|
||||
return true;
|
||||
} else if (message_name == kNameValueSet) {
|
||||
// JavaScript is requesting that preferences be updated to match the
|
||||
// specified JSON representation.
|
||||
|
||||
// Verify the "preferences" key.
|
||||
if (!VerifyKey(request_dict, kPreferencesKey, VTYPE_DICTIONARY, callback))
|
||||
return true;
|
||||
|
||||
CefRefPtr<CefDictionaryValue> preferences =
|
||||
request_dict->GetDictionary(kPreferencesKey);
|
||||
|
||||
OnPreferencesSet(browser, preferences, callback);
|
||||
|
||||
return true;
|
||||
} else if (message_name == kNameValueState) {
|
||||
// JavaScript is requesting global state information.
|
||||
|
||||
OnPreferencesState(browser, callback);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// Execute |callback| with the preferences dictionary as a JSON string.
|
||||
static void OnPreferencesGet(CefRefPtr<CefBrowser> browser,
|
||||
bool include_defaults,
|
||||
CefRefPtr<Callback> callback) {
|
||||
CefRefPtr<CefRequestContext> context =
|
||||
browser->GetHost()->GetRequestContext();
|
||||
|
||||
// Retrieve all preference values.
|
||||
CefRefPtr<CefDictionaryValue> prefs =
|
||||
context->GetAllPreferences(include_defaults);
|
||||
|
||||
// Serialize the preferences to JSON and return to the JavaScript caller.
|
||||
callback->Success(GetJSON(prefs));
|
||||
}
|
||||
|
||||
// Set preferences based on the contents of |preferences|. Execute |callback|
|
||||
// with a descriptive result message.
|
||||
static void OnPreferencesSet(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDictionaryValue> preferences,
|
||||
CefRefPtr<Callback> callback) {
|
||||
CefRefPtr<CefRequestContext> context =
|
||||
browser->GetHost()->GetRequestContext();
|
||||
|
||||
CefRefPtr<CefValue> value = CefValue::Create();
|
||||
value->SetDictionary(preferences);
|
||||
|
||||
std::string error;
|
||||
NameVector changed_names;
|
||||
|
||||
// Apply preferences. This may result in errors.
|
||||
const bool success = ApplyPrefs(context, std::string(), value, error,
|
||||
changed_names);
|
||||
|
||||
// Create a message that accurately represents the result.
|
||||
std::string message;
|
||||
if (!changed_names.empty()) {
|
||||
std::stringstream ss;
|
||||
ss << "Successfully changed " << changed_names.size() <<
|
||||
" preferences; ";
|
||||
for (size_t i = 0; i < changed_names.size(); ++i) {
|
||||
ss << changed_names[i];
|
||||
if (i < changed_names.size() - 1)
|
||||
ss << ", ";
|
||||
}
|
||||
message = ss.str();
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
DCHECK(!error.empty());
|
||||
if (!message.empty())
|
||||
message += "\n";
|
||||
message += error;
|
||||
}
|
||||
|
||||
if (changed_names.empty()) {
|
||||
if (!message.empty())
|
||||
message += "\n";
|
||||
message += "No preferences changed.";
|
||||
}
|
||||
|
||||
// Return the message to the JavaScript caller.
|
||||
if (success)
|
||||
callback->Success(message);
|
||||
else
|
||||
callback->Failure(kPreferenceApplicationError, message);
|
||||
}
|
||||
|
||||
// Execute |callback| with the global state dictionary as a JSON string.
|
||||
static void OnPreferencesState(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<Callback> callback) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
|
||||
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
|
||||
|
||||
// If spell checking is disabled via the command-line then it cannot be
|
||||
// enabled via preferences.
|
||||
dict->SetBool("spellcheck_disabled",
|
||||
command_line->HasSwitch("disable-spell-checking"));
|
||||
|
||||
// If proxy settings are configured via the command-line then they cannot
|
||||
// be modified via preferences.
|
||||
dict->SetBool("proxy_configured",
|
||||
command_line->HasSwitch("no-proxy-server") ||
|
||||
command_line->HasSwitch("proxy-auto-detect") ||
|
||||
command_line->HasSwitch("proxy-pac-url") ||
|
||||
command_line->HasSwitch("proxy-server"));
|
||||
|
||||
// Serialize the state to JSON and return to the JavaScript caller.
|
||||
callback->Success(GetJSON(dict));
|
||||
}
|
||||
|
||||
// Convert a JSON string to a dictionary value.
|
||||
static CefRefPtr<CefDictionaryValue> ParseJSON(const CefString& string) {
|
||||
CefRefPtr<CefValue> value = CefParseJSON(string, JSON_PARSER_RFC);
|
||||
if (value.get() && value->GetType() == VTYPE_DICTIONARY)
|
||||
return value->GetDictionary();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Convert a dictionary value to a JSON string.
|
||||
static CefString GetJSON(CefRefPtr<CefDictionaryValue> dictionary) {
|
||||
CefRefPtr<CefValue> value = CefValue::Create();
|
||||
value->SetDictionary(dictionary);
|
||||
return CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
}
|
||||
|
||||
// Verify that |key| exists in |dictionary| and has type |value_type|. Fails
|
||||
// |callback| and returns false on failure.
|
||||
static bool VerifyKey(CefRefPtr<CefDictionaryValue> dictionary,
|
||||
const char* key,
|
||||
cef_value_type_t value_type,
|
||||
CefRefPtr<Callback> callback) {
|
||||
if (!dictionary->HasKey(key) || dictionary->GetType(key) != value_type) {
|
||||
callback->Failure(kMessageFormatError,
|
||||
"Missing or incorrectly formatted message key: " +
|
||||
std::string(key));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Apply preferences. Returns true on success. Returns false and sets |error|
|
||||
// to a descriptive error string on failure. |changed_names| is the list of
|
||||
// preferences that were successfully changed.
|
||||
static bool ApplyPrefs(CefRefPtr<CefRequestContext> context,
|
||||
const std::string& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
std::string& error,
|
||||
NameVector& changed_names) {
|
||||
if (!name.empty() && context->HasPreference(name)) {
|
||||
// The preference exists. Set the value.
|
||||
return SetPref(context, name, value, error, changed_names);
|
||||
}
|
||||
|
||||
if (value->GetType() == VTYPE_DICTIONARY) {
|
||||
// A dictionary type value that is not an existing preference. Try to set
|
||||
// each of the elements individually.
|
||||
CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
|
||||
|
||||
CefDictionaryValue::KeyList keys;
|
||||
dict->GetKeys(keys);
|
||||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
const std::string& key = keys[i];
|
||||
const std::string& current_name =
|
||||
name.empty() ? key : name + "." + key;
|
||||
if (!ApplyPrefs(context, current_name, dict->GetValue(key), error,
|
||||
changed_names)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
error = "Trying to create an unregistered preference: " + name;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set a specific preference value. Returns true if the value is set
|
||||
// successfully or has not changed. If the value has changed then |name| will
|
||||
// be added to |changed_names|. Returns false and sets |error| to a
|
||||
// descriptive error string on failure.
|
||||
static bool SetPref(CefRefPtr<CefRequestContext> context,
|
||||
const std::string& name,
|
||||
CefRefPtr<CefValue> value,
|
||||
std::string& error,
|
||||
NameVector& changed_names) {
|
||||
CefRefPtr<CefValue> existing_value = context->GetPreference(name);
|
||||
DCHECK(existing_value);
|
||||
|
||||
if (value->GetType() == VTYPE_STRING &&
|
||||
existing_value->GetType() != VTYPE_STRING) {
|
||||
// Since |value| is coming from JSON all basic types will be represented
|
||||
// as strings. Convert to the expected data type.
|
||||
const std::string& string_val = value->GetString();
|
||||
switch (existing_value->GetType()) {
|
||||
case VTYPE_BOOL:
|
||||
if (string_val == "true" || string_val == "1")
|
||||
value->SetBool(true);
|
||||
else if (string_val == "false" || string_val == "0")
|
||||
value->SetBool(false);
|
||||
break;
|
||||
case VTYPE_INT:
|
||||
value->SetInt(atoi(string_val.c_str()));
|
||||
break;
|
||||
case VTYPE_DOUBLE:
|
||||
value->SetInt(atof(string_val.c_str()));
|
||||
break;
|
||||
default:
|
||||
// Other types cannot be converted.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do if the value hasn't changed.
|
||||
if (existing_value->IsEqual(value))
|
||||
return true;
|
||||
|
||||
// Attempt to set the preference.
|
||||
CefString error_str;
|
||||
if (!context->SetPreference(name, value, error_str)) {
|
||||
error = error_str.ToString() + ": " + name;
|
||||
return false;
|
||||
}
|
||||
|
||||
// The preference was set successfully.
|
||||
changed_names.push_back(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Handler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
|
||||
handlers.insert(new Handler());
|
||||
}
|
||||
|
||||
} // namespace preferences_test
|
||||
} // namespace client
|
20
tests/cefclient/browser/preferences_test.h
Normal file
20
tests/cefclient/browser/preferences_test.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2015 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_TESTS_CEFCLIENT_BROWSER_PREFERENCES_TEST_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_PREFERENCES_TEST_H_
|
||||
#pragma once
|
||||
|
||||
#include "cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace preferences_test {
|
||||
|
||||
// Create message handlers. Called from test_runner.cc.
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
|
||||
|
||||
} // namespace preferences_test
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_PREFERENCES_TEST_H_
|
@ -53,10 +53,11 @@
|
||||
#define IDS_PDF_PDF 1007
|
||||
#define IDS_PERFORMANCE_HTML 1008
|
||||
#define IDS_PERFORMANCE2_HTML 1009
|
||||
#define IDS_TRANSPARENCY_HTML 1010
|
||||
#define IDS_URLREQUEST_HTML 1011
|
||||
#define IDS_WINDOW_HTML 1012
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1013
|
||||
#define IDS_PREFERENCES_HTML 1010
|
||||
#define IDS_TRANSPARENCY_HTML 1011
|
||||
#define IDS_URLREQUEST_HTML 1012
|
||||
#define IDS_WINDOW_HTML 1013
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1014
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
@ -47,6 +47,7 @@ int GetResourceId(const char* resource_name) {
|
||||
{"pdf.pdf", IDS_PDF_PDF},
|
||||
{"performance.html", IDS_PERFORMANCE_HTML},
|
||||
{"performance2.html", IDS_PERFORMANCE2_HTML},
|
||||
{"preferences.html", IDS_PREFERENCES_HTML},
|
||||
{"transparency.html", IDS_TRANSPARENCY_HTML},
|
||||
{"urlrequest.html", IDS_URLREQUEST_HTML},
|
||||
{"window.html", IDS_WINDOW_HTML},
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "cefclient/browser/binding_test.h"
|
||||
#include "cefclient/browser/dialog_test.h"
|
||||
#include "cefclient/browser/main_context.h"
|
||||
#include "cefclient/browser/preferences_test.h"
|
||||
#include "cefclient/browser/resource.h"
|
||||
#include "cefclient/browser/resource_util.h"
|
||||
#include "cefclient/browser/root_window_manager.h"
|
||||
@ -663,6 +664,12 @@ std::string GetErrorString(cef_errorcode_t code) {
|
||||
}
|
||||
|
||||
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
// Execute on the browser IO thread.
|
||||
CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager));
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& test_origin = kTestOrigin;
|
||||
|
||||
// Add the URL filter.
|
||||
@ -701,11 +708,14 @@ void Alert(CefRefPtr<CefBrowser> browser, const std::string& message) {
|
||||
void CreateMessageHandlers(MessageHandlerSet& handlers) {
|
||||
handlers.insert(new PromptHandler);
|
||||
|
||||
// Create the binding test handlers.
|
||||
binding_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the dialog test handlers.
|
||||
dialog_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the binding test handlers.
|
||||
binding_test::CreateMessageHandlers(handlers);
|
||||
// Create the preferences test handlers.
|
||||
preferences_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the urlrequest test handlers.
|
||||
urlrequest_test::CreateMessageHandlers(handlers);
|
||||
|
@ -21,6 +21,7 @@
|
||||
<li><a href="http://tests/localstorage">Local Storage</a></li>
|
||||
<li><a href="http://tests/pdf.pdf">PDF Viewer direct</a></li>
|
||||
<li><a href="http://tests/pdf">PDF Viewer iframe</a></li>
|
||||
<li><a href="http://tests/preferences">Preferences</a></li>
|
||||
<li><a href="http://mrdoob.com/lab/javascript/requestanimationframe/">requestAnimationFrame</a></li>
|
||||
<li><a href="client://tests/handler.html">Scheme Handler</a></li>
|
||||
<li><a href="https://www.google.com/intl/en/chrome/demos/speech.html">Speech Input</a> - requires "enable-speech-input" flag</li>
|
||||
|
290
tests/cefclient/resources/preferences.html
Normal file
290
tests/cefclient/resources/preferences.html
Normal file
@ -0,0 +1,290 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Preferences Test</title>
|
||||
|
||||
<!-- When using the mode "code" it's important to specify charset utf-8 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
|
||||
<!-- jsoneditor project from https://github.com/josdejong/jsoneditor/
|
||||
script hosting from http://cdnjs.com/libraries/jsoneditor -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.1/jsoneditor.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.1/jsoneditor.min.js"></script>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<!-- Header -->
|
||||
<div id="simple_links">
|
||||
[ <b>Simple</b> ]
|
||||
[ <a href="#" onClick="toggleView(); return false;">Advanced</a> ]
|
||||
</div>
|
||||
<div id="advanced_links" style="display:none">
|
||||
[ <a href="#" onClick="toggleView(); return false;">Simple</a> ]
|
||||
[ <b>Advanced</b> ]
|
||||
</div>
|
||||
|
||||
<!-- Simple view -->
|
||||
<div id="simple">
|
||||
<p>
|
||||
This page supports display and configuration of a few sample preferences.
|
||||
<table width="100%" style="border: 1px solid #97B0F8">
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" id="enable_spellchecking"/> Enable spell checking
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<br/>
|
||||
Proxy type:
|
||||
<select id="proxy_type" onChange="proxyTypeChange()">
|
||||
<option value="direct">Direct</option>
|
||||
<option value="auto_detect">Auto-Detect</option>
|
||||
<option value="pac_script">PAC Script</option>
|
||||
<option value="fixed_servers">Fixed Servers</option>
|
||||
<option value="system">System</option>
|
||||
</select>
|
||||
<input id="proxy_value" type="text" size="80" disabled/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<input type="button" value="Refresh" onClick="refreshSimple()"/>
|
||||
</td>
|
||||
<td align="right">
|
||||
<input type="button" value="Apply Changes" onClick="applySimpleChanges()"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Advanced view -->
|
||||
<div id="advanced" style="display:none">
|
||||
<p>
|
||||
This page displays all preferences organized in a tree structure. Arbitrary changes are
|
||||
allowed, however <b>changing preferences in arbitrary ways may result in crashes</b>. If you
|
||||
experience a crash while setting preferences then run a Debug build of CEF/Chromium and watch
|
||||
for DCHECKs in the Chromium code to figure out what went wrong.
|
||||
</p>
|
||||
<div id="jsoneditor" style="width: 100%; height: 100%;"></div>
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<input type="button" value="Refresh" onClick="refreshEditor()"/>
|
||||
<input type="checkbox" id="hide_defaults"/> Show modified preferences only
|
||||
</td>
|
||||
<td align="right">
|
||||
<input type="button" value="Apply Changes" onClick="applyEditorChanges()"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Reference to the JSONEditor.
|
||||
var editor = null;
|
||||
|
||||
// Preferences state information.
|
||||
var preferences_state = null;
|
||||
|
||||
// Toggle between the simple and advanced views.
|
||||
function toggleView() {
|
||||
var simple = document.getElementById("simple");
|
||||
var advanced = document.getElementById("advanced");
|
||||
var simple_links = document.getElementById("simple_links");
|
||||
var advanced_links = document.getElementById("advanced_links");
|
||||
|
||||
if (simple.style.display == "none") {
|
||||
// Show the simple view.
|
||||
simple.style.display = "";
|
||||
simple_links.style.display = "";
|
||||
advanced.style.display = "none";
|
||||
advanced_links.style.display = "none";
|
||||
|
||||
// Refresh the simple view contents.
|
||||
refreshSimple();
|
||||
} else {
|
||||
// Show the advanced view.
|
||||
simple.style.display = "none";
|
||||
simple_links.style.display = "none";
|
||||
advanced.style.display = "";
|
||||
advanced_links.style.display = "";
|
||||
|
||||
if (editor == null) {
|
||||
// Create the editor.
|
||||
editor = new JSONEditor(document.getElementById("jsoneditor"));
|
||||
}
|
||||
|
||||
// Refesh the editor contents.
|
||||
refreshEditor();
|
||||
}
|
||||
}
|
||||
|
||||
// Send a request to C++.
|
||||
function sendRequest(request, onSuccessCallback) {
|
||||
// Results in a call to the OnQuery method in preferences_test.cpp.
|
||||
window.cefQuery({
|
||||
request: JSON.stringify(request),
|
||||
onSuccess: onSuccessCallback,
|
||||
onFailure: function(error_code, error_message) {
|
||||
alert(error_message + ' (' + error_code + ')');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get the preferences and execute |onSuccessCallback| with the resulting
|
||||
// JSON object.
|
||||
function getPreferences(include_defaults, onSuccessCallback) {
|
||||
// Create the request object.
|
||||
var request = {};
|
||||
request.name = "preferences_get";
|
||||
request.include_defaults = include_defaults;
|
||||
|
||||
// Send the request to C++.
|
||||
sendRequest(
|
||||
request,
|
||||
function(response) {
|
||||
onSuccessCallback(JSON.parse(response));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Set the preferences.
|
||||
function setPreferences(preferences) {
|
||||
// Create the request object.
|
||||
var request = {};
|
||||
request.name = "preferences_set";
|
||||
request.preferences = preferences;
|
||||
|
||||
// Send the request to C++.
|
||||
sendRequest(
|
||||
request,
|
||||
function(response) {
|
||||
// Show the informative response message.
|
||||
alert(response);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Get the global preference state.
|
||||
function getPreferenceState() {
|
||||
// Create the request object.
|
||||
var request = {};
|
||||
request.name = "preferences_state";
|
||||
|
||||
// Send the request to C++.
|
||||
sendRequest(
|
||||
request,
|
||||
function(response) {
|
||||
// Populate the global state object.
|
||||
preferences_state = JSON.parse(response);
|
||||
|
||||
// Refresh the simple view contents.
|
||||
refreshSimple();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Refresh the editor view contents.
|
||||
function refreshEditor() {
|
||||
include_defaults = !document.getElementById("hide_defaults").checked;
|
||||
getPreferences(include_defaults, function(response) {
|
||||
// Set the JSON in the editor.
|
||||
editor.set(response);
|
||||
});
|
||||
}
|
||||
|
||||
// Apply changes from the editor view.
|
||||
function applyEditorChanges() {
|
||||
setPreferences(editor.get());
|
||||
}
|
||||
|
||||
// Refresh the simple view contents.
|
||||
function refreshSimple() {
|
||||
getPreferences(true, function(response) {
|
||||
// Spellcheck settings.
|
||||
if (preferences_state.spellcheck_disabled) {
|
||||
// Cannot enable spell checking when disabled via the command-line.
|
||||
document.getElementById("enable_spellchecking").checked = false;
|
||||
document.getElementById("enable_spellchecking").disabled = true;
|
||||
} else {
|
||||
document.getElementById("enable_spellchecking").checked =
|
||||
response.browser.enable_spellchecking;
|
||||
}
|
||||
|
||||
// Proxy settings.
|
||||
document.getElementById("proxy_type").value = response.proxy.mode;
|
||||
|
||||
// Some proxy modes have associated values.
|
||||
if (response.proxy.mode == "pac_script")
|
||||
proxy_value = response.proxy.pac_url;
|
||||
else if (response.proxy.mode == "fixed_servers")
|
||||
proxy_value = response.proxy.server;
|
||||
else
|
||||
proxy_value = null;
|
||||
|
||||
if (proxy_value != null)
|
||||
document.getElementById("proxy_value").value = proxy_value;
|
||||
document.getElementById("proxy_value").disabled = (proxy_value == null);
|
||||
|
||||
if (preferences_state.proxy_configured) {
|
||||
// Cannot modify proxy settings that are configured via the command-
|
||||
// line.
|
||||
document.getElementById("proxy_type").disabled = true;
|
||||
document.getElementById("proxy_value").disabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Apply changes from the simple view.
|
||||
function applySimpleChanges() {
|
||||
has_preferences = false;
|
||||
preferences = {};
|
||||
|
||||
// Spellcheck settings.
|
||||
if (!preferences_state.spellcheck_disabled) {
|
||||
has_preferences = true;
|
||||
|
||||
preferences.browser = {};
|
||||
preferences.browser.enable_spellchecking =
|
||||
document.getElementById("enable_spellchecking").checked;
|
||||
}
|
||||
|
||||
// Proxy settings.
|
||||
if (!preferences_state.proxy_configured) {
|
||||
has_preferences = true;
|
||||
|
||||
preferences.proxy = {};
|
||||
preferences.proxy.mode = document.getElementById("proxy_type").value;
|
||||
|
||||
// Some proxy modes have associated values.
|
||||
if (preferences.proxy.mode == "pac_script") {
|
||||
preferences.proxy.pac_script =
|
||||
document.getElementById("proxy_value").value;
|
||||
} else if (preferences.proxy.mode == "fixed_servers") {
|
||||
preferences.proxy.server =
|
||||
document.getElementById("proxy_value").value;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_preferences)
|
||||
setPreferences(preferences);
|
||||
}
|
||||
|
||||
// Called when the proxy type is changed.
|
||||
function proxyTypeChange() {
|
||||
proxy_type = document.getElementById("proxy_type").value;
|
||||
document.getElementById("proxy_value").value = "";
|
||||
|
||||
// Only enable the value field for the proxy modes that require it.
|
||||
document.getElementById("proxy_value").disabled =
|
||||
(proxy_type != "pac_script" && proxy_type != "fixed_servers");
|
||||
}
|
||||
|
||||
// Retrieve global preferences state.
|
||||
getPreferenceState();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -39,6 +39,7 @@ IDS_PDF_HTML BINARY "..\\pdf.html"
|
||||
IDS_PDF_PDF BINARY "..\\pdf.pdf"
|
||||
IDS_PERFORMANCE_HTML BINARY "..\\performance.html"
|
||||
IDS_PERFORMANCE2_HTML BINARY "..\\performance2.html"
|
||||
IDS_PREFERENCES_HTML BINARY "..\\preferences.html"
|
||||
IDS_TRANSPARENCY_HTML BINARY "..\\transparency.html"
|
||||
IDS_URLREQUEST_HTML BINARY "..\\urlrequest.html"
|
||||
IDS_WINDOW_HTML BINARY "..\\window.html"
|
||||
|
@ -24,6 +24,11 @@ void CreateBrowserDelegates(ClientAppBrowser::DelegateSet& delegates) {
|
||||
ClientAppBrowser::DelegateSet& delegates);
|
||||
CreatePluginBrowserTests(delegates);
|
||||
|
||||
// Bring in the preference tests.
|
||||
extern void CreatePreferenceBrowserTests(
|
||||
ClientAppBrowser::DelegateSet& delegates);
|
||||
CreatePreferenceBrowserTests(delegates);
|
||||
|
||||
// Bring in the RequestHandler tests.
|
||||
extern void CreateRequestHandlerBrowserTests(
|
||||
ClientAppBrowser::DelegateSet& delegates);
|
||||
|
553
tests/unittests/preference_unittest.cc
Normal file
553
tests/unittests/preference_unittest.cc
Normal file
@ -0,0 +1,553 @@
|
||||
// Copyright (c) 2015 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 this first to avoid type conflicts with CEF headers.
|
||||
#include "tests/unittests/chromium_includes.h"
|
||||
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "tests/cefclient/browser/client_app_browser.h"
|
||||
#include "tests/unittests/test_handler.h"
|
||||
#include "tests/unittests/test_util.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Fully qualified preference names.
|
||||
const char kPrefTest[] = "test";
|
||||
const char kPrefTestBool[] = "test.bool";
|
||||
const char kPrefTestInt[] = "test.int";
|
||||
const char kPrefTestDouble[] = "test.double";
|
||||
const char kPrefTestString[] = "test.string";
|
||||
const char kPrefTestList[] = "test.list";
|
||||
const char kPrefTestDict[] = "test.dict";
|
||||
const char kPrefTestNoExist[] = "test.noexist";
|
||||
|
||||
// Unqualified preference names.
|
||||
const char kPrefBool[] = "bool";
|
||||
const char kPrefInt[] = "int";
|
||||
const char kPrefDouble[] = "double";
|
||||
const char kPrefString[] = "string";
|
||||
const char kPrefList[] = "list";
|
||||
const char kPrefDict[] = "dict";
|
||||
|
||||
// Browser-side app delegate.
|
||||
class PreferenceBrowserTest : public client::ClientAppBrowser::Delegate {
|
||||
public:
|
||||
PreferenceBrowserTest() {}
|
||||
|
||||
void OnBeforeCommandLineProcessing(
|
||||
CefRefPtr<client::ClientAppBrowser> app,
|
||||
CefRefPtr<CefCommandLine> command_line) override {
|
||||
// Enables testing of preferences.
|
||||
// See CefBrowserPrefStore::CreateService.
|
||||
command_line->AppendSwitch("enable-preference-testing");
|
||||
}
|
||||
|
||||
private:
|
||||
IMPLEMENT_REFCOUNTING(PreferenceBrowserTest);
|
||||
};
|
||||
|
||||
void ValidateReset(CefRefPtr<CefRequestContext> context,
|
||||
const char* name) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, NULL, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
void ValidateBool(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
bool expected,
|
||||
const char* name = kPrefTestBool) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetBool(expected);
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, value, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_EQ(VTYPE_BOOL, value->GetType());
|
||||
EXPECT_EQ(expected, value->GetBool());
|
||||
}
|
||||
|
||||
void ValidateInt(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
int expected,
|
||||
const char* name = kPrefTestInt) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetInt(expected);
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, value, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_EQ(VTYPE_INT, value->GetType());
|
||||
EXPECT_EQ(expected, value->GetInt());
|
||||
}
|
||||
|
||||
void ValidateDouble(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
double expected,
|
||||
const char* name = kPrefTestDouble) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetDouble(expected);
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, value, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_EQ(VTYPE_DOUBLE, value->GetType());
|
||||
EXPECT_EQ(expected, value->GetDouble());
|
||||
}
|
||||
|
||||
void ValidateString(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
const std::string& expected,
|
||||
const char* name = kPrefTestString) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetString(expected);
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, value, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_EQ(VTYPE_STRING, value->GetType());
|
||||
EXPECT_STREQ(expected.c_str(), value->GetString().ToString().c_str());
|
||||
}
|
||||
|
||||
void ValidateList(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
CefRefPtr<CefListValue> expected,
|
||||
const char* name = kPrefTestList) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetList(expected);
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, value, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_EQ(VTYPE_LIST, value->GetType());
|
||||
CefRefPtr<CefListValue> list_val = value->GetList();
|
||||
EXPECT_TRUE(list_val);
|
||||
TestListEqual(expected, list_val);
|
||||
}
|
||||
|
||||
void ValidateDict(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
CefRefPtr<CefDictionaryValue> expected,
|
||||
const char* name = kPrefTestDict) {
|
||||
EXPECT_TRUE(context->HasPreference(name));
|
||||
EXPECT_TRUE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetDictionary(expected);
|
||||
CefString error;
|
||||
EXPECT_TRUE(context->SetPreference(name, value, error));
|
||||
EXPECT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_EQ(VTYPE_DICTIONARY, value->GetType());
|
||||
CefRefPtr<CefDictionaryValue> dict_val = value->GetDictionary();
|
||||
EXPECT_TRUE(dict_val);
|
||||
TestDictionaryEqual(expected, dict_val);
|
||||
}
|
||||
|
||||
void ValidateNoExist(CefRefPtr<CefRequestContext> context,
|
||||
bool set,
|
||||
const char* name = kPrefTestNoExist) {
|
||||
EXPECT_FALSE(context->HasPreference(name));
|
||||
EXPECT_FALSE(context->CanSetPreference(name));
|
||||
|
||||
CefRefPtr<CefValue> value;
|
||||
|
||||
if (set) {
|
||||
value = CefValue::Create();
|
||||
value->SetBool(false);
|
||||
CefString error;
|
||||
EXPECT_FALSE(context->SetPreference(name, value, error));
|
||||
EXPECT_FALSE(error.empty());
|
||||
}
|
||||
|
||||
value = context->GetPreference(name);
|
||||
EXPECT_FALSE(value.get());
|
||||
}
|
||||
|
||||
void PopulateRootDefaults(CefRefPtr<CefDictionaryValue> val) {
|
||||
// Should match the values in CefBrowserPrefStore::CreateService.
|
||||
val->SetBool(kPrefBool, true);
|
||||
val->SetInt(kPrefInt, 2);
|
||||
val->SetDouble(kPrefDouble, 5.0);
|
||||
val->SetString(kPrefString, "default");
|
||||
val->SetList(kPrefList, CefListValue::Create());
|
||||
val->SetDictionary(kPrefDict, CefDictionaryValue::Create());
|
||||
}
|
||||
|
||||
void ValidateRoot(CefRefPtr<CefDictionaryValue> root,
|
||||
CefRefPtr<CefDictionaryValue> expected,
|
||||
const char* name = kPrefTest) {
|
||||
EXPECT_TRUE(root->HasKey(kPrefTest));
|
||||
EXPECT_EQ(VTYPE_DICTIONARY, root->GetType(kPrefTest));
|
||||
|
||||
CefRefPtr<CefDictionaryValue> actual = root->GetDictionary(kPrefTest);
|
||||
TestDictionaryEqual(expected, actual);
|
||||
}
|
||||
|
||||
// Validate getting default values.
|
||||
void ValidateDefaults(CefRefPtr<CefRequestContext> context,
|
||||
bool reset,
|
||||
base::WaitableEvent* event) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(ValidateDefaults, context, reset, event));
|
||||
return;
|
||||
}
|
||||
|
||||
if (reset) {
|
||||
// Reset default values.
|
||||
ValidateReset(context, kPrefTestBool);
|
||||
ValidateReset(context, kPrefTestInt);
|
||||
ValidateReset(context, kPrefTestDouble);
|
||||
ValidateReset(context, kPrefTestString);
|
||||
ValidateReset(context, kPrefTestList);
|
||||
ValidateReset(context, kPrefTestDict);
|
||||
}
|
||||
|
||||
// Test default values.
|
||||
// Should match the values in CefBrowserPrefStore::CreateService.
|
||||
ValidateBool(context, false, true);
|
||||
ValidateInt(context, false, 2);
|
||||
ValidateDouble(context, false, 5.0);
|
||||
ValidateString(context, false, "default");
|
||||
ValidateList(context, false, CefListValue::Create());
|
||||
ValidateDict(context, false, CefDictionaryValue::Create());
|
||||
ValidateNoExist(context, false);
|
||||
|
||||
// Expected value of the tests root.
|
||||
CefRefPtr<CefDictionaryValue> expected = CefDictionaryValue::Create();
|
||||
PopulateRootDefaults(expected);
|
||||
|
||||
// Test all preferences including defaults.
|
||||
ValidateRoot(context->GetAllPreferences(true), expected);
|
||||
|
||||
// Test all preferences excluding defaults.
|
||||
EXPECT_FALSE(context->GetAllPreferences(false)->HasKey(kPrefTest));
|
||||
|
||||
event->Signal();
|
||||
}
|
||||
|
||||
void PopulateListValue(CefRefPtr<CefListValue> val) {
|
||||
// Test list values.
|
||||
val->SetInt(0, 54);
|
||||
val->SetString(1, "foobar");
|
||||
val->SetDouble(2, 99.7643);
|
||||
}
|
||||
|
||||
void PopulateDictValue(CefRefPtr<CefDictionaryValue> val) {
|
||||
// Test dictionary values.
|
||||
val->SetString("key1", "some string");
|
||||
val->SetBool("key2", false);
|
||||
|
||||
CefRefPtr<CefListValue> list_val = CefListValue::Create();
|
||||
PopulateListValue(list_val);
|
||||
val->SetList("key3", list_val);
|
||||
}
|
||||
|
||||
void PopulateRootSet(CefRefPtr<CefDictionaryValue> val) {
|
||||
CefRefPtr<CefListValue> list_val = CefListValue::Create();
|
||||
CefRefPtr<CefDictionaryValue> dict_val = CefDictionaryValue::Create();
|
||||
|
||||
PopulateListValue(list_val);
|
||||
PopulateDictValue(dict_val);
|
||||
|
||||
// Should match the values in ValidateSetGet and ValidateGet.
|
||||
val->SetBool(kPrefBool, true);
|
||||
val->SetInt(kPrefInt, 65);
|
||||
val->SetDouble(kPrefDouble, 54.5443);
|
||||
val->SetString(kPrefString, "My test string");
|
||||
val->SetList(kPrefList, list_val);
|
||||
val->SetDictionary(kPrefDict, dict_val);
|
||||
}
|
||||
|
||||
// Validate getting and setting values.
|
||||
void ValidateSetGet(CefRefPtr<CefRequestContext> context,
|
||||
base::WaitableEvent* event) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(ValidateSetGet, context, event));
|
||||
return;
|
||||
}
|
||||
|
||||
CefRefPtr<CefListValue> list_val = CefListValue::Create();
|
||||
CefRefPtr<CefDictionaryValue> dict_val = CefDictionaryValue::Create();
|
||||
|
||||
PopulateListValue(list_val);
|
||||
PopulateDictValue(dict_val);
|
||||
|
||||
// Test setting/getting values.
|
||||
// Should match the values in PopulateRootSet and ValidateGet.
|
||||
ValidateBool(context, true, true);
|
||||
ValidateInt(context, true, 65);
|
||||
ValidateDouble(context, true, 54.5443);
|
||||
ValidateString(context, true, "My test string");
|
||||
ValidateList(context, true, list_val);
|
||||
ValidateDict(context, true, dict_val);
|
||||
ValidateNoExist(context, true);
|
||||
|
||||
// Expected value of the tests root.
|
||||
CefRefPtr<CefDictionaryValue> expected = CefDictionaryValue::Create();
|
||||
PopulateRootSet(expected);
|
||||
|
||||
// Validate all preferences including defaults.
|
||||
ValidateRoot(context->GetAllPreferences(true), expected);
|
||||
|
||||
// Validate all preferences excluding defaults.
|
||||
ValidateRoot(context->GetAllPreferences(false), expected);
|
||||
|
||||
event->Signal();
|
||||
}
|
||||
|
||||
// Validate getting values.
|
||||
void ValidateGet(CefRefPtr<CefRequestContext> context,
|
||||
base::WaitableEvent* event) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(ValidateGet, context, event));
|
||||
return;
|
||||
}
|
||||
|
||||
CefRefPtr<CefListValue> list_val = CefListValue::Create();
|
||||
CefRefPtr<CefDictionaryValue> dict_val = CefDictionaryValue::Create();
|
||||
|
||||
PopulateListValue(list_val);
|
||||
PopulateDictValue(dict_val);
|
||||
|
||||
// Test getting values.
|
||||
// Should match the values in PopulateRootSet and ValidateSetGet.
|
||||
ValidateBool(context, false, true);
|
||||
ValidateInt(context, false, 65);
|
||||
ValidateDouble(context, false, 54.5443);
|
||||
ValidateString(context, false, "My test string");
|
||||
ValidateList(context, false, list_val);
|
||||
ValidateDict(context, false, dict_val);
|
||||
ValidateNoExist(context, false);
|
||||
|
||||
// Expected value of the tests root.
|
||||
CefRefPtr<CefDictionaryValue> expected = CefDictionaryValue::Create();
|
||||
PopulateRootSet(expected);
|
||||
|
||||
// Validate all preferences including defaults.
|
||||
ValidateRoot(context->GetAllPreferences(true), expected);
|
||||
|
||||
// Validate all preferences excluding defaults.
|
||||
ValidateRoot(context->GetAllPreferences(false), expected);
|
||||
|
||||
event->Signal();
|
||||
}
|
||||
|
||||
// No-op implementation.
|
||||
class TestRequestContextHandler : public CefRequestContextHandler {
|
||||
public:
|
||||
TestRequestContextHandler() {}
|
||||
|
||||
IMPLEMENT_REFCOUNTING(TestRequestContextHandler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// Verify default preference values on the global context.
|
||||
TEST(PreferenceTest, GlobalDefaults) {
|
||||
base::WaitableEvent event(false, false);
|
||||
|
||||
CefRefPtr<CefRequestContext> context = CefRequestContext::GetGlobalContext();
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
ValidateDefaults(context, false, &event);
|
||||
event.Wait();
|
||||
}
|
||||
|
||||
// Verify setting/getting preference values on the global context.
|
||||
TEST(PreferenceTest, GlobalSetGet) {
|
||||
base::WaitableEvent event(false, false);
|
||||
|
||||
CefRefPtr<CefRequestContext> context = CefRequestContext::GetGlobalContext();
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
ValidateSetGet(context, &event);
|
||||
event.Wait();
|
||||
|
||||
// Reset to the default values.
|
||||
ValidateDefaults(context, true, &event);
|
||||
event.Wait();
|
||||
}
|
||||
|
||||
// Verify setting/getting preference values on shared global contexts.
|
||||
TEST(PreferenceTest, GlobalSetGetShared) {
|
||||
base::WaitableEvent event(false, false);
|
||||
|
||||
CefRefPtr<CefRequestContext> context = CefRequestContext::GetGlobalContext();
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
// Sharing storage.
|
||||
CefRefPtr<CefRequestContext> context2 =
|
||||
CefRequestContext::CreateContext(context, NULL);
|
||||
EXPECT_TRUE(context2.get());
|
||||
|
||||
// Sharing storage.
|
||||
CefRefPtr<CefRequestContext> context3 =
|
||||
CefRequestContext::CreateContext(context, new TestRequestContextHandler);
|
||||
EXPECT_TRUE(context3.get());
|
||||
|
||||
// Unassociated context.
|
||||
CefRequestContextSettings settings;
|
||||
CefRefPtr<CefRequestContext> context4 =
|
||||
CefRequestContext::CreateContext(settings, NULL);
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
// Set/get the values on the first context.
|
||||
ValidateSetGet(context, &event);
|
||||
event.Wait();
|
||||
|
||||
// Get the values from the 2nd and 3rd contexts. They should be the same.
|
||||
ValidateGet(context2, &event);
|
||||
event.Wait();
|
||||
ValidateGet(context3, &event);
|
||||
event.Wait();
|
||||
|
||||
// Get the values from the 4th context. They should be at the default.
|
||||
ValidateDefaults(context4, false, &event);
|
||||
event.Wait();
|
||||
|
||||
// Reset to the default values.
|
||||
ValidateDefaults(context, true, &event);
|
||||
event.Wait();
|
||||
}
|
||||
|
||||
// Verify default preference values on a custom context.
|
||||
TEST(PreferenceTest, CustomDefaults) {
|
||||
base::WaitableEvent event(false, false);
|
||||
|
||||
CefRequestContextSettings settings;
|
||||
CefRefPtr<CefRequestContext> context =
|
||||
CefRequestContext::CreateContext(settings, NULL);
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
ValidateDefaults(context, false, &event);
|
||||
event.Wait();
|
||||
}
|
||||
|
||||
// Verify setting/getting preference values on a custom context.
|
||||
TEST(PreferenceTest, CustomSetGet) {
|
||||
base::WaitableEvent event(false, false);
|
||||
|
||||
CefRequestContextSettings settings;
|
||||
CefRefPtr<CefRequestContext> context =
|
||||
CefRequestContext::CreateContext(settings, NULL);
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
ValidateSetGet(context, &event);
|
||||
event.Wait();
|
||||
|
||||
// Reset to the default values.
|
||||
ValidateDefaults(context, true, &event);
|
||||
event.Wait();
|
||||
}
|
||||
|
||||
// Verify setting/getting preference values on shared custom contexts.
|
||||
TEST(PreferenceTest, CustomSetGetShared) {
|
||||
base::WaitableEvent event(false, false);
|
||||
|
||||
CefRequestContextSettings settings;
|
||||
CefRefPtr<CefRequestContext> context =
|
||||
CefRequestContext::CreateContext(settings, NULL);
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
// Sharing storage.
|
||||
CefRefPtr<CefRequestContext> context2 =
|
||||
CefRequestContext::CreateContext(context, NULL);
|
||||
EXPECT_TRUE(context2.get());
|
||||
|
||||
// Sharing storage.
|
||||
CefRefPtr<CefRequestContext> context3 =
|
||||
CefRequestContext::CreateContext(context, new TestRequestContextHandler);
|
||||
EXPECT_TRUE(context3.get());
|
||||
|
||||
// Unassociated context.
|
||||
CefRefPtr<CefRequestContext> context4 =
|
||||
CefRequestContext::CreateContext(settings, NULL);
|
||||
EXPECT_TRUE(context.get());
|
||||
|
||||
// Set/get the values on the first context.
|
||||
ValidateSetGet(context, &event);
|
||||
event.Wait();
|
||||
|
||||
// Get the values from the 2nd and 3d contexts. They should be the same.
|
||||
ValidateGet(context2, &event);
|
||||
event.Wait();
|
||||
ValidateGet(context3, &event);
|
||||
event.Wait();
|
||||
|
||||
// Get the values from the 4th context. They should be at the default.
|
||||
ValidateDefaults(context4, false, &event);
|
||||
event.Wait();
|
||||
|
||||
// Reset to the default values.
|
||||
ValidateDefaults(context, true, &event);
|
||||
event.Wait();
|
||||
}
|
||||
|
||||
|
||||
// Entry point for creating preference browser test objects.
|
||||
// Called from client_app_delegates.cc.
|
||||
void CreatePreferenceBrowserTests(
|
||||
client::ClientAppBrowser::DelegateSet& delegates) {
|
||||
delegates.insert(new PreferenceBrowserTest);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user