diff options
Diffstat (limited to 'chrome/browser/renderer_host')
7 files changed, 101 insertions, 25 deletions
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 6aca057..f54afd9 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -201,6 +201,10 @@ BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) registrar_.Add(this, NotificationType::USER_SCRIPTS_UPDATED, Source<Profile>(profile)); + registrar_.Add(this, NotificationType::EXTENSION_LOADED, + Source<Profile>(profile)); + registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, + Source<Profile>(profile)); registrar_.Add(this, NotificationType::SPELLCHECK_HOST_REINITIALIZED, NotificationService::AllSources()); registrar_.Add(this, NotificationType::SPELLCHECK_WORD_ADDED, @@ -644,6 +648,27 @@ void BrowserRenderProcessHost::SendUserScriptsUpdate( } } +void BrowserRenderProcessHost::SendExtensionExtentsUpdate() { + // Check if the process is still starting and we don't have a handle for it + // yet, in which case this will happen later when InitVisitedLinks is called. + if (!run_renderer_in_process() && + (!child_process_.get() || child_process_->IsStarting())) { + return; + } + + ExtensionsService* service = profile()->GetExtensionsService(); + ViewMsg_ExtensionExtentsUpdated_Params params; + for (size_t i = 0; i < service->extensions()->size(); ++i) { + Extension* extension = service->extensions()->at(i); + if (!extension->web_extent().origin().is_empty()) { + params.extension_apps.push_back( + make_pair(extension->id(), extension->web_extent())); + } + } + + Send(new ViewMsg_ExtensionExtentsUpdated(params)); +} + bool BrowserRenderProcessHost::FastShutdownIfPossible() { if (run_renderer_in_process()) return false; // Single process mode can't do fast shutdown. @@ -909,6 +934,13 @@ void BrowserRenderProcessHost::Observe(NotificationType type, } break; } + case NotificationType::EXTENSION_LOADED: + case NotificationType::EXTENSION_UNLOADED: { + Extension* extension = Details<Extension>(details).ptr(); + if (!extension->web_extent().origin().is_empty()) + SendExtensionExtentsUpdate(); + break; + } case NotificationType::SPELLCHECK_HOST_REINITIALIZED: { InitSpellChecker(); break; @@ -941,6 +973,7 @@ void BrowserRenderProcessHost::OnProcessLaunched() { InitVisitedLinks(); InitUserScripts(); InitExtensions(); + SendExtensionExtentsUpdate(); // We don't want to initialize the spellchecker unless SpellCheckHost has been // created. In InitSpellChecker(), we know if GetSpellCheckHost() is NULL // then the spellchecker has been turned off, but here, we don't know if diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index 277a53e..2a7f8b6 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -126,6 +126,9 @@ class BrowserRenderProcessHost : public RenderProcessHost, // Sends the renderer process a new set of user scripts. void SendUserScriptsUpdate(base::SharedMemory* shared_memory); + // Sends the renderer process a new set of extension extents. + void SendExtensionExtentsUpdate(); + // Generates a command line to be used to spawn a renderer and appends the // results to |*command_line|. void AppendRendererCommandLine(CommandLine* command_line) const; diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 4e68666..e1ac486 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -125,7 +125,8 @@ RenderViewHost::RenderViewHost(SiteInstance* instance, unload_ack_is_for_cross_site_transition_(false), are_javascript_messages_suppressed_(false), sudden_termination_allowed_(false), - session_storage_namespace_id_(session_storage_namespace_id) { + session_storage_namespace_id_(session_storage_namespace_id), + is_extension_process_(false) { DCHECK(instance_); DCHECK(delegate_); } @@ -155,9 +156,7 @@ bool RenderViewHost::CreateRenderView( // initialized it) or may not (we have our own process or the old process // crashed) have been initialized. Calling Init multiple times will be // ignored, so this is safe. - bool is_extensions_process = - BindingsPolicy::is_extension_enabled(enabled_bindings_); - if (!process()->Init(is_extensions_process, request_context)) + if (!process()->Init(is_extension_process_, request_context)) return false; DCHECK(process()->HasConnection()); DCHECK(process()->profile()); @@ -167,7 +166,7 @@ bool RenderViewHost::CreateRenderView( process()->id()); } - if (is_extensions_process) { + if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) { ChildProcessSecurityPolicy::GetInstance()->GrantExtensionBindings( process()->id()); diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index b971679..93c6158 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -315,6 +315,11 @@ class RenderViewHost : public RenderWidgetHost { // RenderView. See BindingsPolicy for details. int enabled_bindings() { return enabled_bindings_; } + // See variable comment. + void set_is_extension_process(bool is_extension_process) { + is_extension_process_ = is_extension_process; + } + // Sets a property with the given name and value on the DOM UI binding object. // Must call AllowDOMUIBindings() on this renderer first. void SetDOMUIProperty(const std::string& name, const std::string& value); @@ -690,6 +695,10 @@ class RenderViewHost : public RenderWidgetHost { // The session storage namespace id to be used by the associated render view. int64 session_storage_namespace_id_; + // Whether this render view will be used for extensions. This controls + // what process type we use. + bool is_extension_process_; + DISALLOW_COPY_AND_ASSIGN(RenderViewHost); }; diff --git a/chrome/browser/renderer_host/site_instance.cc b/chrome/browser/renderer_host/site_instance.cc index 337ce3d..62c6bd7 100644 --- a/chrome/browser/renderer_host/site_instance.cc +++ b/chrome/browser/renderer_host/site_instance.cc @@ -6,6 +6,7 @@ #include "chrome/browser/browsing_instance.h" #include "chrome/browser/dom_ui/dom_ui_factory.h" +#include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" #include "chrome/common/url_constants.h" #include "chrome/common/notification_service.h" @@ -79,7 +80,7 @@ void SiteInstance::SetSite(const GURL& url) { // Remember that this SiteInstance has been used to load a URL, even if the // URL is invalid. has_site_ = true; - site_ = GetSiteForURL(url); + site_ = GetSiteForURL(browsing_instance_->profile(), url); // Now that we have a site, register it with the BrowsingInstance. This // ensures that we won't create another SiteInstance for this site within @@ -111,7 +112,9 @@ SiteInstance* SiteInstance::CreateSiteInstanceForURL(Profile* profile, } /*static*/ -GURL SiteInstance::GetSiteForURL(const GURL& url) { +GURL SiteInstance::GetSiteForURL(Profile* profile, const GURL& real_url) { + GURL url = GetEffectiveURL(profile, real_url); + // URLs with no host should have an empty site. GURL site; @@ -144,7 +147,11 @@ GURL SiteInstance::GetSiteForURL(const GURL& url) { } /*static*/ -bool SiteInstance::IsSameWebSite(const GURL& url1, const GURL& url2) { +bool SiteInstance::IsSameWebSite(Profile* profile, + const GURL& real_url1, const GURL& real_url2) { + GURL url1 = GetEffectiveURL(profile, real_url1); + GURL url2 = GetEffectiveURL(profile, real_url2); + // We infer web site boundaries based on the registered domain name of the // top-level page and the scheme. We do not pay attention to the port if // one is present, because pages served from different ports can still @@ -167,6 +174,22 @@ bool SiteInstance::IsSameWebSite(const GURL& url1, const GURL& url2) { return net::RegistryControlledDomainService::SameDomainOrHost(url1, url2); } +/*static*/ +GURL SiteInstance::GetEffectiveURL(Profile* profile, const GURL& url) { + if (!profile || !profile->GetExtensionsService()) + return url; + + Extension* extension = + profile->GetExtensionsService()->GetExtensionByWebExtent(url); + if (extension) { + // If the URL is part of an extension's web extent, convert it to an + // extension URL. + return extension->GetResourceURL(url.path()); + } else { + return url; + } +} + RenderProcessHost::Type SiteInstance::GetRendererType() { // We may not have a site at this point, which generally means this is a // normal navigation. diff --git a/chrome/browser/renderer_host/site_instance.h b/chrome/browser/renderer_host/site_instance.h index 9c2f3f8..4fbbdc8 100644 --- a/chrome/browser/renderer_host/site_instance.h +++ b/chrome/browser/renderer_host/site_instance.h @@ -117,7 +117,7 @@ class SiteInstance : public base::RefCounted<SiteInstance>, // Returns the site for the given URL, which includes only the scheme and // registered domain. Returns an empty GURL if the URL has no host. - static GURL GetSiteForURL(const GURL& url); + static GURL GetSiteForURL(Profile* profile, const GURL& url); // Return whether both URLs are part of the same web site, for the purpose of // assigning them to processes accordingly. The decision is currently based @@ -126,7 +126,8 @@ class SiteInstance : public base::RefCounted<SiteInstance>, // the same process if they can communicate with other via JavaScript. // (e.g., docs.google.com and mail.google.com have DOM access to each other // if they both set their document.domain properties to google.com.) - static bool IsSameWebSite(const GURL& url1, const GURL& url2); + static bool IsSameWebSite(Profile* profile, + const GURL& url1, const GURL& url2); protected: friend class base::RefCounted<SiteInstance>; @@ -140,6 +141,12 @@ class SiteInstance : public base::RefCounted<SiteInstance>, // GetRelatedSiteInstance instead. explicit SiteInstance(BrowsingInstance* browsing_instance); + // Get the effective URL for the given actual URL. If the URL is part of an + // installed app, the effective URL is an extension URL with the ID of that + // extension as the host. This has the effect of grouping apps together in + // a common SiteInstance. + static GURL GetEffectiveURL(Profile* profile, const GURL& url); + // Returns the type of renderer process this instance belongs in, for grouping // purposes. RenderProcessHost::Type GetRendererType(); diff --git a/chrome/browser/renderer_host/test/site_instance_unittest.cc b/chrome/browser/renderer_host/test/site_instance_unittest.cc index 2c99835..cf5c154 100644 --- a/chrome/browser/renderer_host/test/site_instance_unittest.cc +++ b/chrome/browser/renderer_host/test/site_instance_unittest.cc @@ -216,27 +216,29 @@ TEST_F(SiteInstanceTest, SetSite) { TEST_F(SiteInstanceTest, GetSiteForURL) { // Pages are irrelevant. GURL test_url = GURL("http://www.google.com/index.html"); - EXPECT_EQ(GURL("http://google.com"), SiteInstance::GetSiteForURL(test_url)); + EXPECT_EQ(GURL("http://google.com"), + SiteInstance::GetSiteForURL(NULL, test_url)); // Ports are irrlevant. test_url = GURL("https://www.google.com:8080"); - EXPECT_EQ(GURL("https://google.com"), SiteInstance::GetSiteForURL(test_url)); + EXPECT_EQ(GURL("https://google.com"), + SiteInstance::GetSiteForURL(NULL, test_url)); // Javascript URLs have no site. test_url = GURL("javascript:foo();"); - EXPECT_EQ(GURL(), SiteInstance::GetSiteForURL(test_url)); + EXPECT_EQ(GURL(), SiteInstance::GetSiteForURL(NULL, test_url)); test_url = GURL("http://foo/a.html"); - EXPECT_EQ(GURL("http://foo"), SiteInstance::GetSiteForURL(test_url)); + EXPECT_EQ(GURL("http://foo"), SiteInstance::GetSiteForURL(NULL, test_url)); test_url = GURL("file:///C:/Downloads/"); - EXPECT_EQ(GURL(), SiteInstance::GetSiteForURL(test_url)); + EXPECT_EQ(GURL(), SiteInstance::GetSiteForURL(NULL, test_url)); // TODO(creis): Do we want to special case file URLs to ensure they have // either no site or a special "file://" site? We currently return // "file://home/" as the site, which seems broken. // test_url = GURL("file://home/"); - // EXPECT_EQ(GURL(), SiteInstance::GetSiteForURL(test_url)); + // EXPECT_EQ(GURL(), SiteInstance::GetSiteForURL(NULL, test_url)); } // Test of distinguishing URLs from different sites. Most of this logic is @@ -253,24 +255,24 @@ TEST_F(SiteInstanceTest, IsSameWebSite) { GURL url_shorthang = GURL(chrome::kAboutShorthangURL); // Same scheme and port -> same site. - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_foo, url_foo2)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_foo, url_foo2)); // Different scheme -> different site. - EXPECT_FALSE(SiteInstance::IsSameWebSite(url_foo, url_foo_https)); + EXPECT_FALSE(SiteInstance::IsSameWebSite(NULL, url_foo, url_foo_https)); // Different port -> same site. // (Changes to document.domain make renderer ignore the port.) - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_foo, url_foo_port)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_foo, url_foo_port)); // JavaScript links should be considered same site for anything. - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_javascript, url_foo)); - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_javascript, url_foo_https)); - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_javascript, url_foo_port)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_javascript, url_foo)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_javascript, url_foo_https)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_javascript, url_foo_port)); // The crash/hang URLs should also be treated as same site. (Bug 1143809.) - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_crash, url_foo)); - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_hang, url_foo)); - EXPECT_TRUE(SiteInstance::IsSameWebSite(url_shorthang, url_foo)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_crash, url_foo)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_hang, url_foo)); + EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_shorthang, url_foo)); } // Test to ensure that there is only one SiteInstance per site in a given |