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