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_SERVICE_WORKER_CONTEXT_CORE_H_
6#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
7
8#include <map>
9#include <vector>
10
11#include "base/callback.h"
12#include "base/files/file_path.h"
13#include "base/id_map.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/observer_list_threadsafe.h"
17#include "content/browser/service_worker/service_worker_info.h"
18#include "content/browser/service_worker/service_worker_process_manager.h"
19#include "content/browser/service_worker/service_worker_provider_host.h"
20#include "content/browser/service_worker/service_worker_registration_status.h"
21#include "content/browser/service_worker/service_worker_storage.h"
22#include "content/common/content_export.h"
23
24class GURL;
25
26namespace base {
27class FilePath;
28class SequencedTaskRunner;
29class SingleThreadTaskRunner;
30}
31
32namespace net {
33class URLRequestContext;
34}
35
36namespace storage {
37class QuotaManagerProxy;
38}
39
40namespace content {
41
42class EmbeddedWorkerRegistry;
43class ServiceWorkerCacheStorageManager;
44class ServiceWorkerContextObserver;
45class ServiceWorkerContextWrapper;
46class ServiceWorkerHandle;
47class ServiceWorkerJobCoordinator;
48class ServiceWorkerProviderHost;
49class ServiceWorkerRegistration;
50class ServiceWorkerStorage;
51
52// This class manages data associated with service workers.
53// The class is single threaded and should only be used on the IO thread.
54// In chromium, there is one instance per storagepartition. This class
55// is the root of the containment hierarchy for service worker data
56// associated with a particular partition.
57class CONTENT_EXPORT ServiceWorkerContextCore
58    : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) {
59 public:
60  typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
61  typedef base::Callback<void(ServiceWorkerStatusCode status,
62                              int64 registration_id,
63                              int64 version_id)> RegistrationCallback;
64  typedef base::Callback<
65      void(ServiceWorkerStatusCode status)> UnregistrationCallback;
66  typedef IDMap<ServiceWorkerProviderHost, IDMapOwnPointer> ProviderMap;
67  typedef IDMap<ProviderMap, IDMapOwnPointer> ProcessToProviderMap;
68
69  // Directory for ServiceWorkerStorage and ServiceWorkerCacheManager.
70  static const base::FilePath::CharType kServiceWorkerDirectory[];
71
72  // Iterates over ServiceWorkerProviderHost objects in a ProcessToProviderMap.
73  class ProviderHostIterator {
74   public:
75    ~ProviderHostIterator();
76    ServiceWorkerProviderHost* GetProviderHost();
77    void Advance();
78    bool IsAtEnd();
79
80   private:
81    friend class ServiceWorkerContextCore;
82    explicit ProviderHostIterator(ProcessToProviderMap* map);
83    void Initialize();
84
85    ProcessToProviderMap* map_;
86    scoped_ptr<ProcessToProviderMap::iterator> process_iterator_;
87    scoped_ptr<ProviderMap::iterator> provider_host_iterator_;
88
89    DISALLOW_COPY_AND_ASSIGN(ProviderHostIterator);
90  };
91
92  // This is owned by the StoragePartition, which will supply it with
93  // the local path on disk. Given an empty |user_data_directory|,
94  // nothing will be stored on disk. |observer_list| is created in
95  // ServiceWorkerContextWrapper. When Notify() of |observer_list| is called in
96  // ServiceWorkerContextCore, the methods of ServiceWorkerContextObserver will
97  // be called on the thread which called AddObserver() of |observer_list|.
98  ServiceWorkerContextCore(
99      const base::FilePath& user_data_directory,
100      const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner,
101      const scoped_refptr<base::SequencedTaskRunner>& database_task_runner,
102      const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread,
103      storage::QuotaManagerProxy* quota_manager_proxy,
104      ObserverListThreadSafe<ServiceWorkerContextObserver>* observer_list,
105      ServiceWorkerContextWrapper* wrapper);
106  ServiceWorkerContextCore(
107      ServiceWorkerContextCore* old_context,
108      ServiceWorkerContextWrapper* wrapper);
109  virtual ~ServiceWorkerContextCore();
110
111  // ServiceWorkerVersion::Listener overrides.
112  virtual void OnWorkerStarted(ServiceWorkerVersion* version) OVERRIDE;
113  virtual void OnWorkerStopped(ServiceWorkerVersion* version) OVERRIDE;
114  virtual void OnVersionStateChanged(ServiceWorkerVersion* version) OVERRIDE;
115  virtual void OnErrorReported(ServiceWorkerVersion* version,
116                               const base::string16& error_message,
117                               int line_number,
118                               int column_number,
119                               const GURL& source_url) OVERRIDE;
120  virtual void OnReportConsoleMessage(ServiceWorkerVersion* version,
121                                      int source_identifier,
122                                      int message_level,
123                                      const base::string16& message,
124                                      int line_number,
125                                      const GURL& source_url) OVERRIDE;
126
127  ServiceWorkerStorage* storage() { return storage_.get(); }
128  ServiceWorkerCacheStorageManager* cache_manager() {
129    return cache_manager_.get();
130  }
131  ServiceWorkerProcessManager* process_manager();
132  EmbeddedWorkerRegistry* embedded_worker_registry() {
133    return embedded_worker_registry_.get();
134  }
135  ServiceWorkerJobCoordinator* job_coordinator() {
136    return job_coordinator_.get();
137  }
138
139  // The context class owns the set of ProviderHosts.
140  ServiceWorkerProviderHost* GetProviderHost(int process_id, int provider_id);
141  void AddProviderHost(scoped_ptr<ServiceWorkerProviderHost> provider_host);
142  void RemoveProviderHost(int process_id, int provider_id);
143  void RemoveAllProviderHostsForProcess(int process_id);
144  scoped_ptr<ProviderHostIterator> GetProviderHostIterator();
145
146  // A child process of |source_process_id| may be used to run the created
147  // worker for initial installation.
148  // Non-null |provider_host| must be given if this is called from a document.
149  void RegisterServiceWorker(const GURL& pattern,
150                             const GURL& script_url,
151                             ServiceWorkerProviderHost* provider_host,
152                             const RegistrationCallback& callback);
153  void UnregisterServiceWorker(const GURL& pattern,
154                               const UnregistrationCallback& callback);
155  void UpdateServiceWorker(ServiceWorkerRegistration* registration);
156
157  // This class maintains collections of live instances, this class
158  // does not own these object or influence their lifetime.
159  ServiceWorkerRegistration* GetLiveRegistration(int64 registration_id);
160  void AddLiveRegistration(ServiceWorkerRegistration* registration);
161  void RemoveLiveRegistration(int64 registration_id);
162  ServiceWorkerVersion* GetLiveVersion(int64 version_id);
163  void AddLiveVersion(ServiceWorkerVersion* version);
164  void RemoveLiveVersion(int64 registration_id);
165
166  std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo();
167  std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo();
168
169  // Returns new context-local unique ID.
170  int GetNewServiceWorkerHandleId();
171  int GetNewRegistrationHandleId();
172
173  void ScheduleDeleteAndStartOver() const;
174
175  // Deletes all files on disk and restarts the system. This leaves the system
176  // in a disabled state until it's done.
177  void DeleteAndStartOver(const StatusCallback& callback);
178
179  void SetBlobParametersForCache(
180      net::URLRequestContext* request_context,
181      base::WeakPtr<storage::BlobStorageContext> blob_storage_context);
182
183  base::WeakPtr<ServiceWorkerContextCore> AsWeakPtr() {
184    return weak_factory_.GetWeakPtr();
185  }
186
187 private:
188  typedef std::map<int64, ServiceWorkerRegistration*> RegistrationsMap;
189  typedef std::map<int64, ServiceWorkerVersion*> VersionMap;
190
191  ProviderMap* GetProviderMapForProcess(int process_id) {
192    return providers_->Lookup(process_id);
193  }
194
195  void RegistrationComplete(const GURL& pattern,
196                            const RegistrationCallback& callback,
197                            ServiceWorkerStatusCode status,
198                            ServiceWorkerRegistration* registration,
199                            ServiceWorkerVersion* version);
200
201  void UnregistrationComplete(const GURL& pattern,
202                              const UnregistrationCallback& callback,
203                              ServiceWorkerStatusCode status);
204
205  base::WeakPtrFactory<ServiceWorkerContextCore> weak_factory_;
206  // It's safe to store a raw pointer instead of a scoped_refptr to |wrapper_|
207  // because the Wrapper::Shutdown call that hops threads to destroy |this| uses
208  // Bind() to hold a reference to |wrapper_| until |this| is fully destroyed.
209  ServiceWorkerContextWrapper* wrapper_;
210  scoped_ptr<ProcessToProviderMap> providers_;
211  scoped_ptr<ServiceWorkerStorage> storage_;
212  scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_;
213  scoped_refptr<EmbeddedWorkerRegistry> embedded_worker_registry_;
214  scoped_ptr<ServiceWorkerJobCoordinator> job_coordinator_;
215  std::map<int64, ServiceWorkerRegistration*> live_registrations_;
216  std::map<int64, ServiceWorkerVersion*> live_versions_;
217  int next_handle_id_;
218  int next_registration_handle_id_;
219  scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> >
220      observer_list_;
221
222  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextCore);
223};
224
225}  // namespace content
226
227#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
228