cef/patch/patches/extensions_1947.patch

242 lines
11 KiB
Diff

diff --git content/browser/frame_host/render_frame_host_manager.cc content/browser/frame_host/render_frame_host_manager.cc
index 3263eb9e324a..b5bde4cea8f7 100644
--- content/browser/frame_host/render_frame_host_manager.cc
+++ content/browser/frame_host/render_frame_host_manager.cc
@@ -890,10 +890,11 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
// TODO(alexmos): This check should've been enforced earlier in the
// navigation, in chrome::Navigate(). Verify this, and then convert this to
// a CHECK and remove the fallback.
- DCHECK_EQ(browser_context,
- render_frame_host_->GetSiteInstance()->GetBrowserContext());
- if (browser_context !=
- render_frame_host_->GetSiteInstance()->GetBrowserContext()) {
+ const bool is_same = GetContentClient()->browser()->IsSameBrowserContext(
+ browser_context,
+ render_frame_host_->GetSiteInstance()->GetBrowserContext());
+ DCHECK(is_same);
+ if (!is_same) {
return true;
}
@@ -1032,7 +1033,8 @@ RenderFrameHostManager::GetSiteInstanceForNavigation(
// Double-check that the new SiteInstance is associated with the right
// BrowserContext.
- DCHECK_EQ(new_instance->GetBrowserContext(), browser_context);
+ DCHECK(GetContentClient()->browser()->IsSameBrowserContext(
+ new_instance->GetBrowserContext(), browser_context));
// If |new_instance| is a new SiteInstance for a subframe that requires a
// dedicated process, set its process reuse policy so that such subframes are
diff --git content/public/browser/content_browser_client.h content/public/browser/content_browser_client.h
index 18767b608ce9..41f5dc26ffdc 100644
--- content/public/browser/content_browser_client.h
+++ content/public/browser/content_browser_client.h
@@ -341,6 +341,13 @@ class CONTENT_EXPORT ContentBrowserClient {
const GURL& current_url,
const GURL& new_url);
+ // Returns true if two browser contexts should be considered the same. CEF
+ // uses this to treat *Impl and *Proxy contexts as the same.
+ virtual bool IsSameBrowserContext(BrowserContext* context1,
+ BrowserContext* context2) {
+ return context1 == context2;
+ }
+
// Returns true if the passed in URL should be assigned as the site of the
// current SiteInstance, if it does not yet have a site.
virtual bool ShouldAssignSiteForURL(const GURL& url);
diff --git extensions/browser/extension_host.cc extensions/browser/extension_host.cc
index d60c12116dcc..70d376348c46 100644
--- extensions/browser/extension_host.cc
+++ extensions/browser/extension_host.cc
@@ -68,11 +68,12 @@ ExtensionHost::ExtensionHost(const Extension* extension,
DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE ||
host_type == VIEW_TYPE_EXTENSION_DIALOG ||
host_type == VIEW_TYPE_EXTENSION_POPUP);
- host_contents_.reset(WebContents::Create(
- WebContents::CreateParams(browser_context_, site_instance))),
- content::WebContentsObserver::Observe(host_contents_.get());
+ host_contents_owned_.reset(WebContents::Create(
+ WebContents::CreateParams(browser_context_, site_instance)));
+ 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);
render_view_host_ = host_contents_->GetRenderViewHost();
@@ -87,6 +88,48 @@ ExtensionHost::ExtensionHost(const Extension* extension,
dispatcher()->set_delegate(this);
}
+ExtensionHost::ExtensionHost(ExtensionHostDelegate* delegate,
+ const Extension* extension,
+ content::BrowserContext* browser_context,
+ content::WebContents* host_contents,
+ const GURL& url,
+ ViewType host_type)
+ : delegate_(delegate),
+ extension_(extension),
+ extension_id_(extension->id()),
+ browser_context_(browser_context),
+ host_contents_(host_contents),
+ render_view_host_(nullptr),
+ is_render_view_creation_pending_(false),
+ has_loaded_once_(false),
+ document_element_available_(false),
+ 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 == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE ||
+ host_type == VIEW_TYPE_EXTENSION_DIALOG ||
+ host_type == VIEW_TYPE_EXTENSION_POPUP);
+
+ content::WebContentsObserver::Observe(host_contents_);
+ SetViewType(host_contents_, host_type);
+
+ render_view_host_ = host_contents_->GetRenderViewHost();
+
+ // 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 34812c083bf5..1ccfaf6e1c45 100644
--- extensions/browser/extension_host.h
+++ extensions/browser/extension_host.h
@@ -51,13 +51,19 @@ class ExtensionHost : public DeferredStartRenderHost,
ExtensionHost(const Extension* extension,
content::SiteInstance* site_instance,
const GURL& url, ViewType host_type);
+ ExtensionHost(ExtensionHostDelegate* delegate,
+ const Extension* extension,
+ content::BrowserContext* browser_context,
+ content::WebContents* host_contents,
+ const GURL& url,
+ ViewType host_type);
~ExtensionHost() override;
// This may be null if the extension has been or is being unloaded.
const Extension* extension() const { return extension_; }
const std::string& extension_id() const { return extension_id_; }
- content::WebContents* host_contents() const { return host_contents_.get(); }
+ content::WebContents* host_contents() const { return host_contents_; }
content::RenderViewHost* render_view_host() const;
content::RenderProcessHost* render_process_host() const;
bool has_loaded_once() const { return has_loaded_once_; }
@@ -175,7 +181,8 @@ class ExtensionHost : public DeferredStartRenderHost,
content::BrowserContext* browser_context_;
// The host for our HTML content.
- std::unique_ptr<content::WebContents> host_contents_;
+ std::unique_ptr<content::WebContents> host_contents_owned_;
+ content::WebContents* host_contents_;
// A weak pointer to the current or pending RenderViewHost. We don't access
// this through the host_contents because we want to deal with the pending
diff --git extensions/browser/extensions_browser_client.h extensions/browser/extensions_browser_client.h
index 267a40121d8e..fc68e632465c 100644
--- extensions/browser/extensions_browser_client.h
+++ extensions/browser/extensions_browser_client.h
@@ -53,6 +53,7 @@ class ComponentExtensionResourceManager;
class Extension;
class ExtensionCache;
class ExtensionError;
+class ExtensionHost;
class ExtensionHostDelegate;
class ExtensionPrefsObserver;
class ExtensionApiFrameIdMap;
@@ -108,6 +109,11 @@ class ExtensionsBrowserClient {
virtual content::BrowserContext* GetOriginalContext(
content::BrowserContext* context) = 0;
+ // Returns the CEF *Impl context. Used in cases where we want special CEF
+ // handling without interfering with the side-by-side Chrome build.
+ virtual content::BrowserContext* GetCefImplContext(
+ content::BrowserContext* context) { return nullptr; }
+
#if defined(OS_CHROMEOS)
// Returns a user id hash from |context| or an empty string if no hash could
// be extracted.
@@ -173,6 +179,14 @@ class ExtensionsBrowserClient {
virtual std::unique_ptr<ExtensionHostDelegate>
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 fec28715c0fe..74564954904f 100644
--- extensions/browser/process_manager.cc
+++ extensions/browser/process_manager.cc
@@ -351,9 +351,16 @@ bool ProcessManager::CreateBackgroundHost(const Extension* extension,
return true; // TODO(kalman): return false here? It might break things...
DVLOG(1) << "CreateBackgroundHost " << extension->id();
- ExtensionHost* host =
- new ExtensionHost(extension, GetSiteInstanceForURL(url).get(), url,
- VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
+ 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,
+ VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
+ }
host->CreateRenderViewSoon();
OnBackgroundHostCreated(host);
return true;
diff --git extensions/browser/process_manager_factory.cc extensions/browser/process_manager_factory.cc
index e8929c5da255..5ae43b4361a4 100644
--- extensions/browser/process_manager_factory.cc
+++ extensions/browser/process_manager_factory.cc
@@ -5,6 +5,7 @@
#include "extensions/browser/process_manager_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/extension_registry_factory.h"
#include "extensions/browser/lazy_background_task_queue_factory.h"
#include "extensions/browser/process_manager.h"
@@ -50,6 +51,12 @@ KeyedService* ProcessManagerFactory::BuildServiceInstanceFor(
BrowserContext* ProcessManagerFactory::GetBrowserContextToUse(
BrowserContext* context) const {
+ // CEF wants all extension state routed to the *Impl context.
+ content::BrowserContext* cef_context =
+ ExtensionsBrowserClient::Get()->GetCefImplContext(context);
+ if (cef_context)
+ return cef_context;
+
// ProcessManager::Create handles guest and incognito profiles, returning an
// IncognitoProcessManager in incognito mode.
return context;