summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-23 15:54:36 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-23 15:54:36 +0000
commit2cce7ae32e5cbde8c71c2075e5ac96f35b211d38 (patch)
treed7e1073abfe8be00fa60aa7ec35cc6d084132220
parent3b0895b2ec5eafda9d29ab9267f46767469a16fe (diff)
downloadchromium_src-2cce7ae32e5cbde8c71c2075e5ac96f35b211d38.zip
chromium_src-2cce7ae32e5cbde8c71c2075e5ac96f35b211d38.tar.gz
chromium_src-2cce7ae32e5cbde8c71c2075e5ac96f35b211d38.tar.bz2
Track all extension processes in ExtensionInfoMap, not just
those with bindings. This also allows us to tighten down access in ExtensionFunctionDispatcher a bit more. This is needed to allow us to answer questions about process capabilities on the IO thread. For example: http://codereview.chromium.org/%20%208312005/ Review URL: http://codereview.chromium.org/8361021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106876 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc3
-rw-r--r--chrome/browser/extensions/extension_info_map.cc35
-rw-r--r--chrome/browser/extensions/extension_info_map.h26
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc67
-rw-r--r--chrome/browser/extensions/extension_process_manager.h7
5 files changed, 84 insertions, 54 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index bb263fb..9641187 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -523,7 +523,8 @@ void ExtensionFunctionDispatcher::DispatchOnIOThread(
const Extension* extension =
extension_info_map->extensions().GetByURL(params.source_url);
- if (!extension_info_map->AreBindingsEnabledForProcess(render_process_id)) {
+ 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.";
diff --git a/chrome/browser/extensions/extension_info_map.cc b/chrome/browser/extensions/extension_info_map.cc
index 9c14448..50d75d5 100644
--- a/chrome/browser/extensions/extension_info_map.cc
+++ b/chrome/browser/extensions/extension_info_map.cc
@@ -9,7 +9,7 @@
namespace {
-static void CheckOnValidThread() {
+void CheckOnValidThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
}
@@ -96,20 +96,29 @@ bool ExtensionInfoMap::CanCrossIncognito(const Extension* extension) {
!extension->incognito_split_mode();
}
-// These are duplicated from ExtensionProcessManager so that we can have the
-// information on the IO thread :(.
-void ExtensionInfoMap::BindingsEnabledForProcess(int render_process_id) {
- extension_bindings_process_ids_.insert(render_process_id);
+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));
}
-void ExtensionInfoMap::BindingsDisabledForProcess(int render_process_id) {
- extension_bindings_process_ids_.erase(render_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);
}
-bool ExtensionInfoMap::AreBindingsEnabledForProcess(
- int render_process_id) const {
- // Must behave logically the same as AreBindingsEnabledForProcess() in
- // extension_process_manager.cc.
- return extension_bindings_process_ids_.find(render_process_id) !=
- extension_bindings_process_ids_.end();
+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();
}
diff --git a/chrome/browser/extensions/extension_info_map.h b/chrome/browser/extensions/extension_info_map.h
index abd5019..7ca8848 100644
--- a/chrome/browser/extensions/extension_info_map.h
+++ b/chrome/browser/extensions/extension_info_map.h
@@ -6,7 +6,7 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_INFO_MAP_H_
#pragma once
-#include <set>
+#include <map>
#include <string>
#include "base/basictypes.h"
@@ -50,15 +50,21 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> {
// sub-profile (incognito to original profile, or vice versa).
bool CanCrossIncognito(const Extension* extension);
- // Registers a RenderProcessHost with |render_process_id| as hosting an
- // extension.
- void BindingsEnabledForProcess(int render_process_id);
+ // 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).
+ void RegisterExtensionProcess(const std::string& extension_id,
+ int process_id);
- // Unregisters the RenderProcessHost with |render_process_id|.
- void BindingsDisabledForProcess(int render_process_id);
+ // Remove any record of |extension_id| created with RegisterExtensionProcess.
+ // If |extension_id| is unknown, we ignore it.
+ void UnregisterExtensionProcess(const std::string& extension_id,
+ int process_id);
- // True if this process host is hosting an extension with extension bindings.
- bool AreBindingsEnabledForProcess(int render_process_id) const;
+ // Returns true if |extension_id| is running in |process_id|..
+ bool IsExtensionInProcess(const std::string& extension_id,
+ int process_id) const;
private:
// Extra dynamic data related to an extension.
@@ -72,8 +78,8 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> {
// Extra data associated with enabled extensions.
ExtraDataMap extra_data_;
- // The set of process ids that have extension bindings enabled.
- std::set<int> extension_bindings_process_ids_;
+ typedef std::multimap<std::string, int> ExtensionProcessIDMap;
+ ExtensionProcessIDMap extension_process_ids_;
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INFO_MAP_H_
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index c2a61d8..43b86aa 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -280,20 +280,16 @@ void ExtensionProcessManager::RegisterExtensionSiteInstance(
int site_instance_id = site_instance->id();
int render_process_id = site_instance->GetProcess()->id();
- process_ids_[render_process_id].insert(site_instance_id);
-
- // 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());
- ExtensionService* service = profile->GetExtensionService();
- if (service->ExtensionBindingsAllowed(extension->url())) {
- Profile* profile = Profile::FromBrowserContext(
- site_instance->GetProcess()->browser_context());
+ 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::BindingsEnabledForProcess,
+ base::Bind(&ExtensionInfoMap::RegisterExtensionProcess,
profile->GetExtensionInfoMap(),
+ extension->id(),
render_process_id));
}
@@ -310,27 +306,40 @@ void ExtensionProcessManager::RegisterExtensionSiteInstance(
void ExtensionProcessManager::UnregisterExtensionSiteInstance(
SiteInstance* site_instance) {
int site_instance_id = site_instance->id();
- SiteInstanceIDMap::iterator it = extension_ids_.find(site_instance_id);
- if (it != extension_ids_.end()) {
- extension_ids_.erase(it++);
- }
- if (site_instance->HasProcess()) {
- int render_process_id = site_instance->GetProcess()->id();
- ProcessIDMap::iterator host = process_ids_.find(render_process_id);
- if (host != process_ids_.end()) {
- host->second.erase(site_instance_id);
- if (host->second.empty()) {
- process_ids_.erase(host);
- Profile* profile = Profile::FromBrowserContext(
- site_instance->GetProcess()->browser_context());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ExtensionInfoMap::BindingsDisabledForProcess,
- profile->GetExtensionInfoMap(),
- render_process_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) {
diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h
index 41d0bbb..d99ee09 100644
--- a/chrome/browser/extensions/extension_process_manager.h
+++ b/chrome/browser/extensions/extension_process_manager.h
@@ -147,7 +147,8 @@ class ExtensionProcessManager : public content::NotificationObserver {
SiteInstanceIDMap extension_ids_;
// A map of process ID to site instance ID of the site instances it hosts.
- typedef std::map<int, std::set<int> > ProcessIDMap;
+ typedef std::set<int> SiteInstanceIDSet;
+ typedef std::map<int, SiteInstanceIDSet> ProcessIDMap;
ProcessIDMap process_ids_;
private:
@@ -169,6 +170,10 @@ 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);
};