diff options
author | horo@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-28 21:40:21 +0000 |
---|---|---|
committer | horo@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-28 21:40:21 +0000 |
commit | 896c6d559b1da535b6c6d3c5113bc65431f63b0f (patch) | |
tree | 973ae2942b8d3e0e65be4d0bb38235d4aef5361a | |
parent | 4dc3bcd6bc497ba5299212f9b8f960015c583761 (diff) | |
download | chromium_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.cc | 32 | ||||
-rw-r--r-- | chrome/browser/chrome_content_browser_client.h | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_protocols.cc | 6 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/debugger_extension/worker.js | 6 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/debugger_extension/worker_imported.js | 9 | ||||
-rw-r--r-- | content/browser/worker_host/worker_process_host.cc | 72 | ||||
-rw-r--r-- | content/browser/worker_host/worker_process_host.h | 9 | ||||
-rw-r--r-- | content/browser/worker_host/worker_service_impl.cc | 4 | ||||
-rw-r--r-- | content/public/browser/content_browser_client.h | 8 | ||||
-rw-r--r-- | extensions/browser/info_map.cc | 17 | ||||
-rw-r--r-- | extensions/browser/info_map.h | 16 |
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_; }; |