Home | History | Annotate | Download | only in worker_host
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
      6 #define CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
      7 
      8 #include <list>
      9 #include <string>
     10 #include <utility>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/files/file_path.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "content/browser/worker_host/worker_document_set.h"
     16 #include "content/browser/worker_host/worker_storage_partition.h"
     17 #include "content/common/content_export.h"
     18 #include "content/public/browser/browser_child_process_host_delegate.h"
     19 #include "content/public/browser/browser_child_process_host_iterator.h"
     20 #include "content/public/common/process_type.h"
     21 #include "ipc/ipc_sender.h"
     22 #include "url/gurl.h"
     23 
     24 namespace fileapi {
     25 class FileSystemContext;
     26 }  // namespace fileapi
     27 
     28 namespace webkit_database {
     29 class DatabaseTracker;
     30 }  // namespace webkit_database
     31 
     32 namespace content {
     33 class BrowserChildProcessHostImpl;
     34 class IndexedDBContextImpl;
     35 class ResourceContext;
     36 class SocketStreamDispatcherHost;
     37 class WorkerServiceImpl;
     38 
     39 // The WorkerProcessHost is the interface that represents the browser side of
     40 // the browser <-> worker communication channel. There will be one
     41 // WorkerProcessHost per worker process.  Currently each worker runs in its own
     42 // process, but that may change.  However, we do assume (by storing a
     43 // net::URLRequestContext) that a WorkerProcessHost serves a single
     44 // BrowserContext.
     45 class WorkerProcessHost : public BrowserChildProcessHostDelegate,
     46                           public IPC::Sender {
     47  public:
     48   // Contains information about each worker instance, needed to forward messages
     49   // between the renderer and worker processes.
     50   class WorkerInstance {
     51    public:
     52     WorkerInstance(const GURL& url,
     53                    const string16& name,
     54                    int worker_route_id,
     55                    int parent_process_id,
     56                    int64 main_resource_appcache_id,
     57                    ResourceContext* resource_context,
     58                    const WorkerStoragePartition& partition);
     59     // Used for pending instances. Rest of the parameters are ignored.
     60     WorkerInstance(const GURL& url,
     61                    bool shared,
     62                    const string16& name,
     63                    ResourceContext* resource_context,
     64                    const WorkerStoragePartition& partition);
     65     ~WorkerInstance();
     66 
     67     // Unique identifier for a worker client.
     68     typedef std::pair<WorkerMessageFilter*, int> FilterInfo;
     69 
     70     // APIs to manage the filter list for a given instance.
     71     void AddFilter(WorkerMessageFilter* filter, int route_id);
     72     void RemoveFilter(WorkerMessageFilter* filter, int route_id);
     73     void RemoveFilters(WorkerMessageFilter* filter);
     74     bool HasFilter(WorkerMessageFilter* filter, int route_id) const;
     75     bool RendererIsParent(int render_process_id, int render_view_id) const;
     76     int NumFilters() const { return filters_.size(); }
     77     // Returns the single filter (must only be one).
     78     FilterInfo GetFilter() const;
     79 
     80     typedef std::list<FilterInfo> FilterList;
     81     const FilterList& filters() const { return filters_; }
     82 
     83     // Checks if this WorkerInstance matches the passed url/name params
     84     // (per the comparison algorithm in the WebWorkers spec). This API only
     85     // applies to shared workers.
     86     bool Matches(
     87         const GURL& url,
     88         const string16& name,
     89         const WorkerStoragePartition& partition,
     90         ResourceContext* resource_context) const;
     91 
     92     // Shares the passed instance's WorkerDocumentSet with this instance. This
     93     // instance's current WorkerDocumentSet is dereferenced (and freed if this
     94     // is the only reference) as a result.
     95     void ShareDocumentSet(const WorkerInstance& instance) {
     96       worker_document_set_ = instance.worker_document_set_;
     97     };
     98 
     99     // Accessors
    100     bool closed() const { return closed_; }
    101     void set_closed(bool closed) { closed_ = closed; }
    102     const GURL& url() const { return url_; }
    103     const string16 name() const { return name_; }
    104     int worker_route_id() const { return worker_route_id_; }
    105     int parent_process_id() const { return parent_process_id_; }
    106     int64 main_resource_appcache_id() const {
    107       return main_resource_appcache_id_;
    108     }
    109     WorkerDocumentSet* worker_document_set() const {
    110       return worker_document_set_.get();
    111     }
    112     ResourceContext* resource_context() const {
    113       return resource_context_;
    114     }
    115     const WorkerStoragePartition& partition() const {
    116       return partition_;
    117     }
    118 
    119    private:
    120     // Set of all filters (clients) associated with this worker.
    121     GURL url_;
    122     bool closed_;
    123     string16 name_;
    124     int worker_route_id_;
    125     int parent_process_id_;
    126     int64 main_resource_appcache_id_;
    127     FilterList filters_;
    128     scoped_refptr<WorkerDocumentSet> worker_document_set_;
    129     ResourceContext* const resource_context_;
    130     WorkerStoragePartition partition_;
    131   };
    132 
    133   WorkerProcessHost(ResourceContext* resource_context,
    134                     const WorkerStoragePartition& partition);
    135   virtual ~WorkerProcessHost();
    136 
    137   // IPC::Sender implementation:
    138   virtual bool Send(IPC::Message* message) OVERRIDE;
    139 
    140   // Starts the process.  Returns true iff it succeeded.
    141   // |render_process_id| is the renderer process responsible for starting this
    142   // worker.
    143   bool Init(int render_process_id);
    144 
    145   // Creates a worker object in the process.
    146   void CreateWorker(const WorkerInstance& instance);
    147 
    148   // Returns true iff the given message from a renderer process was forwarded to
    149   // the worker.
    150   bool FilterMessage(const IPC::Message& message, WorkerMessageFilter* filter);
    151 
    152   void FilterShutdown(WorkerMessageFilter* filter);
    153 
    154   // Shuts down any shared workers that are no longer referenced by active
    155   // documents.
    156   void DocumentDetached(WorkerMessageFilter* filter,
    157                         unsigned long long document_id);
    158 
    159   // Terminates the given worker, i.e. based on a UI action.
    160   CONTENT_EXPORT void TerminateWorker(int worker_route_id);
    161 
    162   // Callers can reduce the WorkerProcess' priority.
    163   void SetBackgrounded(bool backgrounded);
    164 
    165   CONTENT_EXPORT const ChildProcessData& GetData();
    166 
    167   typedef std::list<WorkerInstance> Instances;
    168   const Instances& instances() const { return instances_; }
    169 
    170   ResourceContext* resource_context() const {
    171     return resource_context_;
    172   }
    173 
    174   bool process_launched() const { return process_launched_; }
    175 
    176  protected:
    177   friend class WorkerServiceImpl;
    178 
    179   Instances& mutable_instances() { return instances_; }
    180 
    181  private:
    182   // BrowserChildProcessHostDelegate implementation:
    183   virtual void OnProcessLaunched() OVERRIDE;
    184   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
    185 
    186   // Creates and adds the message filters.
    187   void CreateMessageFilters(int render_process_id);
    188 
    189   void OnWorkerContextClosed(int worker_route_id);
    190   void OnAllowDatabase(int worker_route_id,
    191                        const GURL& url,
    192                        const string16& name,
    193                        const string16& display_name,
    194                        unsigned long estimated_size,
    195                        bool* result);
    196   void OnAllowFileSystem(int worker_route_id,
    197                          const GURL& url,
    198                          bool* result);
    199   void OnAllowIndexedDB(int worker_route_id,
    200                         const GURL& url,
    201                         const string16& name,
    202                         bool* result);
    203 
    204   // Relays a message to the given endpoint.  Takes care of parsing the message
    205   // if it contains a message port and sending it a valid route id.
    206   void RelayMessage(const IPC::Message& message,
    207                     WorkerMessageFilter* filter,
    208                     int route_id);
    209 
    210   void ShutdownSocketStreamDispatcherHostIfNecessary();
    211 
    212   virtual bool CanShutdown() OVERRIDE;
    213 
    214   // Updates the title shown in the task manager.
    215   void UpdateTitle();
    216 
    217   // Return a vector of all the render process/render view IDs that use the
    218   // given worker.
    219   std::vector<std::pair<int, int> > GetRenderViewIDsForWorker(int route_id);
    220 
    221   Instances instances_;
    222 
    223   ResourceContext* const resource_context_;
    224   WorkerStoragePartition partition_;
    225 
    226   // A reference to the filter associated with this worker process.  We need to
    227   // keep this around since we'll use it when forward messages to the worker
    228   // process.
    229   scoped_refptr<WorkerMessageFilter> worker_message_filter_;
    230 
    231   scoped_ptr<BrowserChildProcessHostImpl> process_;
    232   bool process_launched_;
    233 
    234   scoped_refptr<SocketStreamDispatcherHost> socket_stream_dispatcher_host_;
    235 
    236   DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost);
    237 };
    238 
    239 class WorkerProcessHostIterator
    240     : public BrowserChildProcessHostTypeIterator<WorkerProcessHost> {
    241  public:
    242   WorkerProcessHostIterator()
    243       : BrowserChildProcessHostTypeIterator<WorkerProcessHost>(
    244             PROCESS_TYPE_WORKER) {
    245   }
    246 };
    247 
    248 }  // namespace content
    249 
    250 #endif  // CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
    251