mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			808 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			808 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (c) 2012 The Chromium 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 "libcef/browser/browser_context.h"
 | |
| 
 | |
| #include <map>
 | |
| #include <utility>
 | |
| 
 | |
| #include "libcef/browser/content_browser_client.h"
 | |
| #include "libcef/browser/context.h"
 | |
| #include "libcef/browser/download_manager_delegate.h"
 | |
| #include "libcef/browser/extensions/extension_system.h"
 | |
| #include "libcef/browser/prefs/browser_prefs.h"
 | |
| #include "libcef/browser/request_context_impl.h"
 | |
| #include "libcef/browser/ssl_host_state_delegate.h"
 | |
| #include "libcef/browser/thread_util.h"
 | |
| #include "libcef/common/cef_switches.h"
 | |
| #include "libcef/common/extensions/extensions_util.h"
 | |
| 
 | |
| #include "base/command_line.h"
 | |
| #include "base/files/file_util.h"
 | |
| #include "base/lazy_instance.h"
 | |
| #include "base/logging.h"
 | |
| #include "base/strings/string_util.h"
 | |
| #include "chrome/browser/font_family_cache.h"
 | |
| #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
 | |
| #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
 | |
| #include "chrome/common/pref_names.h"
 | |
| #include "components/content_settings/core/browser/host_content_settings_map.h"
 | |
| #include "components/guest_view/browser/guest_view_manager.h"
 | |
| #include "components/keyed_service/content/browser_context_dependency_manager.h"
 | |
| #include "components/keyed_service/core/simple_dependency_manager.h"
 | |
| #include "components/keyed_service/core/simple_key_map.h"
 | |
| #include "components/prefs/pref_service.h"
 | |
| #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
 | |
| #include "components/user_prefs/user_prefs.h"
 | |
| #include "components/visitedlink/browser/visitedlink_event_listener.h"
 | |
| #include "components/visitedlink/browser/visitedlink_master.h"
 | |
| #include "components/zoom/zoom_event_manager.h"
 | |
| #include "content/public/browser/browser_task_traits.h"
 | |
| #include "content/public/browser/browser_thread.h"
 | |
| #include "content/public/browser/download_manager.h"
 | |
| #include "content/public/browser/storage_partition.h"
 | |
| #include "extensions/browser/extension_protocols.h"
 | |
| #include "extensions/browser/process_manager.h"
 | |
| #include "extensions/common/constants.h"
 | |
| #include "net/proxy_resolution/proxy_config_service.h"
 | |
| #include "net/proxy_resolution/proxy_resolution_service.h"
 | |
| 
 | |
| using content::BrowserThread;
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| // Manages the global list of Impl instances.
 | |
| class ImplManager {
 | |
|  public:
 | |
|   typedef std::vector<CefBrowserContext*> Vector;
 | |
| 
 | |
|   ImplManager() {}
 | |
|   ~ImplManager() {
 | |
|     DCHECK(all_.empty());
 | |
|     DCHECK(map_.empty());
 | |
|   }
 | |
| 
 | |
|   void AddImpl(CefBrowserContext* impl) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     DCHECK(!IsValidImpl(impl));
 | |
|     all_.push_back(impl);
 | |
|   }
 | |
| 
 | |
|   void RemoveImpl(CefBrowserContext* impl, const base::FilePath& path) {
 | |
|     CEF_REQUIRE_UIT();
 | |
| 
 | |
|     Vector::iterator it = GetImplPos(impl);
 | |
|     DCHECK(it != all_.end());
 | |
|     all_.erase(it);
 | |
| 
 | |
|     if (!path.empty()) {
 | |
|       PathMap::iterator it = map_.find(path);
 | |
|       DCHECK(it != map_.end());
 | |
|       if (it != map_.end())
 | |
|         map_.erase(it);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   bool IsValidImpl(const CefBrowserContext* impl) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     return GetImplPos(impl) != all_.end();
 | |
|   }
 | |
| 
 | |
|   CefBrowserContext* GetImplForIDs(int render_process_id,
 | |
|                                    int render_frame_id,
 | |
|                                    int frame_tree_node_id,
 | |
|                                    bool require_frame_match) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     for (const auto& context : all_) {
 | |
|       if (context->IsAssociatedContext(render_process_id, render_frame_id,
 | |
|                                        frame_tree_node_id,
 | |
|                                        require_frame_match)) {
 | |
|         return context;
 | |
|       }
 | |
|     }
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   CefBrowserContext* GetImplForContext(const content::BrowserContext* context) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     if (!context)
 | |
|       return nullptr;
 | |
| 
 | |
|     Vector::iterator it = all_.begin();
 | |
|     for (; it != all_.end(); ++it) {
 | |
|       if (*it == context)
 | |
|         return *it;
 | |
|     }
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   void SetImplPath(CefBrowserContext* impl, const base::FilePath& path) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     DCHECK(!path.empty());
 | |
|     DCHECK(IsValidImpl(impl));
 | |
|     DCHECK(GetImplForPath(path) == nullptr);
 | |
|     map_.insert(std::make_pair(path, impl));
 | |
|   }
 | |
