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_REGISTRY_H_
6#define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_REGISTRY_H_
7
8#include <map>
9#include <set>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/strings/string16.h"
17#include "content/common/content_export.h"
18#include "content/common/service_worker/service_worker_status_code.h"
19
20struct EmbeddedWorkerMsg_StartWorker_Params;
21class GURL;
22
23namespace IPC {
24class Message;
25class Sender;
26}
27
28namespace content {
29
30class EmbeddedWorkerInstance;
31class ServiceWorkerContextCore;
32
33// Acts as a thin stub between MessageFilter and each EmbeddedWorkerInstance,
34// which sends/receives messages to/from each EmbeddedWorker in child process.
35//
36// Hangs off ServiceWorkerContextCore (its reference is also held by each
37// EmbeddedWorkerInstance).  Operated only on IO thread.
38class CONTENT_EXPORT EmbeddedWorkerRegistry
39    : public NON_EXPORTED_BASE(base::RefCounted<EmbeddedWorkerRegistry>) {
40 public:
41  typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
42
43  static scoped_refptr<EmbeddedWorkerRegistry> Create(
44      const base::WeakPtr<ServiceWorkerContextCore>& contxet);
45
46  // Used for DeleteAndStartOver. Creates a new registry which takes over
47  // |next_embedded_worker_id_| and |process_sender_map_| from |old_registry|.
48  static scoped_refptr<EmbeddedWorkerRegistry> Create(
49      const base::WeakPtr<ServiceWorkerContextCore>& context,
50      EmbeddedWorkerRegistry* old_registry);
51
52  bool OnMessageReceived(const IPC::Message& message);
53
54  // Creates and removes a new worker instance entry for bookkeeping.
55  // This doesn't actually start or stop the worker.
56  scoped_ptr<EmbeddedWorkerInstance> CreateWorker();
57
58  // Called from EmbeddedWorkerInstance, relayed to the child process.
59  void SendStartWorker(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
60                       const StatusCallback& callback,
61                       int process_id);
62  ServiceWorkerStatusCode StopWorker(int process_id,
63                                     int embedded_worker_id);
64
65  // Stop all active workers, even if they're handling events.
66  void Shutdown();
67
68  // Called back from EmbeddedWorker in the child process, relayed via
69  // ServiceWorkerDispatcherHost.
70  void OnWorkerReadyForInspection(int process_id, int embedded_worker_id);
71  void OnWorkerScriptLoaded(int process_id,
72                            int thread_id,
73                            int embedded_worker_id);
74  void OnWorkerScriptLoadFailed(int process_id, int embedded_worker_id);
75  void OnWorkerStarted(int process_id, int embedded_worker_id);
76  void OnWorkerStopped(int process_id, int embedded_worker_id);
77  void OnPausedAfterDownload(int process_id, int embedded_worker_id);
78  void OnReportException(int embedded_worker_id,
79                         const base::string16& error_message,
80                         int line_number,
81                         int column_number,
82                         const GURL& source_url);
83  void OnReportConsoleMessage(int embedded_worker_id,
84                              int source_identifier,
85                              int message_level,
86                              const base::string16& message,
87                              int line_number,
88                              const GURL& source_url);
89
90  // Keeps a map from process_id to sender information.
91  void AddChildProcessSender(int process_id, IPC::Sender* sender);
92  void RemoveChildProcessSender(int process_id);
93
94  // Returns an embedded worker instance for given |embedded_worker_id|.
95  EmbeddedWorkerInstance* GetWorker(int embedded_worker_id);
96
97  // Returns true if |embedded_worker_id| is managed by this registry.
98  bool CanHandle(int embedded_worker_id) const;
99
100 private:
101  friend class base::RefCounted<EmbeddedWorkerRegistry>;
102  friend class EmbeddedWorkerInstance;
103
104  typedef std::map<int, EmbeddedWorkerInstance*> WorkerInstanceMap;
105  typedef std::map<int, IPC::Sender*> ProcessToSenderMap;
106
107  EmbeddedWorkerRegistry(
108      const base::WeakPtr<ServiceWorkerContextCore>& context,
109      int initial_embedded_worker_id);
110  ~EmbeddedWorkerRegistry();
111
112  ServiceWorkerStatusCode Send(int process_id, IPC::Message* message);
113
114  // RemoveWorker is called when EmbeddedWorkerInstance is destructed.
115  // |process_id| could be invalid (i.e. -1) if it's not running.
116  void RemoveWorker(int process_id, int embedded_worker_id);
117
118  base::WeakPtr<ServiceWorkerContextCore> context_;
119
120  WorkerInstanceMap worker_map_;
121  ProcessToSenderMap process_sender_map_;
122
123  // Map from process_id to embedded_worker_id.
124  // This map only contains running workers.
125  std::map<int, std::set<int> > worker_process_map_;
126
127  int next_embedded_worker_id_;
128  const int initial_embedded_worker_id_;
129
130  DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerRegistry);
131};
132
133}  // namespace content
134
135#endif  // CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_REGISTRY_H_
136