blob: c3fa64d6d7459b0c3cabd287447fe3b8b2ac540b [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.
#ifndef CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
#define CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
#include <list>
#include <string>
#include <utility>
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/worker_host/worker_document_set.h"
#include "content/browser/worker_host/worker_storage_partition.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/common/process_type.h"
#include "ipc/ipc_sender.h"
#include "url/gurl.h"
#include "webkit/common/resource_type.h"
struct ResourceHostMsg_Request;
namespace fileapi {
class FileSystemContext;
} // namespace fileapi
namespace net {
class URLRequestContext;
}
namespace webkit_database {
class DatabaseTracker;
} // namespace webkit_database
namespace content {
class BrowserChildProcessHostImpl;
class IndexedDBContextImpl;
class ResourceContext;
class SocketStreamDispatcherHost;
class WorkerServiceImpl;
// The WorkerProcessHost is the interface that represents the browser side of
// the browser <-> worker communication channel. There will be one
// WorkerProcessHost per worker process. Currently each worker runs in its own
// process, but that may change. However, we do assume (by storing a
// net::URLRequestContext) that a WorkerProcessHost serves a single
// BrowserContext.
class WorkerProcessHost : public BrowserChildProcessHostDelegate,
public IPC::Sender {
public:
// Contains information about each worker instance, needed to forward messages
// between the renderer and worker processes.
class WorkerInstance {
public:
WorkerInstance(const GURL& url,
const base::string16& name,
int worker_route_id,
int parent_process_id,
int64 main_resource_appcache_id,
ResourceContext* resource_context,
const WorkerStoragePartition& partition);
// Used for pending instances. Rest of the parameters are ignored.
WorkerInstance(const GURL& url,
bool shared,
const base::string16& name,
ResourceContext* resource_context,
const WorkerStoragePartition& partition);
~WorkerInstance();
// Unique identifier for a worker client.
typedef std::pair<WorkerMessageFilter*, int> FilterInfo;
// APIs to manage the filter list for a given instance.
void AddFilter(WorkerMessageFilter* filter, int route_id);
void RemoveFilter(WorkerMessageFilter* filter, int route_id);
void RemoveFilters(WorkerMessageFilter* filter);
bool HasFilter(WorkerMessageFilter* filter, int route_id) const;
bool RendererIsParent(int render_process_id, int render_view_id) const;
int NumFilters() const { return filters_.size(); }
// Returns the single filter (must only be one).
FilterInfo GetFilter() const;
typedef std::list<FilterInfo> FilterList;
const FilterList& filters() const { return filters_; }
// Checks if this WorkerInstance matches the passed url/name params
// (per the comparison algorithm in the WebWorkers spec). This API only
// applies to shared workers.
bool Matches(
const GURL& url,
const base::string16& name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) const;
// Shares the passed instance's WorkerDocumentSet with this instance. This
// instance's current WorkerDocumentSet is dereferenced (and freed if this
// is the only reference) as a result.
void ShareDocumentSet(const WorkerInstance& instance) {
worker_document_set_ = instance.worker_document_set_;
};
// Accessors
bool closed() const { return closed_; }
void set_closed(bool closed) { closed_ = closed; }
const GURL& url() const { return url_; }
const base::string16 name() const { return name_; }
int worker_route_id() const { return worker_route_id_; }
int parent_process_id() const { return parent_process_id_; }
int64 main_resource_appcache_id() const {
return main_resource_appcache_id_;
}
WorkerDocumentSet* worker_document_set() const {
return worker_document_set_.get();
}
ResourceContext* resource_context() const {
return resource_context_;
}
const WorkerStoragePartition& partition() const {
return partition_;
}
private:
// Set of all filters (clients) associated with this worker.
GURL url_;
bool closed_;
base::string16 name_;
int worker_route_id_;
int parent_process_id_;
int64 main_resource_appcache_id_;
FilterList filters_;
scoped_refptr<WorkerDocumentSet> worker_document_set_;
ResourceContext* const resource_context_;
WorkerStoragePartition partition_;
};
WorkerProcessHost(ResourceContext* resource_context,
const WorkerStoragePartition& partition);
virtual ~WorkerProcessHost();
// IPC::Sender implementation:
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);
// Creates a worker object in the process.
void CreateWorker(const WorkerInstance& instance);
// Returns true iff the given message from a renderer process was forwarded to
// the worker.
bool FilterMessage(const IPC::Message& message, WorkerMessageFilter* filter);
void FilterShutdown(WorkerMessageFilter* filter);
// Shuts down any shared workers that are no longer referenced by active
// documents.
void DocumentDetached(WorkerMessageFilter* filter,
unsigned long long document_id);
// Terminates the given worker, i.e. based on a UI action.
CONTENT_EXPORT void TerminateWorker(int worker_route_id);
// Callers can reduce the WorkerProcess' priority.
void SetBackgrounded(bool backgrounded);
CONTENT_EXPORT const ChildProcessData& GetData();
typedef std::list<WorkerInstance> Instances;
const Instances& instances() const { return instances_; }
ResourceContext* resource_context() const {
return resource_context_;
}
bool process_launched() const { return process_launched_; }
protected:
friend class WorkerServiceImpl;
Instances& mutable_instances() { return instances_; }
private:
// BrowserChildProcessHostDelegate implementation:
virtual void OnProcessLaunched() OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// Creates and adds the message filters.
void CreateMessageFilters(int render_process_id);
void OnWorkerContextClosed(int worker_route_id);
void OnAllowDatabase(int worker_route_id,
const GURL& url,
const base::string16& name,
const base::string16& display_name,
unsigned long estimated_size,
bool* result);
void OnAllowFileSystem(int worker_route_id,
const GURL& url,
bool* result);
void OnAllowIndexedDB(int worker_route_id,
const GURL& url,
const base::string16& name,
bool* result);
void OnForceKillWorkerProcess();
// Relays a message to the given endpoint. Takes care of parsing the message
// if it contains a message port and sending it a valid route id.
void RelayMessage(const IPC::Message& message,
WorkerMessageFilter* filter,
int route_id);
void ShutdownSocketStreamDispatcherHostIfNecessary();
virtual bool CanShutdown() OVERRIDE;
// Updates the title shown in the task manager.
void UpdateTitle();
// Return a vector of all the render process/render view IDs that use the
// given worker.
std::vector<std::pair<int, int> > GetRenderViewIDsForWorker(int route_id);
// Callbacks for ResourceMessageFilter and SocketStreamDispatcherHost.
void GetContexts(const ResourceHostMsg_Request& request,
ResourceContext** resource_context,
net::URLRequestContext** request_context);
net::URLRequestContext* GetRequestContext(ResourceType::Type resource_type);
Instances instances_;
ResourceContext* const resource_context_;
WorkerStoragePartition partition_;
// A reference to the filter associated with this worker process. We need to
// keep this around since we'll use it when forward messages to the worker
// process.
scoped_refptr<WorkerMessageFilter> worker_message_filter_;
scoped_ptr<BrowserChildProcessHostImpl> process_;
bool process_launched_;
scoped_refptr<SocketStreamDispatcherHost> socket_stream_dispatcher_host_;
DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost);
};
class WorkerProcessHostIterator
: public BrowserChildProcessHostTypeIterator<WorkerProcessHost> {
public:
WorkerProcessHostIterator()
: BrowserChildProcessHostTypeIterator<WorkerProcessHost>(
PROCESS_TYPE_WORKER) {
}
};
} // namespace content
#endif // CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_