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