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/weak_ptr.h"
18 #include "content/browser/service_worker/service_worker_database.h"
19 #include "content/browser/service_worker/service_worker_database_task_manager.h"
20 #include "content/browser/service_worker/service_worker_metrics.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 ServiceWorkerDiskCacheMigrator
;
41 class ServiceWorkerRegistration
;
42 class ServiceWorkerResponseMetadataWriter
;
43 class ServiceWorkerResponseReader
;
44 class ServiceWorkerResponseWriter
;
45 struct ServiceWorkerRegistrationInfo
;
47 // This class provides an interface to store and retrieve ServiceWorker
48 // registration data. The lifetime is equal to ServiceWorkerContextCore that is
49 // an owner of this class.
50 class CONTENT_EXPORT ServiceWorkerStorage
51 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener
) {
53 typedef std::vector
<ServiceWorkerDatabase::ResourceRecord
> ResourceList
;
54 typedef base::Callback
<void(ServiceWorkerStatusCode status
)> StatusCallback
;
55 typedef base::Callback
<void(ServiceWorkerStatusCode status
,
56 const scoped_refptr
<ServiceWorkerRegistration
>&
57 registration
)> FindRegistrationCallback
;
58 typedef base::Callback
<void(
59 const std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>&
60 registrations
)> GetRegistrationsCallback
;
61 typedef base::Callback
<void(const std::vector
<ServiceWorkerRegistrationInfo
>&
62 registrations
)> GetRegistrationsInfosCallback
;
63 typedef base::Callback
<
64 void(const std::string
& data
, ServiceWorkerStatusCode status
)>
66 typedef base::Callback
<void(
67 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
68 ServiceWorkerStatusCode status
)>
69 GetUserDataForAllRegistrationsCallback
;
71 ~ServiceWorkerStorage() override
;
73 static scoped_ptr
<ServiceWorkerStorage
> Create(
74 const base::FilePath
& path
,
75 const base::WeakPtr
<ServiceWorkerContextCore
>& context
,
76 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
77 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
78 storage::QuotaManagerProxy
* quota_manager_proxy
,
79 storage::SpecialStoragePolicy
* special_storage_policy
);
81 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
82 static scoped_ptr
<ServiceWorkerStorage
> Create(
83 const base::WeakPtr
<ServiceWorkerContextCore
>& context
,
84 ServiceWorkerStorage
* old_storage
);
86 // Finds registration for |document_url| or |pattern| or |registration_id|.
87 // The Find methods will find stored and initially installing registrations.
88 // Returns SERVICE_WORKER_OK with non-null registration if registration
89 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
90 // registration is found. The FindRegistrationForPattern method is
91 // guaranteed to return asynchronously. However, the methods to find
92 // for |document_url| or |registration_id| may complete immediately
93 // (the callback may be called prior to the method returning) or
95 void FindRegistrationForDocument(const GURL
& document_url
,
96 const FindRegistrationCallback
& callback
);
97 void FindRegistrationForPattern(const GURL
& scope
,
98 const FindRegistrationCallback
& callback
);
99 void FindRegistrationForId(int64 registration_id
,
101 const FindRegistrationCallback
& callback
);
103 // Generally |FindRegistrationForId| should be used to look up a registration
104 // by |registration_id| since it's more efficient. But if a |registration_id|
105 // is all that is available this method can be used instead.
106 // Like |FindRegistrationForId| this method may complete immediately (the
107 // callback may be called prior to the method returning) or asynchronously.
108 void FindRegistrationForIdOnly(int64 registration_id
,
109 const FindRegistrationCallback
& callback
);
111 ServiceWorkerRegistration
* GetUninstallingRegistration(const GURL
& scope
);
113 // Returns all stored registrations for a given origin.
114 void GetRegistrationsForOrigin(const GURL
& origin
,
115 const GetRegistrationsCallback
& callback
);
117 // Returns info about all stored and initially installing registrations.
118 void GetAllRegistrationsInfos(const GetRegistrationsInfosCallback
& callback
);
120 // Commits |registration| with the installed but not activated |version|
121 // to storage, overwritting any pre-existing registration data for the scope.
122 // A pre-existing version's script resources remain available if that version
123 // is live. PurgeResources should be called when it's OK to delete them.
124 void StoreRegistration(ServiceWorkerRegistration
* registration
,
125 ServiceWorkerVersion
* version
,
126 const StatusCallback
& callback
);
128 // Updates the state of the registration's stored version to active.
129 void UpdateToActiveState(
130 ServiceWorkerRegistration
* registration
,
131 const StatusCallback
& callback
);
133 // Updates the stored time to match the value of
134 // registration->last_update_check().
135 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
);
137 // Deletes the registration data for |registration_id|. If the registration's
138 // version is live, its script resources will remain available.
139 // PurgeResources should be called when it's OK to delete them.
140 void DeleteRegistration(int64 registration_id
,
142 const StatusCallback
& callback
);
144 scoped_ptr
<ServiceWorkerResponseReader
> CreateResponseReader(
146 scoped_ptr
<ServiceWorkerResponseWriter
> CreateResponseWriter(
148 scoped_ptr
<ServiceWorkerResponseMetadataWriter
> CreateResponseMetadataWriter(
151 // Adds |id| to the set of resources ids that are in the disk
152 // cache but not yet stored with a registration.
153 void StoreUncommittedResponseId(int64 id
);
155 // Removes |id| from uncommitted list, adds it to the
156 // purgeable list and purges it.
157 void DoomUncommittedResponse(int64 id
);
159 // Provide a storage mechanism to read/write arbitrary data associated with
160 // a registration. Each registration has its own key namespace. Stored data
161 // is deleted when the associated registraton is deleted.
162 void GetUserData(int64 registration_id
,
163 const std::string
& key
,
164 const GetUserDataCallback
& callback
);
165 void StoreUserData(int64 registration_id
,
167 const std::string
& key
,
168 const std::string
& data
,
169 const StatusCallback
& callback
);
170 void ClearUserData(int64 registration_id
,
171 const std::string
& key
,
172 const StatusCallback
& callback
);
173 // Returns all registrations that have user data with a particular key, as
174 // well as that user data.
175 void GetUserDataForAllRegistrations(
176 const std::string
& key
,
177 const GetUserDataForAllRegistrationsCallback
& callback
);
179 // Deletes the storage and starts over.
180 void DeleteAndStartOver(const StatusCallback
& callback
);
182 // Returns new IDs which are guaranteed to be unique in the storage.
183 int64
NewRegistrationId();
184 int64
NewVersionId();
185 int64
NewResourceId();
187 // Intended for use only by ServiceWorkerRegisterJob and
188 // ServiceWorkerRegistration.
189 void NotifyInstallingRegistration(
190 ServiceWorkerRegistration
* registration
);
191 void NotifyDoneInstallingRegistration(
192 ServiceWorkerRegistration
* registration
,
193 ServiceWorkerVersion
* version
,
194 ServiceWorkerStatusCode status
);
195 void NotifyUninstallingRegistration(ServiceWorkerRegistration
* registration
);
196 void NotifyDoneUninstallingRegistration(
197 ServiceWorkerRegistration
* registration
);
200 bool IsDisabled() const;
202 // |resources| must already be on the purgeable list.
203 void PurgeResources(const ResourceList
& resources
);
206 friend class ServiceWorkerHandleTest
;
207 friend class ServiceWorkerStorageTest
;
208 friend class ServiceWorkerResourceStorageTest
;
209 friend class ServiceWorkerControlleeRequestHandlerTest
;
210 friend class ServiceWorkerContextRequestHandlerTest
;
211 friend class ServiceWorkerDiskCacheMigratorTest
;
212 friend class ServiceWorkerRequestHandlerTest
;
213 friend class ServiceWorkerURLRequestJobTest
;
214 friend class ServiceWorkerVersionBrowserTest
;
215 friend class ServiceWorkerVersionTest
;
216 friend class ServiceWorkerWriteToCacheJobTest
;
217 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest
,
218 MigrateOnDiskCacheAccess
);
219 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest
,
220 NotMigrateOnDatabaseAccess
);
221 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest
,
222 NotMigrateForEmptyDatabase
);
223 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest
,
224 CleanupOnRendererCrash
);
225 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
226 DeleteRegistration_NoLiveVersion
);
227 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
228 DeleteRegistration_WaitingVersion
);
229 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
230 DeleteRegistration_ActiveVersion
);
231 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
233 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
235 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
237 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
239 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
240 DeleteAndStartOver_UnrelatedFileExists
);
241 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
242 DeleteAndStartOver_OpenedFileExists
);
245 int64 next_registration_id
;
246 int64 next_version_id
;
247 int64 next_resource_id
;
248 std::set
<GURL
> origins
;
249 bool disk_cache_migration_needed
;
250 bool old_disk_cache_deletion_needed
;
256 // Because there are too many params for base::Bind to wrap a closure around.
257 struct DidDeleteRegistrationParams
{
258 int64 registration_id
;
260 StatusCallback callback
;
262 DidDeleteRegistrationParams();
263 ~DidDeleteRegistrationParams();
266 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
267 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
268 RegistrationRefsById
;
269 typedef base::Callback
<void(scoped_ptr
<InitialData
> data
,
270 ServiceWorkerDatabase::Status status
)>
272 typedef base::Callback
<void(ServiceWorkerDatabase::Status status
)>
273 DatabaseStatusCallback
;
274 typedef base::Callback
<void(
276 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
277 const std::vector
<int64
>& newly_purgeable_resources
,
278 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
279 typedef base::Callback
<void(
280 bool origin_is_deletable
,
281 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
282 const std::vector
<int64
>& newly_purgeable_resources
,
283 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
284 typedef base::Callback
<void(
285 const ServiceWorkerDatabase::RegistrationData
& data
,
286 const ResourceList
& resources
,
287 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
288 typedef base::Callback
<void(
289 const std::string
& data
,
290 ServiceWorkerDatabase::Status
)> GetUserDataInDBCallback
;
291 typedef base::Callback
<void(
292 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
293 ServiceWorkerDatabase::Status
)>
294 GetUserDataForAllRegistrationsInDBCallback
;
295 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
296 ServiceWorkerDatabase::Status status
)>
297 GetResourcesCallback
;
299 ServiceWorkerStorage(
300 const base::FilePath
& path
,
301 base::WeakPtr
<ServiceWorkerContextCore
> context
,
302 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
303 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
304 storage::QuotaManagerProxy
* quota_manager_proxy
,
305 storage::SpecialStoragePolicy
* special_storage_policy
);
307 base::FilePath
GetDatabasePath();
308 base::FilePath
GetDiskCachePath();
310 // Returns a path to an old diskcache backed with BlockFile. This is used for
311 // the diskcache migration (see service_worker_disk_cache_migrator.h).
312 // TODO(nhiroki): Remove this after several milestones pass
313 // (http://crbug.com/487482)
314 base::FilePath
GetOldDiskCachePath();
317 const base::Closure
& callback
);
318 void DidReadInitialData(scoped_ptr
<InitialData
> data
,
319 ServiceWorkerDatabase::Status status
);
320 void DidFindRegistrationForDocument(
321 const GURL
& document_url
,
322 const FindRegistrationCallback
& callback
,
324 const ServiceWorkerDatabase::RegistrationData
& data
,
325 const ResourceList
& resources
,
326 ServiceWorkerDatabase::Status status
);
327 void DidFindRegistrationForPattern(
329 const FindRegistrationCallback
& callback
,
330 const ServiceWorkerDatabase::RegistrationData
& data
,
331 const ResourceList
& resources
,
332 ServiceWorkerDatabase::Status status
);
333 void DidFindRegistrationForId(
334 const FindRegistrationCallback
& callback
,
335 const ServiceWorkerDatabase::RegistrationData
& data
,
336 const ResourceList
& resources
,
337 ServiceWorkerDatabase::Status status
);
338 void DidGetRegistrations(const GetRegistrationsCallback
& callback
,
339 RegistrationList
* registration_data_list
,
340 std::vector
<ResourceList
>* resources_list
,
341 const GURL
& origin_filter
,
342 ServiceWorkerDatabase::Status status
);
343 void DidGetRegistrationsInfos(const GetRegistrationsInfosCallback
& callback
,
344 RegistrationList
* registration_data_list
,
345 const GURL
& origin_filter
,
346 ServiceWorkerDatabase::Status status
);
347 void DidStoreRegistration(
348 const StatusCallback
& callback
,
349 const ServiceWorkerDatabase::RegistrationData
& new_version
,
351 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
352 const std::vector
<int64
>& newly_purgeable_resources
,
353 ServiceWorkerDatabase::Status status
);
354 void DidUpdateToActiveState(
355 const StatusCallback
& callback
,
356 ServiceWorkerDatabase::Status status
);
357 void DidDeleteRegistration(
358 const DidDeleteRegistrationParams
& params
,
359 bool origin_is_deletable
,
360 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
361 const std::vector
<int64
>& newly_purgeable_resources
,
362 ServiceWorkerDatabase::Status status
);
363 void DidStoreUserData(
364 const StatusCallback
& callback
,
365 ServiceWorkerDatabase::Status status
);
367 const GetUserDataCallback
& callback
,
368 const std::string
& data
,
369 ServiceWorkerDatabase::Status status
);
370 void DidDeleteUserData(
371 const StatusCallback
& callback
,
372 ServiceWorkerDatabase::Status status
);
373 void DidGetUserDataForAllRegistrations(
374 const GetUserDataForAllRegistrationsCallback
& callback
,
375 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
376 ServiceWorkerDatabase::Status status
);
377 void ReturnFoundRegistration(
378 const FindRegistrationCallback
& callback
,
379 const ServiceWorkerDatabase::RegistrationData
& data
,
380 const ResourceList
& resources
);
382 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
383 const ServiceWorkerDatabase::RegistrationData
& data
,
384 const ResourceList
& resources
);
385 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
386 const GURL
& document_url
);
387 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
389 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
390 int64 registration_id
);
392 // Lazy disk_cache getter.
393 ServiceWorkerDiskCache
* disk_cache();
394 void MigrateDiskCache();
395 void DidMigrateDiskCache(ServiceWorkerStatusCode status
);
396 void DidSetDiskCacheMigrationNotNeeded(ServiceWorkerDatabase::Status status
);
397 void OnDiskCacheMigrationFailed(
398 ServiceWorkerMetrics::DiskCacheMigrationResult result
);
399 void InitializeDiskCache();
400 void OnDiskCacheInitialized(int rv
);
402 void DeleteOldDiskCache();
404 void StartPurgingResources(const std::vector
<int64
>& ids
);
405 void StartPurgingResources(const ResourceList
& resources
);
406 void ContinuePurgingResources();
407 void PurgeResource(int64 id
);
408 void OnResourcePurged(int64 id
, int rv
);
410 // Deletes purgeable and uncommitted resources left over from the previous
411 // browser session. This must be called once per session before any database
412 // operation that may mutate the purgeable or uncommitted resource lists.
413 void DeleteStaleResources();
414 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
415 ServiceWorkerDatabase::Status status
);
417 void ClearSessionOnlyOrigins();
419 // Static cross-thread helpers.
420 static void CollectStaleResourcesFromDB(
421 ServiceWorkerDatabase
* database
,
422 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
423 const GetResourcesCallback
& callback
);
424 static void ReadInitialDataFromDB(
425 ServiceWorkerDatabase
* database
,
426 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
427 const InitializeCallback
& callback
);
428 static void DeleteOldDiskCacheInDB(ServiceWorkerDatabase
* database
,
429 const base::FilePath
& disk_cache_path
);
430 static void DeleteRegistrationFromDB(
431 ServiceWorkerDatabase
* database
,
432 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
433 int64 registration_id
,
435 const DeleteRegistrationCallback
& callback
);
436 static void WriteRegistrationInDB(
437 ServiceWorkerDatabase
* database
,
438 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
439 const ServiceWorkerDatabase::RegistrationData
& registration
,
440 const ResourceList
& resources
,
441 const WriteRegistrationCallback
& callback
);
442 static void FindForDocumentInDB(
443 ServiceWorkerDatabase
* database
,
444 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
445 const GURL
& document_url
,
446 const FindInDBCallback
& callback
);
447 static void FindForPatternInDB(
448 ServiceWorkerDatabase
* database
,
449 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
451 const FindInDBCallback
& callback
);
452 static void FindForIdInDB(
453 ServiceWorkerDatabase
* database
,
454 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
455 int64 registration_id
,
457 const FindInDBCallback
& callback
);
458 static void FindForIdOnlyInDB(
459 ServiceWorkerDatabase
* database
,
460 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
461 int64 registration_id
,
462 const FindInDBCallback
& callback
);
463 static void GetUserDataInDB(
464 ServiceWorkerDatabase
* database
,
465 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
466 int64 registration_id
,
467 const std::string
& key
,
468 const GetUserDataInDBCallback
& callback
);
469 static void GetUserDataForAllRegistrationsInDB(
470 ServiceWorkerDatabase
* database
,
471 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
472 const std::string
& key
,
473 const GetUserDataForAllRegistrationsInDBCallback
& callback
);
474 static void DeleteAllDataForOriginsFromDB(
475 ServiceWorkerDatabase
* database
,
476 const std::set
<GURL
>& origins
);
478 void ScheduleDeleteAndStartOver();
479 void DidDeleteDatabase(
480 const StatusCallback
& callback
,
481 ServiceWorkerDatabase::Status status
);
482 void DidDeleteDiskCache(
483 const StatusCallback
& callback
,
486 // For finding registrations being installed or uninstalled.
487 RegistrationRefsById installing_registrations_
;
488 RegistrationRefsById uninstalling_registrations_
;
490 // Origins having registations.
491 std::set
<GURL
> registered_origins_
;
493 // Pending database tasks waiting for initialization.
494 std::vector
<base::Closure
> pending_tasks_
;
496 int64 next_registration_id_
;
497 int64 next_version_id_
;
498 int64 next_resource_id_
;
508 base::FilePath path_
;
510 // The context should be valid while the storage is alive.
511 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
513 // Only accessed using |database_task_manager_|.
514 scoped_ptr
<ServiceWorkerDatabase
> database_
;
516 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager_
;
517 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
518 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
519 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
521 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
522 scoped_ptr
<ServiceWorkerDiskCacheMigrator
> disk_cache_migrator_
;
523 bool disk_cache_migration_needed_
;
524 bool old_disk_cache_deletion_needed_
;
526 std::deque
<int64
> purgeable_resource_ids_
;
527 bool is_purge_pending_
;
528 bool has_checked_for_stale_resources_
;
529 std::set
<int64
> pending_deletions_
;
531 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
533 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
536 } // namespace content
538 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_