Home | History | Annotate | Download | only in service_worker
      1 // Copyright 2013 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_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
      6 #define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
      7 
      8 #include <map>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/callback_forward.h"
     13 #include "base/gtest_prod_util.h"
     14 #include "base/logging.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/observer_list.h"
     18 #include "base/strings/string16.h"
     19 #include "content/common/content_export.h"
     20 #include "content/common/service_worker/service_worker_status_code.h"
     21 #include "url/gurl.h"
     22 
     23 struct EmbeddedWorkerMsg_StartWorker_Params;
     24 
     25 namespace IPC {
     26 class Message;
     27 }
     28 
     29 namespace content {
     30 
     31 class EmbeddedWorkerRegistry;
     32 class ServiceWorkerContextCore;
     33 struct ServiceWorkerFetchRequest;
     34 
     35 // This gives an interface to control one EmbeddedWorker instance, which
     36 // may be 'in-waiting' or running in one of the child processes added by
     37 // AddProcessReference().
     38 class CONTENT_EXPORT EmbeddedWorkerInstance {
     39  public:
     40   typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
     41   enum Status {
     42     STOPPED,
     43     STARTING,
     44     RUNNING,
     45     STOPPING,
     46   };
     47 
     48   class Listener {
     49    public:
     50     virtual ~Listener() {}
     51     virtual void OnStarted() = 0;
     52     virtual void OnStopped() = 0;
     53     virtual void OnReportException(const base::string16& error_message,
     54                                    int line_number,
     55                                    int column_number,
     56                                    const GURL& source_url) {}
     57     virtual void OnReportConsoleMessage(int source_identifier,
     58                                         int message_level,
     59                                         const base::string16& message,
     60                                         int line_number,
     61                                         const GURL& source_url) {}
     62     // These should return false if the message is not handled by this
     63     // listener. (TODO(kinuko): consider using IPC::Listener interface)
     64     // TODO(kinuko): Deprecate OnReplyReceived.
     65     virtual bool OnMessageReceived(const IPC::Message& message) = 0;
     66   };
     67 
     68   ~EmbeddedWorkerInstance();
     69 
     70   // Starts the worker. It is invalid to call this when the worker is not in
     71   // STOPPED status. |callback| is invoked when the worker's process is created
     72   // if necessary and the IPC to evaluate the worker's script is sent.
     73   // Observer::OnStarted() is run when the worker is actually started.
     74   void Start(int64 service_worker_version_id,
     75              const GURL& scope,
     76              const GURL& script_url,
     77              const std::vector<int>& possible_process_ids,
     78              const StatusCallback& callback);
     79 
     80   // Stops the worker. It is invalid to call this when the worker is
     81   // not in STARTING or RUNNING status.
     82   // This returns false if stopping a worker fails immediately, e.g. when
     83   // IPC couldn't be sent to the worker.
     84   ServiceWorkerStatusCode Stop();
     85 
     86   // Sends |message| to the embedded worker running in the child process.
     87   // It is invalid to call this while the worker is not in RUNNING status.
     88   ServiceWorkerStatusCode SendMessage(const IPC::Message& message);
     89 
     90   // Add or remove |process_id| to the internal process set where this
     91   // worker can be started.
     92   void AddProcessReference(int process_id);
     93   void ReleaseProcessReference(int process_id);
     94   bool HasProcessToRun() const { return !process_refs_.empty(); }
     95 
     96   int embedded_worker_id() const { return embedded_worker_id_; }
     97   Status status() const { return status_; }
     98   int process_id() const { return process_id_; }
     99   int thread_id() const { return thread_id_; }
    100   int worker_devtools_agent_route_id() const {
    101     return worker_devtools_agent_route_id_;
    102   }
    103 
    104   void AddListener(Listener* listener);
    105   void RemoveListener(Listener* listener);
    106 
    107  private:
    108   typedef ObserverList<Listener> ListenerList;
    109 
    110   friend class EmbeddedWorkerRegistry;
    111   FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StartAndStop);
    112   FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, SortProcesses);
    113 
    114   typedef std::map<int, int> ProcessRefMap;
    115 
    116   // Constructor is called via EmbeddedWorkerRegistry::CreateWorker().
    117   // This instance holds a ref of |registry|.
    118   EmbeddedWorkerInstance(base::WeakPtr<ServiceWorkerContextCore> context,
    119                          int embedded_worker_id);
    120 
    121   // Called back from ServiceWorkerProcessManager after Start() passes control
    122   // to the UI thread to acquire a reference to the process.
    123   static void RunProcessAllocated(
    124       base::WeakPtr<EmbeddedWorkerInstance> instance,
    125       base::WeakPtr<ServiceWorkerContextCore> context,
    126       scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
    127       const EmbeddedWorkerInstance::StatusCallback& callback,
    128       ServiceWorkerStatusCode status,
    129       int process_id);
    130   void ProcessAllocated(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
    131                         const StatusCallback& callback,
    132                         int process_id,
    133                         ServiceWorkerStatusCode status);
    134   // Called back after ProcessAllocated() passes control to the UI thread to
    135   // register to WorkerDevToolsManager.
    136   void SendStartWorker(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
    137                        const StatusCallback& callback,
    138                        int worker_devtools_agent_route_id,
    139                        bool pause_on_start);
    140 
    141   // Called back from Registry when the worker instance has ack'ed that
    142   // it finished loading the script.
    143   void OnScriptLoaded();
    144 
    145   // Called back from Registry when the worker instance has ack'ed that
    146   // it failed to load the script.
    147   void OnScriptLoadFailed();
    148 
    149   // Called back from Registry when the worker instance has ack'ed that
    150   // its WorkerGlobalScope is actually started and parsed on |thread_id| in the
    151   // child process.
    152   // This will change the internal status from STARTING to RUNNING.
    153   void OnStarted(int thread_id);
    154 
    155   // Called back from Registry when the worker instance has ack'ed that
    156   // its WorkerGlobalScope is actually stopped in the child process.
    157   // This will change the internal status from STARTING or RUNNING to
    158   // STOPPED.
    159   void OnStopped();
    160 
    161   // Called back from Registry when the worker instance sends message
    162   // to the browser (i.e. EmbeddedWorker observers).
    163   // Returns false if the message is not handled.
    164   bool OnMessageReceived(const IPC::Message& message);
    165 
    166   // Called back from Registry when the worker instance reports the exception.
    167   void OnReportException(const base::string16& error_message,
    168                          int line_number,
    169                          int column_number,
    170                          const GURL& source_url);
    171 
    172   // Called back from Registry when the worker instance reports to the console.
    173   void OnReportConsoleMessage(int source_identifier,
    174                               int message_level,
    175                               const base::string16& message,
    176                               int line_number,
    177                               const GURL& source_url);
    178 
    179   // Chooses a list of processes to try to start this worker in, ordered by how
    180   // many clients are currently in those processes.
    181   std::vector<int> SortProcesses(
    182       const std::vector<int>& possible_process_ids) const;
    183 
    184   base::WeakPtr<ServiceWorkerContextCore> context_;
    185   scoped_refptr<EmbeddedWorkerRegistry> registry_;
    186   const int embedded_worker_id_;
    187   Status status_;
    188 
    189   // Current running information. -1 indicates the worker is not running.
    190   int process_id_;
    191   int thread_id_;
    192   int worker_devtools_agent_route_id_;
    193 
    194   ProcessRefMap process_refs_;
    195   ListenerList listener_list_;
    196 
    197   base::WeakPtrFactory<EmbeddedWorkerInstance> weak_factory_;
    198 
    199   DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstance);
    200 };
    201 
    202 }  // namespace content
    203 
    204 #endif  // CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
    205