summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-09 06:45:46 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-09 06:45:46 +0000
commit6f37144dd7bbeded7d56dc37952342fa09e5a7bc (patch)
tree313f077bdd22d3e361d066753f7672ec77006d0c
parent5790d92e12c225bfe1683c81cf223dcf64302d1d (diff)
downloadchromium_src-6f37144dd7bbeded7d56dc37952342fa09e5a7bc.zip
chromium_src-6f37144dd7bbeded7d56dc37952342fa09e5a7bc.tar.gz
chromium_src-6f37144dd7bbeded7d56dc37952342fa09e5a7bc.tar.bz2
Extract a ProcessMap class from ExtensionProcessManager. This is a dumb data class that can be used on both the IO and UI threads to test extension/process associations.
BUG=95111,102617 TEST=Already covered by tests Review URL: http://codereview.chromium.org/8387061 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109194 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc90
-rw-r--r--chrome/browser/chrome_content_browser_client.h2
-rw-r--r--chrome/browser/extensions/app_process_apitest.cc61
-rw-r--r--chrome/browser/extensions/extension_crash_recovery_browsertest.cc6
-rw-r--r--chrome/browser/extensions/extension_event_router.cc20
-rw-r--r--chrome/browser/extensions/extension_file_browser_private_api.cc24
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc55
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.h6
-rw-r--r--chrome/browser/extensions/extension_info_map.cc34
-rw-r--r--chrome/browser/extensions/extension_info_map.h23
-rw-r--r--chrome/browser/extensions/extension_message_service.cc18
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc183
-rw-r--r--chrome/browser/extensions/extension_process_manager.h44
-rw-r--r--chrome/browser/extensions/extension_service.cc7
-rw-r--r--chrome/browser/extensions/extension_service.h5
-rw-r--r--chrome/browser/extensions/extension_tab_helper.cc7
-rw-r--r--chrome/browser/extensions/process_map.cc89
-rw-r--r--chrome/browser/extensions/process_map.h73
-rw-r--r--chrome/browser/extensions/process_map_unittest.cc52
-rw-r--r--chrome/browser/geolocation/chrome_geolocation_permission_context.cc17
-rw-r--r--chrome/browser/memory_details.cc25
-rw-r--r--chrome/browser/metrics/metrics_service.cc11
-rw-r--r--chrome/browser/profiles/profile.h4
-rw-r--r--chrome/browser/tab_contents/render_view_host_delegate_helper.cc17
-rw-r--r--chrome/browser/task_manager/task_manager_resource_providers.cc14
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--content/browser/mock_content_browser_client.cc8
-rw-r--r--content/browser/mock_content_browser_client.h2
-rw-r--r--content/browser/site_instance.cc7
-rw-r--r--content/public/browser/content_browser_client.h7
-rw-r--r--content/public/browser/notification_types.h4
-rw-r--r--content/shell/shell_content_browser_client.cc8
-rw-r--r--content/shell/shell_content_browser_client.h2
34 files changed, 508 insertions, 420 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 946d7dd..365b2b2 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -193,16 +193,19 @@ RenderProcessHostPrivilege GetPrivilegeRequiredByUrl(
RenderProcessHostPrivilege GetProcessPrivilege(
RenderProcessHost* process_host,
- ExtensionProcessManager* extension_process_manager) {
- if (!extension_process_manager->IsExtensionProcess(process_host->id()))
+ extensions::ProcessMap* process_map,
+ ExtensionService* service) {
+ // TODO(aa): It seems like hosted apps should be grouped separately from
+ // extensions: crbug.com/102533.
+ std::set<std::string> extension_ids =
+ process_map->GetExtensionsInProcess(process_host->id());
+ if (extension_ids.empty())
return PRIV_NORMAL;
- std::set<const Extension*> extensions_for_process(
- extension_process_manager->GetExtensionsForProcess(process_host->id()));
- for (std::set<const Extension*>::iterator iter =
- extensions_for_process.begin();
- iter != extensions_for_process.end(); ++iter) {
- if ((*iter)->is_storage_isolated())
+ for (std::set<std::string>::iterator iter = extension_ids.begin();
+ iter != extension_ids.end(); ++iter) {
+ const Extension* extension = service->GetExtensionById(*iter, false);
+ if (extension && extension->is_storage_isolated())
return PRIV_ISOLATED;
}
@@ -396,13 +399,12 @@ bool ChromeContentBrowserClient::IsSuitableHost(
const GURL& site_url) {
Profile* profile =
Profile::FromBrowserContext(process_host->browser_context());
- ExtensionProcessManager* extension_process_manager =
- profile->GetExtensionProcessManager();
ExtensionService* service = profile->GetExtensionService();
+ extensions::ProcessMap* process_map = service->process_map();
// These may be NULL during tests. In that case, just assume any site can
// share any host.
- if (!extension_process_manager || !service)
+ if (!service || !process_map)
return true;
// Experimental:
@@ -415,10 +417,65 @@ bool ChromeContentBrowserClient::IsSuitableHost(
if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation))
return false;
- return GetProcessPrivilege(process_host, extension_process_manager) ==
+ return GetProcessPrivilege(process_host, process_map, service) ==
GetPrivilegeRequiredByUrl(site_url, service);
}
+void ChromeContentBrowserClient::SiteInstanceGotProcess(
+ SiteInstance* site_instance) {
+ CHECK(site_instance->HasProcess());
+
+ Profile* profile = Profile::FromBrowserContext(
+ site_instance->browsing_instance()->browser_context());
+ ExtensionService* service = profile->GetExtensionService();
+ if (!service)
+ return;
+
+ const Extension* extension =
+ service->GetExtensionByURL(site_instance->site());
+ if (!extension)
+ extension = service->GetExtensionByWebExtent(site_instance->site());
+ if (!extension)
+ return;
+
+ service->process_map()->Insert(
+ extension->id(), site_instance->GetProcess()->id());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ExtensionInfoMap::RegisterExtensionProcess,
+ profile->GetExtensionInfoMap(),
+ extension->id(),
+ site_instance->GetProcess()->id()));
+}
+
+void ChromeContentBrowserClient::SiteInstanceDeleting(
+ SiteInstance* site_instance) {
+ if (!site_instance->HasProcess())
+ return;
+
+ Profile* profile = Profile::FromBrowserContext(
+ site_instance->browsing_instance()->browser_context());
+ ExtensionService* service = profile->GetExtensionService();
+ if (!service)
+ return;
+
+ const Extension* extension =
+ service->GetExtensionByURL(site_instance->site());
+ if (!extension)
+ extension = service->GetExtensionByWebExtent(site_instance->site());
+ if (!extension)
+ return;
+
+ service->process_map()->Remove(
+ extension->id(), site_instance->GetProcess()->id());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ExtensionInfoMap::UnregisterExtensionProcess,
+ profile->GetExtensionInfoMap(),
+ extension->id(),
+ site_instance->GetProcess()->id()));
+}
+
bool ChromeContentBrowserClient::ShouldSwapProcessesForNavigation(
const GURL& current_url,
const GURL& new_url) {
@@ -483,13 +540,10 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
Profile* profile = Profile::FromBrowserContext(process->browser_context());
-
- ExtensionProcessManager* extension_process_manager =
- profile->GetExtensionProcessManager();
- if (extension_process_manager->IsExtensionProcess(
- process->id())) {
+ extensions::ProcessMap* process_map =
+ profile->GetExtensionService()->process_map();
+ if (process_map && process_map->Contains(process->id()))
command_line->AppendSwitch(switches::kExtensionProcess);
- }
PrefService* prefs = profile->GetPrefs();
// Currently this pref is only registered if applied via a policy.
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index f978af8..14aba9d 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -35,6 +35,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
virtual bool IsURLSameAsAnySiteInstance(const GURL& url) OVERRIDE;
virtual bool IsSuitableHost(RenderProcessHost* process_host,
const GURL& url) OVERRIDE;
+ virtual void SiteInstanceGotProcess(SiteInstance* site_instance) OVERRIDE;
+ virtual void SiteInstanceDeleting(SiteInstance* site_instance) OVERRIDE;
virtual bool ShouldSwapProcessesForNavigation(const GURL& current_url,
const GURL& new_url) OVERRIDE;
virtual std::string GetCanonicalEncodingNameByAliasName(
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index 6872c1e..75f57b5 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -5,7 +5,8 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
@@ -84,8 +85,8 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisablePopupBlocking);
- ExtensionProcessManager* extension_process_manager =
- browser()->profile()->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
@@ -103,7 +104,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) {
ui_test_utils::NavigateToURLWithDisposition(
browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
browser()->GetTabContentsAt(1)->render_view_host()->process()->id()));
EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
LOG(INFO) << "Nav 1.";
@@ -111,7 +112,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) {
ui_test_utils::NavigateToURLWithDisposition(
browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
browser()->GetTabContentsAt(2)->render_view_host()->process()->id()));
EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
LOG(INFO) << "Nav 2.";
@@ -124,7 +125,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) {
LOG(INFO) << "New tab.";
ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
LOG(INFO) << "Nav 3.";
- EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
+ EXPECT_FALSE(process_map->Contains(
browser()->GetTabContentsAt(3)->render_view_host()->process()->id()));
EXPECT_FALSE(browser()->GetTabContentsAt(3)->web_ui());
@@ -196,8 +197,8 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessInstances) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisablePopupBlocking);
- ExtensionProcessManager* extension_process_manager =
- browser()->profile()->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
@@ -215,7 +216,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessInstances) {
browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
LOG(INFO) << "Nav 1.";
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
browser()->GetTabContentsAt(1)->render_view_host()->process()->id()));
EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
@@ -227,7 +228,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessInstances) {
LOG(INFO) << "New tab.";
ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
LOG(INFO) << "Nav 2.";
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
browser()->GetTabContentsAt(2)->render_view_host()->process()->id()));
EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
@@ -293,8 +294,8 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisablePopupBlocking);
- ExtensionProcessManager* extension_process_manager =
- browser()->profile()->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
@@ -306,7 +307,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
// Load an app URL before loading the app.
ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
TabContents* contents = browser()->GetTabContentsAt(0);
- EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
+ EXPECT_FALSE(process_map->Contains(
contents->render_view_host()->process()->id()));
// Load app and navigate to the page.
@@ -314,13 +315,13 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
LoadExtension(test_data_dir_.AppendASCII("app_process"));
ASSERT_TRUE(app);
ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
contents->render_view_host()->process()->id()));
// Disable app and navigate to the page.
DisableExtension(app->id());
ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
- EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
+ EXPECT_FALSE(process_map->Contains(
contents->render_view_host()->process()->id()));
// Enable app and reload the page.
@@ -331,7 +332,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
&browser()->GetSelectedTabContentsWrapper()->controller()));
browser()->Reload(CURRENT_TAB);
reload_observer.Wait();
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
contents->render_view_host()->process()->id()));
// Disable app and reload the page.
@@ -342,7 +343,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
&browser()->GetSelectedTabContentsWrapper()->controller()));
browser()->Reload(CURRENT_TAB);
reload_observer2.Wait();
- EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
+ EXPECT_FALSE(process_map->Contains(
contents->render_view_host()->process()->id()));
// Enable app and reload via JavaScript.
@@ -354,7 +355,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
L"", L"location.reload();"));
js_reload_observer.Wait();
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
contents->render_view_host()->process()->id()));
// Disable app and reload via JavaScript.
@@ -366,7 +367,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
L"", L"location.reload();"));
js_reload_observer2.Wait();
- EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
+ EXPECT_FALSE(process_map->Contains(
contents->render_view_host()->process()->id()));
}
@@ -379,8 +380,8 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisablePopupBlocking);
- ExtensionProcessManager* extension_process_manager =
- browser()->profile()->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
@@ -397,7 +398,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
CURRENT_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
- EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
+ EXPECT_FALSE(process_map->Contains(
browser()->GetTabContentsAt(0)->render_view_host()->process()->id()));
// Wait for popup window to appear.
@@ -419,7 +420,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
}
// Popup window should be in the app's process.
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
last_active_browser->GetTabContentsAt(0)->render_view_host()->process()->
id()));
}
@@ -435,8 +436,8 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisablePopupBlocking);
- ExtensionProcessManager* extension_process_manager =
- browser()->profile()->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
@@ -458,8 +459,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
RenderProcessHost* process =
browser()->GetTabContentsAt(0)->render_view_host()->process();
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
- process->id()));
+ EXPECT_TRUE(process_map->Contains(process->id()));
// Wait for popup window to appear. The new Browser may not have been
// added with SetLastActive, in which case we need to show it first.
@@ -485,8 +485,9 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
}
IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadAppAfterCrash) {
- ExtensionProcessManager* extension_process_manager =
- browser()->profile()->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
+
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
@@ -497,7 +498,7 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadAppAfterCrash) {
// Load the app, chrome.app.isInstalled should be true.
ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
TabContents* contents = browser()->GetTabContentsAt(0);
- EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
+ EXPECT_TRUE(process_map->Contains(
contents->render_view_host()->process()->id()));
bool is_installed = false;
ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
index ee1bec2..98f63f5 100644
--- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
+++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
@@ -90,8 +90,10 @@ class ExtensionCrashRecoveryTest : public ExtensionBrowserTest {
ASSERT_TRUE(extension_host);
ASSERT_TRUE(GetExtensionProcessManager()->HasExtensionHost(extension_host));
ASSERT_TRUE(extension_host->IsRenderViewLive());
- ASSERT_EQ(extension_host->render_view_host()->process(),
- GetExtensionProcessManager()->GetExtensionProcess(extension->id()));
+ extensions::ProcessMap* process_map =
+ browser()->profile()->GetExtensionService()->process_map();
+ ASSERT_TRUE(process_map->Contains(
+ extension->id(), extension_host->render_view_host()->process()->id()));
}
void LoadTestExtension() {
diff --git a/chrome/browser/extensions/extension_event_router.cc b/chrome/browser/extensions/extension_event_router.cc
index 963477f..01b7c1b 100644
--- a/chrome/browser/extensions/extension_event_router.cc
+++ b/chrome/browser/extensions/extension_event_router.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extension_webrequest_api.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
@@ -29,7 +30,7 @@ namespace {
const char kDispatchEvent[] = "Event.dispatchJSON";
-static void NotifyEventListenerRemovedOnIOThread(
+void NotifyEventListenerRemovedOnIOThread(
void* profile,
const std::string& extension_id,
const std::string& sub_event_name) {
@@ -257,16 +258,6 @@ void ExtensionEventRouter::DispatchEventImpl(
// Send the event only to renderers that are listening for it.
for (std::set<EventListener>::iterator listener = listeners.begin();
listener != listeners.end(); ++listener) {
- Profile* listener_profile = Profile::FromBrowserContext(
- listener->process->browser_context());
- ExtensionProcessManager* extension_process_manager =
- listener_profile->GetExtensionProcessManager();
- if (!extension_process_manager->AreBindingsEnabledForProcess(
- listener->process->id())) {
- // Don't send browser-level events to unprivileged processes.
- continue;
- }
-
if (!event->extension_id.empty() &&
event->extension_id != listener->extension_id)
continue;
@@ -279,6 +270,13 @@ void ExtensionEventRouter::DispatchEventImpl(
if (!extension)
continue;
+ Profile* listener_profile = Profile::FromBrowserContext(
+ listener->process->browser_context());
+ extensions::ProcessMap* process_map =
+ listener_profile->GetExtensionService()->process_map();
+ if (!process_map->Contains(extension->id(), listener->process->id()))
+ continue;
+
// Is this event from a different profile than the renderer (ie, an
// incognito tab event sent to a normal process, or vice versa).
bool cross_incognito = event->restrict_to_profile &&
diff --git a/chrome/browser/extensions/extension_file_browser_private_api.cc b/chrome/browser/extensions/extension_file_browser_private_api.cc
index f0af322..ee540d0 100644
--- a/chrome/browser/extensions/extension_file_browser_private_api.cc
+++ b/chrome/browser/extensions/extension_file_browser_private_api.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/file_manager_util.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
@@ -633,12 +634,17 @@ class ExecuteTasksFileSystemCallbackDispatcher
const std::string task_id,
const std::vector<GURL>& file_urls)
: function_(function),
+ process_id_(0),
profile_(profile),
source_url_(source_url),
extension_(extension),
task_id_(task_id),
origin_file_urls_(file_urls) {
DCHECK(function_);
+ if (function_->render_view_host() &&
+ function_->render_view_host()->process()) {
+ process_id_ = function_->render_view_host()->process()->id();
+ }
}
// fileapi::FileSystemCallbackDispatcher overrides.
@@ -708,10 +714,13 @@ class ExecuteTasksFileSystemCallbackDispatcher
// Checks legitimacy of file url and grants file RO access permissions from
// handler (target) extension and its renderer process.
bool SetupFileAccessPermissions(const GURL& origin_file_url,
- GURL* target_file_url, FilePath* file_path, bool* is_directory) {
+ GURL* target_file_url, FilePath* file_path, bool* is_directory) {
if (!extension_.get())
return false;
+ if (process_id_ == 0)
+ return false;
+
GURL file_origin_url;
FilePath virtual_path;
fileapi::FileSystemType type;
@@ -776,19 +785,13 @@ class ExecuteTasksFileSystemCallbackDispatcher
// TODO(zelidrag): Add explicit R/W + R/O permissions for non-component
// extensions.
- // Get target extension's process.
- RenderProcessHost* target_host =
- profile_->GetExtensionProcessManager()->GetExtensionProcess(
- target_extension_id);
- if (!target_host)
- return false;
-
// Grant R/O access permission to non-component extension and R/W to
// component extensions.
ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
- target_host->id(), final_file_path,
+ process_id_,
+ final_file_path,
extension_->location() != Extension::COMPONENT ?
- kReadOnlyFilePermissions : kReadWriteFilePermissions);
+ kReadOnlyFilePermissions : kReadWriteFilePermissions);
// Grant access to this particular file to target extension. This will
// ensure that the target extension can access only this FS entry and
@@ -809,6 +812,7 @@ class ExecuteTasksFileSystemCallbackDispatcher
}
ExecuteTasksFileBrowserFunction* function_;
+ int process_id_;
Profile* profile_;
// Extension source URL.
GURL source_url_;
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 068ae7a..4d0c94b 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -527,17 +527,10 @@ void ExtensionFunctionDispatcher::DispatchOnIOThread(
const Extension* extension =
extension_info_map->extensions().GetByURL(params.source_url);
- if (!extension_info_map->IsExtensionInProcess(extension->id(),
- render_process_id)) {
- // TODO(aa): Allow content scripts access to low-threat extension APIs.
- // See: crbug.com/80308.
- LOG(ERROR) << "Extension API called from non-extension process.";
- SendAccessDenied(ipc_sender, routing_id, params.request_id);
- return;
- }
-
- scoped_refptr<ExtensionFunction> function(CreateExtensionFunction(
- params, extension, profile, ipc_sender, routing_id));
+ scoped_refptr<ExtensionFunction> function(
+ CreateExtensionFunction(params, extension, render_process_id,
+ extension_info_map->process_map(), profile,
+ ipc_sender, routing_id));
if (!function)
return;
@@ -600,27 +593,9 @@ void ExtensionFunctionDispatcher::Dispatch(
const ExtensionHostMsg_Request_Params& params,
RenderViewHost* render_view_host) {
ExtensionService* service = profile()->GetExtensionService();
- ExtensionProcessManager* extension_process_manager =
- profile()->GetExtensionProcessManager();
- if (!service || !extension_process_manager)
- return;
-
- if (!service->ExtensionBindingsAllowed(params.source_url)) {
- LOG(ERROR) << "Extension bindings not allowed for URL: "
- << params.source_url.spec();
- SendAccessDenied(render_view_host, render_view_host->routing_id(),
- params.request_id);
+ extensions::ProcessMap* process_map = service->process_map();
+ if (!service || !process_map)
return;
- }
- if (!extension_process_manager->AreBindingsEnabledForProcess(
- render_view_host->process()->id())) {
- // TODO(aa): Allow content scripts access to low-threat extension APIs.
- // See: crbug.com/80308.
- LOG(ERROR) << "Extension API called from non-extension process.";
- SendAccessDenied(render_view_host, render_view_host->routing_id(),
- params.request_id);
- return;
- }
// TODO(aa): When we allow content scripts to call extension APIs, we will
// have to pass the extension ID explicitly here, not use the source URL.
@@ -629,7 +604,10 @@ void ExtensionFunctionDispatcher::Dispatch(
extension = service->GetExtensionByWebExtent(params.source_url);
scoped_refptr<ExtensionFunction> function(
- CreateExtensionFunction(params, extension, profile(), render_view_host,
+ CreateExtensionFunction(params, extension,
+ render_view_host->process()->id(),
+ *(service->process_map()),
+ profile(), render_view_host,
render_view_host->routing_id()));
if (!function)
return;
@@ -661,12 +639,21 @@ void ExtensionFunctionDispatcher::Dispatch(
ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction(
const ExtensionHostMsg_Request_Params& params,
const Extension* extension,
+ int requesting_process_id,
+ const extensions::ProcessMap& process_map,
void* profile,
IPC::Message::Sender* ipc_sender,
int routing_id) {
if (!extension) {
- LOG(ERROR) << "Extension does not exist for URL: "
- << params.source_url.spec();
+ LOG(ERROR) << "Specified extension does not exist.";
+ SendAccessDenied(ipc_sender, routing_id, params.request_id);
+ return NULL;
+ }
+
+ if (!process_map.Contains(extension->id(), requesting_process_id)) {
+ LOG(ERROR) << "Extension API called from incorrect process "
+ << requesting_process_id
+ << " from URL " << params.source_url.spec();
SendAccessDenied(ipc_sender, routing_id, params.request_id);
return NULL;
}
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index a45efc4c..fd4c7da 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -24,6 +24,10 @@ class RenderViewHost;
class TabContents;
struct ExtensionHostMsg_Request_Params;
+namespace extensions {
+class ProcessMap;
+}
+
// A factory function for creating new ExtensionFunction instances.
typedef ExtensionFunction* (*ExtensionFunctionFactory)();
@@ -117,6 +121,8 @@ class ExtensionFunctionDispatcher
static ExtensionFunction* CreateExtensionFunction(
const ExtensionHostMsg_Request_Params& params,
const Extension* extension,
+ int requesting_process_id,
+ const extensions::ProcessMap& process_map,
void* profile,
IPC::Message::Sender* ipc_sender,
int routing_id);
diff --git a/chrome/browser/extensions/extension_info_map.cc b/chrome/browser/extensions/extension_info_map.cc
index ed3fd7d..01ee98b 100644
--- a/chrome/browser/extensions/extension_info_map.cc
+++ b/chrome/browser/extensions/extension_info_map.cc
@@ -44,6 +44,10 @@ ExtensionInfoMap::ExtensionInfoMap() {
ExtensionInfoMap::~ExtensionInfoMap() {
}
+const extensions::ProcessMap& ExtensionInfoMap::process_map() const {
+ return process_map_;
+}
+
void ExtensionInfoMap::AddExtension(const Extension* extension,
base::Time install_time,
bool incognito_enabled) {
@@ -102,29 +106,23 @@ bool ExtensionInfoMap::CanCrossIncognito(const Extension* extension) {
void ExtensionInfoMap::RegisterExtensionProcess(const std::string& extension_id,
int process_id) {
- DCHECK(!IsExtensionInProcess(extension_id, process_id));
- extension_process_ids_.insert(
- ExtensionProcessIDMap::value_type(extension_id, process_id));
+ if (!process_map_.Insert(extension_id, process_id)) {
+ NOTREACHED() << "Duplicate extension process registration for: "
+ << extension_id << "," << process_id << ".";
+ }
}
void ExtensionInfoMap::UnregisterExtensionProcess(
const std::string& extension_id,
int process_id) {
- ExtensionProcessIDMap::iterator iter =
- std::find(extension_process_ids_.begin(),
- extension_process_ids_.end(),
- ExtensionProcessIDMap::value_type(extension_id, process_id));
- if (iter != extension_process_ids_.end())
- extension_process_ids_.erase(iter);
+ if (!process_map_.Remove(extension_id, process_id)) {
+ NOTREACHED() << "Unknown extension process registration for: "
+ << extension_id << "," << process_id << ".";
+ }
}
-bool ExtensionInfoMap::IsExtensionInProcess(
- const std::string& extension_id, int process_id) const {
- return std::find(
- extension_process_ids_.begin(),
- extension_process_ids_.end(),
- ExtensionProcessIDMap::value_type(extension_id, process_id)) !=
- extension_process_ids_.end();
+void ExtensionInfoMap::UnregisterAllExtensionsInProcess(int process_id) {
+ process_map_.Remove(process_id);
}
bool ExtensionInfoMap::SecurityOriginHasAPIPermission(
@@ -133,13 +131,13 @@ bool ExtensionInfoMap::SecurityOriginHasAPIPermission(
if (origin.SchemeIs(chrome::kExtensionScheme)) {
const std::string& id = origin.host();
return extensions_.GetByID(id)->HasAPIPermission(permission) &&
- IsExtensionInProcess(id, process_id);
+ process_map_.Contains(id, process_id);
}
ExtensionSet::ExtensionMap::const_iterator i = extensions_.begin();
for (; i != extensions_.end(); ++i) {
if (i->second->web_extent().MatchesSecurityOrigin(origin) &&
- IsExtensionInProcess(i->first, process_id) &&
+ process_map_.Contains(i->first, process_id) &&
i->second->HasAPIPermission(permission)) {
return true;
}
diff --git a/chrome/browser/extensions/extension_info_map.h b/chrome/browser/extensions/extension_info_map.h
index 6aaf6b0..e8f1afa 100644
--- a/chrome/browser/extensions/extension_info_map.h
+++ b/chrome/browser/extensions/extension_info_map.h
@@ -6,13 +6,13 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_INFO_MAP_H_
#pragma once
-#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/time.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_set.h"
@@ -31,6 +31,8 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> {
return disabled_extensions_;
}
+ const extensions::ProcessMap& process_map() const;
+
// Callback for when new extensions are loaded.
void AddExtension(const Extension* extension,
base::Time install_time,
@@ -51,21 +53,14 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> {
// sub-profile (incognito to original profile, or vice versa).
bool CanCrossIncognito(const Extension* extension);
- // Record that |extension_id| is running in |process_id|. We normally have
- // this information in ExtensionProcessManager on the UI thread, but we also
- // sometimes need it on the IO thread. Note that this can be any of
- // (extension, packaged app, hosted app).
+ // Adds an entry to process_map_.
void RegisterExtensionProcess(const std::string& extension_id,
int process_id);
- // Remove any record of |extension_id| created with RegisterExtensionProcess.
- // If |extension_id| is unknown, we ignore it.
+ // Removes an entry from process_map_.
void UnregisterExtensionProcess(const std::string& extension_id,
int process_id);
-
- // Returns true if |extension_id| is running in |process_id|..
- bool IsExtensionInProcess(const std::string& extension_id,
- int process_id) const;
+ void UnregisterAllExtensionsInProcess(int process_id);
// Returns true if there is exists an extension with the same origin as
// |origin| in |process_id| with |permission|.
@@ -87,11 +82,11 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> {
// Extra data associated with enabled extensions.
ExtraDataMap extra_data_;
- typedef std::multimap<std::string, int> ExtensionProcessIDMap;
- ExtensionProcessIDMap extension_process_ids_;
-
// Used by dispatchers to limit API quota for individual extensions.
ExtensionsQuotaService quota_service_;
+
+ // Assignment of extensions to processes.
+ extensions::ProcessMap process_map_;
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INFO_MAP_H_
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index f1febd7..d89b6e6 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -10,6 +10,7 @@
#include "base/values.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_tab_util.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
@@ -93,6 +94,18 @@ static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
port.routing_id, target_port_id, message));
}
+static RenderProcessHost* GetExtensionProcess(Profile* profile,
+ const std::string& extension_id) {
+ SiteInstance* site_instance =
+ profile->GetExtensionProcessManager()->GetSiteInstanceForURL(
+ Extension::GetBaseURLFromExtensionId(extension_id));
+
+ if (!site_instance->HasProcess())
+ return NULL;
+
+ return site_instance->GetProcess();
+}
+
} // namespace
// static
@@ -149,8 +162,7 @@ void ExtensionMessageService::OpenChannelToExtension(
// process, we will use the incognito EPM to find the right extension process,
// which depends on whether the extension uses spanning or split mode.
MessagePort receiver(
- profile->GetExtensionProcessManager()->GetExtensionProcess(
- target_extension_id),
+ GetExtensionProcess(profile, target_extension_id),
MSG_ROUTING_CONTROL);
TabContents* source_contents = tab_util::GetTabContentsByID(
source_process_id, source_routing_id);
@@ -258,7 +270,7 @@ int ExtensionMessageService::OpenSpecialChannelToExtension(
AllocatePortIdPair(&port1_id, &port2_id);
MessagePort receiver(
- profile_->GetExtensionProcessManager()->GetExtensionProcess(extension_id),
+ GetExtensionProcess(profile_, extension_id),
MSG_ROUTING_CONTROL);
if (!OpenChannelImpl(source, tab_json, receiver, port2_id,
extension_id, extension_id, channel_name))
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index cf9b70b..2fa8461 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -47,8 +47,6 @@ class IncognitoExtensionProcessManager : public ExtensionProcessManager {
virtual void CreateBackgroundHost(const Extension* extension,
const GURL& url);
virtual SiteInstance* GetSiteInstanceForURL(const GURL& url);
- virtual RenderProcessHost* GetExtensionProcess(const GURL& url);
- virtual const Extension* GetExtensionForSiteInstance(int site_instance_id);
private:
// content::NotificationObserver:
@@ -109,10 +107,6 @@ ExtensionProcessManager::ExtensionProcessManager(Profile* profile)
content::Source<Profile>(profile));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
content::Source<Profile>(profile));
- // We can listen to everything for SITE_INSTANCE_DELETED because we check the
- // |site_instance_id| in UnregisterExtensionSiteInstance.
- registrar_.Add(this, content::NOTIFICATION_SITE_INSTANCE_DELETED,
- content::NotificationService::AllBrowserContextsAndSources());
registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
}
@@ -265,7 +259,6 @@ void ExtensionProcessManager::RegisterRenderViewHost(
RenderViewHost* render_view_host,
const Extension* extension) {
all_extension_views_.insert(render_view_host);
- RegisterExtensionSiteInstance(render_view_host->site_instance(), extension);
}
void ExtensionProcessManager::UnregisterRenderViewHost(
@@ -273,155 +266,6 @@ void ExtensionProcessManager::UnregisterRenderViewHost(
all_extension_views_.erase(render_view_host);
}
-void ExtensionProcessManager::RegisterExtensionSiteInstance(
- SiteInstance* site_instance,
- const Extension* extension) {
- if (!site_instance->HasProcess()) {
- NOTREACHED();
- return;
- }
-
- int site_instance_id = site_instance->id();
- int render_process_id = site_instance->GetProcess()->id();
- if (process_ids_[render_process_id].insert(site_instance_id).second) {
- // Register process hosting extensions that have access to extension
- // bindings with the ExtensionInfoMap on the IO thread.
- Profile* profile =
- Profile::FromBrowserContext(browsing_instance_->browser_context());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ExtensionInfoMap::RegisterExtensionProcess,
- profile->GetExtensionInfoMap(),
- extension->id(),
- render_process_id));
- }
-
- SiteInstanceIDMap::const_iterator it = extension_ids_.find(site_instance_id);
- if (it != extension_ids_.end() && (*it).second == extension->id())
- return;
-
- // SiteInstance ids should get removed from the map before the extension ids
- // get used for a new SiteInstance.
- DCHECK(it == extension_ids_.end());
- extension_ids_[site_instance_id] = extension->id();
-}
-
-void ExtensionProcessManager::UnregisterExtensionSiteInstance(
- SiteInstance* site_instance) {
- int site_instance_id = site_instance->id();
- std::string extension_id = extension_ids_[site_instance_id];
- if (!extension_id.empty())
- extension_ids_.erase(site_instance_id);
-
- int render_process_id = ClearSiteInstanceID(site_instance_id);
- if (render_process_id == -1)
- return;
-
- Profile* profile = Profile::FromBrowserContext(
- browsing_instance_->browser_context());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ExtensionInfoMap::UnregisterExtensionProcess,
- profile->GetExtensionInfoMap(),
- extension_id,
- render_process_id));
-}
-
-int ExtensionProcessManager::ClearSiteInstanceID(int site_instance_id) {
- for (ProcessIDMap::iterator i = process_ids_.begin();
- i != process_ids_.end(); ++i) {
- SiteInstanceIDSet& site_instance_id_set = i->second;
- for (SiteInstanceIDSet::iterator j = site_instance_id_set.begin();
- j != site_instance_id_set.end(); ++j) {
- if (*j == site_instance_id) {
- int render_process_id = i->first;
- site_instance_id_set.erase(j);
- if (site_instance_id_set.empty())
- process_ids_.erase(i);
- return render_process_id;
- }
- }
- }
- return -1;
-}
-
-bool ExtensionProcessManager::IsExtensionProcess(int render_process_id) {
- return process_ids_.find(render_process_id) != process_ids_.end();
-}
-
-bool ExtensionProcessManager::AreBindingsEnabledForProcess(
- int render_process_id) {
- // Must behave logically the same as AreBindingsEnabledForProcess() in
- // extension_info_map.cc.
- ProcessIDMap::iterator it = process_ids_.find(render_process_id);
- if (it == process_ids_.end())
- return false;
-
- Profile* profile =
- Profile::FromBrowserContext(browsing_instance_->browser_context());
- ExtensionService* service = profile->GetExtensionService();
- for (std::set<int>::iterator site_instance_id = it->second.begin();
- site_instance_id != it->second.end(); ++site_instance_id) {
- const Extension* extension =
- GetExtensionForSiteInstance(*site_instance_id);
- if (extension == NULL)
- continue;
- if (service->ExtensionBindingsAllowed(extension->url()))
- return true;
- }
- return false;
-}
-
-RenderProcessHost* ExtensionProcessManager::GetExtensionProcess(
- const GURL& url) {
- if (!browsing_instance_->HasSiteInstance(url))
- return NULL;
- scoped_refptr<SiteInstance> site(
- browsing_instance_->GetSiteInstanceForURL(url));
- if (site->HasProcess())
- return site->GetProcess();
- return NULL;
-}
-
-RenderProcessHost* ExtensionProcessManager::GetExtensionProcess(
- const std::string& extension_id) {
- return GetExtensionProcess(
- Extension::GetBaseURLFromExtensionId(extension_id));
-}
-
-const Extension* ExtensionProcessManager::GetExtensionForSiteInstance(
- int site_instance_id) {
- SiteInstanceIDMap::const_iterator it = extension_ids_.find(site_instance_id);
- if (it != extension_ids_.end()) {
- // Look up the extension by ID, including disabled extensions in case
- // this gets called while an old process is still around.
- Profile* profile =
- Profile::FromBrowserContext(browsing_instance_->browser_context());
- ExtensionService* service = profile->GetExtensionService();
- return service->GetExtensionById(it->second, false);
- }
-
- return NULL;
-}
-
-std::set<const Extension*> ExtensionProcessManager::GetExtensionsForProcess(
- int process_id) {
- std::set<const Extension*> result;
-
- ProcessIDMap::iterator site_id_set = process_ids_.find(process_id);
- if (site_id_set == process_ids_.end())
- return result;
-
- for (std::set<int>::iterator site_id = site_id_set->second.begin();
- site_id != site_id_set->second.end(); ++site_id) {
- const Extension* extension = GetExtensionForSiteInstance(*site_id);
- if (extension)
- result.insert(extension);
- }
-
- return result;
-}
-
SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) {
return browsing_instance_->GetSiteInstanceForURL(url);
}
@@ -499,12 +343,6 @@ void ExtensionProcessManager::Observe(
break;
}
- case content::NOTIFICATION_SITE_INSTANCE_DELETED: {
- SiteInstance* site_instance = content::Source<SiteInstance>(source).ptr();
- UnregisterExtensionSiteInstance(site_instance);
- break;
- }
-
case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: {
ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();
if (host->extension_host_type() ==
@@ -609,27 +447,6 @@ SiteInstance* IncognitoExtensionProcessManager::GetSiteInstanceForURL(
}
}
-RenderProcessHost* IncognitoExtensionProcessManager::GetExtensionProcess(
- const GURL& url) {
- const Extension* extension = GetExtensionOrAppByURL(url);
- if (!extension || extension->incognito_split_mode()) {
- return ExtensionProcessManager::GetExtensionProcess(url);
- } else {
- return original_manager_->GetExtensionProcess(url);
- }
-}
-
-const Extension* IncognitoExtensionProcessManager::GetExtensionForSiteInstance(
- int site_instance_id) {
- const Extension* extension =
- ExtensionProcessManager::GetExtensionForSiteInstance(site_instance_id);
- if (extension && extension->incognito_split_mode()) {
- return extension;
- } else {
- return original_manager_->GetExtensionForSiteInstance(site_instance_id);
- }
-}
-
const Extension* IncognitoExtensionProcessManager::GetExtensionOrAppByURL(
const GURL& url) {
Profile* profile =
diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h
index 476c053..3ee2a4f 100644
--- a/chrome/browser/extensions/extension_process_manager.h
+++ b/chrome/browser/extensions/extension_process_manager.h
@@ -68,6 +68,8 @@ class ExtensionProcessManager : public content::NotificationObserver {
ExtensionHost* GetBackgroundHostForExtension(const std::string& extension_id);
// Returns the SiteInstance that the given URL belongs to.
+ // TODO(aa): This only returns correct results for extensions and packaged
+ // apps, not hosted apps.
virtual SiteInstance* GetSiteInstanceForURL(const GURL& url);
// Registers a RenderViewHost as hosting a given extension.
@@ -82,28 +84,6 @@ class ExtensionProcessManager : public content::NotificationObserver {
std::set<RenderViewHost*> GetRenderViewHostsForExtension(
const std::string& extension_id);
- // True if this process host is hosting an extension.
- bool IsExtensionProcess(int render_process_id);
-
- // True if this process host is hosting an extension with extension bindings
- // enabled.
- bool AreBindingsEnabledForProcess(int render_process_id);
-
- // Returns the extension process that |url| is associated with if it exists.
- // This is not valid for hosted apps without the background permission, since
- // such apps may have multiple processes.
- virtual RenderProcessHost* GetExtensionProcess(const GURL& url);
-
- // Returns the process that the extension with the given ID is running in.
- RenderProcessHost* GetExtensionProcess(const std::string& extension_id);
-
- // Returns the Extension associated with the given SiteInstance id, if any.
- virtual const Extension* GetExtensionForSiteInstance(int site_instance_id);
-
- // Returns the set of extensions for the specified process. If the process is
- // not an extension process, or contains no extensions, returns an empty set.
- std::set<const Extension*> GetExtensionsForProcess(int process_id);
-
// Returns true if |host| is managed by this process manager.
bool HasExtensionHost(ExtensionHost* host) const;
@@ -142,23 +122,7 @@ class ExtensionProcessManager : public content::NotificationObserver {
// controls process grouping.
scoped_refptr<BrowsingInstance> browsing_instance_;
- // A map of site instance ID to the ID of the extension it hosts.
- typedef std::map<int, std::string> SiteInstanceIDMap;
- SiteInstanceIDMap extension_ids_;
-
- // A map of process ID to site instance ID of the site instances it hosts.
- typedef std::set<int> SiteInstanceIDSet;
- typedef std::map<int, SiteInstanceIDSet> ProcessIDMap;
- ProcessIDMap process_ids_;
-
private:
- // Registers a site instance as hosting a given extension.
- void RegisterExtensionSiteInstance(SiteInstance* site_instance,
- const Extension* extension);
-
- // Unregisters the extension associated with |site_instance|.
- void UnregisterExtensionSiteInstance(SiteInstance* site_instance);
-
// Contains all extension-related RenderViewHost instances for all extensions.
typedef std::set<RenderViewHost*> RenderViewHostSet;
RenderViewHostSet all_extension_views_;
@@ -169,10 +133,6 @@ class ExtensionProcessManager : public content::NotificationObserver {
// Excludes background page.
bool HasVisibleViews(const std::string& extension_id);
- // Clears the mapping for the specified site instance. Returns the process the
- // site was mapped to, or -1 if it wasn't found.
- int ClearSiteInstanceID(int site_instance_id);
-
DISALLOW_COPY_AND_ASSIGN(ExtensionProcessManager);
};
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index b2d09b6..a42fe0f 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -2339,6 +2339,13 @@ void ExtensionService::Observe(int type,
break;
installed_app_hosts_.erase(process->id());
+
+ process_map_.Remove(process->id());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ExtensionInfoMap::UnregisterAllExtensionsInProcess,
+ profile_->GetExtensionInfoMap(),
+ process->id()));
break;
}
case chrome::NOTIFICATION_PREF_CHANGED: {
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 47cc52d..60da15b 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -33,6 +33,7 @@
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/extensions/external_extension_provider_interface.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/browser/sync/api/sync_change.h"
@@ -186,6 +187,8 @@ class ExtensionService
AppsPromo* apps_promo() { return &apps_promo_; }
+ extensions::ProcessMap* process_map() { return &process_map_; }
+
// Whether this extension can run in an incognito window.
virtual bool IsIncognitoEnabled(const std::string& extension_id) const;
virtual void SetIsIncognitoEnabled(const std::string& extension_id,
@@ -788,6 +791,8 @@ class ExtensionService
// Contains an entry for each warning that shall be currently shown.
ExtensionWarningSet extension_warnings_;
+ extensions::ProcessMap process_map_;
+
FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
InstallAppsWithUnlimtedStorage);
FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
diff --git a/chrome/browser/extensions/extension_tab_helper.cc b/chrome/browser/extensions/extension_tab_helper.cc
index d597396..7aa3ce5 100644
--- a/chrome/browser/extensions/extension_tab_helper.cc
+++ b/chrome/browser/extensions/extension_tab_helper.cc
@@ -168,19 +168,16 @@ void ExtensionTabHelper::OnGetAppNotifyChannel(
Profile* profile =
Profile::FromBrowserContext(tab_contents()->browser_context());
ExtensionService* extension_service = profile->GetExtensionService();
- ExtensionProcessManager* process_manager =
- profile->GetExtensionProcessManager();
+ extensions::ProcessMap* process_map = extension_service->process_map();
RenderProcessHost* process =
tab_contents_wrapper()->render_view_host()->process();
const Extension* extension =
extension_service->GetInstalledApp(requestor_url);
bool allowed =
extension &&
- extension->is_app() &&
extension->HasAPIPermission(
ExtensionAPIPermission::kExperimental) &&
- (extension->is_hosted_app() ||
- process_manager->GetExtensionProcess(requestor_url) == process);
+ process_map->Contains(extension->id(), process->id());
if (!allowed) {
AppNotifyChannelSetupComplete("", "permission_error", return_route_id,
callback_id);
diff --git a/chrome/browser/extensions/process_map.cc b/chrome/browser/extensions/process_map.cc
new file mode 100644
index 0000000..fa12f6c
--- /dev/null
+++ b/chrome/browser/extensions/process_map.cc
@@ -0,0 +1,89 @@
+// Copyright (c) 2011 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 "chrome/browser/extensions/process_map.h"
+
+namespace extensions {
+
+// Item
+ProcessMap::Item::Item() {
+}
+
+ProcessMap::Item::Item(const ProcessMap::Item& other)
+ : extension_id(other.extension_id), process_id(other.process_id) {
+}
+
+ProcessMap::Item::Item(const std::string& extension_id, int process_id)
+ : extension_id(extension_id), process_id(process_id) {
+}
+
+ProcessMap::Item::~Item() {
+}
+
+bool ProcessMap::Item::operator<(const ProcessMap::Item& other) const {
+ if (extension_id < other.extension_id)
+ return true;
+
+ if (extension_id == other.extension_id &&
+ process_id < other.process_id) {
+ return true;
+ }
+
+ return false;
+}
+
+
+// ProcessMap
+ProcessMap::ProcessMap() {
+}
+
+ProcessMap::~ProcessMap() {
+}
+
+bool ProcessMap::Insert(const std::string& extension_id, int process_id) {
+ return items_.insert(Item(extension_id, process_id)).second;
+}
+
+bool ProcessMap::Remove(const std::string& extension_id, int process_id) {
+ return items_.erase(Item(extension_id, process_id)) > 0;
+}
+
+int ProcessMap::Remove(int process_id) {
+ int result = 0;
+ for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end(); ) {
+ if (iter->process_id == process_id) {
+ items_.erase(iter++);
+ ++result;
+ } else {
+ ++iter;
+ }
+ }
+ return result;
+}
+
+bool ProcessMap::Contains(const std::string& extension_id,
+ int process_id) const {
+ return items_.find(Item(extension_id, process_id)) != items_.end();
+}
+
+bool ProcessMap::Contains(int process_id) const {
+ for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
+ ++iter) {
+ if (iter->process_id == process_id)
+ return true;
+ }
+ return false;
+}
+
+std::set<std::string> ProcessMap::GetExtensionsInProcess(int process_id) const {
+ std::set<std::string> result;
+ for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
+ ++iter) {
+ if (iter->process_id == process_id)
+ result.insert(iter->extension_id);
+ }
+ return result;
+}
+
+} // extensions
diff --git a/chrome/browser/extensions/process_map.h b/chrome/browser/extensions/process_map.h
new file mode 100644
index 0000000..9d43505
--- /dev/null
+++ b/chrome/browser/extensions/process_map.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2011 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_PROCESS_MAP_H_
+#define CHROME_BROWSER_EXTENSIONS_PROCESS_MAP_H_
+#pragma once
+
+#include <set>
+#include <string>
+
+#include "base/basictypes.h"
+
+namespace extensions {
+
+// Contains information about which extensions are assigned to which processes.
+//
+// The relationship between extensions and processes is complex:
+// - Extensions can be either "split" mode or "spanning" mode.
+// - In spanning mode, extensions share a single process between all incognito
+// and normal windows. This was the original mode for extensions.
+// - In split mode, extensions have separate processes in incognito windows.
+// - There are also hosted apps, which are a kind of extensions, and those
+// usually have a process model similar to normal web sites: multiple
+// processes per-profile.
+//
+// In general, we seem to play with the process model of extensions a lot, so
+// it is safest to assume it is many-to-many in most places in the codebase.
+//
+// Note that because of content scripts, frames, and other edge cases in
+// Chrome's process isolation, extension code can still end up running outside
+// an assigned process.
+//
+// But we only allow high-privilege operations to be performed by an extension
+// when it is running in an assigned process.
+class ProcessMap {
+ public:
+ ProcessMap();
+ ~ProcessMap();
+
+ size_t size() const { return items_.size(); }
+
+ bool Insert(const std::string& extension_id, int process_id);
+ bool Remove(const std::string& extension_id, int process_id);
+ int Remove(int process_id);
+ bool Contains(const std::string& extension_id, int process_id) const;
+ bool Contains(int process_id) const;
+
+ std::set<std::string> GetExtensionsInProcess(int process_id) const;
+
+ private:
+ struct Item {
+ Item();
+ Item(const Item& other);
+ Item(const std::string& extension_id, int process_id);
+ ~Item();
+
+ // Required for set membership.
+ bool operator<(const Item& other) const;
+
+ std::string extension_id;
+ int process_id;
+ };
+
+ typedef std::set<Item> ItemSet;
+ std::set<Item> items_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessMap);
+};
+
+} // extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_PROCESS_MAP_H_
diff --git a/chrome/browser/extensions/process_map_unittest.cc b/chrome/browser/extensions/process_map_unittest.cc
new file mode 100644
index 0000000..40b3e595
--- /dev/null
+++ b/chrome/browser/extensions/process_map_unittest.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2011 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 "chrome/browser/extensions/process_map.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+using extensions::ProcessMap;
+
+TEST(ExtensionProcessMapTest, Test) {
+ ProcessMap map;
+
+ // Test behavior when empty.
+ EXPECT_FALSE(map.Contains("a", 1));
+ EXPECT_FALSE(map.Remove("a", 1));
+ EXPECT_EQ(0u, map.size());
+
+ // Test insertion and behavior with one item.
+ EXPECT_TRUE(map.Insert("a", 1));
+ EXPECT_TRUE(map.Contains("a", 1));
+ EXPECT_FALSE(map.Contains("a", 2));
+ EXPECT_FALSE(map.Contains("b", 1));
+ EXPECT_EQ(1u, map.size());
+
+ // Test inserting a duplicate item.
+ EXPECT_FALSE(map.Insert("a", 1));
+ EXPECT_TRUE(map.Contains("a", 1));
+ EXPECT_EQ(1u, map.size());
+
+ // Insert some more items.
+ EXPECT_TRUE(map.Insert("a", 2));
+ EXPECT_TRUE(map.Insert("b", 1));
+ EXPECT_TRUE(map.Insert("b", 2));
+ EXPECT_EQ(4u, map.size());
+
+ EXPECT_TRUE(map.Contains("a", 1));
+ EXPECT_TRUE(map.Contains("a", 2));
+ EXPECT_TRUE(map.Contains("b", 1));
+ EXPECT_TRUE(map.Contains("b", 2));
+ EXPECT_FALSE(map.Contains("a", 3));
+
+ // Test removal.
+ EXPECT_TRUE(map.Remove("a", 1));
+ EXPECT_FALSE(map.Remove("a", 1));
+ EXPECT_EQ(3u, map.size());
+
+ EXPECT_EQ(2, map.Remove(2));
+ EXPECT_EQ(1u, map.size());
+ EXPECT_EQ(0, map.Remove(2));
+ EXPECT_EQ(1u, map.size());
+}
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
index b160c38..0328da9 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
@@ -530,18 +530,11 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
if (!ext)
ext = extensions->GetExtensionByWebExtent(requesting_frame);
if (ext && ext->HasAPIPermission(ExtensionAPIPermission::kGeolocation)) {
- // Make sure this matches the current extension.
- RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
- render_view_id);
- if (rvh && rvh->site_instance()) {
- ExtensionProcessManager* epm = profile_->GetExtensionProcessManager();
- const Extension* current_ext = epm->GetExtensionForSiteInstance(
- rvh->site_instance()->id());
- if (ext == current_ext) {
- NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
- requesting_frame, true);
- return;
- }
+ // Make sure the extension is in the calling process.
+ if (extensions->process_map()->Contains(ext->id(), render_process_id)) {
+ NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
+ requesting_frame, true);
+ return;
}
}
}
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index 138a51d..3f5cb15 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -144,8 +144,8 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
Profile* profile =
Profile::FromBrowserContext(render_process_host->browser_context());
ExtensionService* extension_service = profile->GetExtensionService();
- ExtensionProcessManager* extension_process_manager =
- profile->GetExtensionProcessManager();
+ extensions::ProcessMap* extension_process_map =
+ extension_service->process_map();
// The RenderProcessHost may host multiple TabContents. Any
// of them which contain diagnostics information make the whole
@@ -175,14 +175,25 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
process.renderer_type = ChildProcessInfo::RENDERER_DEVTOOLS;
else
process.renderer_type = ChildProcessInfo::RENDERER_CHROME;
- } else if (extension_process_manager->AreBindingsEnabledForProcess(
- host->process()->id())) {
- process.renderer_type = ChildProcessInfo::RENDERER_EXTENSION;
+ } else if (extension_process_map->Contains(host->process()->id())) {
+ // For our purposes, don't count processes containing only hosted apps
+ // as extension processes. See also: crbug.com/102533.
+ std::set<std::string> extension_ids =
+ extension_process_map->GetExtensionsInProcess(
+ host->process()->id());
+ for (std::set<std::string>::iterator iter = extension_ids.begin();
+ iter != extension_ids.end(); ++iter) {
+ const Extension* extension =
+ extension_service->GetExtensionById(*iter, false);
+ if (extension && !extension->is_hosted_app()) {
+ process.renderer_type = ChildProcessInfo::RENDERER_EXTENSION;
+ break;
+ }
+ }
}
TabContents* contents = host_delegate->GetAsTabContents();
if (!contents) {
- if (extension_process_manager->IsExtensionProcess(
- host->process()->id())) {
+ if (extension_process_map->Contains(host->process()->id())) {
const Extension* extension =
extension_service->GetExtensionByURL(url);
if (extension) {
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index 7f2db89..9a299da 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -156,7 +156,8 @@
#include "base/values.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/metrics/metrics_log.h"
@@ -1243,11 +1244,9 @@ void MetricsService::LogRendererCrash(RenderProcessHost* host,
base::TerminationStatus status,
bool was_alive) {
Profile* profile = Profile::FromBrowserContext(host->browser_context());
- ExtensionProcessManager* extension_process_manager =
- profile->GetExtensionProcessManager();
- bool was_extension_process = extension_process_manager ?
- extension_process_manager->IsExtensionProcess(host->id()) :
- false;
+ ExtensionService* service = profile->GetExtensionService();
+ bool was_extension_process =
+ service && service->process_map()->Contains(host->id());
if (status == base::TERMINATION_STATUS_PROCESS_CRASHED ||
status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
if (was_extension_process)
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 0d32bd0..0e3df82 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -217,6 +217,10 @@ class Profile : public content::BrowserContext {
// Return the incognito version of this profile. The returned pointer
// is owned by the receiving profile. If the receiving profile is off the
// record, the same profile is returned.
+ //
+ // WARNING: This will create the OffTheRecord profile if it doesn't already
+ // exist. If this isn't what you want, you need to check
+ // HasOffTheRecordProfile() first.
virtual Profile* GetOffTheRecordProfile() = 0;
// Destroys the incognito profile.
diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
index 96c841c..28f4eda 100644
--- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
+++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_webkit_preferences.h"
+#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/prerender/prerender_manager.h"
@@ -114,11 +115,11 @@ RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents(
return NULL;
// Ensure that we're trying to open this from the extension's process.
- ExtensionProcessManager* process_manager =
- profile->GetExtensionProcessManager();
- if (!site->GetProcess() || !process_manager ||
- site->GetProcess() != process_manager->GetExtensionProcess(opener_url))
+ extensions::ProcessMap* process_map = extensions_service->process_map();
+ if (!site->GetProcess() ||
+ !process_map->Contains(extension->id(), site->GetProcess()->id())) {
return NULL;
+ }
// Only allow a single background contents per app. If one already exists,
// close it (even if it was specified in the manifest).
@@ -542,12 +543,10 @@ WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
web_prefs.is_online = !net::NetworkChangeNotifier::IsOffline();
- ExtensionProcessManager* extension_process_manager =
- profile->GetExtensionProcessManager();
- if (extension_process_manager) {
+ ExtensionService* service = profile->GetExtensionService();
+ if (service) {
const Extension* extension =
- extension_process_manager->GetExtensionForSiteInstance(
- rvh->site_instance()->id());
+ service->GetExtensionByURL(rvh->site_instance()->site());
extension_webkit_preferences::SetPreferences(&web_prefs, extension);
}
diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc
index fb2f2ed..7094b64 100644
--- a/chrome/browser/task_manager/task_manager_resource_providers.cc
+++ b/chrome/browser/task_manager/task_manager_resource_providers.cc
@@ -267,13 +267,11 @@ string16 TaskManagerTabContentsResource::GetTitle() const {
// Only classify as an app if the URL is an app and the tab is hosting an
// extension process. (It's possible to be showing the URL from before it
// was installed as an app.)
- ExtensionService* extensions_service =
+ ExtensionService* extension_service =
tab_contents_->profile()->GetExtensionService();
- ExtensionProcessManager* extension_process_manager =
- tab_contents_->profile()->GetExtensionProcessManager();
- bool is_app = extensions_service->IsInstalledApp(url) &&
- extension_process_manager->IsExtensionProcess(
- contents->GetRenderProcessHost()->id());
+ extensions::ProcessMap* process_map = extension_service->process_map();
+ bool is_app = extension_service->IsInstalledApp(url) &&
+ process_map->Contains(contents->GetRenderProcessHost()->id());
int message_id = GetMessagePrefixID(
is_app,
@@ -306,9 +304,9 @@ TabContentsWrapper* TaskManagerTabContentsResource::GetTabContents() const {
const Extension* TaskManagerTabContentsResource::GetExtension() const {
if (HostsExtension()) {
- ExtensionService* extensions_service =
+ ExtensionService* extension_service =
tab_contents_->profile()->GetExtensionService();
- return extensions_service->GetExtensionByURL(
+ return extension_service->GetExtensionByURL(
tab_contents_->tab_contents()->GetURL());
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 569a004..53e86cb 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1250,6 +1250,8 @@
'browser/extensions/pending_extension_info.h',
'browser/extensions/pending_extension_manager.cc',
'browser/extensions/pending_extension_manager.h',
+ 'browser/extensions/process_map.cc',
+ 'browser/extensions/process_map.h',
'browser/extensions/sandboxed_extension_unpacker.cc',
'browser/extensions/sandboxed_extension_unpacker.h',
'browser/extensions/speech_input/extension_speech_input_api.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 939dfa6..a292bd8 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1367,6 +1367,7 @@
'browser/extensions/in_memory_extension_settings_storage_unittest.cc',
'browser/extensions/key_identifier_conversion_views_unittest.cc',
'browser/extensions/network_delay_listener_unittest.cc',
+ 'browser/extensions/process_map_unittest.cc',
'browser/extensions/sandboxed_extension_unpacker_unittest.cc',
'browser/extensions/user_script_listener_unittest.cc',
'browser/extensions/user_script_master_unittest.cc',
diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc
index ed558df..98b8ecd 100644
--- a/content/browser/mock_content_browser_client.cc
+++ b/content/browser/mock_content_browser_client.cc
@@ -79,6 +79,14 @@ bool MockContentBrowserClient::IsSuitableHost(
return true;
}
+void MockContentBrowserClient::SiteInstanceGotProcess(
+ SiteInstance* site_instance) {
+}
+
+void MockContentBrowserClient::SiteInstanceDeleting(
+ SiteInstance* site_instance) {
+}
+
bool MockContentBrowserClient::ShouldSwapProcessesForNavigation(
const GURL& current_url,
const GURL& new_url) {
diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h
index 79e700c..23d53b1 100644
--- a/content/browser/mock_content_browser_client.h
+++ b/content/browser/mock_content_browser_client.h
@@ -42,6 +42,8 @@ class MockContentBrowserClient : public ContentBrowserClient {
virtual bool IsURLSameAsAnySiteInstance(const GURL& url) OVERRIDE;
virtual bool IsSuitableHost(RenderProcessHost* process_host,
const GURL& site_url) OVERRIDE;
+ virtual void SiteInstanceGotProcess(SiteInstance* site_instance) OVERRIDE;
+ virtual void SiteInstanceDeleting(SiteInstance* site_instance) OVERRIDE;
virtual bool ShouldSwapProcessesForNavigation(const GURL& current_url,
const GURL& new_url) OVERRIDE;
virtual std::string GetCanonicalEncodingNameByAliasName(
diff --git a/content/browser/site_instance.cc b/content/browser/site_instance.cc
index ad79d74..d41f49b 100644
--- a/content/browser/site_instance.cc
+++ b/content/browser/site_instance.cc
@@ -42,10 +42,7 @@ SiteInstance::SiteInstance(BrowsingInstance* browsing_instance)
}
SiteInstance::~SiteInstance() {
- content::NotificationService::current()->Notify(
- content::NOTIFICATION_SITE_INSTANCE_DELETED,
- content::Source<SiteInstance>(this),
- content::NotificationService::NoDetails());
+ content::GetContentClient()->browser()->SiteInstanceDeleting(this);
// Now that no one is referencing us, we can safely remove ourselves from
// the BrowsingInstance. Any future visits to a page from this site
@@ -84,6 +81,8 @@ RenderProcessHost* SiteInstance::GetProcess() {
}
}
+ content::GetContentClient()->browser()->SiteInstanceGotProcess(this);
+
// Make sure the process starts at the right max_page_id
process_->UpdateMaxPageID(max_page_id_);
}
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index a404112..727e6c9 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -29,6 +29,7 @@ class RenderViewHost;
class RenderWidgetHost;
class RenderWidgetHostView;
class ResourceDispatcherHost;
+class SiteInstance;
class SSLCertErrorHandler;
class SSLClientAuthHandler;
class SkBitmap;
@@ -145,6 +146,12 @@ class ContentBrowserClient {
virtual bool IsSuitableHost(RenderProcessHost* process_host,
const GURL& site_url) = 0;
+ // Called when a site instance is first associated with a process.
+ virtual void SiteInstanceGotProcess(SiteInstance* site_instance) = 0;
+
+ // Called from a site instance's destructor.
+ virtual void SiteInstanceDeleting(SiteInstance* site_instance) = 0;
+
// Returns true if for the navigation from |current_url| to |new_url|,
// processes should be swapped (even if we are in a process model that
// doesn't usually swap).
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h
index c0e465d..1d6e503 100644
--- a/content/public/browser/notification_types.h
+++ b/content/public/browser/notification_types.h
@@ -356,10 +356,6 @@ enum NotificationType {
// the new state is "visible."
NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
- // Sent from ~SiteInstance. The source is the SiteInstance, and the details
- // are unused.
- NOTIFICATION_SITE_INSTANCE_DELETED,
-
// The focused element inside a page has changed. The source is the
// TabContents containing the render view host for the page. The details is
// a Details<const bool> that indicates whether or not an editable node was
diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc
index 1379e82..2a31c9a 100644
--- a/content/shell/shell_content_browser_client.cc
+++ b/content/shell/shell_content_browser_client.cc
@@ -93,6 +93,14 @@ bool ShellContentBrowserClient::IsSuitableHost(
return true;
}
+void ShellContentBrowserClient::SiteInstanceGotProcess(
+ SiteInstance* site_instance) {
+}
+
+void ShellContentBrowserClient::SiteInstanceDeleting(
+ SiteInstance* site_instance) {
+}
+
bool ShellContentBrowserClient::ShouldSwapProcessesForNavigation(
const GURL& current_url,
const GURL& new_url) {
diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h
index 2e44aa9..e8aa52f 100644
--- a/content/shell/shell_content_browser_client.h
+++ b/content/shell/shell_content_browser_client.h
@@ -54,6 +54,8 @@ class ShellContentBrowserClient : public ContentBrowserClient
virtual bool IsURLSameAsAnySiteInstance(const GURL& url) OVERRIDE;
virtual bool IsSuitableHost(RenderProcessHost* process_host,
const GURL& site_url) OVERRIDE;
+ virtual void SiteInstanceGotProcess(SiteInstance* site_instance) OVERRIDE;
+ virtual void SiteInstanceDeleting(SiteInstance* site_instance) OVERRIDE;
virtual bool ShouldSwapProcessesForNavigation(const GURL& current_url,
const GURL& new_url) OVERRIDE;