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 ServiceWorkerResponseMetadataWriter
;
43 class ServiceWorkerResponseReader
;
44 class ServiceWorkerResponseWriter
;
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 ServiceWorkerStorageTest
;
211 friend class ServiceWorkerResourceStorageTest
;
212 friend class ServiceWorkerControlleeRequestHandlerTest
;
213 friend class ServiceWorkerContextRequestHandlerTest
;
214 friend class ServiceWorkerRequestHandlerTest
;
215 friend class ServiceWorkerWriteToCacheJobTest
;
216 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
217 DeleteRegistration_NoLiveVersion
);
218 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
219 DeleteRegistration_WaitingVersion
);
220 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
221 DeleteRegistration_ActiveVersion
);
222 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
224 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
226 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
230 int64 next_registration_id
;
231 int64 next_version_id
;
232 int64 next_resource_id
;
233 std::set
<GURL
> origins
;
239 // Because there are too many params for base::Bind to wrap a closure around.
240 struct DidDeleteRegistrationParams
{
241 int64 registration_id
;
243 StatusCallback callback
;
245 DidDeleteRegistrationParams();
246 ~DidDeleteRegistrationParams();
249 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
250 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
251 RegistrationRefsById
;
252 typedef base::Callback
<void(
254 ServiceWorkerDatabase::Status status
)> InitializeCallback
;
255 typedef base::Callback
<void(
257 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
258 const std::vector
<int64
>& newly_purgeable_resources
,
259 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
260 typedef base::Callback
<void(
261 bool origin_is_deletable
,
262 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
263 const std::vector
<int64
>& newly_purgeable_resources
,
264 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
265 typedef base::Callback
<void(
266 const ServiceWorkerDatabase::RegistrationData
& data
,
267 const ResourceList
& resources
,
268 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
269 typedef base::Callback
<void(
270 const std::string
& data
,
271 ServiceWorkerDatabase::Status
)> GetUserDataInDBCallback
;
272 typedef base::Callback
<void(
273 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
274 ServiceWorkerDatabase::Status
)>
275 GetUserDataForAllRegistrationsInDBCallback
;
276 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
277 ServiceWorkerDatabase::Status status
)>
278 GetResourcesCallback
;
280 ServiceWorkerStorage(
281 const base::FilePath
& path
,
282 base::WeakPtr
<ServiceWorkerContextCore
> context
,
283 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
284 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
285 storage::QuotaManagerProxy
* quota_manager_proxy
,
286 storage::SpecialStoragePolicy
* special_storage_policy
);
288 base::FilePath
GetDatabasePath();
289 base::FilePath
GetDiskCachePath();
292 const base::Closure
& callback
);
293 void DidReadInitialData(
295 ServiceWorkerDatabase::Status status
);
296 void DidFindRegistrationForDocument(
297 const GURL
& document_url
,
298 const FindRegistrationCallback
& callback
,
300 const ServiceWorkerDatabase::RegistrationData
& data
,
301 const ResourceList
& resources
,
302 ServiceWorkerDatabase::Status status
);
303 void DidFindRegistrationForPattern(
305 const FindRegistrationCallback
& callback
,
306 const ServiceWorkerDatabase::RegistrationData
& data
,
307 const ResourceList
& resources
,
308 ServiceWorkerDatabase::Status status
);
309 void DidFindRegistrationForId(
310 const FindRegistrationCallback
& callback
,
311 const ServiceWorkerDatabase::RegistrationData
& data
,
312 const ResourceList
& resources
,
313 ServiceWorkerDatabase::Status status
);
314 void DidGetRegistrations(
315 const GetRegistrationsInfosCallback
& callback
,
316 RegistrationList
* registrations
,
317 const GURL
& origin_filter
,
318 ServiceWorkerDatabase::Status status
);
319 void DidStoreRegistration(
320 const StatusCallback
& callback
,
321 const ServiceWorkerDatabase::RegistrationData
& new_version
,
323 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
324 const std::vector
<int64
>& newly_purgeable_resources
,
325 ServiceWorkerDatabase::Status status
);
326 void DidUpdateToActiveState(
327 const StatusCallback
& callback
,
328 ServiceWorkerDatabase::Status status
);
329 void DidDeleteRegistration(
330 const DidDeleteRegistrationParams
& params
,
331 bool origin_is_deletable
,
332 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
333 const std::vector
<int64
>& newly_purgeable_resources
,
334 ServiceWorkerDatabase::Status status
);
335 void DidStoreUserData(
336 const StatusCallback
& callback
,
337 ServiceWorkerDatabase::Status status
);
339 const GetUserDataCallback
& callback
,
340 const std::string
& data
,
341 ServiceWorkerDatabase::Status status
);
342 void DidDeleteUserData(
343 const StatusCallback
& callback
,
344 ServiceWorkerDatabase::Status status
);
345 void DidGetUserDataForAllRegistrations(
346 const GetUserDataForAllRegistrationsCallback
& callback
,
347 const std::vector
<std::pair
<int64
, std::string
>>& user_data
,
348 ServiceWorkerDatabase::Status status
);
349 void ReturnFoundRegistration(
350 const FindRegistrationCallback
& callback
,
351 const ServiceWorkerDatabase::RegistrationData
& data
,
352 const ResourceList
& resources
);
354 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
355 const ServiceWorkerDatabase::RegistrationData
& data
,
356 const ResourceList
& resources
);
357 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
358 const GURL
& document_url
);
359 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
361 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
362 int64 registration_id
);
364 // Lazy disk_cache getter.
365 ServiceWorkerDiskCache
* disk_cache();
366 void OnDiskCacheInitialized(int rv
);
368 void StartPurgingResources(const std::vector
<int64
>& ids
);
369 void StartPurgingResources(const ResourceList
& resources
);
370 void ContinuePurgingResources();
371 void PurgeResource(int64 id
);
372 void OnResourcePurged(int64 id
, int rv
);
374 // Deletes purgeable and uncommitted resources left over from the previous
375 // browser session. This must be called once per session before any database
376 // operation that may mutate the purgeable or uncommitted resource lists.
377 void DeleteStaleResources();
378 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
379 ServiceWorkerDatabase::Status status
);
381 void ClearSessionOnlyOrigins();
383 // Static cross-thread helpers.
384 static void CollectStaleResourcesFromDB(
385 ServiceWorkerDatabase
* database
,
386 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
387 const GetResourcesCallback
& callback
);
388 static void ReadInitialDataFromDB(
389 ServiceWorkerDatabase
* database
,
390 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
391 const InitializeCallback
& callback
);
392 static void DeleteRegistrationFromDB(
393 ServiceWorkerDatabase
* database
,
394 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
395 int64 registration_id
,
397 const DeleteRegistrationCallback
& callback
);
398 static void WriteRegistrationInDB(
399 ServiceWorkerDatabase
* database
,
400 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
401 const ServiceWorkerDatabase::RegistrationData
& registration
,
402 const ResourceList
& resources
,
403 const WriteRegistrationCallback
& callback
);
404 static void FindForDocumentInDB(
405 ServiceWorkerDatabase
* database
,
406 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
407 const GURL
& document_url
,
408 const FindInDBCallback
& callback
);
409 static void FindForPatternInDB(
410 ServiceWorkerDatabase
* database
,
411 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
413 const FindInDBCallback
& callback
);
414 static void FindForIdInDB(
415 ServiceWorkerDatabase
* database
,
416 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
417 int64 registration_id
,
419 const FindInDBCallback
& callback
);
420 static void FindForIdOnlyInDB(
421 ServiceWorkerDatabase
* database
,
422 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
423 int64 registration_id
,
424 const FindInDBCallback
& callback
);
425 static void GetUserDataInDB(
426 ServiceWorkerDatabase
* database
,
427 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
428 int64 registration_id
,
429 const std::string
& key
,
430 const GetUserDataInDBCallback
& callback
);
431 static void GetUserDataForAllRegistrationsInDB(
432 ServiceWorkerDatabase
* database
,
433 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
434 const std::string
& key
,
435 const GetUserDataForAllRegistrationsInDBCallback
& callback
);
436 static void DeleteAllDataForOriginsFromDB(
437 ServiceWorkerDatabase
* database
,
438 const std::set
<GURL
>& origins
);
440 void ScheduleDeleteAndStartOver();
441 void DidDeleteDatabase(
442 const StatusCallback
& callback
,
443 ServiceWorkerDatabase::Status status
);
444 void DidDeleteDiskCache(
445 const StatusCallback
& callback
,
448 // For finding registrations being installed or uninstalled.
449 RegistrationRefsById installing_registrations_
;
450 RegistrationRefsById uninstalling_registrations_
;
452 // Origins having registations.
453 std::set
<GURL
> registered_origins_
;
455 // Pending database tasks waiting for initialization.
456 std::vector
<base::Closure
> pending_tasks_
;
458 int64 next_registration_id_
;
459 int64 next_version_id_
;
460 int64 next_resource_id_
;
470 base::FilePath path_
;
471 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
473 // Only accessed using |database_task_manager_|.
474 scoped_ptr
<ServiceWorkerDatabase
> database_
;
476 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager_
;
477 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
478 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
479 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
480 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
481 std::deque
<int64
> purgeable_resource_ids_
;
482 bool is_purge_pending_
;
483 bool has_checked_for_stale_resources_
;
484 std::set
<int64
> pending_deletions_
;
486 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
488 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
491 } // namespace content
493 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_