diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/content_browser_client.h | 6 | ||||
-rw-r--r-- | content/browser/mock_content_browser_client.cc | 6 | ||||
-rw-r--r-- | content/browser/mock_content_browser_client.h | 2 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host.cc | 22 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host.h | 17 | ||||
-rw-r--r-- | content/browser/site_instance.cc | 36 | ||||
-rw-r--r-- | content/browser/site_instance.h | 7 | ||||
-rw-r--r-- | content/browser/site_instance_unittest.cc | 86 | ||||
-rw-r--r-- | content/content_tests.gypi | 1 | ||||
-rw-r--r-- | content/shell/shell_content_browser_client.cc | 6 | ||||
-rw-r--r-- | content/shell/shell_content_browser_client.h | 2 |
11 files changed, 103 insertions, 88 deletions
diff --git a/content/browser/content_browser_client.h b/content/browser/content_browser_client.h index 787273e..faabda4 100644 --- a/content/browser/content_browser_client.h +++ b/content/browser/content_browser_client.h @@ -23,6 +23,7 @@ class GURL; class MHTMLGenerationManager; class PluginProcessHost; class QuotaPermissionContext; +class RenderProcessHost; class RenderViewHost; class ResourceDispatcherHost; class SSLCertErrorHandler; @@ -124,6 +125,11 @@ class ContentBrowserClient { // SiteInstance. virtual bool IsURLSameAsAnySiteInstance(const GURL& url) = 0; + // Returns whether a new view for a given |site_url| can be launched in a + // given |process_host|. + virtual bool IsSuitableHost(RenderProcessHost* process_host, + const GURL& site_url) = 0; + // See CharacterEncoding's comment. virtual std::string GetCanonicalEncodingNameByAliasName( const std::string& alias_name) = 0; diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index 7544246..9daa752 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -68,6 +68,12 @@ bool MockContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) { return false; } +bool MockContentBrowserClient::IsSuitableHost( + RenderProcessHost* process_host, + const GURL& site_url) { + return true; +} + std::string MockContentBrowserClient::GetCanonicalEncodingNameByAliasName( const std::string& alias_name) { return std::string(); diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index e5ae25b..b8c88b71 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -37,6 +37,8 @@ class MockContentBrowserClient : public ContentBrowserClient { virtual bool ShouldUseProcessPerSite(BrowserContext* browser_context, const GURL& effective_url) OVERRIDE; virtual bool IsURLSameAsAnySiteInstance(const GURL& url) OVERRIDE; + virtual bool IsSuitableHost(RenderProcessHost* process_host, + const GURL& site_url) OVERRIDE; virtual std::string GetCanonicalEncodingNameByAliasName( const std::string& alias_name) OVERRIDE; virtual void AppendExtraCommandLineSwitches(CommandLine* command_line, diff --git a/content/browser/renderer_host/render_process_host.cc b/content/browser/renderer_host/render_process_host.cc index 958a30d..8fc7764 100644 --- a/content/browser/renderer_host/render_process_host.cc +++ b/content/browser/renderer_host/render_process_host.cc @@ -9,7 +9,10 @@ #include "base/sys_info.h" #include "content/browser/browser_thread.h" #include "content/browser/child_process_security_policy.h" +#include "content/browser/content_browser_client.h" +#include "content/browser/webui/web_ui_factory.h" #include "content/common/child_process_info.h" +#include "content/common/content_client.h" #include "content/common/content_constants.h" #include "content/common/content_switches.h" #include "content/common/notification_service.h" @@ -64,19 +67,15 @@ size_t GetMaxRendererProcessCount() { // associated with the given browser context. static bool IsSuitableHost(RenderProcessHost* host, content::BrowserContext* browser_context, - RenderProcessHost::Type type) { + const GURL& site_url) { if (host->browser_context() != browser_context) return false; - RenderProcessHost::Type host_type = RenderProcessHost::TYPE_NORMAL; - if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id())) - host_type = RenderProcessHost::TYPE_WEBUI; - if (ChildProcessSecurityPolicy::GetInstance()-> - HasExtensionBindings(host->id()) || - host->is_extension_process()) - host_type = RenderProcessHost::TYPE_EXTENSION; + if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id()) != + content::WebUIFactory::Get()->HasWebUIScheme(site_url)) + return false; - return host_type == type; + return content::GetContentClient()->browser()->IsSuitableHost(host, site_url); } // the global list of all renderer processes @@ -219,7 +218,8 @@ bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { // static RenderProcessHost* RenderProcessHost::GetExistingProcessHost( - content::BrowserContext* browser_context, Type type) { + content::BrowserContext* browser_context, + const GURL& site_url) { // First figure out which existing renderers we can use. std::vector<RenderProcessHost*> suitable_renderers; suitable_renderers.reserve(all_hosts.size()); @@ -227,7 +227,7 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost( iterator iter(AllHostsIterator()); while (!iter.IsAtEnd()) { if (run_renderer_in_process() || - IsSuitableHost(iter.GetCurrentValue(), browser_context, type)) + IsSuitableHost(iter.GetCurrentValue(), browser_context, site_url)) suitable_renderers.push_back(iter.GetCurrentValue()); iter.Advance(); diff --git a/content/browser/renderer_host/render_process_host.h b/content/browser/renderer_host/render_process_host.h index 44d5dc8..8dcefdf 100644 --- a/content/browser/renderer_host/render_process_host.h +++ b/content/browser/renderer_host/render_process_host.h @@ -32,6 +32,8 @@ namespace net { class URLRequestContextGetter; } +class GURL; + // Virtual interface that represents the browser side of the browser <-> // renderer communication channel. There will generally be one // RenderProcessHost per renderer process. @@ -44,16 +46,6 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Channel::Sender, public: typedef IDMap<RenderProcessHost>::iterator iterator; - // We classify renderers according to their highest privilege, and try - // to group pages into renderers with similar privileges. - // Note: it may be possible for a renderer to have multiple privileges, - // in which case we call it an "extension" renderer. - enum Type { - TYPE_NORMAL, // Normal renderer, no extra privileges. - TYPE_WEBUI, // Renderer with WebUI privileges, like New Tab. - TYPE_EXTENSION, // Renderer with extension privileges. - }; - // Details for RENDERER_PROCESS_CLOSED notifications. struct RendererClosedDetails { RendererClosedDetails(base::TerminationStatus status, @@ -274,11 +266,12 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Channel::Sender, // Get an existing RenderProcessHost associated with the given browser // context, if possible. The renderer process is chosen randomly from - // suitable renderers that share the same context and type. + // suitable renderers that share the same context and type (determined by the + // site url). // Returns NULL if no suitable renderer process is available, in which case // the caller is free to create a new renderer. static RenderProcessHost* GetExistingProcessHost( - content::BrowserContext* browser_context, Type type); + content::BrowserContext* browser_context, const GURL& site_url); // Overrides the default heuristic for limiting the max renderer process // count. This is useful for unit testing process limit behaviors. diff --git a/content/browser/site_instance.cc b/content/browser/site_instance.cc index cd68b7b..44a9f2e 100644 --- a/content/browser/site_instance.cc +++ b/content/browser/site_instance.cc @@ -71,7 +71,7 @@ RenderProcessHost* SiteInstance::GetProcess() { // See if we should reuse an old process if (RenderProcessHost::ShouldTryToUseExistingProcessHost()) process_ = RenderProcessHost::GetExistingProcessHost( - browsing_instance_->browser_context(), GetRendererType()); + browsing_instance_->browser_context(), site_); // Otherwise (or if that fails), create a new one. if (!process_) { @@ -125,12 +125,12 @@ bool SiteInstance::HasWrongProcessForURL(const GURL& url) const { if (!HasProcess()) return false; - // If the effective URL is an extension (e.g., for hosted apps) but the + // If the site URL is an extension (e.g., for hosted apps) but the // process is not (or vice versa), make sure we notice and fix it. - GURL effective_url = GetEffectiveURL(browsing_instance_->browser_context(), - url); - return effective_url.SchemeIs(chrome::kExtensionScheme) != - process_->is_extension_process(); + GURL site_url = GetSiteForURL(browsing_instance_->browser_context(), url); + content::ContentBrowserClient* browser = + content::GetContentClient()->browser(); + return !browser->IsSuitableHost(process_, site_url); } /*static*/ @@ -220,30 +220,6 @@ GURL SiteInstance::GetEffectiveURL(content::BrowserContext* browser_context, GetEffectiveURL(browser_context, url); } -/*static*/ -RenderProcessHost::Type SiteInstance::RendererTypeForURL(const GURL& url) { - if (!url.is_valid()) - return RenderProcessHost::TYPE_NORMAL; - - if (url.SchemeIs(chrome::kExtensionScheme)) - return RenderProcessHost::TYPE_EXTENSION; - - // TODO(erikkay) creis recommends using UseWebUIForURL instead. - if (content::WebUIFactory::Get()->HasWebUIScheme(url)) - return RenderProcessHost::TYPE_WEBUI; - - return RenderProcessHost::TYPE_NORMAL; -} - -RenderProcessHost::Type SiteInstance::GetRendererType() { - // We may not have a site at this point, which generally means this is a - // normal navigation. - if (!has_site_) - return RenderProcessHost::TYPE_NORMAL; - - return RendererTypeForURL(site_); -} - void SiteInstance::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/content/browser/site_instance.h b/content/browser/site_instance.h index 6ff2588..0a3494f 100644 --- a/content/browser/site_instance.h +++ b/content/browser/site_instance.h @@ -148,9 +148,6 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance>, static bool IsSameWebSite(content::BrowserContext* browser_context, const GURL& url1, const GURL& url2); - // Returns the renderer type for this URL. - static RenderProcessHost::Type RendererTypeForURL(const GURL& url); - protected: friend class base::RefCounted<SiteInstance>; friend class BrowsingInstance; @@ -167,10 +164,6 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance>, static GURL GetEffectiveURL(content::BrowserContext* browser_context, const GURL& url); - // Returns the type of renderer process this instance belongs in, for grouping - // purposes. - RenderProcessHost::Type GetRendererType(); - private: // NotificationObserver implementation. virtual void Observe(int type, diff --git a/content/browser/site_instance_unittest.cc b/content/browser/site_instance_unittest.cc index 58bc415..3a7cc0a 100644 --- a/content/browser/site_instance_unittest.cc +++ b/content/browser/site_instance_unittest.cc @@ -5,7 +5,6 @@ #include "base/compiler_specific.h" #include "base/stl_util.h" #include "base/string16.h" -#include "chrome/test/base/testing_profile.h" #include "content/browser/browser_thread.h" #include "content/browser/browsing_instance.h" #include "content/browser/child_process_security_policy.h" @@ -20,12 +19,16 @@ #include "content/common/content_client.h" #include "content/common/content_constants.h" #include "content/common/url_constants.h" +#include "content/test/test_browser_context.h" +#include "googleurl/src/url_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace { const char kSameAsAnyInstanceURL[] = "about:internets"; +const char kPrivilegedScheme[] = "privileged"; + class SiteInstanceTestWebUIFactory : public content::EmptyWebUIFactory { public: virtual bool UseWebUIForURL(content::BrowserContext* browser_context, @@ -39,7 +42,9 @@ class SiteInstanceTestWebUIFactory : public content::EmptyWebUIFactory { class SiteInstanceTestBrowserClient : public content::MockContentBrowserClient { public: - SiteInstanceTestBrowserClient() : old_browser_client_(NULL) { + SiteInstanceTestBrowserClient() + : old_browser_client_(NULL), + privileged_process_id_(-1) { } virtual TabContentsView* CreateTabContentsView(TabContents* tab_contents) { @@ -60,6 +65,12 @@ class SiteInstanceTestBrowserClient : public content::MockContentBrowserClient { url == GURL(chrome::kAboutCrashURL); } + virtual bool IsSuitableHost(RenderProcessHost* process_host, + const GURL& site_url) OVERRIDE { + return (privileged_process_id_ == process_host->id()) == + site_url.SchemeIs(kPrivilegedScheme); + } + virtual GURL GetEffectiveURL(content::BrowserContext* browser_context, const GURL& url) OVERRIDE { return url; @@ -69,9 +80,14 @@ class SiteInstanceTestBrowserClient : public content::MockContentBrowserClient { old_browser_client_ = old_browser_client; } + void SetPrivilegedProcessId(int process_id) { + privileged_process_id_ = process_id; + } + private: SiteInstanceTestWebUIFactory factory_; content::ContentBrowserClient* old_browser_client_; + int privileged_process_id_; }; class SiteInstanceTest : public testing::Test { @@ -85,12 +101,18 @@ class SiteInstanceTest : public testing::Test { old_browser_client_ = content::GetContentClient()->browser(); browser_client_.SetOriginalClient(old_browser_client_); content::GetContentClient()->set_browser(&browser_client_); + url_util::AddStandardScheme(kPrivilegedScheme); + url_util::AddStandardScheme(chrome::kChromeUIScheme); } virtual void TearDown() { content::GetContentClient()->set_browser(old_browser_client_); } + void SetPrivilegedProcessId(int process_id) { + browser_client_.SetPrivilegedProcessId(process_id); + } + private: MessageLoopForUI message_loop_; BrowserThread ui_thread_; @@ -101,8 +123,9 @@ class SiteInstanceTest : public testing::Test { class TestBrowsingInstance : public BrowsingInstance { public: - TestBrowsingInstance(Profile* profile, int* deleteCounter) - : BrowsingInstance(profile), + TestBrowsingInstance(content::BrowserContext* browser_context, + int* deleteCounter) + : BrowsingInstance(browser_context), use_process_per_site(false), deleteCounter_(deleteCounter) { } @@ -126,11 +149,12 @@ class TestBrowsingInstance : public BrowsingInstance { class TestSiteInstance : public SiteInstance { public: - static TestSiteInstance* CreateTestSiteInstance(Profile* profile, - int* siteDeleteCounter, - int* browsingDeleteCounter) { + static TestSiteInstance* CreateTestSiteInstance( + content::BrowserContext* browser_context, + int* siteDeleteCounter, + int* browsingDeleteCounter) { TestBrowsingInstance* browsing_instance = - new TestBrowsingInstance(profile, browsingDeleteCounter); + new TestBrowsingInstance(browser_context, browsingDeleteCounter); return new TestSiteInstance(browsing_instance, siteDeleteCounter); } @@ -186,13 +210,17 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) { // browsing_instance is now deleted // Ensure that instances are deleted when their RenderViewHosts are gone. - scoped_ptr<TestingProfile> profile(new TestingProfile()); + scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); instance = - TestSiteInstance::CreateTestSiteInstance(profile.get(), + TestSiteInstance::CreateTestSiteInstance(browser_context.get(), &siteDeleteCounter, &browsingDeleteCounter); { - TabContents contents(profile.get(), instance, MSG_ROUTING_NONE, NULL, NULL); + TabContents contents(browser_context.get(), + instance, + MSG_ROUTING_NONE, + NULL, + NULL); EXPECT_EQ(1, siteDeleteCounter); EXPECT_EQ(1, browsingDeleteCounter); } @@ -260,16 +288,16 @@ TEST_F(SiteInstanceTest, UpdateMaxPageID) { // Test to ensure GetProcess returns and creates processes correctly. TEST_F(SiteInstanceTest, GetProcess) { // Ensure that GetProcess returns a process. - scoped_ptr<TestingProfile> profile(new TestingProfile()); + scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); scoped_ptr<RenderProcessHost> host1; scoped_refptr<SiteInstance> instance( - SiteInstance::CreateSiteInstance(profile.get())); + SiteInstance::CreateSiteInstance(browser_context.get())); host1.reset(instance->GetProcess()); EXPECT_TRUE(host1.get() != NULL); // Ensure that GetProcess creates a new process. scoped_refptr<SiteInstance> instance2( - SiteInstance::CreateSiteInstance(profile.get())); + SiteInstance::CreateSiteInstance(browser_context.get())); scoped_ptr<RenderProcessHost> host2(instance2->GetProcess()); EXPECT_TRUE(host2.get() != NULL); EXPECT_NE(host1.get(), host2.get()); @@ -382,7 +410,7 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSite) { site_instance_a1->GetRelatedSiteInstance(url_a2)); // A visit to the original site in a new BrowsingInstance (same or different - // profile) should return a different SiteInstance. + // browser context) should return a different SiteInstance. TestBrowsingInstance* browsing_instance2 = new TestBrowsingInstance(NULL, &deleteCounter); browsing_instance2->use_process_per_site = false; @@ -409,8 +437,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSite) { } // Test to ensure that there is only one SiteInstance per site for an entire -// Profile, if process-per-site is in use. -TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInProfile) { +// BrowserContext, if process-per-site is in use. +TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInBrowserContext) { int deleteCounter = 0; TestBrowsingInstance* browsing_instance = new TestBrowsingInstance(NULL, &deleteCounter); @@ -439,8 +467,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInProfile) { EXPECT_EQ(site_instance_a1.get(), site_instance_a1->GetRelatedSiteInstance(url_a2)); - // A visit to the original site in a new BrowsingInstance (same profile) - // should also return the same SiteInstance. + // A visit to the original site in a new BrowsingInstance (same browser + // context) should also return the same SiteInstance. // This BrowsingInstance doesn't get its own SiteInstance within the test, so // it won't be deleted by its children. Thus, we'll keep a ref count to it // to make sure it gets deleted. @@ -450,11 +478,11 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInProfile) { EXPECT_EQ(site_instance_a1.get(), browsing_instance2->GetSiteInstanceForURL(url_a2)); - // A visit to the original site in a new BrowsingInstance (different profile) - // should return a different SiteInstance. - scoped_ptr<TestingProfile> profile(new TestingProfile()); + // A visit to the original site in a new BrowsingInstance (different browser + // context) should return a different SiteInstance. + scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); TestBrowsingInstance* browsing_instance3 = - new TestBrowsingInstance(profile.get(), &deleteCounter); + new TestBrowsingInstance(browser_context.get(), &deleteCounter); browsing_instance3->use_process_per_site = true; // Ensure the new SiteInstance is ref counted so that it gets deleted. scoped_refptr<SiteInstance> site_instance_a2_3( @@ -469,13 +497,13 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInProfile) { EXPECT_TRUE(browsing_instance->HasSiteInstance( GURL("http://mail.yahoo.com"))); // visited before EXPECT_TRUE(browsing_instance2->HasSiteInstance( - GURL("http://www.yahoo.com"))); // different BI, but same profile + GURL("http://www.yahoo.com"))); // different BI, but same browser context // Should be able to see that we don't have SiteInstances. EXPECT_FALSE(browsing_instance->HasSiteInstance( GURL("https://www.google.com"))); // not visited before EXPECT_FALSE(browsing_instance3->HasSiteInstance( - GURL("http://www.yahoo.com"))); // different BI, different profile + GURL("http://www.yahoo.com"))); // different BI, different context // browsing_instances will be deleted when their SiteInstances are deleted } @@ -501,11 +529,13 @@ TEST_F(SiteInstanceTest, ProcessSharingByType) { // Create some extension instances and make sure they share a process. scoped_refptr<SiteInstance> extension1_instance( - CreateSiteInstance(&rph_factory, GURL("chrome-extension://foo/bar"))); - policy->GrantExtensionBindings(extension1_instance->GetProcess()->id()); + CreateSiteInstance(&rph_factory, + GURL(kPrivilegedScheme + std::string("://foo/bar")))); + SetPrivilegedProcessId(extension1_instance->GetProcess()->id()); scoped_refptr<SiteInstance> extension2_instance( - CreateSiteInstance(&rph_factory, GURL("chrome-extension://baz/bar"))); + CreateSiteInstance(&rph_factory, + GURL(kPrivilegedScheme + std::string("://baz/bar")))); scoped_ptr<RenderProcessHost> extension_host( extension1_instance->GetProcess()); diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 5146d05..c6224ee 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -129,6 +129,7 @@ 'browser/renderer_host/resource_dispatcher_host_unittest.cc', 'browser/renderer_host/resource_queue_unittest.cc', 'browser/resolve_proxy_msg_helper_unittest.cc', + 'browser/site_instance_unittest.cc', 'browser/speech/endpointer/endpointer_unittest.cc', 'browser/speech/speech_recognition_request_unittest.cc', 'browser/speech/speech_recognizer_unittest.cc', diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc index 9452759..a8eb258 100644 --- a/content/shell/shell_content_browser_client.cc +++ b/content/shell/shell_content_browser_client.cc @@ -76,6 +76,12 @@ bool ShellContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) { return false; } +bool ShellContentBrowserClient::IsSuitableHost( + RenderProcessHost* process_host, + const GURL& site_url) { + return true; +} + std::string ShellContentBrowserClient::GetCanonicalEncodingNameByAliasName( const std::string& alias_name) { return std::string(); diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h index 6c2ce10..033897c 100644 --- a/content/shell/shell_content_browser_client.h +++ b/content/shell/shell_content_browser_client.h @@ -49,6 +49,8 @@ class ShellContentBrowserClient : public ContentBrowserClient virtual bool ShouldUseProcessPerSite(BrowserContext* browser_context, const GURL& effective_url) OVERRIDE; virtual bool IsURLSameAsAnySiteInstance(const GURL& url) OVERRIDE; + virtual bool IsSuitableHost(RenderProcessHost* process_host, + const GURL& site_url) OVERRIDE; virtual std::string GetCanonicalEncodingNameByAliasName( const std::string& alias_name) OVERRIDE; virtual void AppendExtraCommandLineSwitches(CommandLine* command_line, |