| 
 | |
|   CefBrowserContext* GetImplForPath(const base::FilePath& path) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     DCHECK(!path.empty());
 | |
|     PathMap::const_iterator it = map_.find(path);
 | |
|     if (it != map_.end())
 | |
|       return it->second;
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   const Vector GetAllImpl() const { return all_; }
 | |
| 
 | |
|  private:
 | |
|   Vector::iterator GetImplPos(const CefBrowserContext* impl) {
 | |
|     Vector::iterator it = all_.begin();
 | |
|     for (; it != all_.end(); ++it) {
 | |
|       if (*it == impl)
 | |
|         return it;
 | |
|     }
 | |
|     return all_.end();
 | |
|   }
 | |
| 
 | |
|   typedef std::map<base::FilePath, CefBrowserContext*> PathMap;
 | |
|   PathMap map_;
 | |
| 
 | |
|   Vector all_;
 | |
| 
 | |
|   DISALLOW_COPY_AND_ASSIGN(ImplManager);
 | |
| };
 | |
| 
 | |
| #if DCHECK_IS_ON()
 | |
| // Because of DCHECK()s in the object destructor.
 | |
| base::LazyInstance<ImplManager>::DestructorAtExit g_manager =
 | |
|     LAZY_INSTANCE_INITIALIZER;
 | |
| #else
 | |
| base::LazyInstance<ImplManager>::Leaky g_manager = LAZY_INSTANCE_INITIALIZER;
 | |
| #endif
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| // Creates and manages VisitedLinkEventListener objects for each
 | |
| // CefBrowserContext sharing the same VisitedLinkMaster.
 | |
| class CefVisitedLinkListener : public visitedlink::VisitedLinkMaster::Listener {
 | |
|  public:
 | |
|   CefVisitedLinkListener() { DCHECK(listener_map_.empty()); }
 | |
| 
 | |
|   void CreateListenerForContext(const CefBrowserContext* context) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     auto listener = std::make_unique<visitedlink::VisitedLinkEventListener>(
 | |
|         const_cast<CefBrowserContext*>(context));
 | |
|     listener_map_.insert(std::make_pair(context, std::move(listener)));
 | |
|   }
 | |
| 
 | |
|   void RemoveListenerForContext(const CefBrowserContext* context) {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     ListenerMap::iterator it = listener_map_.find(context);
 | |
|     DCHECK(it != listener_map_.end());
 | |
|     listener_map_.erase(it);
 | |
|   }
 | |
| 
 | |
|   // visitedlink::VisitedLinkMaster::Listener methods.
 | |
| 
 | |
|   void NewTable(base::ReadOnlySharedMemoryRegion* table_region) override {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     ListenerMap::iterator it = listener_map_.begin();
 | |
|     for (; it != listener_map_.end(); ++it)
 | |
|       it->second->NewTable(table_region);
 | |
|   }
 | |
| 
 | |
|   void Add(visitedlink::VisitedLinkCommon::Fingerprint fingerprint) override {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     ListenerMap::iterator it = listener_map_.begin();
 | |
|     for (; it != listener_map_.end(); ++it)
 | |
|       it->second->Add(fingerprint);
 | |
|   }
 | |
| 
 | |
|   void Reset(bool invalidate_hashes) override {
 | |
|     CEF_REQUIRE_UIT();
 | |
|     ListenerMap::iterator it = listener_map_.begin();
 | |
|     for (; it != listener_map_.end(); ++it)
 | |
|       it->second->Reset(invalidate_hashes);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   // Map of CefBrowserContext to the associated VisitedLinkEventListener.
 | |
|   typedef std::map<const CefBrowserContext*,
 | |
|                    std::unique_ptr<visitedlink::VisitedLinkEventListener>>
 | |
|       ListenerMap;
 | |
|   ListenerMap listener_map_;
 | |
| 
 | |
|   DISALLOW_COPY_AND_ASSIGN(CefVisitedLinkListener);
 | |
| };
 | |
