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_
14 #include "base/bind.h"
15 #include "base/files/file_path.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/memory/weak_ptr.h"
19 #include "content/browser/service_worker/service_worker_database.h"
20 #include "content/browser/service_worker/service_worker_database_task_manager.h"
21 #include "content/browser/service_worker/service_worker_version.h"
22 #include "content/common/content_export.h"
23 #include "content/common/service_worker/service_worker_status_code.h"
27 class SequencedTaskRunner
;
28 class SingleThreadTaskRunner
;
32 class QuotaManagerProxy
;
33 class SpecialStoragePolicy
;
38 class ServiceWorkerContextCore
;
39 class ServiceWorkerDiskCache
;
40 class ServiceWorkerRegistration
;
41 class ServiceWorkerRegistrationInfo
;
42 class ServiceWorkerResponseReader
;
43 class ServiceWorkerResponseWriter
;
45 // This class provides an interface to store and retrieve ServiceWorker
47 class CONTENT_EXPORT ServiceWorkerStorage
48 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener
) {
50 typedef std::vector
<ServiceWorkerDatabase::ResourceRecord
> ResourceList
;
51 typedef base::Callback
<void(ServiceWorkerStatusCode status
)> StatusCallback
;
52 typedef base::Callback
<void(ServiceWorkerStatusCode status
,
53 const scoped_refptr
<ServiceWorkerRegistration
>&
54 registration
)> FindRegistrationCallback
;
55 typedef base::Callback
<
56 void(const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
)>
57 GetRegistrationsInfosCallback
;
58 typedef base::Callback
<
59 void(ServiceWorkerStatusCode status
, bool are_equal
)>
61 typedef base::Callback
<
62 void(const std::string
& data
, ServiceWorkerStatusCode status
)>
64 typedef base::Callback
<void(
65 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
66 ServiceWorkerStatusCode status
)>
67 GetUserDataForAllRegistrationsCallback
;
69 ~ServiceWorkerStorage() override
;
71 static scoped_ptr
<ServiceWorkerStorage
> Create(
72 const base::FilePath
& path
,
73 base::WeakPtr
<ServiceWorkerContextCore
> context
,
74 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
75 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
76 storage::QuotaManagerProxy
* quota_manager_proxy
,
77 storage::SpecialStoragePolicy
* special_storage_policy
);
79 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
80 static scoped_ptr
<ServiceWorkerStorage
> Create(
81 base::WeakPtr
<ServiceWorkerContextCore
> context
,
82 ServiceWorkerStorage
* old_storage
);
84 // Finds registration for |document_url| or |pattern| or |registration_id|.
85 // The Find methods will find stored and initially installing registrations.
86 // Returns SERVICE_WORKER_OK with non-null registration if registration
87 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
88 // registration is found. The FindRegistrationForPattern method is
89 // guaranteed to return asynchronously. However, the methods to find
90 // for |document_url| or |registration_id| may complete immediately
91 // (the callback may be called prior to the method returning) or
93 void FindRegistrationForDocument(const GURL
& document_url
,
94 const FindRegistrationCallback
& callback
);
95 void FindRegistrationForPattern(const GURL
& scope
,
96 const FindRegistrationCallback
& callback
);
97 void FindRegistrationForId(int64 registration_id
,
99 const FindRegistrationCallback
& callback
);
101 // Generally |FindRegistrationForId| should be used to look up a registration
102 // by |registration_id| since it's more efficient. But if a |registration_id|
103 // is all that is available this method can be used instead.
104 // Like |FindRegistrationForId| this method may complete immediately (the
105 // callback may be called prior to the method returning) or asynchronously.
106 void FindRegistrationForIdOnly(int64 registration_id
,
107 const FindRegistrationCallback
& callback
);
109 ServiceWorkerRegistration
* GetUninstallingRegistration(const GURL
& scope
);
111 // Returns info about all stored and initially installing registrations for
113 void GetRegistrationsForOrigin(
114 const GURL
& origin
, const GetRegistrationsInfosCallback
& callback
);
116 // Returns info about all stored and initially installing registrations.
117 void GetAllRegistrations(const GetRegistrationsInfosCallback
& callback
);
119 // Commits |registration| with the installed but not activated |version|
120 // to storage, overwritting any pre-existing registration data for the scope.
121 // A pre-existing version's script resources remain available if that version
122 // is live. PurgeResources should be called when it's OK to delete them.
123 void StoreRegistration(ServiceWorkerRegistration
* registration
,
124 ServiceWorkerVersion
* version
,
125 const StatusCallback
& callback
);
127 // Updates the state of the registration's stored version to active.
128 void UpdateToActiveState(
129 ServiceWorkerRegistration
* registration
,
130 const StatusCallback
& callback
);
132 // Updates the stored time to match the value of
133 // registration->last_update_check().
134 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
);
136 // Deletes the registration data for |registration_id|. If the registration's
137 // version is live, its script resources will remain available.
138 // PurgeResources should be called when it's OK to delete them.
139 void DeleteRegistration(int64 registration_id
,
141 const StatusCallback
& callback
);
143 scoped_ptr
<ServiceWorkerResponseReader
> CreateResponseReader(
145 scoped_ptr
<ServiceWorkerResponseWriter
> CreateResponseWriter(
148 // Adds |id| to the set of resources ids that are in the disk
149 // cache but not yet stored with a registration.
150 void StoreUncommittedResponseId(int64 id
);
152 // Removes |id| from uncommitted list, adds it to the
153 // purgeable list and purges it.
154 void DoomUncommittedResponse(int64 id
);
156 // Compares only the response bodies.
157 void CompareScriptResources(int64 lhs_id
, int64 rhs_id
,
158 const CompareCallback
& callback
);
160 // Provide a storage mechanism to read/write arbitrary data associated with
161 // a registration. Each registration has its own key namespace. Stored data
162 // is deleted when the associated registraton is deleted.
163 void GetUserData(int64 registration_id
,
164 const std::string
& key
,
165 const GetUserDataCallback
& callback
);
166 void StoreUserData(int64 registration_id
,
168 const std::string
& key
,
169 const std::string
& data
,
170 const StatusCallback
& callback
);
171 void ClearUserData(int64 registration_id
,
172 const std::string
& key
,
173 const StatusCallback
& callback
);
174 // Returns all registrations that have user data with a particular key, as
175 // well as that user data.
176 void GetUserDataForAllRegistrations(
177 const std::string
& key
,
178 const GetUserDataForAllRegistrationsCallback
& callback
);
180 // Deletes the storage and starts over.
181 void DeleteAndStartOver(const StatusCallback
& callback
);
183 // Returns new IDs which are guaranteed to be unique in the storage.
184 int64
NewRegistrationId();
185 int64
NewVersionId();
186 int64
NewResourceId();
188 // Intended for use only by ServiceWorkerRegisterJob and
189 // ServiceWorkerRegistration.
190 void NotifyInstallingRegistration(
191 ServiceWorkerRegistration
* registration
);
192 void NotifyDoneInstallingRegistration(
193 ServiceWorkerRegistration
* registration
,
194 ServiceWorkerVersion
* version
,
195 ServiceWorkerStatusCode status
);
196 void NotifyUninstallingRegistration(ServiceWorkerRegistration
* registration
);
197 void NotifyDoneUninstallingRegistration(
198 ServiceWorkerRegistration
* registration
);
201 bool IsDisabled() const;
203 // |resources| must already be on the purgeable list.
204 void PurgeResources(const ResourceList
& resources
);
207 friend class ServiceWorkerStorageTest
;
208 friend class ServiceWorkerResourceStorageTest
;
209 friend class ServiceWorkerControlleeRequestHandlerTest
;
210 friend class ServiceWorkerContextRequestHandlerTest
;
211 friend class ServiceWorkerRequestHandlerTest
;
212 friend class ServiceWorkerWriteToCacheJobTest
;
213 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
214 DeleteRegistration_NoLiveVersion
);
215 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
216 DeleteRegistration_WaitingVersion
);
217 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
218 DeleteRegistration_ActiveVersion
);
219 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
221 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
223 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
227 int64 next_registration_id
;
228 int64 next_version_id
;
229 int64 next_resource_id
;
230 std::set
<GURL
> origins
;
236 // Because there are too many params for base::Bind to wrap a closure around.
237 struct DidDeleteRegistrationParams
{
238 int64 registration_id
;
240 StatusCallback callback
;
242 DidDeleteRegistrationParams();
243 ~DidDeleteRegistrationParams();
246 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
247 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
248 RegistrationRefsById
;
249 typedef base::Callback
<void(
251 ServiceWorkerDatabase::Status status
)> InitializeCallback
;
252 typedef base::Callback
<void(
254 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
255 const std::vector
<int64
>& newly_purgeable_resources
,
256 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
257 typedef base::Callback
<void(
258 bool origin_is_deletable
,
259 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
260 const std::vector
<int64
>& newly_purgeable_resources
,
261 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
262 typedef base::Callback
<void(
263 const ServiceWorkerDatabase::RegistrationData
& data
,
264 const ResourceList
& resources
,
265 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
266 typedef base::Callback
<void(
267 const std::string
& data
,
268 ServiceWorkerDatabase::Status
)> GetUserDataInDBCallback
;
269 typedef base::Callback
<void(
270 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
271 ServiceWorkerDatabase::Status
)>
272 GetUserDataForAllRegistrationsInDBCallback
;
273 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
274 ServiceWorkerDatabase::Status status
)>
275 GetResourcesCallback
;
277 ServiceWorkerStorage(
278 const base::FilePath
& path
,
279 base::WeakPtr
<ServiceWorkerContextCore
> context
,
280 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
281 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
282 storage::QuotaManagerProxy
* quota_manager_proxy
,
283 storage::SpecialStoragePolicy
* special_storage_policy
);
285 base::FilePath
GetDatabasePath();
286 base::FilePath
GetDiskCachePath();
289 const base::Closure
& callback
);
290 void DidReadInitialData(
292 ServiceWorkerDatabase::Status status
);
293 void DidFindRegistrationForDocument(
294 const GURL
& document_url
,
295 const FindRegistrationCallback
& callback
,
297 const ServiceWorkerDatabase::RegistrationData
& data
,
298 const ResourceList
& resources
,
299 ServiceWorkerDatabase::Status status
);
300 void DidFindRegistrationForPattern(
302 const FindRegistrationCallback
& callback
,
303 const ServiceWorkerDatabase::RegistrationData
& data
,
304 const ResourceList
& resources
,
305 ServiceWorkerDatabase::Status status
);
306 void DidFindRegistrationForId(
307 const FindRegistrationCallback
& callback
,
308 const ServiceWorkerDatabase::RegistrationData
& data
,
309 const ResourceList
& resources
,
310 ServiceWorkerDatabase::Status status
);
311 void DidGetRegistrations(
312 const GetRegistrationsInfosCallback
& callback
,
313 RegistrationList
* registrations
,
314 const GURL
& origin_filter
,
315 ServiceWorkerDatabase::Status status
);
316 void DidStoreRegistration(
317 const StatusCallback
& callback
,
318 const ServiceWorkerDatabase::RegistrationData
& new_version
,
320 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
321 const std::vector
<int64
>& newly_purgeable_resources
,
322 ServiceWorkerDatabase::Status status
);
323 void DidUpdateToActiveState(
324 const StatusCallback
& callback
,
325 ServiceWorkerDatabase::Status status
);
326 void DidDeleteRegistration(
327 const DidDeleteRegistrationParams
& params
,
328 bool origin_is_deletable
,
329 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
330 const std::vector
<int64
>& newly_purgeable_resources
,
331 ServiceWorkerDatabase::Status status
);
332 void DidStoreUserData(
333 const StatusCallback
& callback
,
334 ServiceWorkerDatabase::Status status
);
336 const GetUserDataCallback
& callback
,
337 const std::string
& data
,
338 ServiceWorkerDatabase::Status status
);
339 void DidDeleteUserData(
340 const StatusCallback
& callback
,
341 ServiceWorkerDatabase::Status status
);
342 void DidGetUserDataForAllRegistrations(
343 const GetUserDataForAllRegistrationsCallback
& callback
,
344 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
345 ServiceWorkerDatabase::Status status
);
346 void ReturnFoundRegistration(
347 const FindRegistrationCallback
& callback
,
348 const ServiceWorkerDatabase::RegistrationData
& data
,
349 const ResourceList
& resources
);
351 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
352 const ServiceWorkerDatabase::RegistrationData
& data
,
353 const ResourceList
& resources
);
354 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
355 const GURL
& document_url
);
356 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
358 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
359 int64 registration_id
);
361 // Lazy disk_cache getter.
362 ServiceWorkerDiskCache
* disk_cache();
363 void OnDiskCacheInitialized(int rv
);
365 void StartPurgingResources(const std::vector
<int64
>& ids
);
366 void StartPurgingResources(const ResourceList
& resources
);
367 void ContinuePurgingResources();
368 void PurgeResource(int64 id
);
369 void OnResourcePurged(int64 id
, int rv
);
371 // Deletes purgeable and uncommitted resources left over from the previous
372 // browser session. This must be called once per session before any database
373 // operation that may mutate the purgeable or uncommitted resource lists.
374 void DeleteStaleResources();
375 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
376 ServiceWorkerDatabase::Status status
);
378 void ClearSessionOnlyOrigins();
380 // Static cross-thread helpers.
381 static void CollectStaleResourcesFromDB(
382 ServiceWorkerDatabase
* database
,
383 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
384 const GetResourcesCallback
& callback
);
385 static void ReadInitialDataFromDB(
386 ServiceWorkerDatabase
* database
,
387 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
388 const InitializeCallback
& callback
);
389 static void DeleteRegistrationFromDB(
390 ServiceWorkerDatabase
* database
,
391 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
392 int64 registration_id
,
394 const DeleteRegistrationCallback
& callback
);
395 static void WriteRegistrationInDB(
396 ServiceWorkerDatabase
* database
,
397 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
398 const ServiceWorkerDatabase::RegistrationData
& registration
,
399 const ResourceList
& resources
,
400 const WriteRegistrationCallback
& callback
);
401 static void FindForDocumentInDB(
402 ServiceWorkerDatabase
* database
,
403 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
404 const GURL
& document_url
,
405 const FindInDBCallback
& callback
);
406 static void FindForPatternInDB(
407 ServiceWorkerDatabase
* database
,
408 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
410 const FindInDBCallback
& callback
);
411 static void FindForIdInDB(
412 ServiceWorkerDatabase
* database
,
413 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
414 int64 registration_id
,
416 const FindInDBCallback
& callback
);
417 static void FindForIdOnlyInDB(
418 ServiceWorkerDatabase
* database
,
419 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
420 int64 registration_id
,
421 const FindInDBCallback
& callback
);
422 static void GetUserDataInDB(
423 ServiceWorkerDatabase
* database
,
424 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
425 int64 registration_id
,
426 const std::string
& key
,
427 const GetUserDataInDBCallback
& callback
);
428 static void GetUserDataForAllRegistrationsInDB(
429 ServiceWorkerDatabase
* database
,
430 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
431 const std::string
& key
,
432 const GetUserDataForAllRegistrationsInDBCallback
& callback
);
433 static void DeleteAllDataForOriginsFromDB(
434 ServiceWorkerDatabase
* database
,
435 const std::set
<GURL
>& origins
);
437 void ScheduleDeleteAndStartOver();
438 void DidDeleteDatabase(
439 const StatusCallback
& callback
,
440 ServiceWorkerDatabase::Status status
);
441 void DidDeleteDiskCache(
442 const StatusCallback
& callback
,
445 // For finding registrations being installed or uninstalled.
446 RegistrationRefsById installing_registrations_
;
447 RegistrationRefsById uninstalling_registrations_
;
449 // Origins having registations.
450 std::set
<GURL
> registered_origins_
;
452 // Pending database tasks waiting for initialization.
453 std::vector
<base::Closure
> pending_tasks_
;
455 int64 next_registration_id_
;
456 int64 next_version_id_
;
457 int64 next_resource_id_
;
467 base::FilePath path_
;
468 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
470 // Only accessed using |database_task_manager_|.
471 scoped_ptr
<ServiceWorkerDatabase
> database_
;
473 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager_
;
474 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
475 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
476 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
477 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
478 std::deque
<int64
> purgeable_resource_ids_
;
479 bool is_purge_pending_
;
480 bool has_checked_for_stale_resources_
;
481 std::set
<int64
> pending_deletions_
;
483 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
485 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
488 } // namespace content
490 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_