diff --git a/cef.gyp b/cef.gyp index 32cde2a98..4f6205331 100644 --- a/cef.gyp +++ b/cef.gyp @@ -968,6 +968,7 @@ '<(DEPTH)/components/components.gyp:data_use_measurement_core', '<(DEPTH)/components/components.gyp:devtools_discovery', '<(DEPTH)/components/components.gyp:devtools_http_handler', + '<(DEPTH)/components/components.gyp:google_core_browser', '<(DEPTH)/components/components.gyp:keyed_service_content', '<(DEPTH)/components/components.gyp:keyed_service_core', '<(DEPTH)/components/components.gyp:navigation_interception', @@ -1505,6 +1506,9 @@ # Include sources for permissions support. '<(DEPTH)/chrome/browser/permissions/permission_request_id.h', '<(DEPTH)/chrome/browser/permissions/permission_request_id.cc', + # Include sources for SafeSearch support. + '<(DEPTH)/chrome/browser/net/safe_search_util.cc', + '<(DEPTH)/chrome/browser/net/safe_search_util.h', ], 'conditions': [ ['OS=="win"', { diff --git a/libcef/browser/browser_context_impl.cc b/libcef/browser/browser_context_impl.cc index 8b12d7463..afb4641ec 100644 --- a/libcef/browser/browser_context_impl.cc +++ b/libcef/browser/browser_context_impl.cc @@ -209,12 +209,14 @@ CefBrowserContextImpl::~CefBrowserContextImpl() { pref_proxy_config_tracker_->DetachFromPrefService(); - if (host_content_settings_map_.get()) + if (url_request_getter_) + url_request_getter_->ShutdownOnUIThread(); + if (host_content_settings_map_) host_content_settings_map_->ShutdownOnUIThread(); // Delete the download manager delegate here because otherwise we'll crash // when it's accessed from the content::BrowserContext destructor. - if (download_manager_delegate_.get()) + if (download_manager_delegate_) download_manager_delegate_.reset(NULL); g_manager.Get().RemoveImpl(this, cache_path_); diff --git a/libcef/browser/net/network_delegate.cc b/libcef/browser/net/network_delegate.cc index 7f987c2cb..544b32336 100644 --- a/libcef/browser/net/network_delegate.cc +++ b/libcef/browser/net/network_delegate.cc @@ -18,6 +18,9 @@ #include "base/command_line.h" #include "base/metrics/field_trial.h" #include "base/strings/string_util.h" +#include "chrome/browser/net/safe_search_util.h" +#include "components/prefs/pref_member.h" +#include "components/prefs/pref_service.h" #include "content/public/common/content_switches.h" #include "net/base/net_errors.h" #include "net/filter/filter.h" @@ -38,10 +41,12 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { CefRefPtr cef_request, GURL* new_url, net::URLRequest* url_request, + bool force_google_safesearch, const CallbackType& callback) : cef_request_(cef_request), new_url_(new_url), url_request_(url_request), + force_google_safesearch_(force_google_safesearch), callback_(callback) { DCHECK(new_url); DCHECK(url_request_); @@ -54,11 +59,13 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { if (!callback_.is_null()) { // The callback is still pending. Cancel it now. if (CEF_CURRENTLY_ON_IOT()) { - RunNow(cef_request_, new_url_, url_request_, callback_, false); + RunNow(cef_request_, new_url_, url_request_, callback_, + force_google_safesearch_, false); } else { CEF_POST_TASK(CEF_IOT, base::Bind(&CefBeforeResourceLoadCallbackImpl::RunNow, - cef_request_, new_url_, url_request_, callback_, false)); + cef_request_, new_url_, url_request_, callback_, + force_google_safesearch_, false)); } } } @@ -77,7 +84,8 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { void ContinueNow(bool allow) { CEF_REQUIRE_IOT(); if (!callback_.is_null()) { - RunNow(cef_request_, new_url_, url_request_, callback_, allow); + RunNow(cef_request_, new_url_, url_request_, callback_, + force_google_safesearch_, allow); Disconnect(); } } @@ -115,6 +123,7 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { GURL* new_url, net::URLRequest* request, const CallbackType& callback, + bool force_google_safesearch, bool allow) { CEF_REQUIRE_IOT(); @@ -139,8 +148,12 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { request->RemoveUserData(UserDataKey()); // Only execute the callback if the request has not been canceled. - if (request->status().status() != net::URLRequestStatus::CANCELED) + if (request->status().status() != net::URLRequestStatus::CANCELED) { + if (force_google_safesearch && allow && new_url->is_empty()) + safe_search_util::ForceGoogleSafeSearch(request, new_url); + callback.Run(allow ? net::OK : net::ERR_ABORTED); + } } static inline void* UserDataKey() { @@ -151,6 +164,7 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { const GURL old_url_; GURL* new_url_; net::URLRequest* url_request_; + bool force_google_safesearch_; CallbackType callback_; // The user data key. @@ -224,7 +238,8 @@ class CefAuthCallbackImpl : public CefAuthCallback { } // namespace -CefNetworkDelegate::CefNetworkDelegate() { +CefNetworkDelegate::CefNetworkDelegate() + : force_google_safesearch_(nullptr) { } CefNetworkDelegate::~CefNetworkDelegate() { @@ -255,6 +270,9 @@ int CefNetworkDelegate::OnBeforeURLRequest( net::URLRequest* request, const net::CompletionCallback& callback, GURL* new_url) { + const bool force_google_safesearch = + (force_google_safesearch_ && force_google_safesearch_->GetValue()); + CefRefPtr browser = CefBrowserHostImpl::GetBrowserForRequest(request); if (browser.get()) { @@ -279,6 +297,7 @@ int CefNetworkDelegate::OnBeforeURLRequest( CefRefPtr callbackImpl( new CefBeforeResourceLoadCallbackImpl(requestPtr, new_url, request, + force_google_safesearch, callback)); // Give the client an opportunity to evaluate the request. @@ -298,6 +317,9 @@ int CefNetworkDelegate::OnBeforeURLRequest( } } + if (force_google_safesearch && new_url->is_empty()) + safe_search_util::ForceGoogleSafeSearch(request, new_url); + // Continue the request immediately. return net::OK; } diff --git a/libcef/browser/net/network_delegate.h b/libcef/browser/net/network_delegate.h index 16c821e22..e87b61f97 100644 --- a/libcef/browser/net/network_delegate.h +++ b/libcef/browser/net/network_delegate.h @@ -9,6 +9,9 @@ #include "base/macros.h" #include "net/base/network_delegate_impl.h" +template class PrefMember; +typedef PrefMember BooleanPrefMember; + // Used for intercepting resource requests, redirects and responses. The single // instance of this class is managed by CefURLRequestContextGetter. class CefNetworkDelegate : public net::NetworkDelegateImpl { @@ -21,6 +24,11 @@ class CefNetworkDelegate : public net::NetworkDelegateImpl { static bool AreExperimentalCookieFeaturesEnabled(); static bool AreStrictSecureCookiesEnabled(); + void set_force_google_safesearch( + BooleanPrefMember* force_google_safesearch) { + force_google_safesearch_ = force_google_safesearch; + } + private: // net::NetworkDelegate methods. int OnBeforeURLRequest(net::URLRequest* request, @@ -39,6 +47,9 @@ class CefNetworkDelegate : public net::NetworkDelegateImpl { net::Filter* SetupFilter(net::URLRequest* request, net::Filter* filter_list) override; + // Weak, owned by our owner (CefURLRequestContextGetterImpl). + BooleanPrefMember* force_google_safesearch_; + DISALLOW_COPY_AND_ASSIGN(CefNetworkDelegate); }; diff --git a/libcef/browser/net/url_request_context_getter_impl.cc b/libcef/browser/net/url_request_context_getter_impl.cc index e56994939..e4d429f37 100644 --- a/libcef/browser/net/url_request_context_getter_impl.cc +++ b/libcef/browser/net/url_request_context_getter_impl.cc @@ -120,6 +120,10 @@ CefURLRequestContextGetterImpl::CefURLRequestContextGetterImpl( std::swap(protocol_handlers_, *protocol_handlers); + force_google_safesearch_.Init(prefs::kForceGoogleSafeSearch, pref_service); + force_google_safesearch_.MoveToThread( + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); + #if defined(OS_POSIX) && !defined(OS_ANDROID) gsapi_library_name_ = pref_service->GetString(prefs::kGSSAPILibraryName); #endif @@ -134,6 +138,11 @@ CefURLRequestContextGetterImpl::~CefURLRequestContextGetterImpl() { storage_->set_proxy_service(NULL); } +void CefURLRequestContextGetterImpl::ShutdownOnUIThread() { + CEF_REQUIRE_UIT(); + force_google_safesearch_.Destroy(); +} + net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() { CEF_REQUIRE_IOT(); @@ -152,7 +161,10 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() { SetCookieStoragePath(cache_path, settings_.persist_session_cookies ? true : false); - storage_->set_network_delegate(base::WrapUnique(new CefNetworkDelegate)); + std::unique_ptr network_delegate( + new CefNetworkDelegate()); + network_delegate->set_force_google_safesearch(&force_google_safesearch_); + storage_->set_network_delegate(std::move(network_delegate)); storage_->set_channel_id_service(base::WrapUnique( new net::ChannelIDService( diff --git a/libcef/browser/net/url_request_context_getter_impl.h b/libcef/browser/net/url_request_context_getter_impl.h index 50d1d15da..9645da358 100644 --- a/libcef/browser/net/url_request_context_getter_impl.h +++ b/libcef/browser/net/url_request_context_getter_impl.h @@ -17,6 +17,7 @@ #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" +#include "components/prefs/pref_member.h" #include "content/public/browser/browser_context.h" #include "net/url_request/url_request_job_factory.h" @@ -52,6 +53,9 @@ class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter { content::URLRequestInterceptorScopedVector request_interceptors); ~CefURLRequestContextGetterImpl() override; + // Called when the BrowserContextImpl is destroyed. + void ShutdownOnUIThread(); + // net::URLRequestContextGetter implementation. net::URLRequestContext* GetURLRequestContext() override; scoped_refptr @@ -102,6 +106,9 @@ class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter { std::vector > handler_list_; + // Member variables which are pointed to by the various context objects. + mutable BooleanPrefMember force_google_safesearch_; + DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetterImpl); }; diff --git a/libcef/browser/prefs/browser_prefs.cc b/libcef/browser/prefs/browser_prefs.cc index 3122cf316..88d55437c 100644 --- a/libcef/browser/prefs/browser_prefs.cc +++ b/libcef/browser/prefs/browser_prefs.cc @@ -161,6 +161,8 @@ std::unique_ptr CreatePrefService(const base::FilePath& pref_path) registry->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize, false); // Network preferences. + // Based on ProfileImpl::RegisterProfilePrefs. + registry->RegisterBooleanPref(prefs::kForceGoogleSafeSearch, false); // Based on IOThread::RegisterPrefs. #if defined(OS_POSIX) && !defined(OS_ANDROID) registry->RegisterStringPref(prefs::kGSSAPILibraryName, std::string());