cef/libcef/browser/browser_context_proxy.cc

257 lines
8.1 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_proxy.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/net/url_request_context_getter_proxy.h"
#include "libcef/browser/storage_partition_proxy.h"
#include "libcef/browser/thread_util.h"
#include "base/logging.h"
#include "chrome/browser/font_family_cache.h"
#include "components/guest_view/common/guest_view_constants.h"
#include "components/visitedlink/browser/visitedlink_master.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/streams/stream_context.h"
#include "content/browser/webui/url_data_manager.h"
#include "content/public/browser/storage_partition.h"
#include "services/service_manager/public/cpp/service.h"
namespace {
bool ShouldProxyUserData(const void* key) {
// If this value is not proxied then multiple StoragePartitionImpl objects
// will be created and filesystem API access will fail, among other things.
if (key == content::BrowserContext::GetStoragePartitionMapUserDataKey())
return true;
// If these values are not proxied then blob data fails to load for the PDF
// extension.
// See also the call to InitializeResourceContext().
if (key == content::ChromeBlobStorageContext::GetUserDataKey() ||
key == content::StreamContext::GetUserDataKey()) {
return true;
}
// If this value is not proxied then CefBrowserContextImpl::GetGuestManager()
// returns NULL.
// See also CefExtensionsAPIClient::CreateGuestViewManagerDelegate.
if (key == guest_view::kGuestViewManagerKeyName)
return true;
// If this value is not proxied then there will be a use-after-free while
// destroying the FontFamilyCache because it will try to access the
// ProxyService owned by CefBrowserContextImpl (which has already been freed).
if (key == kFontFamilyCacheKey)
return true;
// If this value is not proxied WebUI will fail to load.
if (key == content::URLDataManager::GetUserDataKey())
return true;
return false;
}
} // namespace
CefBrowserContextProxy::CefBrowserContextProxy(
CefRequestContextImpl* const request_context,
CefRefPtr<CefRequestContextHandler> handler,
CefBrowserContextImpl* parent)
: CefBrowserContext(true),
request_context_(request_context),
handler_(handler),
parent_(parent) {
DCHECK(handler_.get());
DCHECK(parent_);
parent_->AddProxy(this);
}
CefBrowserContextProxy::~CefBrowserContextProxy() {
CEF_REQUIRE_UIT();
Shutdown();
parent_->RemoveProxy(this);
}
void CefBrowserContextProxy::Initialize() {
CefBrowserContext::Initialize();
// This object's CefResourceContext needs to proxy some UserData requests to
// the parent object's CefResourceContext.
resource_context()->set_parent(parent_->resource_context());
CefBrowserContext::PostInitialize();
}
base::SupportsUserData::Data* CefBrowserContextProxy::GetUserData(
const void* key) const {
if (ShouldProxyUserData(key))
return parent_->GetUserData(key);
return BrowserContext::GetUserData(key);
}
void CefBrowserContextProxy::SetUserData(const void* key,
std::unique_ptr<Data> data) {
if (ShouldProxyUserData(key))
parent_->SetUserData(key, std::move(data));
else
BrowserContext::SetUserData(key, std::move(data));
}
void CefBrowserContextProxy::RemoveUserData(const void* key) {
if (ShouldProxyUserData(key))
parent_->RemoveUserData(key);
else
BrowserContext::RemoveUserData(key);
}
base::FilePath CefBrowserContextProxy::GetPath() const {
return parent_->GetPath();
}
std::unique_ptr<content::ZoomLevelDelegate>
CefBrowserContextProxy::CreateZoomLevelDelegate(
const base::FilePath& partition_path) {
return parent_->CreateZoomLevelDelegate(partition_path);
}
bool CefBrowserContextProxy::IsOffTheRecord() const {
return parent_->IsOffTheRecord();
}
content::DownloadManagerDelegate*
CefBrowserContextProxy::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* CefBrowserContextProxy::GetGuestManager() {
return parent_->GetGuestManager();
}
storage::SpecialStoragePolicy*
CefBrowserContextProxy::GetSpecialStoragePolicy() {
return parent_->GetSpecialStoragePolicy();
}
content::PushMessagingService*
CefBrowserContextProxy::GetPushMessagingService() {
return parent_->GetPushMessagingService();
}
content::SSLHostStateDelegate*
CefBrowserContextProxy::GetSSLHostStateDelegate() {
return parent_->GetSSLHostStateDelegate();
}
content::ClientHintsControllerDelegate*
CefBrowserContextProxy::GetClientHintsControllerDelegate() {
return parent_->GetClientHintsControllerDelegate();
}
content::PermissionControllerDelegate*
CefBrowserContextProxy::GetPermissionControllerDelegate() {
return parent_->GetPermissionControllerDelegate();
}
content::BackgroundFetchDelegate*
CefBrowserContextProxy::GetBackgroundFetchDelegate() {
return parent_->GetBackgroundFetchDelegate();
}
content::BackgroundSyncController*
CefBrowserContextProxy::GetBackgroundSyncController() {
return parent_->GetBackgroundSyncController();
}
content::BrowsingDataRemoverDelegate*
CefBrowserContextProxy::GetBrowsingDataRemoverDelegate() {
return parent_->GetBrowsingDataRemoverDelegate();
}
net::URLRequestContextGetter* CefBrowserContextProxy::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
// CefBrowserContextImpl::GetOrCreateStoragePartitionProxy is called instead
// of this method.
NOTREACHED();
return nullptr;
}
net::URLRequestContextGetter*
CefBrowserContextProxy::CreateRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
return nullptr;
}
std::unique_ptr<service_manager::Service>
CefBrowserContextProxy::HandleServiceRequest(
const std::string& service_name,
service_manager::mojom::ServiceRequest request) {
return parent_->HandleServiceRequest(service_name, std::move(request));
}
PrefService* CefBrowserContextProxy::GetPrefs() {
return parent_->GetPrefs();
}
const PrefService* CefBrowserContextProxy::GetPrefs() const {
return parent_->GetPrefs();
}
CefRequestContextImpl* CefBrowserContextProxy::GetCefRequestContext() const {
return request_context_;
}
const CefRequestContextSettings& CefBrowserContextProxy::GetSettings() const {
return parent_->GetSettings();
}
CefRefPtr<CefRequestContextHandler> CefBrowserContextProxy::GetHandler() const {
return handler_;
}
HostContentSettingsMap* CefBrowserContextProxy::GetHostContentSettingsMap() {
return parent_->GetHostContentSettingsMap();
}
void CefBrowserContextProxy::AddVisitedURLs(const std::vector<GURL>& urls) {
parent_->AddVisitedURLs(urls);
}
content::StoragePartition*
CefBrowserContextProxy::GetOrCreateStoragePartitionProxy(
content::StoragePartition* partition_impl) {
CEF_REQUIRE_UIT();
if (!storage_partition_proxy_) {
scoped_refptr<CefURLRequestContextGetterProxy> url_request_getter =
new CefURLRequestContextGetterProxy(handler_,
parent_->request_context_getter());
storage_partition_proxy_.reset(
new CefStoragePartitionProxy(partition_impl, url_request_getter.get()));
// Associates UserData keys with the ResourceContext.
// Called from StoragePartitionImplMap::Get() for CefBrowserContextImpl.
content::InitializeResourceContext(this);
}
// There should only be one CefStoragePartitionProxy for this
// CefBrowserContextProxy.
DCHECK_EQ(storage_partition_proxy_->parent(), partition_impl);
return storage_partition_proxy_.get();
}