mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-14 02:24:03 +01:00
48fc0bd220
Existing CefBrowserContext functionality is now split between CefBrowserContext and AlloyBrowserContext. Runtime implementations of CefBrowserContext will provide access to the content::BrowserContext and Profile types via different inheritance paths. For example, the Alloy runtime uses ChromeProfileAlloy and the Chrome runtime uses ProfileImpl. This change also renames CefResourceContext to CefIOThreadState to more accurately represent its purpose as it no longer needs to extend content::ResourceContext.
387 lines
12 KiB
C++
387 lines
12 KiB
C++
// Copyright 2015 The Chromium Embedded Framework Authors.
|
|
// Portions copyright 2014 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/extensions/extensions_browser_client.h"
|
|
|
|
#include <utility>
|
|
|
|
#include "libcef/browser/browser_context.h"
|
|
#include "libcef/browser/browser_host_impl.h"
|
|
#include "libcef/browser/extensions/component_extension_resource_manager.h"
|
|
#include "libcef/browser/extensions/extension_system.h"
|
|
#include "libcef/browser/extensions/extension_system_factory.h"
|
|
#include "libcef/browser/extensions/extension_web_contents_observer.h"
|
|
#include "libcef/browser/extensions/extensions_api_client.h"
|
|
#include "libcef/browser/extensions/extensions_browser_api_provider.h"
|
|
#include "libcef/browser/request_context_impl.h"
|
|
|
|
#include "chrome/browser/browser_process.h"
|
|
#include "chrome/browser/extensions/chrome_url_request_util.h"
|
|
#include "chrome/browser/extensions/event_router_forwarder.h"
|
|
#include "content/public/browser/browser_context.h"
|
|
#include "content/public/browser/browser_thread.h"
|
|
#include "content/public/browser/render_frame_host.h"
|
|
#include "extensions/browser/api/extensions_api_client.h"
|
|
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
|
|
#include "extensions/browser/api/runtime/runtime_api_delegate.h"
|
|
#include "extensions/browser/app_sorting.h"
|
|
#include "extensions/browser/core_extensions_browser_api_provider.h"
|
|
#include "extensions/browser/event_router.h"
|
|
#include "extensions/browser/extension_host_delegate.h"
|
|
#include "extensions/browser/extensions_browser_interface_binders.h"
|
|
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
|
#include "extensions/browser/kiosk/kiosk_delegate.h"
|
|
#include "extensions/browser/url_request_util.h"
|
|
#include "extensions/common/api/mime_handler.mojom.h"
|
|
#include "extensions/common/constants.h"
|
|
|
|
using content::BrowserContext;
|
|
using content::BrowserThread;
|
|
|
|
namespace extensions {
|
|
|
|
namespace {
|
|
|
|
void BindMimeHandlerService(
|
|
content::RenderFrameHost* frame_host,
|
|
mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService>
|
|
receiver) {
|
|
auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host);
|
|
if (!web_contents)
|
|
return;
|
|
|
|
auto* guest_view =
|
|
extensions::MimeHandlerViewGuest::FromWebContents(web_contents);
|
|
if (!guest_view)
|
|
return;
|
|
extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(),
|
|
std::move(receiver));
|
|
}
|
|
|
|
void BindBeforeUnloadControl(
|
|
content::RenderFrameHost* frame_host,
|
|
mojo::PendingReceiver<extensions::mime_handler::BeforeUnloadControl>
|
|
receiver) {
|
|
auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host);
|
|
if (!web_contents)
|
|
return;
|
|
|
|
auto* guest_view =
|
|
extensions::MimeHandlerViewGuest::FromWebContents(web_contents);
|
|
if (!guest_view)
|
|
return;
|
|
guest_view->FuseBeforeUnloadControl(std::move(receiver));
|
|
}
|
|
|
|
// Dummy KiosDelegate that always returns false
|
|
class CefKioskDelegate : public extensions::KioskDelegate {
|
|
public:
|
|
CefKioskDelegate() = default;
|
|
~CefKioskDelegate() override = default;
|
|
|
|
// KioskDelegate overrides:
|
|
bool IsAutoLaunchedKioskApp(const ExtensionId& id) const override {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
CefExtensionsBrowserClient::CefExtensionsBrowserClient()
|
|
: api_client_(new CefExtensionsAPIClient),
|
|
resource_manager_(new CefComponentExtensionResourceManager) {
|
|
AddAPIProvider(std::make_unique<CoreExtensionsBrowserAPIProvider>());
|
|
AddAPIProvider(std::make_unique<CefExtensionsBrowserAPIProvider>());
|
|
}
|
|
|
|
CefExtensionsBrowserClient::~CefExtensionsBrowserClient() {}
|
|
|
|
// static
|
|
CefExtensionsBrowserClient* CefExtensionsBrowserClient::Get() {
|
|
return static_cast<CefExtensionsBrowserClient*>(
|
|
ExtensionsBrowserClient::Get());
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsShuttingDown() {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::AreExtensionsDisabled(
|
|
const base::CommandLine& command_line,
|
|
BrowserContext* context) {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsValidContext(BrowserContext* context) {
|
|
return GetOriginalContext(context) != nullptr;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsSameContext(BrowserContext* first,
|
|
BrowserContext* second) {
|
|
// Returns true if |first| and |second| share the same underlying
|
|
// CefBrowserContext.
|
|
return GetOriginalContext(first) == GetOriginalContext(second);
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::HasOffTheRecordContext(
|
|
BrowserContext* context) {
|
|
// CEF doesn't use incognito contexts.
|
|
return false;
|
|
}
|
|
|
|
BrowserContext* CefExtensionsBrowserClient::GetOffTheRecordContext(
|
|
BrowserContext* context) {
|
|
return nullptr;
|
|
}
|
|
|
|
BrowserContext* CefExtensionsBrowserClient::GetOriginalContext(
|
|
BrowserContext* context) {
|
|
auto cef_browser_context = CefBrowserContext::FromBrowserContext(context);
|
|
if (cef_browser_context)
|
|
return cef_browser_context->AsBrowserContext();
|
|
return nullptr;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsGuestSession(BrowserContext* context) const {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsExtensionIncognitoEnabled(
|
|
const std::string& extension_id,
|
|
content::BrowserContext* context) const {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::CanExtensionCrossIncognito(
|
|
const Extension* extension,
|
|
content::BrowserContext* context) const {
|
|
return false;
|
|
}
|
|
|
|
base::FilePath CefExtensionsBrowserClient::GetBundleResourcePath(
|
|
const network::ResourceRequest& request,
|
|
const base::FilePath& extension_resources_path,
|
|
int* resource_id) const {
|
|
return chrome_url_request_util::GetBundleResourcePath(
|
|
request, extension_resources_path, resource_id);
|
|
}
|
|
|
|
void CefExtensionsBrowserClient::LoadResourceFromResourceBundle(
|
|
const network::ResourceRequest& request,
|
|
mojo::PendingReceiver<network::mojom::URLLoader> loader,
|
|
const base::FilePath& resource_relative_path,
|
|
const int resource_id,
|
|
const std::string& content_security_policy,
|
|
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
|
|
bool send_cors_header) {
|
|
chrome_url_request_util::LoadResourceFromResourceBundle(
|
|
request, std::move(loader), resource_relative_path, resource_id,
|
|
content_security_policy, std::move(client), send_cors_header);
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::AllowCrossRendererResourceLoad(
|
|
const GURL& url,
|
|
blink::mojom::ResourceType resource_type,
|
|
ui::PageTransition page_transition,
|
|
int child_id,
|
|
bool is_incognito,
|
|
const Extension* extension,
|
|
const ExtensionSet& extensions,
|
|
const ProcessMap& process_map) {
|
|
bool allowed = false;
|
|
if (url_request_util::AllowCrossRendererResourceLoad(
|
|
url, resource_type, page_transition, child_id, is_incognito,
|
|
extension, extensions, process_map, &allowed)) {
|
|
return allowed;
|
|
}
|
|
|
|
// Couldn't determine if resource is allowed. Block the load.
|
|
return false;
|
|
}
|
|
|
|
PrefService* CefExtensionsBrowserClient::GetPrefServiceForContext(
|
|
BrowserContext* context) {
|
|
return CefBrowserContext::FromBrowserContext(context)
|
|
->AsProfile()
|
|
->GetPrefs();
|
|
}
|
|
|
|
void CefExtensionsBrowserClient::GetEarlyExtensionPrefsObservers(
|
|
content::BrowserContext* context,
|
|
std::vector<EarlyExtensionPrefsObserver*>* observers) const {}
|
|
|
|
ProcessManagerDelegate* CefExtensionsBrowserClient::GetProcessManagerDelegate()
|
|
const {
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<ExtensionHostDelegate>
|
|
CefExtensionsBrowserClient::CreateExtensionHostDelegate() {
|
|
// CEF does not use the ExtensionHost constructor that calls this method.
|
|
NOTREACHED();
|
|
return std::unique_ptr<ExtensionHostDelegate>();
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::CreateBackgroundExtensionHost(
|
|
const Extension* extension,
|
|
content::BrowserContext* browser_context,
|
|
const GURL& url,
|
|
ExtensionHost** host) {
|
|
auto cef_browser_context =
|
|
CefBrowserContext::FromBrowserContext(browser_context);
|
|
|
|
// A CEF representation should always exist.
|
|
CefRefPtr<CefExtension> cef_extension =
|
|
cef_browser_context->GetExtension(extension->id());
|
|
DCHECK(cef_extension);
|
|
if (!cef_extension) {
|
|
// Cancel the background host creation.
|
|
return true;
|
|
}
|
|
|
|
// Always use the same request context that the extension was registered with.
|
|
// GetLoaderContext() will return NULL for internal extensions.
|
|
CefRefPtr<CefRequestContext> request_context =
|
|
cef_extension->GetLoaderContext();
|
|
if (!request_context) {
|
|
// Cancel the background host creation.
|
|
return true;
|
|
}
|
|
|
|
CefBrowserHostImpl::CreateParams create_params;
|
|
create_params.url = url;
|
|
create_params.request_context = request_context;
|
|
|
|
CefRefPtr<CefExtensionHandler> handler = cef_extension->GetHandler();
|
|
if (handler.get() && handler->OnBeforeBackgroundBrowser(
|
|
cef_extension, url.spec(), create_params.client,
|
|
create_params.settings)) {
|
|
// Cancel the background host creation.
|
|
return true;
|
|
}
|
|
|
|
// This triggers creation of the background host.
|
|
create_params.extension = extension;
|
|
create_params.extension_host_type =
|
|
extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
|
|
|
|
// Browser creation may fail under certain rare circumstances. Fail the
|
|
// background host creation in that case.
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
|
CefBrowserHostImpl::Create(create_params);
|
|
if (browser) {
|
|
*host = browser->extension_host();
|
|
DCHECK(*host);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::DidVersionUpdate(BrowserContext* context) {
|
|
// TODO(jamescook): We might want to tell extensions when app_shell updates.
|
|
return false;
|
|
}
|
|
|
|
void CefExtensionsBrowserClient::PermitExternalProtocolHandler() {}
|
|
|
|
bool CefExtensionsBrowserClient::IsInDemoMode() {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsScreensaverInDemoMode(
|
|
const std::string& app_id) {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsRunningInForcedAppMode() {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsAppModeForcedForApp(
|
|
const ExtensionId& extension_id) {
|
|
return false;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsLoggedInAsPublicAccount() {
|
|
return false;
|
|
}
|
|
|
|
ExtensionSystemProvider*
|
|
CefExtensionsBrowserClient::GetExtensionSystemFactory() {
|
|
return CefExtensionSystemFactory::GetInstance();
|
|
}
|
|
|
|
void CefExtensionsBrowserClient::RegisterBrowserInterfaceBindersForFrame(
|
|
mojo::BinderMapWithContext<content::RenderFrameHost*>* map,
|
|
content::RenderFrameHost* render_frame_host,
|
|
const Extension* extension) const {
|
|
PopulateExtensionFrameBinders(map, render_frame_host, extension);
|
|
|
|
map->Add<extensions::mime_handler::MimeHandlerService>(
|
|
base::BindRepeating(&BindMimeHandlerService));
|
|
map->Add<extensions::mime_handler::BeforeUnloadControl>(
|
|
base::BindRepeating(&BindBeforeUnloadControl));
|
|
}
|
|
|
|
std::unique_ptr<RuntimeAPIDelegate>
|
|
CefExtensionsBrowserClient::CreateRuntimeAPIDelegate(
|
|
content::BrowserContext* context) const {
|
|
// TODO(extensions): Implement to support Apps.
|
|
NOTREACHED();
|
|
return nullptr;
|
|
}
|
|
|
|
const ComponentExtensionResourceManager*
|
|
CefExtensionsBrowserClient::GetComponentExtensionResourceManager() {
|
|
return resource_manager_.get();
|
|
}
|
|
|
|
void CefExtensionsBrowserClient::BroadcastEventToRenderers(
|
|
events::HistogramValue histogram_value,
|
|
const std::string& event_name,
|
|
std::unique_ptr<base::ListValue> args,
|
|
bool dispatch_to_off_the_record_profiles) {
|
|
g_browser_process->extension_event_router_forwarder()
|
|
->BroadcastEventToRenderers(histogram_value, event_name, std::move(args),
|
|
GURL(), dispatch_to_off_the_record_profiles);
|
|
}
|
|
|
|
ExtensionCache* CefExtensionsBrowserClient::GetExtensionCache() {
|
|
// Only used by Chrome via ExtensionService.
|
|
NOTREACHED();
|
|
return nullptr;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsBackgroundUpdateAllowed() {
|
|
return true;
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsMinBrowserVersionSupported(
|
|
const std::string& min_version) {
|
|
return true;
|
|
}
|
|
|
|
ExtensionWebContentsObserver*
|
|
CefExtensionsBrowserClient::GetExtensionWebContentsObserver(
|
|
content::WebContents* web_contents) {
|
|
return CefExtensionWebContentsObserver::FromWebContents(web_contents);
|
|
}
|
|
|
|
KioskDelegate* CefExtensionsBrowserClient::GetKioskDelegate() {
|
|
if (!kiosk_delegate_)
|
|
kiosk_delegate_.reset(new CefKioskDelegate());
|
|
return kiosk_delegate_.get();
|
|
}
|
|
|
|
bool CefExtensionsBrowserClient::IsLockScreenContext(
|
|
content::BrowserContext* context) {
|
|
return false;
|
|
}
|
|
|
|
std::string CefExtensionsBrowserClient::GetApplicationLocale() {
|
|
return g_browser_process->GetApplicationLocale();
|
|
}
|
|
|
|
} // namespace extensions
|