| 
 | |
| CefBrowserContext::CefBrowserContext(const CefRequestContextSettings& settings)
 | |
|     : settings_(settings) {
 | |
|   g_manager.Get().AddImpl(this);
 | |
| }
 | |
| 
 | |
| CefBrowserContext::~CefBrowserContext() {
 | |
|   CEF_REQUIRE_UIT();
 | |
| 
 | |
|   // No CefRequestContext should be referencing this object any longer.
 | |
|   DCHECK(request_context_set_.empty());
 | |
| 
 | |
|   // Unregister the context first to avoid re-entrancy during shutdown.
 | |
|   g_manager.Get().RemoveImpl(this, cache_path_);
 | |
| 
 | |
|   // Send notifications to clean up objects associated with this Profile.
 | |
|   MaybeSendDestroyedNotification();
 | |
| 
 | |
|   ChromePluginServiceFilter::GetInstance()->UnregisterProfile(this);
 | |
| 
 | |
|   // Remove any BrowserContextKeyedServiceFactory associations. This must be
 | |
|   // called before the ProxyService owned by CefBrowserContext is destroyed.
 | |
|   // The SimpleDependencyManager should always be passed after the
 | |
|   // BrowserContextDependencyManager. This is because the KeyedService instances
 | |
|   // in the BrowserContextDependencyManager's dependency graph can depend on the
 | |
|   // ones in the SimpleDependencyManager's graph.
 | |
|   DependencyManager::PerformInterlockedTwoPhaseShutdown(
 | |
|       BrowserContextDependencyManager::GetInstance(), this,
 | |
|       SimpleDependencyManager::GetInstance(), key_.get());
 | |
| 
 | |
|   key_.reset();
 | |
|   SimpleKeyMap::GetInstance()->Dissociate(this);
 | |
| 
 | |
|   // Shuts down the storage partitions associated with this browser context.
 | |
|   // This must be called before the browser context is actually destroyed
 | |
|   // and before a clean-up task for its corresponding IO thread residents
 | |
|   // (e.g. ResourceContext) is posted, so that the classes that hung on
 | |
|   // StoragePartition can have time to do necessary cleanups on IO thread.
 | |
|   ShutdownStoragePartitions();
 | |
| 
 | |
|   if (resource_context_.get()) {
 | |
|     // Destruction of the ResourceContext will trigger destruction of all
 | |
|     // associated network requests.
 | |
|     content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE,
 | |
|                                        resource_context_.release());
 | |
|   }
 | |
| 
 | |
|   visitedlink_listener_->RemoveListenerForContext(this);
 | |
| 
 | |
|   // The FontFamilyCache references the ProxyService so delete it before the
 | |
|   // ProxyService is deleted.
 | |
|   SetUserData(&kFontFamilyCacheKey, nullptr);
 | |
| 
 | |
|   pref_proxy_config_tracker_->DetachFromPrefService();
 | |
| 
 | |
|   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_)
 | |
|     download_manager_delegate_.reset(nullptr);
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::Initialize() {
 | |
|   CefContext* context = CefContext::Get();
 | |
| 
 | |
|   cache_path_ = base::FilePath(CefString(&settings_.cache_path));
 | |
|   if (!context->ValidateCachePath(cache_path_)) {
 | |
|     // Reset to in-memory storage.
 | |
|     CefString(&settings_.cache_path).clear();
 | |
|     cache_path_ = base::FilePath();
 | |
|   }
 | |
| 
 | |
|   if (!cache_path_.empty())
 | |
|     g_manager.Get().SetImplPath(this, cache_path_);
 | |
| 
 | |
|   if (settings_.accept_language_list.length == 0) {
 | |
|     // Use the global language list setting.
 | |
|     CefString(&settings_.accept_language_list) =
 | |
|         CefString(&context->settings().accept_language_list);
 | |
|   }
 | |
| 
 | |
|   if (!!settings_.persist_session_cookies) {
 | |
|     set_should_persist_session_cookies(true);
 | |
|   }
 | |
| 
 | |
|   key_ = std::make_unique<ProfileKey>(GetPath());
 | |
|   SimpleKeyMap::GetInstance()->Associate(this, key_.get());
 | |
| 
 | |
|   // Initialize the PrefService object.
 | |
|   pref_service_ = browser_prefs::CreatePrefService(
 | |
|       this, cache_path_, !!settings_.persist_user_preferences);
 | |
| 
 | |
|   content::BrowserContext::Initialize(this, GetPath());
 | |
| 
 | |
|   resource_context_.reset(new CefResourceContext(IsOffTheRecord()));
 | |
| 
 | |
|   // This must be called before creating any services to avoid hitting
 | |
|   // DependencyManager::AssertContextWasntDestroyed when creating/destroying
 | |
|   // multiple browser contexts (due to pointer address reuse).
 | |
|   BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
 | |
|       this);
 | |
