mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-13 10:06:28 +01:00
815 lines
27 KiB
C++
815 lines
27 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/profiles/profile_key.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"
|
|
#include "services/network/public/mojom/cors_origin_pattern.mojom.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::StorageNotificationService*
|
|
CefBrowserContext::GetStorageNotificationService() {
|
|
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);
|
|
}
|