| 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
|
|
|