| 
 | |
|   const bool extensions_enabled = extensions::ExtensionsEnabled();
 | |
|   if (extensions_enabled) {
 | |
|     // Create the custom ExtensionSystem first because other KeyedServices
 | |
|     // depend on it.
 | |
|     extension_system_ = static_cast<extensions::CefExtensionSystem*>(
 | |
|         extensions::ExtensionSystem::Get(this));
 | |
|     extension_system_->InitForRegularProfile(true);
 | |
| 
 | |
|     // Make sure the ProcessManager is created so that it receives extension
 | |
|     // load notifications. This is necessary for the proper initialization of
 | |
|     // background/event pages.
 | |
|     extensions::ProcessManager::Get(this);
 | |
|   }
 | |
| 
 | |
|   // Initialize visited links management.
 | |
|   base::FilePath visited_link_path;
 | |
|   if (!cache_path_.empty())
 | |
|     visited_link_path = cache_path_.Append(FILE_PATH_LITERAL("Visited Links"));
 | |
|   visitedlink_listener_ = new CefVisitedLinkListener;
 | |
|   visitedlink_master_.reset(new visitedlink::VisitedLinkMaster(
 | |
|       visitedlink_listener_, this, !visited_link_path.empty(), false,
 | |
|       visited_link_path, 0));
 | |
|   visitedlink_listener_->CreateListenerForContext(this);
 | |
|   visitedlink_master_->Init();
 | |
| 
 | |
|   // Initialize proxy configuration tracker.
 | |
|   pref_proxy_config_tracker_.reset(new PrefProxyConfigTrackerImpl(
 | |
|       GetPrefs(), base::CreateSingleThreadTaskRunner({BrowserThread::IO})));
 | |
| 
 | |
|   // Spell checking support and possibly other subsystems retrieve the
 | |
|   // PrefService associated with a BrowserContext via UserPrefs::Get().
 | |
|   PrefService* pref_service = GetPrefs();
 | |
|   DCHECK(pref_service);
 | |
|   user_prefs::UserPrefs::Set(this, pref_service);
 | |
|   key_->SetPrefs(pref_service);
 | |
| 
 | |
|   if (extensions_enabled)
 | |
|     extension_system_->Init();
 | |
| 
 | |
|   ChromePluginServiceFilter::GetInstance()->RegisterProfile(this);
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::AddCefRequestContext(CefRequestContextImpl* context) {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   request_context_set_.insert(context);
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::RemoveCefRequestContext(
 | |
|     CefRequestContextImpl* context) {
 | |
|   CEF_REQUIRE_UIT();
 | |
| 
 | |
|   if (extensions::ExtensionsEnabled()) {
 | |
|     extension_system()->OnRequestContextDeleted(context);
 | |
|   }
 | |
| 
 | |
|   request_context_set_.erase(context);
 | |
| 
 | |
|   // Delete ourselves when the reference count reaches zero.
 | |
|   if (request_context_set_.empty())
 | |
|     delete this;
 | |
| }
 | |
| 
 | |
| // static
 | |
| CefBrowserContext* CefBrowserContext::GetForCachePath(
 | |
|     const base::FilePath& cache_path) {
 | |
|   return g_manager.Get().GetImplForPath(cache_path);
 | |
| }
 | |
| 
 | |
| // static
 | |
| CefBrowserContext* CefBrowserContext::GetForIDs(int render_process_id,
 | |
|                                                 int render_frame_id,
 | |
|                                                 int frame_tree_node_id,
 | |
|                                                 bool require_frame_match) {
 | |
|   return g_manager.Get().GetImplForIDs(render_process_id, render_frame_id,
 | |
|                                        frame_tree_node_id, require_frame_match);
 | |
| }
 | |
| 
 | |
| // static
 | |
| CefBrowserContext* CefBrowserContext::GetForContext(
 | |
|     content::BrowserContext* context) {
 | |
|   return g_manager.Get().GetImplForContext(context);
 | |
| }
 | |
| 
 | |
| // static
 | |
| std::vector<CefBrowserContext*> CefBrowserContext::GetAll() {
 | |
|   return g_manager.Get().GetAllImpl();
 | |
| }
 | |
| 
 | |
| content::ResourceContext* CefBrowserContext::GetResourceContext() {
 | |
|   return resource_context_.get();
 | |
| }
 | |
| 
 | |
| content::ClientHintsControllerDelegate*
 | |
| CefBrowserContext::GetClientHintsControllerDelegate() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::SetCorsOriginAccessListForOrigin(
 | |
|     const url::Origin& source_origin,
 | |
|     std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
 | |
|     std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
 | |
|     base::OnceClosure closure) {
 | |
|   // This method is called for Extension support.
 | |
|   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(closure));
 | |
| }
 | |
