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 ServiceWorkerResponseMetadataWriter
;
42 class ServiceWorkerResponseReader
;
43 class ServiceWorkerResponseWriter
;
44 struct ServiceWorkerRegistrationInfo
;
46 // This class provides an interface to store and retrieve ServiceWorker
48 class CONTENT_EXPORT ServiceWorkerStorage
49 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener
) {
51 typedef std::vector
<ServiceWorkerDatabase::ResourceRecord
> ResourceList
;
52 typedef base::Callback
<void(ServiceWorkerStatusCode status
)> StatusCallback
;
53 typedef base::Callback
<void(ServiceWorkerStatusCode status
,
54 const scoped_refptr
<ServiceWorkerRegistration
>&
55 registration
)> FindRegistrationCallback
;
56 typedef base::Callback
<
57 void(const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
)>
58 GetRegistrationsInfosCallback
;
59 typedef base::Callback
<
60 void(ServiceWorkerStatusCode status
, bool are_equal
)>
62 typedef base::Callback
<
63 void(const std::string
& data
, ServiceWorkerStatusCode status
)>
65 typedef base::Callback
<void(
66 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
67 ServiceWorkerStatusCode status
)>
68 GetUserDataForAllRegistrationsCallback
;
70 ~ServiceWorkerStorage() override
;
72 static scoped_ptr
<ServiceWorkerStorage
> Create(
73 const base::FilePath
& path
,
74 base::WeakPtr
<ServiceWorkerContextCore
> context
,
75 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
76 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
77 storage::QuotaManagerProxy
* quota_manager_proxy
,
78 storage::SpecialStoragePolicy
* special_storage_policy
);
80 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
81 static scoped_ptr
<ServiceWorkerStorage
> Create(
82 base::WeakPtr
<ServiceWorkerContextCore
> context
,
83 ServiceWorkerStorage
* old_storage
);
85 // Finds registration for |document_url| or |pattern| or |registration_id|.
86 // The Find methods will find stored and initially installing registrations.
87 // Returns SERVICE_WORKER_OK with non-null registration if registration
88 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
89 // registration is found. The FindRegistrationForPattern method is
90 // guaranteed to return asynchronously. However, the methods to find
91 // for |document_url| or |registration_id| may complete immediately
92 // (the callback may be called prior to the method returning) or
94 void FindRegistrationForDocument(const GURL
& document_url
,
95 const FindRegistrationCallback
& callback
);
96 void FindRegistrationForPattern(const GURL
& scope
,
97 const FindRegistrationCallback
& callback
);
98 void FindRegistrationForId(int64 registration_id
,
100 const FindRegistrationCallback
& callback
);
102 // Generally |FindRegistrationForId| should be used to look up a registration
103 // by |registration_id| since it's more efficient. But if a |registration_id|
104 // is all that is available this method can be used instead.
105 // Like |FindRegistrationForId| this method may complete immediately (the
106 // callback may be called prior to the method returning) or asynchronously.
107 void FindRegistrationForIdOnly(int64 registration_id
,
108 const FindRegistrationCallback
& callback
);
110 ServiceWorkerRegistration
* GetUninstallingRegistration(const GURL
& scope
);
112 // Returns info about all stored and initially installing registrations for
114 void GetRegistrationsForOrigin(
115 const GURL
& origin
, const GetRegistrationsInfosCallback
& callback
);
117 // Returns info about all stored and initially installing registrations.
118 void GetAllRegistrations(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 // Compares only the response bodies.
160 void CompareScriptResources(int64 lhs_id
, int64 rhs_id
,
161 const CompareCallback
& callback
);
163 // Provide a storage mechanism to read/write arbitrary data associated with
164 // a registration. Each registration has its own key namespace. Stored data
165 // is deleted when the associated registraton is deleted.
166 void GetUserData(int64 registration_id
,
167 const std::string
& key
,
168 const GetUserDataCallback
& callback
);
169 void StoreUserData(int64 registration_id
,
171 const std::string
& key
,
172 const std::string
& data
,
173 const StatusCallback
& callback
);
174 void ClearUserData(int64 registration_id
,
175 const std::string
& key
,
176 const StatusCallback
& callback
);
177 // Returns all registrations that have user data with a particular key, as
178 // well as that user data.
179 void GetUserDataForAllRegistrations(
180 const std::string
& key
,
181 const GetUserDataForAllRegistrationsCallback
& callback
);
183 // Deletes the storage and starts over.
184 void DeleteAndStartOver(const StatusCallback
& callback
);
186 // Returns new IDs which are guaranteed to be unique in the storage.
187 int64
NewRegistrationId();
188 int64
NewVersionId();
189 int64
NewResourceId();
191 // Intended for use only by ServiceWorkerRegisterJob and
192 // ServiceWorkerRegistration.
193 void NotifyInstallingRegistration(
194 ServiceWorkerRegistration
* registration
);
195 void NotifyDoneInstallingRegistration(
196 ServiceWorkerRegistration
* registration
,
197 ServiceWorkerVersion
* version
,
198 ServiceWorkerStatusCode status
);
199 void NotifyUninstallingRegistration(ServiceWorkerRegistration
* registration
);
200 void NotifyDoneUninstallingRegistration(
201 ServiceWorkerRegistration
* registration
);
204 bool IsDisabled() const;
206 // |resources| must already be on the purgeable list.
207 void PurgeResources(const ResourceList
& resources
);
210 friend class ServiceWorkerHandleTest
;
211 friend class ServiceWorkerStorageTest
;
212 friend class ServiceWorkerResourceStorageTest
;
213 friend class ServiceWorkerControlleeRequestHandlerTest
;
214 friend class ServiceWorkerContextRequestHandlerTest
;
215 friend class ServiceWorkerRequestHandlerTest
;
216 friend class ServiceWorkerURLRequestJobTest
;
217 friend class ServiceWorkerVersionBrowserTest
;
218 friend class ServiceWorkerVersionTest
;
219 friend class ServiceWorkerWriteToCacheJobTest
;
220 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest
,
221 CleanupOnRendererCrash
);
222 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
223 DeleteRegistration_NoLiveVersion
);
224 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
225 DeleteRegistration_WaitingVersion
);
226 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
227 DeleteRegistration_ActiveVersion
);
228 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
230 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
232 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
236 int64 next_registration_id
;
237 int64 next_version_id
;
238 int64 next_resource_id
;
239 std::set
<GURL
> origins
;
245 // Because there are too many params for base::Bind to wrap a closure around.
246 struct DidDeleteRegistrationParams
{
247 int64 registration_id
;
249 StatusCallback callback
;
251 DidDeleteRegistrationParams();
252 ~DidDeleteRegistrationParams();
255 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
256 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
257 RegistrationRefsById
;
258 typedef base::Callback
<void(
260 ServiceWorkerDatabase::Status status
)> InitializeCallback
;
261 typedef base::Callback
<void(
263 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
264 const std::vector
<int64
>& newly_purgeable_resources
,
265 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
266 typedef base::Callback
<void(
267 bool origin_is_deletable
,
268 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
269 const std::vector
<int64
>& newly_purgeable_resources
,
270 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
271 typedef base::Callback
<void(
272 const ServiceWorkerDatabase::RegistrationData
& data
,
273 const ResourceList
& resources
,
274 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
275 typedef base::Callback
<void(
276 const std::string
& data
,
277 ServiceWorkerDatabase::Status
)> GetUserDataInDBCallback
;
278 typedef base::Callback
<void(
279 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
280 ServiceWorkerDatabase::Status
)>
281 GetUserDataForAllRegistrationsInDBCallback
;
282 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
283 ServiceWorkerDatabase::Status status
)>
284 GetResourcesCallback
;
286 ServiceWorkerStorage(
287 const base::FilePath
& path
,
288 base::WeakPtr
<ServiceWorkerContextCore
> context
,
289 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
290 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
291 storage::QuotaManagerProxy
* quota_manager_proxy
,
292 storage::SpecialStoragePolicy
* special_storage_policy
);
294 base::FilePath
GetDatabasePath();
295 base::FilePath
GetDiskCachePath();
297 // Loads the registration data from backend storage. This must be called
298 // before any method that requires registration data.
300 const base::Closure
& callback
);
301 void DidReadInitialData(
303 ServiceWorkerDatabase::Status status
);
304 void DidFindRegistrationForDocument(
305 const GURL
& document_url
,
306 const FindRegistrationCallback
& callback
,
308 const ServiceWorkerDatabase::RegistrationData
& data
,
309 const ResourceList
& resources
,
310 ServiceWorkerDatabase::Status status
);
311 void DidFindRegistrationForPattern(
313 const FindRegistrationCallback
& callback
,
314 const ServiceWorkerDatabase::RegistrationData
& data
,
315 const ResourceList
& resources
,
316 ServiceWorkerDatabase::Status status
);
317 void DidFindRegistrationForId(
318 const FindRegistrationCallback
& callback
,
319 const ServiceWorkerDatabase::RegistrationData
& data
,
320 const ResourceList
& resources
,
321 ServiceWorkerDatabase::Status status
);
322 void DidGetRegistrations(
323 const GetRegistrationsInfosCallback
& callback
,
324 RegistrationList
* registrations
,
325 const GURL
& origin_filter
,
326 ServiceWorkerDatabase::Status status
);
327 void DidStoreRegistration(
328 const StatusCallback
& callback
,
329 const ServiceWorkerDatabase::RegistrationData
& new_version
,
331 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
332 const std::vector
<int64
>& newly_purgeable_resources
,
333 ServiceWorkerDatabase::Status status
);
334 void DidUpdateToActiveState(
335 const StatusCallback
& callback
,
336 ServiceWorkerDatabase::Status status
);
337 void DidDeleteRegistration(
338 const DidDeleteRegistrationParams
& params
,
339 bool origin_is_deletable
,
340 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
341 const std::vector
<int64
>& newly_purgeable_resources
,
342 ServiceWorkerDatabase::Status status
);
343 void DidStoreUserData(
344 const StatusCallback
& callback
,
345 ServiceWorkerDatabase::Status status
);
347 const GetUserDataCallback
& callback
,
348 const std::string
& data
,
349 ServiceWorkerDatabase::Status status
);
350 void DidDeleteUserData(
351 const StatusCallback
& callback
,
352 ServiceWorkerDatabase::Status status
);
353 void DidGetUserDataForAllRegistrations(
354 const GetUserDataForAllRegistrationsCallback
& callback
,
355 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
356 ServiceWorkerDatabase::Status status
);
357 void ReturnFoundRegistration(
358 const FindRegistrationCallback
& callback
,
359 const ServiceWorkerDatabase::RegistrationData
& data
,
360 const ResourceList
& resources
);
362 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
363 const ServiceWorkerDatabase::RegistrationData
& data
,
364 const ResourceList
& resources
);
365 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
366 const GURL
& document_url
);
367 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
369 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
370 int64 registration_id
);
372 // Lazy disk_cache getter.
373 ServiceWorkerDiskCache
* disk_cache();
374 void OnDiskCacheInitialized(int rv
);
376 void StartPurgingResources(const std::vector
<int64
>& ids
);
377 void StartPurgingResources(const ResourceList
& resources
);
378 void ContinuePurgingResources();
379 void PurgeResource(int64 id
);
380 void OnResourcePurged(int64 id
, int rv
);
382 // Deletes purgeable and uncommitted resources left over from the previous
383 // browser session. This must be called once per session before any database
384 // operation that may mutate the purgeable or uncommitted resource lists.
385 void DeleteStaleResources();
386 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
387 ServiceWorkerDatabase::Status status
);
389 void ClearSessionOnlyOrigins();
391 // Static cross-thread helpers.
392 static void CollectStaleResourcesFromDB(
393 ServiceWorkerDatabase
* database
,
394 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
395 const GetResourcesCallback
& callback
);
396 static void ReadInitialDataFromDB(
397 ServiceWorkerDatabase
* database
,
398 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
399 const InitializeCallback
& callback
);
400 static void DeleteRegistrationFromDB(
401 ServiceWorkerDatabase
* database
,
402 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
403 int64 registration_id
,
405 const DeleteRegistrationCallback
& callback
);
406 static void WriteRegistrationInDB(
407 ServiceWorkerDatabase
* database
,
408 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
409 const ServiceWorkerDatabase::RegistrationData
& registration
,
410 const ResourceList
& resources
,
411 const WriteRegistrationCallback
& callback
);
412 static void FindForDocumentInDB(
413 ServiceWorkerDatabase
* database
,
414 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
415 const GURL
& document_url
,
416 const FindInDBCallback
& callback
);
417 static void FindForPatternInDB(
418 ServiceWorkerDatabase
* database
,
419 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
421 const FindInDBCallback
& callback
);
422 static void FindForIdInDB(
423 ServiceWorkerDatabase
* database
,
424 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
425 int64 registration_id
,
427 const FindInDBCallback
& callback
);
428 static void FindForIdOnlyInDB(
429 ServiceWorkerDatabase
* database
,
430 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
431 int64 registration_id
,
432 const FindInDBCallback
& callback
);
433 static void GetUserDataInDB(
434 ServiceWorkerDatabase
* database
,
435 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
436 int64 registration_id
,
437 const std::string
& key
,
438 const GetUserDataInDBCallback
& callback
);
439 static void GetUserDataForAllRegistrationsInDB(
440 ServiceWorkerDatabase
* database
,
441 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
442 const std::string
& key
,
443 const GetUserDataForAllRegistrationsInDBCallback
& callback
);
444 static void DeleteAllDataForOriginsFromDB(
445 ServiceWorkerDatabase
* database
,
446 const std::set
<GURL
>& origins
);
448 void ScheduleDeleteAndStartOver();
449 void DidDeleteDatabase(
450 const StatusCallback
& callback
,
451 ServiceWorkerDatabase::Status status
);
452 void DidDeleteDiskCache(
453 const StatusCallback
& callback
,
456 // For finding registrations being installed or uninstalled.
457 RegistrationRefsById installing_registrations_
;
458 RegistrationRefsById uninstalling_registrations_
;
460 // Origins having registations.
461 std::set
<GURL
> registered_origins_
;
463 // Pending database tasks waiting for initialization.
464 std::vector
<base::Closure
> pending_tasks_
;
466 int64 next_registration_id_
;
467 int64 next_version_id_
;
468 int64 next_resource_id_
;
478 base::FilePath path_
;
479 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
481 // Only accessed using |database_task_manager_|.
482 scoped_ptr
<ServiceWorkerDatabase
> database_
;
484 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager_
;
485 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
486 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
487 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
488 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
489 std::deque
<int64
> purgeable_resource_ids_
;
490 bool is_purge_pending_
;
491 bool has_checked_for_stale_resources_
;
492 std::set
<int64
> pending_deletions_
;
494 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
496 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
499 } // namespace content
501 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_