summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhoro@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-28 21:40:21 +0000
committerhoro@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-28 21:40:21 +0000
commit896c6d559b1da535b6c6d3c5113bc65431f63b0f (patch)
tree973ae2942b8d3e0e65be4d0bb38235d4aef5361a
parent4dc3bcd6bc497ba5299212f9b8f960015c583761 (diff)
downloadchromium_src-896c6d559b1da535b6c6d3c5113bc65431f63b0f.zip
chromium_src-896c6d559b1da535b6c6d3c5113bc65431f63b0f.tar.gz
chromium_src-896c6d559b1da535b6c6d3c5113bc65431f63b0f.tar.bz2
Register the worker process ID of the extension to ProcessMap in ExtensionSystem.
This change makes importScripts() work correctly in the Shared Worker of packaged app. BUG=258695,329786 Review URL: https://codereview.chromium.org/139163002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247513 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc32
-rw-r--r--chrome/browser/chrome_content_browser_client.h4
-rw-r--r--chrome/browser/extensions/extension_protocols.cc6
-rw-r--r--chrome/test/data/extensions/api_test/debugger_extension/worker.js6
-rw-r--r--chrome/test/data/extensions/api_test/debugger_extension/worker_imported.js9
-rw-r--r--content/browser/worker_host/worker_process_host.cc72
-rw-r--r--content/browser/worker_host/worker_process_host.h9
-rw-r--r--content/browser/worker_host/worker_service_impl.cc4
-rw-r--r--content/public/browser/content_browser_client.h8
-rw-r--r--extensions/browser/info_map.cc17
-rw-r--r--extensions/browser/info_map.h16
11 files changed, 170 insertions, 13 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 95c2430..90107c2 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -124,6 +124,7 @@
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/url_utils.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/info_map.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
@@ -1336,6 +1337,37 @@ void ChromeContentBrowserClient::SiteInstanceDeleting(
site_instance->GetId()));
}
+void ChromeContentBrowserClient::WorkerProcessCreated(
+ SiteInstance* site_instance,
+ int worker_process_id) {
+ extensions::ExtensionRegistry* extension_registry =
+ extensions::ExtensionRegistry::Get(site_instance->GetBrowserContext());
+ if (!extension_registry)
+ return;
+ const Extension* extension =
+ extension_registry->enabled_extensions().GetExtensionOrAppByURL(
+ site_instance->GetSiteURL());
+ if (!extension)
+ return;
+ extensions::ExtensionSystem* extension_system =
+ extensions::ExtensionSystem::GetForBrowserContext(
+ site_instance->GetBrowserContext());
+ extension_system->info_map()->RegisterExtensionWorkerProcess(
+ extension->id(),
+ worker_process_id,
+ site_instance->GetId());
+}
+
+void ChromeContentBrowserClient::WorkerProcessTerminated(
+ SiteInstance* site_instance,
+ int worker_process_id) {
+ extensions::ExtensionSystem* extension_system =
+ extensions::ExtensionSystem::GetForBrowserContext(
+ site_instance->GetBrowserContext());
+ extension_system->info_map()->UnregisterExtensionWorkerProcess(
+ worker_process_id);
+}
+
bool ChromeContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
SiteInstance* site_instance,
const GURL& current_url,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index f1030a5..d0f17dc 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -98,6 +98,10 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
content::SiteInstance* site_instance) OVERRIDE;
virtual void SiteInstanceDeleting(content::SiteInstance* site_instance)
OVERRIDE;
+ virtual void WorkerProcessCreated(content::SiteInstance* site_instance,
+ int worker_process_id) OVERRIDE;
+ virtual void WorkerProcessTerminated(content::SiteInstance* site_instance,
+ int worker_process_id) OVERRIDE;
virtual bool ShouldSwapBrowsingInstancesForNavigation(
content::SiteInstance* site_instance,
const GURL& current_url,
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index 4223894..1ff45d2 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -400,6 +400,12 @@ bool AllowExtensionResourceLoad(net::URLRequest* request,
return true;
}
+ // Check workers so that importScripts works from extension workers.
+ if (extension_info_map->worker_process_map().Contains(
+ request->url().host(), info->GetChildID())) {
+ return true;
+ }
+
// Extensions with webview: allow loading certain resources by guest renderers
// with privileged partition IDs as specified in the manifest file.
ExtensionRendererState* renderer_state =
diff --git a/chrome/test/data/extensions/api_test/debugger_extension/worker.js b/chrome/test/data/extensions/api_test/debugger_extension/worker.js
index 4d310c5..4fa5120 100644
--- a/chrome/test/data/extensions/api_test/debugger_extension/worker.js
+++ b/chrome/test/data/extensions/api_test/debugger_extension/worker.js
@@ -2,8 +2,4 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-self.addEventListener('connect', function(e) {
- var port = e.ports[0];
- port.start();
- port.postMessage({});
-}); \ No newline at end of file
+importScripts('worker_imported.js');
diff --git a/chrome/test/data/extensions/api_test/debugger_extension/worker_imported.js b/chrome/test/data/extensions/api_test/debugger_extension/worker_imported.js
new file mode 100644
index 0000000..8ae5a31
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/debugger_extension/worker_imported.js
@@ -0,0 +1,9 @@
+// Copyright 2014 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.
+
+self.addEventListener('connect', function(e) {
+ var port = e.ports[0];
+ port.start();
+ port.postMessage({});
+}); \ No newline at end of file
diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc
index 35e2444..43284d1 100644
--- a/content/browser/worker_host/worker_process_host.cc
+++ b/content/browser/worker_host/worker_process_host.cc
@@ -79,8 +79,6 @@ class WorkerSandboxedProcessLauncherDelegate
};
#endif // OS_WIN
-} // namespace
-
// Notifies RenderViewHost that one or more worker objects crashed.
void WorkerCrashCallback(int render_process_unique_id, int render_frame_id) {
RenderFrameHostImpl* host =
@@ -89,6 +87,34 @@ void WorkerCrashCallback(int render_process_unique_id, int render_frame_id) {
host->delegate()->WorkerCrashed();
}
+void WorkerCreatedCallback(int render_process_id,
+ int render_frame_id,
+ int worker_process_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(render_process_id, render_frame_id);
+ if (!render_frame_host)
+ return;
+ SiteInstance* site_instance = render_frame_host->GetSiteInstance();
+ GetContentClient()->browser()->WorkerProcessCreated(site_instance,
+ worker_process_id);
+}
+
+void WorkerTerminatedCallback(int render_process_id,
+ int render_frame_id,
+ int worker_process_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(render_process_id, render_frame_id);
+ if (!render_frame_host)
+ return;
+ SiteInstance* site_instance = render_frame_host->GetSiteInstance();
+ GetContentClient()->browser()->WorkerProcessTerminated(site_instance,
+ worker_process_id);
+}
+
+} // namespace
+
WorkerProcessHost::WorkerProcessHost(
ResourceContext* resource_context,
const WorkerStoragePartition& partition)
@@ -125,7 +151,7 @@ bool WorkerProcessHost::Send(IPC::Message* message) {
return process_->Send(message);
}
-bool WorkerProcessHost::Init(int render_process_id) {
+bool WorkerProcessHost::Init(int render_process_id, int render_frame_id) {
std::string channel_id = process_->GetHost()->CreateChannel();
if (channel_id.empty())
return false;
@@ -205,6 +231,12 @@ bool WorkerProcessHost::Init(int render_process_id) {
process_->GetData().id, render_process_id);
CreateMessageFilters(render_process_id);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&WorkerCreatedCallback,
+ render_process_id,
+ render_frame_id,
+ process_->GetData().id));
return true;
}
@@ -465,11 +497,27 @@ void WorkerProcessHost::FilterShutdown(WorkerMessageFilter* filter) {
bool shutdown = false;
i->RemoveFilters(filter);
+ int render_frame_id = 0;
+ const WorkerDocumentSet::DocumentInfoSet& documents =
+ i->worker_document_set()->documents();
+ for (WorkerDocumentSet::DocumentInfoSet::const_iterator doc =
+ documents.begin(); doc != documents.end(); ++doc) {
+ if (doc->filter() == filter) {
+ render_frame_id = doc->render_frame_id();
+ break;
+ }
+ }
i->worker_document_set()->RemoveAll(filter);
if (i->worker_document_set()->IsEmpty()) {
shutdown = true;
}
if (shutdown) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&WorkerTerminatedCallback,
+ filter->render_process_id(),
+ render_frame_id,
+ process_->GetData().id));
Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id()));
i = instances_.erase(i);
} else {
@@ -521,8 +569,24 @@ void WorkerProcessHost::DocumentDetached(WorkerMessageFilter* filter,
unsigned long long document_id) {
// Walk all instances and remove the document from their document set.
for (Instances::iterator i = instances_.begin(); i != instances_.end();) {
+ int render_frame_id = 0;
+ const WorkerDocumentSet::DocumentInfoSet& documents =
+ i->worker_document_set()->documents();
+ for (WorkerDocumentSet::DocumentInfoSet::const_iterator doc =
+ documents.begin(); doc != documents.end(); ++doc) {
+ if (doc->filter() == filter && doc->document_id() == document_id) {
+ render_frame_id = doc->render_frame_id();
+ break;
+ }
+ }
i->worker_document_set()->Remove(filter, document_id);
if (i->worker_document_set()->IsEmpty()) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&WorkerTerminatedCallback,
+ filter->render_process_id(),
+ render_frame_id,
+ process_->GetData().id));
// This worker has no more associated documents - shut it down.
Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id()));
i = instances_.erase(i);
@@ -583,6 +647,7 @@ WorkerProcessHost::WorkerInstance::WorkerInstance(
blink::WebContentSecurityPolicyType security_policy_type,
int worker_route_id,
int parent_process_id,
+ int render_frame_id,
int64 main_resource_appcache_id,
ResourceContext* resource_context,
const WorkerStoragePartition& partition)
@@ -593,6 +658,7 @@ WorkerProcessHost::WorkerInstance::WorkerInstance(
security_policy_type_(security_policy_type),
worker_route_id_(worker_route_id),
parent_process_id_(parent_process_id),
+ render_frame_id_(render_frame_id),
main_resource_appcache_id_(main_resource_appcache_id),
worker_document_set_(new WorkerDocumentSet()),
resource_context_(resource_context),
diff --git a/content/browser/worker_host/worker_process_host.h b/content/browser/worker_host/worker_process_host.h
index 0d286e0..b555313 100644
--- a/content/browser/worker_host/worker_process_host.h
+++ b/content/browser/worker_host/worker_process_host.h
@@ -63,6 +63,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
blink::WebContentSecurityPolicyType security_policy_type,
int worker_route_id,
int parent_process_id,
+ int render_frame_id,
int64 main_resource_appcache_id,
ResourceContext* resource_context,
const WorkerStoragePartition& partition);
@@ -119,6 +120,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
}
int worker_route_id() const { return worker_route_id_; }
int parent_process_id() const { return parent_process_id_; }
+ int render_frame_id() const { return render_frame_id_; }
int64 main_resource_appcache_id() const {
return main_resource_appcache_id_;
}
@@ -141,6 +143,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
blink::WebContentSecurityPolicyType security_policy_type_;
int worker_route_id_;
int parent_process_id_;
+ int render_frame_id_;
int64 main_resource_appcache_id_;
FilterList filters_;
scoped_refptr<WorkerDocumentSet> worker_document_set_;
@@ -156,9 +159,9 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
virtual bool Send(IPC::Message* message) OVERRIDE;
// Starts the process. Returns true iff it succeeded.
- // |render_process_id| is the renderer process responsible for starting this
- // worker.
- bool Init(int render_process_id);
+ // |render_process_id| and |render_frame_id| are the renderer process and the
+ // renderer frame responsible for starting this worker.
+ bool Init(int render_process_id, int render_frame_id);
// Creates a worker object in the process.
void CreateWorker(const WorkerInstance& instance);
diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc
index 15215ee..84cd39c 100644
--- a/content/browser/worker_host/worker_service_impl.cc
+++ b/content/browser/worker_host/worker_service_impl.cc
@@ -316,6 +316,7 @@ void WorkerServiceImpl::CreateWorker(
params.security_policy_type,
next_worker_route_id(),
0,
+ params.render_frame_route_id,
params.script_resource_appcache_id,
resource_context,
partition);
@@ -490,7 +491,8 @@ bool WorkerServiceImpl::CreateWorkerFromInstance(
// We don't support that yet though (this message is only sent from
// renderers) but when we do, we'll need to add code to pass in the current
// worker's document set for nested workers.
- if (!worker->Init(first_filter->render_process_id())) {
+ if (!worker->Init(first_filter->render_process_id(),
+ instance.render_frame_id())) {
delete worker;
return false;
}
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 56f6150..38a3c6f 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -237,6 +237,14 @@ class CONTENT_EXPORT ContentBrowserClient {
// Called from a site instance's destructor.
virtual void SiteInstanceDeleting(SiteInstance* site_instance) {}
+ // Called when a worker process is created.
+ virtual void WorkerProcessCreated(SiteInstance* site_instance,
+ int worker_process_id) {}
+
+ // Called when a worker process is terminated.
+ virtual void WorkerProcessTerminated(SiteInstance* site_instance,
+ int worker_process_id) {}
+
// Returns true if for the navigation from |current_url| to |new_url|
// in |site_instance|, a new SiteInstance and BrowsingInstance should be
// created (even if we are in a process model that doesn't usually swap.)
diff --git a/extensions/browser/info_map.cc b/extensions/browser/info_map.cc
index 3f55ceb..7122eb0 100644
--- a/extensions/browser/info_map.cc
+++ b/extensions/browser/info_map.cc
@@ -44,6 +44,10 @@ InfoMap::InfoMap() : signin_process_id_(-1) {}
const ProcessMap& InfoMap::process_map() const { return process_map_; }
+const ProcessMap& InfoMap::worker_process_map() const {
+ return worker_process_map_;
+}
+
void InfoMap::AddExtension(const Extension* extension,
base::Time install_time,
bool incognito_enabled,
@@ -124,6 +128,19 @@ void InfoMap::UnregisterAllExtensionsInProcess(int process_id) {
process_map_.RemoveAllFromProcess(process_id);
}
+void InfoMap::RegisterExtensionWorkerProcess(const std::string& extension_id,
+ int process_id,
+ int site_instance_id) {
+ if (!worker_process_map_.Insert(extension_id, process_id, site_instance_id)) {
+ NOTREACHED() << "Duplicate extension worker process registration for: "
+ << extension_id << "," << process_id << ".";
+ }
+}
+
+void InfoMap::UnregisterExtensionWorkerProcess(int process_id) {
+ worker_process_map_.RemoveAllFromProcess(process_id);
+}
+
void InfoMap::GetExtensionsWithAPIPermissionForSecurityOrigin(
const GURL& origin,
int process_id,
diff --git a/extensions/browser/info_map.h b/extensions/browser/info_map.h
index 34e1a9a..6609604 100644
--- a/extensions/browser/info_map.h
+++ b/extensions/browser/info_map.h
@@ -30,7 +30,10 @@ class InfoMap : public base::RefCountedThreadSafe<InfoMap> {
return disabled_extensions_;
}
+ // Information about which extensions are assigned to which render processes.
const extensions::ProcessMap& process_map() const;
+ // Information about which extensions are assigned to which worker processes.
+ const extensions::ProcessMap& worker_process_map() const;
// Callback for when new extensions are loaded.
void AddExtension(const extensions::Extension* extension,
@@ -64,6 +67,14 @@ class InfoMap : public base::RefCountedThreadSafe<InfoMap> {
int site_instance_id);
void UnregisterAllExtensionsInProcess(int process_id);
+ // Adds an entry to worker_process_map_.
+ void RegisterExtensionWorkerProcess(const std::string& extension_id,
+ int process_id,
+ int site_instance_id);
+
+ // Removes an entry from worker_process_map_.
+ void UnregisterExtensionWorkerProcess(int process_id);
+
// Returns the subset of extensions which has the same |origin| in
// |process_id| with the specified |permission|.
void GetExtensionsWithAPIPermissionForSecurityOrigin(
@@ -113,9 +124,12 @@ class InfoMap : public base::RefCountedThreadSafe<InfoMap> {
// the IO thread.
scoped_ptr<QuotaService> quota_service_;
- // Assignment of extensions to processes.
+ // Assignment of extensions to renderer processes.
extensions::ProcessMap process_map_;
+ // Assignment of extensions to worker processes.
+ extensions::ProcessMap worker_process_map_;
+
int signin_process_id_;
};