| 
 | |
| ChromeZoomLevelPrefs* CefBrowserContext::GetZoomLevelPrefs() {
 | |
|   return static_cast<ChromeZoomLevelPrefs*>(
 | |
|       GetStoragePartition(this, nullptr)->GetZoomLevelDelegate());
 | |
| }
 | |
| 
 | |
| scoped_refptr<network::SharedURLLoaderFactory>
 | |
| CefBrowserContext::GetURLLoaderFactory() {
 | |
|   return GetDefaultStoragePartition(this)
 | |
|       ->GetURLLoaderFactoryForBrowserProcess();
 | |
| }
 | |
| 
 | |
| base::FilePath CefBrowserContext::GetPath() {
 | |
|   return cache_path_;
 | |
| }
 | |
| 
 | |
| base::FilePath CefBrowserContext::GetPath() const {
 | |
|   return cache_path_;
 | |
| }
 | |
| 
 | |
| std::unique_ptr<content::ZoomLevelDelegate>
 | |
| CefBrowserContext::CreateZoomLevelDelegate(
 | |
|     const base::FilePath& partition_path) {
 | |
|   if (cache_path_.empty())
 | |
|     return std::unique_ptr<content::ZoomLevelDelegate>();
 | |
| 
 | |
|   return base::WrapUnique(new ChromeZoomLevelPrefs(
 | |
|       GetPrefs(), cache_path_, partition_path,
 | |
|       zoom::ZoomEventManager::GetForBrowserContext(this)->GetWeakPtr()));
 | |
| }
 | |
| 
 | |
