blob: 486479a30d3084e4a4c66787333e94cb7560dd74 [file] [log] [blame]
// 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/worker/websharedworkerclient_proxy.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "content/child/shared_worker_devtools_agent.h"
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/worker_messages.h"
#include "content/public/common/content_switches.h"
#include "content/worker/shared_worker_permission_client_proxy.h"
#include "content/worker/websharedworker_stub.h"
#include "content/worker/worker_thread.h"
#include "content/worker/worker_webapplicationcachehost_impl.h"
#include "ipc/ipc_logging.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
using blink::WebApplicationCacheHost;
using blink::WebFrame;
using blink::WebMessagePortChannel;
using blink::WebMessagePortChannelArray;
using blink::WebSecurityOrigin;
using blink::WebString;
using blink::WebWorker;
using blink::WebSharedWorkerClient;
namespace content {
// How long to wait for worker to finish after it's been told to terminate.
#define kMaxTimeForRunawayWorkerSeconds 3
WebSharedWorkerClientProxy::WebSharedWorkerClientProxy(
int route_id, WebSharedWorkerStub* stub)
: route_id_(route_id),
appcache_host_id_(0),
stub_(stub),
weak_factory_(this),
devtools_agent_(NULL),
app_cache_host_(NULL) {
}
WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() {
}
void WebSharedWorkerClientProxy::workerContextClosed() {
Send(new WorkerHostMsg_WorkerContextClosed(route_id_));
}
void WebSharedWorkerClientProxy::workerContextDestroyed() {
Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_));
// Tell the stub that the worker has shutdown - frees this object.
if (stub_)
stub_->Shutdown();
}
void WebSharedWorkerClientProxy::workerScriptLoaded() {
Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_));
if (stub_)
stub_->WorkerScriptLoaded();
}
void WebSharedWorkerClientProxy::workerScriptLoadFailed() {
Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_));
if (stub_)
stub_->WorkerScriptLoadFailed();
}
void WebSharedWorkerClientProxy::selectAppCacheID(long long app_cache_id) {
if (app_cache_host_) {
// app_cache_host_ could become stale as it's owned by blink's
// DocumentLoader. This method is assumed to be called while it's valid.
app_cache_host_->backend()->SelectCacheForSharedWorker(
app_cache_host_->host_id(),
app_cache_id);
}
}
blink::WebNotificationPresenter*
WebSharedWorkerClientProxy::notificationPresenter() {
// TODO(johnnyg): Notifications are not yet hooked up to workers.
// Coming soon.
NOTREACHED();
return NULL;
}
WebApplicationCacheHost* WebSharedWorkerClientProxy::createApplicationCacheHost(
blink::WebApplicationCacheHostClient* client) {
DCHECK(!app_cache_host_);
app_cache_host_ = new WorkerWebApplicationCacheHostImpl(client);
// Remember the id of the instance we create so we have access to that
// value when creating nested dedicated workers in createWorker.
appcache_host_id_ = app_cache_host_->host_id();
return app_cache_host_;
}
blink::WebWorkerPermissionClientProxy*
WebSharedWorkerClientProxy::createWorkerPermissionClientProxy(
const blink::WebSecurityOrigin& origin) {
return new SharedWorkerPermissionClientProxy(
GURL(origin.toString()), origin.isUnique(), route_id_,
ChildThread::current()->thread_safe_sender());
}
void WebSharedWorkerClientProxy::dispatchDevToolsMessage(
const WebString& message) {
if (devtools_agent_)
devtools_agent_->SendDevToolsMessage(message);
}
void WebSharedWorkerClientProxy::saveDevToolsAgentState(
const blink::WebString& state) {
if (devtools_agent_)
devtools_agent_->SaveDevToolsAgentState(state);
}
bool WebSharedWorkerClientProxy::Send(IPC::Message* message) {
return WorkerThread::current()->Send(message);
}
void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() {
// This shuts down the process cleanly from the perspective of the browser
// process, and avoids the crashed worker infobar from appearing to the new
// page. It's ok to post several of theese, because the first executed task
// will exit the message loop and subsequent ones won't be executed.
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds));
}
} // namespace content