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 SequencedTaskRunner; 29 class SingleThreadTaskRunner; 30 } 31 32 namespace net { 33 class URLRequestContext; 34 } 35 36 namespace storage { 37 class QuotaManagerProxy; 38 } 39 40 namespace content { 41 42 class EmbeddedWorkerRegistry; 43 class ServiceWorkerCacheStorageManager; 44 class ServiceWorkerContextObserver; 45 class ServiceWorkerContextWrapper; 46 class ServiceWorkerHandle; 47 class ServiceWorkerJobCoordinator; 48 class ServiceWorkerProviderHost; 49 class ServiceWorkerRegistration; 50 class 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. 57 class 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