Index: content/browser/worker_host/worker_process_host.cc |
diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc |
deleted file mode 100644 |
index 960baf693e0d312eac8d433d021e0740e8f07ef6..0000000000000000000000000000000000000000 |
--- a/content/browser/worker_host/worker_process_host.cc |
+++ /dev/null |
@@ -1,845 +0,0 @@ |
-// Copyright (c) 2012 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 "content/browser/worker_host/worker_process_host.h" |
- |
-#include <set> |
-#include <string> |
-#include <vector> |
- |
-#include "base/base_switches.h" |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/callback.h" |
-#include "base/command_line.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "content/browser/appcache/appcache_dispatcher_host.h" |
-#include "content/browser/appcache/chrome_appcache_service.h" |
-#include "content/browser/browser_child_process_host_impl.h" |
-#include "content/browser/child_process_security_policy_impl.h" |
-#include "content/browser/devtools/worker_devtools_manager.h" |
-#include "content/browser/devtools/worker_devtools_message_filter.h" |
-#include "content/browser/fileapi/fileapi_message_filter.h" |
-#include "content/browser/frame_host/render_frame_host_delegate.h" |
-#include "content/browser/frame_host/render_frame_host_impl.h" |
-#include "content/browser/indexed_db/indexed_db_dispatcher_host.h" |
-#include "content/browser/loader/resource_message_filter.h" |
-#include "content/browser/message_port_message_filter.h" |
-#include "content/browser/message_port_service.h" |
-#include "content/browser/mime_registry_message_filter.h" |
-#include "content/browser/quota_dispatcher_host.h" |
-#include "content/browser/renderer_host/database_message_filter.h" |
-#include "content/browser/renderer_host/file_utilities_message_filter.h" |
-#include "content/browser/renderer_host/render_view_host_delegate.h" |
-#include "content/browser/renderer_host/render_view_host_impl.h" |
-#include "content/browser/renderer_host/socket_stream_dispatcher_host.h" |
-#include "content/browser/renderer_host/websocket_dispatcher_host.h" |
-#include "content/browser/resource_context_impl.h" |
-#include "content/browser/worker_host/worker_message_filter.h" |
-#include "content/browser/worker_host/worker_service_impl.h" |
-#include "content/common/child_process_host_impl.h" |
-#include "content/common/view_messages.h" |
-#include "content/common/worker_messages.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/content_browser_client.h" |
-#include "content/public/browser/user_metrics.h" |
-#include "content/public/common/content_switches.h" |
-#include "content/public/common/resource_type.h" |
-#include "content/public/common/result_codes.h" |
-#include "content/public/common/sandboxed_process_launcher_delegate.h" |
-#include "ipc/ipc_switches.h" |
-#include "net/base/mime_util.h" |
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
-#include "net/url_request/url_request_context_getter.h" |
-#include "ui/base/ui_base_switches.h" |
-#include "webkit/browser/fileapi/file_system_context.h" |
-#include "webkit/browser/fileapi/sandbox_file_system_backend.h" |
- |
-#if defined(OS_WIN) |
-#include "content/common/sandbox_win.h" |
-#endif |
- |
-namespace content { |
-namespace { |
- |
-// NOTE: changes to this class need to be reviewed by the security team. |
-class WorkerSandboxedProcessLauncherDelegate |
- : public content::SandboxedProcessLauncherDelegate { |
- public: |
- WorkerSandboxedProcessLauncherDelegate(ChildProcessHost* host, |
- bool debugging_child) |
-#if defined(OS_POSIX) |
- : ipc_fd_(host->TakeClientFileDescriptor()), |
- debugging_child_(debugging_child) |
-#endif // OS_POSIX |
- {} |
- |
- virtual ~WorkerSandboxedProcessLauncherDelegate() {} |
- |
-#if defined(OS_WIN) |
- virtual void PreSpawnTarget(sandbox::TargetPolicy* policy, |
- bool* success) { |
- AddBaseHandleClosePolicy(policy); |
- } |
-#elif defined(OS_POSIX) |
- virtual bool ShouldUseZygote() OVERRIDE { |
- return !debugging_child_; |
- } |
- virtual int GetIpcFd() OVERRIDE { |
- return ipc_fd_; |
- } |
-#endif // OS_WIN |
- |
- private: |
-#if defined(OS_POSIX) |
- int ipc_fd_; |
- bool debugging_child_; |
-#endif // OS_POSIX |
-}; |
- |
-// Notifies RenderViewHost that one or more worker objects crashed. |
-void WorkerCrashCallback(int render_process_unique_id, int render_frame_id) { |
- RenderFrameHostImpl* host = |
- RenderFrameHostImpl::FromID(render_process_unique_id, render_frame_id); |
- if (host) |
- host->delegate()->WorkerCrashed(host); |
-} |
- |
-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) |
- : resource_context_(resource_context), |
- partition_(partition), |
- process_launched_(false), |
- weak_factory_(this) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK(resource_context_); |
- process_.reset( |
- new BrowserChildProcessHostImpl(PROCESS_TYPE_WORKER, this)); |
-} |
- |
-WorkerProcessHost::~WorkerProcessHost() { |
- // If we crashed, tell the RenderViewHosts. |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- if (!i->load_failed()) { |
- const WorkerDocumentSet::DocumentInfoSet& parents = |
- i->worker_document_set()->documents(); |
- for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = |
- parents.begin(); parent_iter != parents.end(); ++parent_iter) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&WorkerCrashCallback, parent_iter->render_process_id(), |
- parent_iter->render_frame_id())); |
- } |
- } |
- WorkerServiceImpl::GetInstance()->NotifyWorkerDestroyed( |
- this, i->worker_route_id()); |
- } |
- |
- ChildProcessSecurityPolicyImpl::GetInstance()->Remove( |
- process_->GetData().id); |
-} |
- |
-bool WorkerProcessHost::Send(IPC::Message* message) { |
- return process_->Send(message); |
-} |
- |
-bool WorkerProcessHost::Init(int render_process_id, int render_frame_id) { |
- std::string channel_id = process_->GetHost()->CreateChannel(); |
- if (channel_id.empty()) |
- return false; |
- |
-#if defined(OS_LINUX) |
- int flags = ChildProcessHost::CHILD_ALLOW_SELF; |
-#else |
- int flags = ChildProcessHost::CHILD_NORMAL; |
-#endif |
- |
- base::FilePath exe_path = ChildProcessHost::GetChildPath(flags); |
- if (exe_path.empty()) |
- return false; |
- |
- CommandLine* cmd_line = new CommandLine(exe_path); |
- cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess); |
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
- std::string locale = GetContentClient()->browser()->GetApplicationLocale(); |
- cmd_line->AppendSwitchASCII(switches::kLang, locale); |
- |
- static const char* const kSwitchNames[] = { |
- switches::kDisableApplicationCache, |
- switches::kDisableDatabases, |
-#if defined(OS_WIN) |
- switches::kDisableDesktopNotifications, |
-#endif |
- switches::kDisableFileSystem, |
- switches::kDisableSeccompFilterSandbox, |
- switches::kEnableExperimentalWebPlatformFeatures, |
- switches::kEnablePreciseMemoryInfo, |
-#if defined(OS_MACOSX) |
- switches::kEnableSandboxLogging, |
-#endif |
- switches::kJavaScriptFlags, |
- switches::kNoSandbox |
- }; |
- cmd_line->CopySwitchesFrom(*CommandLine::ForCurrentProcess(), kSwitchNames, |
- arraysize(kSwitchNames)); |
- |
-bool debugging_child = false; |
-#if defined(OS_POSIX) |
- if (CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kWaitForDebuggerChildren)) { |
- // Look to pass-on the kWaitForDebugger flag. |
- std::string value = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
- switches::kWaitForDebuggerChildren); |
- if (value.empty() || value == switches::kWorkerProcess) { |
- cmd_line->AppendSwitch(switches::kWaitForDebugger); |
- debugging_child = true; |
- } |
- } |
-#endif |
- |
- process_->Launch( |
- new WorkerSandboxedProcessLauncherDelegate(process_->GetHost(), |
- debugging_child), |
- cmd_line); |
- |
- ChildProcessSecurityPolicyImpl::GetInstance()->AddWorker( |
- 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; |
-} |
- |
-void WorkerProcessHost::CreateMessageFilters(int render_process_id) { |
- ChromeBlobStorageContext* blob_storage_context = |
- GetChromeBlobStorageContextForResourceContext(resource_context_); |
- StreamContext* stream_context = |
- GetStreamContextForResourceContext(resource_context_); |
- |
- net::URLRequestContextGetter* url_request_context = |
- partition_.url_request_context(); |
- |
- ResourceMessageFilter::GetContextsCallback get_contexts_callback( |
- base::Bind(&WorkerProcessHost::GetContexts, |
- base::Unretained(this))); |
- |
- ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( |
- process_->GetData().id, PROCESS_TYPE_WORKER, |
- partition_.appcache_service(), |
- blob_storage_context, |
- partition_.filesystem_context(), |
- partition_.service_worker_context(), |
- get_contexts_callback); |
- process_->AddFilter(resource_message_filter); |
- |
- MessagePortMessageFilter* message_port_message_filter = |
- new MessagePortMessageFilter( |
- base::Bind(&WorkerServiceImpl::next_worker_route_id, |
- base::Unretained(WorkerServiceImpl::GetInstance()))); |
- process_->AddFilter(message_port_message_filter); |
- worker_message_filter_ = new WorkerMessageFilter(render_process_id, |
- resource_context_, |
- partition_, |
- message_port_message_filter); |
- process_->AddFilter(worker_message_filter_.get()); |
- process_->AddFilter(new AppCacheDispatcherHost( |
- partition_.appcache_service(), process_->GetData().id)); |
- process_->AddFilter(new FileAPIMessageFilter( |
- process_->GetData().id, |
- url_request_context, |
- partition_.filesystem_context(), |
- blob_storage_context, |
- stream_context)); |
- process_->AddFilter(new FileUtilitiesMessageFilter( |
- process_->GetData().id)); |
- process_->AddFilter(new MimeRegistryMessageFilter()); |
- process_->AddFilter(new DatabaseMessageFilter(partition_.database_tracker())); |
- process_->AddFilter(new QuotaDispatcherHost( |
- process_->GetData().id, |
- partition_.quota_manager(), |
- GetContentClient()->browser()->CreateQuotaPermissionContext())); |
- |
- SocketStreamDispatcherHost::GetRequestContextCallback |
- request_context_callback( |
- base::Bind(&WorkerProcessHost::GetRequestContext, |
- base::Unretained(this))); |
- |
- SocketStreamDispatcherHost* socket_stream_dispatcher_host = |
- new SocketStreamDispatcherHost( |
- render_process_id, |
- request_context_callback, |
- resource_context_); |
- socket_stream_dispatcher_host_ = socket_stream_dispatcher_host; |
- process_->AddFilter(socket_stream_dispatcher_host); |
- |
- WebSocketDispatcherHost::GetRequestContextCallback |
- websocket_request_context_callback( |
- base::Bind(&WorkerProcessHost::GetRequestContext, |
- base::Unretained(this), |
- ResourceType::SUB_RESOURCE)); |
- |
- process_->AddFilter(new WebSocketDispatcherHost( |
- render_process_id, websocket_request_context_callback)); |
- |
- process_->AddFilter(new WorkerDevToolsMessageFilter(process_->GetData().id)); |
- process_->AddFilter( |
- new IndexedDBDispatcherHost(process_->GetData().id, |
- url_request_context, |
- partition_.indexed_db_context(), |
- blob_storage_context)); |
-} |
- |
-void WorkerProcessHost::CreateWorker(const WorkerInstance& instance, |
- bool pause_on_start) { |
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( |
- process_->GetData().id, instance.url()); |
- |
- instances_.push_back(instance); |
- |
- WorkerProcessMsg_CreateWorker_Params params; |
- params.url = instance.url(); |
- params.name = instance.name(); |
- params.content_security_policy = instance.content_security_policy(); |
- params.security_policy_type = instance.security_policy_type(); |
- params.pause_on_start = pause_on_start; |
- params.route_id = instance.worker_route_id(); |
- Send(new WorkerProcessMsg_CreateWorker(params)); |
- |
- UpdateTitle(); |
- |
- // Walk all pending filters and let them know the worker has been created |
- // (could be more than one in the case where we had to queue up worker |
- // creation because the worker process limit was reached). |
- for (WorkerInstance::FilterList::const_iterator i = |
- instance.filters().begin(); |
- i != instance.filters().end(); ++i) { |
- i->filter()->Send(new ViewMsg_WorkerCreated(i->route_id())); |
- } |
-} |
- |
-bool WorkerProcessHost::FilterMessage(const IPC::Message& message, |
- WorkerMessageFilter* filter) { |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- if (!i->closed() && i->HasFilter(filter, message.routing_id())) { |
- RelayMessage(message, filter, &(*i)); |
- return true; |
- } |
- } |
- |
- return false; |
-} |
- |
-void WorkerProcessHost::OnProcessLaunched() { |
- process_launched_ = true; |
- |
- WorkerServiceImpl::GetInstance()->NotifyWorkerProcessCreated(); |
-} |
- |
-bool WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { |
- bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(WorkerProcessHost, message) |
- IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerContextClosed, |
- OnWorkerContextClosed) |
- IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerContextDestroyed, |
- OnWorkerContextDestroyed) |
- IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerScriptLoaded, |
- OnWorkerScriptLoaded) |
- IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerScriptLoadFailed, |
- OnWorkerScriptLoadFailed) |
- IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerConnected, |
- OnWorkerConnected) |
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_AllowDatabase, OnAllowDatabase) |
- IPC_MESSAGE_HANDLER_DELAY_REPLY( |
- WorkerProcessHostMsg_RequestFileSystemAccessSync, |
- OnRequestFileSystemAccess) |
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_AllowIndexedDB, OnAllowIndexedDB) |
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_ForceKillWorker, |
- OnForceKillWorkerProcess) |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP() |
- |
- return handled; |
-} |
- |
-// Sent to notify the browser process when a worker context invokes close(), so |
-// no new connections are sent to shared workers. |
-void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) { |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- if (i->worker_route_id() == worker_route_id) { |
- // Set the closed flag - this will stop any further messages from |
- // being sent to the worker (messages can still be sent from the worker, |
- // for exception reporting, etc). |
- i->set_closed(true); |
- break; |
- } |
- } |
-} |
- |
-void WorkerProcessHost::OnWorkerContextDestroyed(int worker_route_id) { |
- WorkerServiceImpl::GetInstance()->NotifyWorkerDestroyed( |
- this, worker_route_id); |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- if (i->worker_route_id() == worker_route_id) { |
- instances_.erase(i); |
- UpdateTitle(); |
- return; |
- } |
- } |
-} |
- |
-void WorkerProcessHost::OnWorkerScriptLoaded(int worker_route_id) { |
- WorkerDevToolsManager::GetInstance()->WorkerContextStarted(this, |
- worker_route_id); |
-} |
- |
-void WorkerProcessHost::OnWorkerScriptLoadFailed(int worker_route_id) { |
- bool shutdown = true; |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- if (i->worker_route_id() != worker_route_id) { |
- shutdown = false; |
- continue; |
- } |
- i->set_load_failed(true); |
- for (WorkerInstance::FilterList::const_iterator j = i->filters().begin(); |
- j != i->filters().end(); ++j) { |
- j->filter()->Send(new ViewMsg_WorkerScriptLoadFailed(j->route_id())); |
- } |
- } |
- if (shutdown) { |
- base::KillProcess( |
- process_->GetData().handle, RESULT_CODE_NORMAL_EXIT, false); |
- } |
-} |
- |
-void WorkerProcessHost::OnWorkerConnected(int message_port_id, |
- int worker_route_id) { |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- if (i->worker_route_id() != worker_route_id) |
- continue; |
- for (WorkerInstance::FilterList::const_iterator j = i->filters().begin(); |
- j != i->filters().end(); ++j) { |
- if (j->message_port_id() != message_port_id) |
- continue; |
- j->filter()->Send(new ViewMsg_WorkerConnected(j->route_id())); |
- return; |
- } |
- } |
-} |
- |
-void WorkerProcessHost::OnAllowDatabase(int worker_route_id, |
- const GURL& url, |
- const base::string16& name, |
- const base::string16& display_name, |
- unsigned long estimated_size, |
- bool* result) { |
- *result = GetContentClient()->browser()->AllowWorkerDatabase( |
- url, name, display_name, estimated_size, resource_context_, |
- GetRenderFrameIDsForWorker(worker_route_id)); |
-} |
- |
-void WorkerProcessHost::OnRequestFileSystemAccess(int worker_route_id, |
- const GURL& url, |
- IPC::Message* reply_msg) { |
- GetContentClient()->browser()->AllowWorkerFileSystem( |
- url, |
- resource_context_, |
- GetRenderFrameIDsForWorker(worker_route_id), |
- base::Bind(&WorkerProcessHost::OnRequestFileSystemAccessResponse, |
- weak_factory_.GetWeakPtr(), |
- base::Passed(scoped_ptr<IPC::Message>(reply_msg)))); |
-} |
- |
-void WorkerProcessHost::OnRequestFileSystemAccessResponse( |
- scoped_ptr<IPC::Message> reply_msg, |
- bool allowed) { |
- WorkerProcessHostMsg_RequestFileSystemAccessSync::WriteReplyParams( |
- reply_msg.get(), |
- allowed); |
- Send(reply_msg.release()); |
-} |
- |
-void WorkerProcessHost::OnAllowIndexedDB(int worker_route_id, |
- const GURL& url, |
- const base::string16& name, |
- bool* result) { |
- *result = GetContentClient()->browser()->AllowWorkerIndexedDB( |
- url, name, resource_context_, |
- GetRenderFrameIDsForWorker(worker_route_id)); |
-} |
- |
-void WorkerProcessHost::OnForceKillWorkerProcess() { |
- if (process_ && process_launched_) |
- base::KillProcess( |
- process_->GetData().handle, RESULT_CODE_NORMAL_EXIT, false); |
- else |
- RecordAction(base::UserMetricsAction("WorkerProcess_BadProcessToKill")); |
-} |
- |
-void WorkerProcessHost::RelayMessage( |
- const IPC::Message& message, |
- WorkerMessageFilter* incoming_filter, |
- WorkerInstance* instance) { |
- if (message.type() == WorkerMsg_Connect::ID) { |
- // Crack the SharedWorker Connect message to setup routing for the port. |
- WorkerMsg_Connect::Param params; |
- if (!WorkerMsg_Connect::Read(&message, ¶ms)) |
- return; |
- |
- int sent_message_port_id = params.a; |
- int new_routing_id = params.b; |
- new_routing_id = worker_message_filter_->GetNextRoutingID(); |
- MessagePortService::GetInstance()->UpdateMessagePort( |
- sent_message_port_id, |
- worker_message_filter_->message_port_message_filter(), |
- new_routing_id); |
- |
- instance->SetMessagePortID(incoming_filter, |
- message.routing_id(), |
- sent_message_port_id); |
- // Resend the message with the new routing id. |
- worker_message_filter_->Send(new WorkerMsg_Connect( |
- instance->worker_route_id(), sent_message_port_id, new_routing_id)); |
- |
- // Send any queued messages for the sent port. |
- MessagePortService::GetInstance()->SendQueuedMessagesIfPossible( |
- sent_message_port_id); |
- } else { |
- IPC::Message* new_message = new IPC::Message(message); |
- new_message->set_routing_id(instance->worker_route_id()); |
- worker_message_filter_->Send(new_message); |
- return; |
- } |
-} |
- |
-void WorkerProcessHost::ShutdownSocketStreamDispatcherHostIfNecessary() { |
- if (!instances_.size() && socket_stream_dispatcher_host_.get()) { |
- // We can assume that this object is going to delete, because |
- // currently a WorkerInstance will never be added to a WorkerProcessHost |
- // once it is initialized. |
- |
- // SocketStreamDispatcherHost should be notified now that the worker |
- // process will shutdown soon. |
- socket_stream_dispatcher_host_->Shutdown(); |
- socket_stream_dispatcher_host_ = NULL; |
- } |
-} |
- |
-void WorkerProcessHost::FilterShutdown(WorkerMessageFilter* filter) { |
- for (Instances::iterator i = instances_.begin(); i != instances_.end();) { |
- 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 { |
- ++i; |
- } |
- } |
- ShutdownSocketStreamDispatcherHostIfNecessary(); |
-} |
- |
-bool WorkerProcessHost::CanShutdown() { |
- return instances_.empty(); |
-} |
- |
-void WorkerProcessHost::UpdateTitle() { |
- std::set<std::string> titles; |
- for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
- // Allow the embedder first crack at special casing the title. |
- std::string title = GetContentClient()->browser()-> |
- GetWorkerProcessTitle(i->url(), resource_context_); |
- |
- if (title.empty()) { |
- title = net::registry_controlled_domains::GetDomainAndRegistry( |
- i->url(), |
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); |
- } |
- |
- // Use the host name if the domain is empty, i.e. localhost or IP address. |
- if (title.empty()) |
- title = i->url().host(); |
- |
- // If the host name is empty, i.e. file url, use the path. |
- if (title.empty()) |
- title = i->url().path(); |
- titles.insert(title); |
- } |
- |
- std::string display_title; |
- for (std::set<std::string>::iterator i = titles.begin(); |
- i != titles.end(); ++i) { |
- if (!display_title.empty()) |
- display_title += ", "; |
- display_title += *i; |
- } |
- |
- process_->SetName(base::UTF8ToUTF16(display_title)); |
-} |
- |
-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); |
- } else { |
- ++i; |
- } |
- } |
- ShutdownSocketStreamDispatcherHostIfNecessary(); |
-} |
- |
-void WorkerProcessHost::TerminateWorker(int worker_route_id) { |
- Send(new WorkerMsg_TerminateWorkerContext(worker_route_id)); |
-} |
- |
-void WorkerProcessHost::SetBackgrounded(bool backgrounded) { |
- process_->SetBackgrounded(backgrounded); |
-} |
- |
-const ChildProcessData& WorkerProcessHost::GetData() { |
- return process_->GetData(); |
-} |
- |
-std::vector<std::pair<int, int> > WorkerProcessHost::GetRenderFrameIDsForWorker( |
- int worker_route_id) { |
- std::vector<std::pair<int, int> > result; |
- WorkerProcessHost::Instances::const_iterator i; |
- for (i = instances_.begin(); i != instances_.end(); ++i) { |
- if (i->worker_route_id() != worker_route_id) |
- continue; |
- const WorkerDocumentSet::DocumentInfoSet& documents = |
- i->worker_document_set()->documents(); |
- for (WorkerDocumentSet::DocumentInfoSet::const_iterator doc = |
- documents.begin(); doc != documents.end(); ++doc) { |
- result.push_back( |
- std::make_pair(doc->render_process_id(), doc->render_frame_id())); |
- } |
- break; |
- } |
- return result; |
-} |
- |
-void WorkerProcessHost::GetContexts(const ResourceHostMsg_Request& request, |
- ResourceContext** resource_context, |
- net::URLRequestContext** request_context) { |
- *resource_context = resource_context_; |
- *request_context = partition_.url_request_context()->GetURLRequestContext(); |
-} |
- |
-net::URLRequestContext* WorkerProcessHost::GetRequestContext( |
- ResourceType::Type resource_type) { |
- return partition_.url_request_context()->GetURLRequestContext(); |
-} |
- |
-WorkerProcessHost::WorkerInstance::WorkerInstance( |
- const GURL& url, |
- const base::string16& name, |
- const base::string16& content_security_policy, |
- blink::WebContentSecurityPolicyType security_policy_type, |
- int worker_route_id, |
- int render_frame_id, |
- ResourceContext* resource_context, |
- const WorkerStoragePartition& partition) |
- : url_(url), |
- closed_(false), |
- name_(name), |
- content_security_policy_(content_security_policy), |
- security_policy_type_(security_policy_type), |
- worker_route_id_(worker_route_id), |
- render_frame_id_(render_frame_id), |
- worker_document_set_(new WorkerDocumentSet()), |
- resource_context_(resource_context), |
- partition_(partition), |
- load_failed_(false) { |
- DCHECK(resource_context_); |
-} |
- |
-WorkerProcessHost::WorkerInstance::~WorkerInstance() { |
-} |
- |
-void WorkerProcessHost::WorkerInstance::SetMessagePortID( |
- WorkerMessageFilter* filter, |
- int route_id, |
- int message_port_id) { |
- for (FilterList::iterator i = filters_.begin(); i != filters_.end(); ++i) { |
- if (i->filter() == filter && i->route_id() == route_id) { |
- i->set_message_port_id(message_port_id); |
- return; |
- } |
- } |
-} |
- |
-// Compares an instance based on the algorithm in the WebWorkers spec - an |
-// instance matches if the origins of the URLs match, and: |
-// a) the names are non-empty and equal |
-// -or- |
-// b) the names are both empty, and the urls are equal |
-bool WorkerProcessHost::WorkerInstance::Matches( |
- const GURL& match_url, |
- const base::string16& match_name, |
- const WorkerStoragePartition& partition, |
- ResourceContext* resource_context) const { |
- // Only match open shared workers. |
- if (closed_) |
- return false; |
- |
- // ResourceContext equivalence is being used as a proxy to ensure we only |
- // matched shared workers within the same BrowserContext. |
- if (resource_context_ != resource_context) |
- return false; |
- |
- // We must be in the same storage partition otherwise sharing will violate |
- // isolation. |
- if (!partition_.Equals(partition)) |
- return false; |
- |
- if (url_.GetOrigin() != match_url.GetOrigin()) |
- return false; |
- |
- if (name_.empty() && match_name.empty()) |
- return url_ == match_url; |
- |
- return name_ == match_name; |
-} |
- |
-void WorkerProcessHost::WorkerInstance::AddFilter(WorkerMessageFilter* filter, |
- int route_id) { |
- CHECK(filter); |
- if (!HasFilter(filter, route_id)) { |
- FilterInfo info(filter, route_id); |
- filters_.push_back(info); |
- } |
-} |
- |
-void WorkerProcessHost::WorkerInstance::RemoveFilter( |
- WorkerMessageFilter* filter, int route_id) { |
- for (FilterList::iterator i = filters_.begin(); i != filters_.end();) { |
- if (i->filter() == filter && i->route_id() == route_id) |
- i = filters_.erase(i); |
- else |
- ++i; |
- } |
- // Should not be duplicate copies in the filter set. |
- DCHECK(!HasFilter(filter, route_id)); |
-} |
- |
-void WorkerProcessHost::WorkerInstance::RemoveFilters( |
- WorkerMessageFilter* filter) { |
- for (FilterList::iterator i = filters_.begin(); i != filters_.end();) { |
- if (i->filter() == filter) |
- i = filters_.erase(i); |
- else |
- ++i; |
- } |
-} |
- |
-bool WorkerProcessHost::WorkerInstance::HasFilter( |
- WorkerMessageFilter* filter, int route_id) const { |
- for (FilterList::const_iterator i = filters_.begin(); i != filters_.end(); |
- ++i) { |
- if (i->filter() == filter && i->route_id() == route_id) |
- return true; |
- } |
- return false; |
-} |
- |
-bool WorkerProcessHost::WorkerInstance::FrameIsParent( |
- int render_process_id, int render_frame_id) const { |
- const WorkerDocumentSet::DocumentInfoSet& parents = |
- worker_document_set()->documents(); |
- for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = |
- parents.begin(); |
- parent_iter != parents.end(); ++parent_iter) { |
- if (parent_iter->render_process_id() == render_process_id && |
- parent_iter->render_frame_id() == render_frame_id) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-WorkerProcessHost::WorkerInstance::FilterInfo |
-WorkerProcessHost::WorkerInstance::GetFilter() const { |
- DCHECK(NumFilters() == 1); |
- return *filters_.begin(); |
-} |
- |
-} // namespace content |