diff --git chrome/browser/extensions/api/streams_private/streams_private_api.cc chrome/browser/extensions/api/streams_private/streams_private_api.cc index cead7cfa14bae..24142c2e4896f 100644 --- chrome/browser/extensions/api/streams_private/streams_private_api.cc +++ chrome/browser/extensions/api/streams_private/streams_private_api.cc @@ -6,6 +6,7 @@ #include +#include "cef/libcef/features/runtime.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h" #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" @@ -18,6 +19,10 @@ #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" #include "extensions/common/manifest_handlers/mime_types_handler.h" +#if BUILDFLAG(ENABLE_CEF) +#include "cef/libcef/browser/extensions/alloy_extensions_util.h" +#endif + namespace extensions { void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( @@ -34,6 +39,7 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( if (!web_contents) return; + if (!cef::IsAlloyRuntimeEnabled()) { // If the request was for NoStatePrefetch, abort the prefetcher and do not // continue. This is because plugins cancel NoStatePrefetch, see // http://crbug.com/343590. @@ -44,6 +50,7 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( no_state_prefetch_contents->Destroy(prerender::FINAL_STATUS_DOWNLOAD); return; } + } auto* browser_context = web_contents->GetBrowserContext(); @@ -70,9 +77,18 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( // forms of zooming won't work). // TODO(1042323): Present a coherent representation of a tab id for portal // contents. - int tab_id = web_contents->GetOuterWebContents() - ? SessionID::InvalidValue().id() - : ExtensionTabUtil::GetTabId(web_contents); + int tab_id; + if (web_contents->GetOuterWebContents()) { + tab_id = SessionID::InvalidValue().id(); + } else +#if BUILDFLAG(ENABLE_CEF) + if (cef::IsAlloyRuntimeEnabled()) { + tab_id = alloy::GetTabIdForWebContents(web_contents); + } else +#endif // BUILDFLAG(ENABLE_CEF) + { + tab_id = ExtensionTabUtil::GetTabId(web_contents); + } std::unique_ptr stream_container( new StreamContainer(tab_id, embedded, handler_url, extension_id, diff --git extensions/browser/extension_host.cc extensions/browser/extension_host.cc index 3d2108f13ea2f..261b0a42bfb21 100644 --- extensions/browser/extension_host.cc +++ extensions/browser/extension_host.cc @@ -62,11 +62,12 @@ ExtensionHost::ExtensionHost(const Extension* extension, host_type == mojom::ViewType::kExtensionDialog || host_type == mojom::ViewType::kExtensionPopup || host_type == mojom::ViewType::kExtensionSidePanel); - host_contents_ = WebContents::Create( + host_contents_owned_ = WebContents::Create( WebContents::CreateParams(browser_context_, site_instance)), - content::WebContentsObserver::Observe(host_contents_.get()); + host_contents_ = host_contents_owned_.get(); + content::WebContentsObserver::Observe(host_contents_); host_contents_->SetDelegate(this); - SetViewType(host_contents_.get(), host_type); + SetViewType(host_contents_, host_type); main_frame_host_ = host_contents_->GetPrimaryMainFrame(); // Listen for when an extension is unloaded from the same profile, as it may @@ -82,11 +83,49 @@ ExtensionHost::ExtensionHost(const Extension* extension, // Create password reuse detection manager when new extension web contents are // created. ExtensionsBrowserClient::Get()->CreatePasswordReuseDetectionManager( - host_contents_.get()); + host_contents_); ExtensionHostRegistry::Get(browser_context_)->ExtensionHostCreated(this); } +ExtensionHost::ExtensionHost(ExtensionHostDelegate* delegate, + const Extension* extension, + content::BrowserContext* browser_context, + content::WebContents* host_contents, + const GURL& url, + mojom::ViewType host_type) + : delegate_(delegate), + extension_(extension), + extension_id_(extension->id()), + browser_context_(browser_context), + host_contents_(host_contents), + initial_url_(url), + extension_host_type_(host_type) { + DCHECK(delegate); + DCHECK(browser_context); + DCHECK(host_contents); + + // Not used for panels, see PanelHost. + DCHECK(host_type == mojom::ViewType::kExtensionBackgroundPage || + host_type == mojom::ViewType::kExtensionDialog || + host_type == mojom::ViewType::kExtensionPopup); + + content::WebContentsObserver::Observe(host_contents_); + SetViewType(host_contents_, host_type); + + main_frame_host_ = host_contents_->GetPrimaryMainFrame(); + + // Listen for when an extension is unloaded from the same profile, as it may + // be the same extension that this points to. + ExtensionRegistry::Get(browser_context_)->AddObserver(this); + + // Set up web contents observers and pref observers. + delegate_->OnExtensionHostCreated(host_contents_); + + ExtensionWebContentsObserver::GetForWebContents(host_contents_)-> + dispatcher()->set_delegate(this); +} + ExtensionHost::~ExtensionHost() { ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); diff --git extensions/browser/extension_host.h extensions/browser/extension_host.h index dda0620251895..4014bd801f727 100644 --- extensions/browser/extension_host.h +++ extensions/browser/extension_host.h @@ -62,6 +62,12 @@ class ExtensionHost : public DeferredStartRenderHost, content::SiteInstance* site_instance, const GURL& url, mojom::ViewType host_type); + ExtensionHost(ExtensionHostDelegate* delegate, + const Extension* extension, + content::BrowserContext* browser_context, + content::WebContents* host_contents, + const GURL& url, + mojom::ViewType host_type); ExtensionHost(const ExtensionHost&) = delete; ExtensionHost& operator=(const ExtensionHost&) = delete; @@ -72,7 +78,7 @@ class ExtensionHost : public DeferredStartRenderHost, const Extension* extension() const { return extension_; } const ExtensionId& extension_id() const { return extension_id_; } - content::WebContents* host_contents() const { return host_contents_.get(); } + content::WebContents* host_contents() const { return host_contents_; } content::RenderFrameHost* main_frame_host() const { return main_frame_host_; } content::RenderProcessHost* render_process_host() const; bool has_loaded_once() const { return has_loaded_once_; } @@ -223,7 +229,8 @@ class ExtensionHost : public DeferredStartRenderHost, raw_ptr browser_context_; // The host for our HTML content. - std::unique_ptr host_contents_; + std::unique_ptr host_contents_owned_; + content::WebContents* host_contents_; // A pointer to the current or speculative main frame in `host_contents_`. We // can't access this frame through the `host_contents_` directly as it does diff --git extensions/browser/extension_registry.cc extensions/browser/extension_registry.cc index c3197eb4790fa..1e7ae767b0582 100644 --- extensions/browser/extension_registry.cc +++ extensions/browser/extension_registry.cc @@ -6,9 +6,14 @@ #include "base/observer_list.h" #include "base/strings/string_util.h" +#include "cef/libcef/features/runtime.h" #include "extensions/browser/extension_registry_factory.h" #include "extensions/browser/extension_registry_observer.h" +#if BUILDFLAG(ENABLE_CEF) +#include "cef/libcef/common/extensions/extensions_util.h" +#endif + namespace extensions { ExtensionRegistry::ExtensionRegistry(content::BrowserContext* browser_context) @@ -17,6 +22,11 @@ ExtensionRegistry::~ExtensionRegistry() = default; // static ExtensionRegistry* ExtensionRegistry::Get(content::BrowserContext* context) { +#if BUILDFLAG(ENABLE_CEF) + if (cef::IsAlloyRuntimeEnabled() && !extensions::ExtensionsEnabled()) { + return nullptr; + } +#endif return ExtensionRegistryFactory::GetForBrowserContext(context); } diff --git extensions/browser/extensions_browser_client.h extensions/browser/extensions_browser_client.h index 058367b7ab78d..99a9e901566ce 100644 --- extensions/browser/extensions_browser_client.h +++ extensions/browser/extensions_browser_client.h @@ -32,6 +32,7 @@ #include "url/gurl.h" class ExtensionFunctionRegistry; +class GURL; class PrefService; namespace base { @@ -80,6 +81,7 @@ class ComponentExtensionResourceManager; class Extension; class ExtensionCache; class ExtensionError; +class ExtensionHost; class ExtensionHostDelegate; class ExtensionSet; class ExtensionSystem; @@ -265,6 +267,14 @@ class ExtensionsBrowserClient { virtual std::unique_ptr CreateExtensionHostDelegate() = 0; + // CEF creates a custom ExtensionHost for background pages. If the return + // value is true and |host| is NULL then fail the background host creation. + virtual bool CreateBackgroundExtensionHost( + const Extension* extension, + content::BrowserContext* browser_context, + const GURL& url, + ExtensionHost** host) { return false; } + // Returns true if the client version has updated since the last run. Called // once each time the extensions system is loaded per browser_context. The // implementation may wish to use the BrowserContext to record the current diff --git extensions/browser/process_manager.cc extensions/browser/process_manager.cc index 580df6d9b0ae7..39b2d5ccc074c 100644 --- extensions/browser/process_manager.cc +++ extensions/browser/process_manager.cc @@ -380,9 +380,17 @@ bool ProcessManager::CreateBackgroundHost(const Extension* extension, return true; // TODO(kalman): return false here? It might break things... DVLOG(1) << "CreateBackgroundHost " << extension->id(); - ExtensionHost* host = + ExtensionHost* host = nullptr; + if (ExtensionsBrowserClient::Get()->CreateBackgroundExtensionHost( + extension, browser_context_, url, &host) && !host) { + // Explicitly fail if the client can't create the host. + return false; + } + if (!host) { + host = new ExtensionHost(extension, GetSiteInstanceForURL(url).get(), url, mojom::ViewType::kExtensionBackgroundPage); + } host->SetCloseHandler( base::BindOnce(&ProcessManager::HandleCloseExtensionHost, weak_ptr_factory_.GetWeakPtr())); diff --git extensions/common/extensions_client.cc extensions/common/extensions_client.cc index a8108350ddde2..7ae49e78b4327 100644 --- extensions/common/extensions_client.cc +++ extensions/common/extensions_client.cc @@ -23,7 +23,7 @@ ExtensionsClient* g_client = nullptr; } // namespace ExtensionsClient* ExtensionsClient::Get() { - DCHECK(g_client); + // May be nullptr if using CEF Alloy with extensions disabled. return g_client; }