| bool CefBrowserContext::IsOffTheRecord() const {
 | |
|   // CEF contexts are never flagged as off-the-record. It causes problems
 | |
|   // for the extension system.
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| content::DownloadManagerDelegate*
 | |
| CefBrowserContext::GetDownloadManagerDelegate() {
 | |
|   if (!download_manager_delegate_) {
 | |
|     content::DownloadManager* manager =
 | |
|         BrowserContext::GetDownloadManager(this);
 | |
|     download_manager_delegate_.reset(new CefDownloadManagerDelegate(manager));
 | |
|   }
 | |
|   return download_manager_delegate_.get();
 | |
| }
 | |
| 
 | |
| content::BrowserPluginGuestManager* CefBrowserContext::GetGuestManager() {
 | |
|   DCHECK(extensions::ExtensionsEnabled());
 | |
|   return guest_view::GuestViewManager::FromBrowserContext(this);
 | |
| }
 | |
| 
 | |
| storage::SpecialStoragePolicy* CefBrowserContext::GetSpecialStoragePolicy() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| content::PushMessagingService* CefBrowserContext::GetPushMessagingService() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| content::SSLHostStateDelegate* CefBrowserContext::GetSSLHostStateDelegate() {
 | |
|   if (!ssl_host_state_delegate_.get())
 | |
|     ssl_host_state_delegate_.reset(new CefSSLHostStateDelegate());
 | |
|   return ssl_host_state_delegate_.get();
 | |
| }
 | |
| 
 | |
| content::PermissionControllerDelegate*
 | |
| CefBrowserContext::GetPermissionControllerDelegate() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| content::BackgroundFetchDelegate*
 | |
| CefBrowserContext::GetBackgroundFetchDelegate() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| content::BackgroundSyncController*
 | |
| CefBrowserContext::GetBackgroundSyncController() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| content::BrowsingDataRemoverDelegate*
 | |
| CefBrowserContext::GetBrowsingDataRemoverDelegate() {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| PrefService* CefBrowserContext::GetPrefs() {
 | |
|   return pref_service_.get();
 | |
| }
 | |
| 
 | |
| const PrefService* CefBrowserContext::GetPrefs() const {
 | |
|   return pref_service_.get();
 | |
| }
 | |
| 
 | |
| ProfileKey* CefBrowserContext::GetProfileKey() const {
 | |
|   DCHECK(key_);
 | |
|   return key_.get();
 | |
| }
 | |
| 
 | |
| policy::SchemaRegistryService*
 | |
| CefBrowserContext::GetPolicySchemaRegistryService() {
 | |
|   NOTREACHED();
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| policy::UserCloudPolicyManager* CefBrowserContext::GetUserCloudPolicyManager() {
 | |
|   NOTREACHED();
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| policy::ProfilePolicyConnector* CefBrowserContext::GetProfilePolicyConnector() {
 | |
|   NOTREACHED();
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| const policy::ProfilePolicyConnector*
 | |
| CefBrowserContext::GetProfilePolicyConnector() const {
 | |
|   NOTREACHED();
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| const CefRequestContextSettings& CefBrowserContext::GetSettings() const {
 | |
|   return settings_;
 | |
| }
 | |
| 
 | |
| HostContentSettingsMap* CefBrowserContext::GetHostContentSettingsMap() {
 | |
|   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 | |
|   if (!host_content_settings_map_.get()) {
 | |
|     // The |is_incognito_profile| and |is_guest_profile| arguments are
 | |
|     // intentionally set to false as they otherwise limit the types of values
 | |
|     // that can be stored in the settings map (for example, default values set
 | |
|     // via DefaultProvider::SetWebsiteSetting).
 | |
|     host_content_settings_map_ =
 | |
|         new HostContentSettingsMap(GetPrefs(), false, false, false);
 | |
| 
 | |
|     // Change the default plugin policy.
 | |
|     const base::CommandLine* command_line =
 | |
|         base::CommandLine::ForCurrentProcess();
 | |
|     const std::string& plugin_policy_str =
 | |
|         command_line->GetSwitchValueASCII(switches::kPluginPolicy);
 | |
|     if (!plugin_policy_str.empty()) {
 | |
|       ContentSetting plugin_policy = CONTENT_SETTING_ALLOW;
 | |
|       if (base::LowerCaseEqualsASCII(plugin_policy_str,
 | |
|                                      switches::kPluginPolicy_Detect)) {
 | |
|         plugin_policy = CONTENT_SETTING_DETECT_IMPORTANT_CONTENT;
 | |
|       } else if (base::LowerCaseEqualsASCII(plugin_policy_str,
 | |
|                                             switches::kPluginPolicy_Block)) {
 | |
|         plugin_policy = CONTENT_SETTING_BLOCK;
 | |
|       }
 | |
|       host_content_settings_map_->SetDefaultContentSetting(
 | |
|           CONTENT_SETTINGS_TYPE_PLUGINS, plugin_policy);
 | |
|     }
 | |
|   }
 | |
|   return host_content_settings_map_.get();
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
 | |
|   visitedlink_master_->AddURLs(urls);
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::RebuildTable(
 | |
|     const scoped_refptr<URLEnumerator>& enumerator) {
 | |
|   // Called when visited links will not or cannot be loaded from disk.
 | |
|   enumerator->OnComplete(true);
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::OnRenderFrameCreated(
 | |
|     CefRequestContextImpl* request_context,
 | |
|     int render_process_id,
 | |
|     int render_frame_id,
 | |
|     int frame_tree_node_id,
 | |
|     bool is_main_frame,
 | |
|     bool is_guest_view) {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   DCHECK_GE(render_process_id, 0);
 | |
|   DCHECK_GE(render_frame_id, 0);
 | |
|   DCHECK_GE(frame_tree_node_id, 0);
 | |
| 
 | |
|   render_id_set_.insert(std::make_pair(render_process_id, render_frame_id));
 | |
|   node_id_set_.insert(frame_tree_node_id);
 | |
| 
 | |
|   CefRefPtr<CefRequestContextHandler> handler = request_context->GetHandler();
 | |
|   if (handler) {
 | |
|     handler_map_.AddHandler(render_process_id, render_frame_id,
 | |
|                             frame_tree_node_id, handler);
 | |
| 
 | |
|     if (resource_context_) {
 | |
|       // Using base::Unretained() is safe because both this callback and
 | |
|       // possible deletion of |resource_context_| will execute on the IO thread,
 | |
|       // and this callback will be executed first.
 | |
|       CEF_POST_TASK(CEF_IOT,
 | |
|                     base::Bind(&CefResourceContext::AddHandler,
 | |
|                                base::Unretained(resource_context_.get()),
 | |
|                                render_process_id, render_frame_id,
 | |
|                                frame_tree_node_id, handler));
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::OnRenderFrameDeleted(
 | |
|     CefRequestContextImpl* request_context,
 | |
|     int render_process_id,
 | |
|     int render_frame_id,
 | |
|     int frame_tree_node_id,
 | |
|     bool is_main_frame,
 | |
|     bool is_guest_view) {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   DCHECK_GE(render_process_id, 0);
 | |
|   DCHECK_GE(render_frame_id, 0);
 | |
|   DCHECK_GE(frame_tree_node_id, 0);
 | |
| 
 | |
|   auto it1 =
 | |
|       render_id_set_.find(std::make_pair(render_process_id, render_frame_id));
 | |
|   if (it1 != render_id_set_.end())
 | |
|     render_id_set_.erase(it1);
 | |
| 
 | |
|   auto it2 = node_id_set_.find(frame_tree_node_id);
 | |
|   if (it2 != node_id_set_.end())
 | |
|     node_id_set_.erase(it2);
 | |
| 
 | |
|   CefRefPtr<CefRequestContextHandler> handler = request_context->GetHandler();
 | |
|   if (handler) {
 | |
|     handler_map_.RemoveHandler(render_process_id, render_frame_id,
 | |
|                                frame_tree_node_id);
 | |
| 
 | |
|     if (resource_context_) {
 | |
|       // Using base::Unretained() is safe because both this callback and
 | |
|       // possible deletion of |resource_context_| will execute on the IO thread,
 | |
|       // and this callback will be executed first.
 | |
|       CEF_POST_TASK(
 | |
|           CEF_IOT,
 | |
|           base::Bind(&CefResourceContext::RemoveHandler,
 | |
|                      base::Unretained(resource_context_.get()),
 | |
|                      render_process_id, render_frame_id, frame_tree_node_id));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (is_main_frame) {
 | |
|     ClearPluginLoadDecision(render_process_id);
 | |
|   }
 | |
| }
 | |
| 
 | |
| CefRefPtr<CefRequestContextHandler> CefBrowserContext::GetHandler(
 | |
|     int render_process_id,
 | |
|     int render_frame_id,
 | |
|     int frame_tree_node_id,
 | |
|     bool require_frame_match) const {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   return handler_map_.GetHandler(render_process_id, render_frame_id,
 | |
|                                  frame_tree_node_id, require_frame_match);
 | |
| }
 | |
| 
 | |
| bool CefBrowserContext::IsAssociatedContext(int render_process_id,
 | |
|                                             int render_frame_id,
 | |
|                                             int frame_tree_node_id,
 | |
|                                             bool require_frame_match) const {
 | |
|   CEF_REQUIRE_UIT();
 | |
| 
 | |
|   if (render_process_id >= 0 && render_frame_id >= 0) {
 | |
|     const auto it1 =
 | |
|         render_id_set_.find(std::make_pair(render_process_id, render_frame_id));
 | |
|     if (it1 != render_id_set_.end())
 | |
|       return true;
 | |
|   }
 | |
| 
 | |
|   if (frame_tree_node_id >= 0) {
 | |
|     const auto it2 = node_id_set_.find(frame_tree_node_id);
 | |
|     if (it2 != node_id_set_.end())
 | |
|       return true;
 | |
|   }
 | |
| 
 | |
|   if (render_process_id >= 0 && !require_frame_match) {
 | |
|     // Choose an arbitrary handler for the same process.
 | |
|     for (const auto& render_ids : render_id_set_) {
 | |
|       if (render_ids.first == render_process_id)
 | |
|         return true;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::AddPluginLoadDecision(
 | |
|     int render_process_id,
 | |
|     const base::FilePath& plugin_path,
 | |
|     bool is_main_frame,
 | |
|     const url::Origin& main_frame_origin,
 | |
|     chrome::mojom::PluginStatus status) {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   DCHECK_GE(render_process_id, 0);
 | |
|   DCHECK(!plugin_path.empty());
 | |
| 
 | |
|   plugin_load_decision_map_.insert(std::make_pair(
 | |
|       std::make_pair(std::make_pair(render_process_id, plugin_path),
 | |
|                      std::make_pair(is_main_frame, main_frame_origin)),
 | |
|       status));
 | |
| }
 | |
| 
 | |
| bool CefBrowserContext::HasPluginLoadDecision(
 | |
|     int render_process_id,
 | |
|     const base::FilePath& plugin_path,
 | |
|     bool is_main_frame,
 | |
|     const url::Origin& main_frame_origin,
 | |
|     chrome::mojom::PluginStatus* status) const {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   DCHECK_GE(render_process_id, 0);
 | |
|   DCHECK(!plugin_path.empty());
 | |
| 
 | |
|   PluginLoadDecisionMap::const_iterator it = plugin_load_decision_map_.find(
 | |
|       std::make_pair(std::make_pair(render_process_id, plugin_path),
 | |
|                      std::make_pair(is_main_frame, main_frame_origin)));
 | |
|   if (it == plugin_load_decision_map_.end())
 | |
|     return false;
 | |
| 
 | |
|   *status = it->second;
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::ClearPluginLoadDecision(int render_process_id) {
 | |
|   CEF_REQUIRE_UIT();
 | |
| 
 | |
|   if (render_process_id == -1) {
 | |
|     plugin_load_decision_map_.clear();
 | |
|   } else {
 | |
|     PluginLoadDecisionMap::iterator it = plugin_load_decision_map_.begin();
 | |
|     while (it != plugin_load_decision_map_.end()) {
 | |
|       if (it->first.first.first == render_process_id)
 | |
|         it = plugin_load_decision_map_.erase(it);
 | |
|       else
 | |
|         ++it;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::RegisterSchemeHandlerFactory(
 | |
|     const std::string& scheme_name,
 | |
|     const std::string& domain_name,
 | |
|     CefRefPtr<CefSchemeHandlerFactory> factory) {
 | |
|   if (resource_context_) {
 | |
|     // Using base::Unretained() is safe because both this callback and possible
 | |
|     // deletion of |resource_context_| will execute on the IO thread, and this
 | |
|     // callback will be executed first.
 | |
|     CEF_POST_TASK(CEF_IOT,
 | |
|                   base::Bind(&CefResourceContext::RegisterSchemeHandlerFactory,
 | |
|                              base::Unretained(resource_context_.get()),
 | |
|                              scheme_name, domain_name, factory));
 | |
|   }
 | |
| }
 | |
| 
 | |
| void CefBrowserContext::ClearSchemeHandlerFactories() {
 | |
|   if (resource_context_) {
 | |
|     // Using base::Unretained() is safe because both this callback and possible
 | |
|     // deletion of |resource_context_| will execute on the IO thread, and this
 | |
|     // callback will be executed first.
 | |
|     CEF_POST_TASK(CEF_IOT,
 | |
|                   base::Bind(&CefResourceContext::ClearSchemeHandlerFactories,
 | |
|                              base::Unretained(resource_context_.get())));
 | |
|   }
 | |
| }
 | |
| 
 | |
| network::mojom::NetworkContext* CefBrowserContext::GetNetworkContext() {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   return GetDefaultStoragePartition(this)->GetNetworkContext();
 | |
| }
 | |
| 
 | |
| DownloadPrefs* CefBrowserContext::GetDownloadPrefs() {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   if (!download_prefs_) {
 | |
|     download_prefs_.reset(new DownloadPrefs(this));
 | |
|   }
 | |
|   return download_prefs_.get();
 | |
| }
 | |
| 
 | |
| bool CefBrowserContext::IsPrintPreviewSupported() const {
 | |
|   CEF_REQUIRE_UIT();
 | |
|   if (!extensions::PrintPreviewEnabled())
 | |
|     return false;
 | |
| 
 | |
|   return !GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled);
 | |
| }
 |