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.
5 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
13 #include "base/bind.h"
14 #include "base/files/file_path.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/memory/weak_ptr.h"
18 #include "content/browser/service_worker/service_worker_database.h"
19 #include "content/browser/service_worker/service_worker_version.h"
20 #include "content/common/content_export.h"
21 #include "content/common/service_worker/service_worker_status_code.h"
25 class SequencedTaskRunner
;
26 class SingleThreadTaskRunner
;
30 class QuotaManagerProxy
;
35 class ServiceWorkerContextCore
;
36 class ServiceWorkerDiskCache
;
37 class ServiceWorkerRegistration
;
38 class ServiceWorkerRegistrationInfo
;
39 class ServiceWorkerResponseReader
;
40 class ServiceWorkerResponseWriter
;
42 // This class provides an interface to store and retrieve ServiceWorker
44 class CONTENT_EXPORT ServiceWorkerStorage
45 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener
) {
47 typedef std::vector
<ServiceWorkerDatabase::ResourceRecord
> ResourceList
;
48 typedef base::Callback
<void(ServiceWorkerStatusCode status
)> StatusCallback
;
49 typedef base::Callback
<void(ServiceWorkerStatusCode status
,
50 const scoped_refptr
<ServiceWorkerRegistration
>&
51 registration
)> FindRegistrationCallback
;
52 typedef base::Callback
<
53 void(const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
)>
54 GetAllRegistrationInfosCallback
;
55 typedef base::Callback
<
56 void(ServiceWorkerStatusCode status
, bool are_equal
)>
59 virtual ~ServiceWorkerStorage();
61 static scoped_ptr
<ServiceWorkerStorage
> Create(
62 const base::FilePath
& path
,
63 base::WeakPtr
<ServiceWorkerContextCore
> context
,
64 const scoped_refptr
<base::SequencedTaskRunner
>& database_task_runner
,
65 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
66 storage::QuotaManagerProxy
* quota_manager_proxy
);
68 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
69 static scoped_ptr
<ServiceWorkerStorage
> Create(
70 base::WeakPtr
<ServiceWorkerContextCore
> context
,
71 ServiceWorkerStorage
* old_storage
);
73 // Finds registration for |document_url| or |pattern| or |registration_id|.
74 // The Find methods will find stored and initially installing registrations.
75 // Returns SERVICE_WORKER_OK with non-null registration if registration
76 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
77 // registration is found. The FindRegistrationForPattern method is
78 // guaranteed to return asynchronously. However, the methods to find
79 // for |document_url| or |registration_id| may complete immediately
80 // (the callback may be called prior to the method returning) or
82 void FindRegistrationForDocument(const GURL
& document_url
,
83 const FindRegistrationCallback
& callback
);
84 void FindRegistrationForPattern(const GURL
& scope
,
85 const FindRegistrationCallback
& callback
);
86 void FindRegistrationForId(int64 registration_id
,
88 const FindRegistrationCallback
& callback
);
90 ServiceWorkerRegistration
* GetUninstallingRegistration(const GURL
& scope
);
92 // Returns info about all stored and initially installing registrations.
93 void GetAllRegistrations(const GetAllRegistrationInfosCallback
& callback
);
95 // Commits |registration| with the installed but not activated |version|
96 // to storage, overwritting any pre-existing registration data for the scope.
97 // A pre-existing version's script resources remain available if that version
98 // is live. PurgeResources should be called when it's OK to delete them.
99 void StoreRegistration(
100 ServiceWorkerRegistration
* registration
,
101 ServiceWorkerVersion
* version
,
102 const StatusCallback
& callback
);
104 // Updates the state of the registration's stored version to active.
105 void UpdateToActiveState(
106 ServiceWorkerRegistration
* registration
,
107 const StatusCallback
& callback
);
109 // Updates the stored time to match the value of
110 // registration->last_update_check().
111 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
);
113 // Deletes the registration data for |registration_id|. If the registration's
114 // version is live, its script resources will remain available.
115 // PurgeResources should be called when it's OK to delete them.
116 void DeleteRegistration(int64 registration_id
,
118 const StatusCallback
& callback
);
120 scoped_ptr
<ServiceWorkerResponseReader
> CreateResponseReader(
122 scoped_ptr
<ServiceWorkerResponseWriter
> CreateResponseWriter(
125 // Adds |id| to the set of resources ids that are in the disk
126 // cache but not yet stored with a registration.
127 void StoreUncommittedResponseId(int64 id
);
129 // Removes |id| from uncommitted list, adds it to the
130 // purgeable list and purges it.
131 void DoomUncommittedResponse(int64 id
);
133 // Compares only the response bodies.
134 void CompareScriptResources(int64 lhs_id
, int64 rhs_id
,
135 const CompareCallback
& callback
);
137 // Deletes the storage and starts over.
138 void DeleteAndStartOver(const StatusCallback
& callback
);
140 // Returns new IDs which are guaranteed to be unique in the storage.
141 int64
NewRegistrationId();
142 int64
NewVersionId();
143 int64
NewResourceId();
145 // Intended for use only by ServiceWorkerRegisterJob and
146 // ServiceWorkerRegistration.
147 void NotifyInstallingRegistration(
148 ServiceWorkerRegistration
* registration
);
149 void NotifyDoneInstallingRegistration(
150 ServiceWorkerRegistration
* registration
,
151 ServiceWorkerVersion
* version
,
152 ServiceWorkerStatusCode status
);
153 void NotifyUninstallingRegistration(ServiceWorkerRegistration
* registration
);
154 void NotifyDoneUninstallingRegistration(
155 ServiceWorkerRegistration
* registration
);
158 bool IsDisabled() const;
160 // |resources| must already be on the purgeable list.
161 void PurgeResources(const ResourceList
& resources
);
164 friend class ServiceWorkerResourceStorageTest
;
165 friend class ServiceWorkerControlleeRequestHandlerTest
;
166 friend class ServiceWorkerContextRequestHandlerTest
;
167 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
168 DeleteRegistration_NoLiveVersion
);
169 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
170 DeleteRegistration_WaitingVersion
);
171 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
172 DeleteRegistration_ActiveVersion
);
173 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
175 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
179 int64 next_registration_id
;
180 int64 next_version_id
;
181 int64 next_resource_id
;
182 std::set
<GURL
> origins
;
188 // Because there are too many params for base::Bind to wrap a closure around.
189 struct DidDeleteRegistrationParams
{
190 int64 registration_id
;
192 StatusCallback callback
;
194 DidDeleteRegistrationParams();
195 ~DidDeleteRegistrationParams();
198 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
199 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
200 RegistrationRefsById
;
201 typedef base::Callback
<void(
203 ServiceWorkerDatabase::Status status
)> InitializeCallback
;
204 typedef base::Callback
<
205 void(const GURL
& origin
,
206 int64 deleted_version_id
,
207 const std::vector
<int64
>& newly_purgeable_resources
,
208 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
209 typedef base::Callback
<
210 void(bool origin_is_deletable
,
212 const std::vector
<int64
>& newly_purgeable_resources
,
213 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
214 typedef base::Callback
<void(
215 const ServiceWorkerDatabase::RegistrationData
& data
,
216 const ResourceList
& resources
,
217 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
218 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
219 ServiceWorkerDatabase::Status status
)>
220 GetResourcesCallback
;
222 ServiceWorkerStorage(
223 const base::FilePath
& path
,
224 base::WeakPtr
<ServiceWorkerContextCore
> context
,
225 const scoped_refptr
<base::SequencedTaskRunner
>& database_task_runner
,
226 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
227 storage::QuotaManagerProxy
* quota_manager_proxy
);
229 base::FilePath
GetDatabasePath();
230 base::FilePath
GetDiskCachePath();
233 const base::Closure
& callback
);
234 void DidReadInitialData(
236 ServiceWorkerDatabase::Status status
);
237 void DidFindRegistrationForDocument(
238 const GURL
& document_url
,
239 const FindRegistrationCallback
& callback
,
240 const ServiceWorkerDatabase::RegistrationData
& data
,
241 const ResourceList
& resources
,
242 ServiceWorkerDatabase::Status status
);
243 void DidFindRegistrationForPattern(
245 const FindRegistrationCallback
& callback
,
246 const ServiceWorkerDatabase::RegistrationData
& data
,
247 const ResourceList
& resources
,
248 ServiceWorkerDatabase::Status status
);
249 void DidFindRegistrationForId(
250 const FindRegistrationCallback
& callback
,
251 const ServiceWorkerDatabase::RegistrationData
& data
,
252 const ResourceList
& resources
,
253 ServiceWorkerDatabase::Status status
);
254 void DidGetAllRegistrations(
255 const GetAllRegistrationInfosCallback
& callback
,
256 RegistrationList
* registrations
,
257 ServiceWorkerDatabase::Status status
);
258 void DidStoreRegistration(const StatusCallback
& callback
,
260 int64 deleted_version_id
,
261 const std::vector
<int64
>& newly_purgeable_resources
,
262 ServiceWorkerDatabase::Status status
);
263 void DidUpdateToActiveState(
264 const StatusCallback
& callback
,
265 ServiceWorkerDatabase::Status status
);
266 void DidDeleteRegistration(
267 const DidDeleteRegistrationParams
& params
,
268 bool origin_is_deletable
,
270 const std::vector
<int64
>& newly_purgeable_resources
,
271 ServiceWorkerDatabase::Status status
);
272 void ReturnFoundRegistration(
273 const FindRegistrationCallback
& callback
,
274 const ServiceWorkerDatabase::RegistrationData
& data
,
275 const ResourceList
& resources
);
277 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
278 const ServiceWorkerDatabase::RegistrationData
& data
,
279 const ResourceList
& resources
);
280 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
281 const GURL
& document_url
);
282 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
284 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
285 int64 registration_id
);
287 // Lazy disk_cache getter.
288 ServiceWorkerDiskCache
* disk_cache();
289 void OnDiskCacheInitialized(int rv
);
291 void StartPurgingResources(const std::vector
<int64
>& ids
);
292 void StartPurgingResources(const ResourceList
& resources
);
293 void ContinuePurgingResources();
294 void PurgeResource(int64 id
);
295 void OnResourcePurged(int64 id
, int rv
);
297 // Deletes purgeable and uncommitted resources left over from the previous
298 // browser session. This must be called once per session before any database
299 // operation that may mutate the purgeable or uncommitted resource lists.
300 void DeleteStaleResources();
301 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
302 ServiceWorkerDatabase::Status status
);
304 // Static cross-thread helpers.
305 static void CollectStaleResourcesFromDB(
306 ServiceWorkerDatabase
* database
,
307 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
308 const GetResourcesCallback
& callback
);
309 static void ReadInitialDataFromDB(
310 ServiceWorkerDatabase
* database
,
311 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
312 const InitializeCallback
& callback
);
313 static void DeleteRegistrationFromDB(
314 ServiceWorkerDatabase
* database
,
315 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
316 int64 registration_id
,
318 const DeleteRegistrationCallback
& callback
);
319 static void WriteRegistrationInDB(
320 ServiceWorkerDatabase
* database
,
321 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
322 const ServiceWorkerDatabase::RegistrationData
& registration
,
323 const ResourceList
& resources
,
324 const WriteRegistrationCallback
& callback
);
325 static void FindForDocumentInDB(
326 ServiceWorkerDatabase
* database
,
327 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
328 const GURL
& document_url
,
329 const FindInDBCallback
& callback
);
330 static void FindForPatternInDB(
331 ServiceWorkerDatabase
* database
,
332 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
334 const FindInDBCallback
& callback
);
335 static void FindForIdInDB(
336 ServiceWorkerDatabase
* database
,
337 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
338 int64 registration_id
,
340 const FindInDBCallback
& callback
);
342 void ScheduleDeleteAndStartOver();
343 void DidDeleteDatabase(
344 const StatusCallback
& callback
,
345 ServiceWorkerDatabase::Status status
);
346 void DidDeleteDiskCache(
347 const StatusCallback
& callback
,
350 // For finding registrations being installed or uninstalled.
351 RegistrationRefsById installing_registrations_
;
352 RegistrationRefsById uninstalling_registrations_
;
354 // Origins having registations.
355 std::set
<GURL
> registered_origins_
;
357 // Pending database tasks waiting for initialization.
358 std::vector
<base::Closure
> pending_tasks_
;
360 int64 next_registration_id_
;
361 int64 next_version_id_
;
362 int64 next_resource_id_
;
372 base::FilePath path_
;
373 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
375 // Only accessed on |database_task_runner_|.
376 scoped_ptr
<ServiceWorkerDatabase
> database_
;
378 scoped_refptr
<base::SequencedTaskRunner
> database_task_runner_
;
379 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
380 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
381 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
382 std::deque
<int64
> purgeable_resource_ids_
;
383 bool is_purge_pending_
;
384 bool has_checked_for_stale_resources_
;
385 std::set
<int64
> pending_deletions_
;
387 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
389 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
392 } // namespace content
394 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_