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 GetAllRegistrationInfosCallback
;
58 typedef base::Callback
<
59 void(ServiceWorkerStatusCode status
, bool are_equal
)>
61 typedef base::Callback
<
62 void(const std::string
& data
, ServiceWorkerStatusCode status
)>
65 ~ServiceWorkerStorage() override
;
67 static scoped_ptr
<ServiceWorkerStorage
> Create(
68 const base::FilePath
& path
,
69 base::WeakPtr
<ServiceWorkerContextCore
> context
,
70 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
71 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
72 storage::QuotaManagerProxy
* quota_manager_proxy
,
73 storage::SpecialStoragePolicy
* special_storage_policy
);
75 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
76 static scoped_ptr
<ServiceWorkerStorage
> Create(
77 base::WeakPtr
<ServiceWorkerContextCore
> context
,
78 ServiceWorkerStorage
* old_storage
);
80 // Finds registration for |document_url| or |pattern| or |registration_id|.
81 // The Find methods will find stored and initially installing registrations.
82 // Returns SERVICE_WORKER_OK with non-null registration if registration
83 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
84 // registration is found. The FindRegistrationForPattern method is
85 // guaranteed to return asynchronously. However, the methods to find
86 // for |document_url| or |registration_id| may complete immediately
87 // (the callback may be called prior to the method returning) or
89 void FindRegistrationForDocument(const GURL
& document_url
,
90 const FindRegistrationCallback
& callback
);
91 void FindRegistrationForPattern(const GURL
& scope
,
92 const FindRegistrationCallback
& callback
);
93 void FindRegistrationForId(int64 registration_id
,
95 const FindRegistrationCallback
& callback
);
97 ServiceWorkerRegistration
* GetUninstallingRegistration(const GURL
& scope
);
99 // Returns info about all stored and initially installing registrations.
100 void GetAllRegistrations(const GetAllRegistrationInfosCallback
& callback
);
102 // Commits |registration| with the installed but not activated |version|
103 // to storage, overwritting any pre-existing registration data for the scope.
104 // A pre-existing version's script resources remain available if that version
105 // is live. PurgeResources should be called when it's OK to delete them.
106 void StoreRegistration(ServiceWorkerRegistration
* registration
,
107 ServiceWorkerVersion
* version
,
108 const StatusCallback
& callback
);
110 // Updates the state of the registration's stored version to active.
111 void UpdateToActiveState(
112 ServiceWorkerRegistration
* registration
,
113 const StatusCallback
& callback
);
115 // Updates the stored time to match the value of
116 // registration->last_update_check().
117 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
);
119 // Deletes the registration data for |registration_id|. If the registration's
120 // version is live, its script resources will remain available.
121 // PurgeResources should be called when it's OK to delete them.
122 void DeleteRegistration(int64 registration_id
,
124 const StatusCallback
& callback
);
126 scoped_ptr
<ServiceWorkerResponseReader
> CreateResponseReader(
128 scoped_ptr
<ServiceWorkerResponseWriter
> CreateResponseWriter(
131 // Adds |id| to the set of resources ids that are in the disk
132 // cache but not yet stored with a registration.
133 void StoreUncommittedResponseId(int64 id
);
135 // Removes |id| from uncommitted list, adds it to the
136 // purgeable list and purges it.
137 void DoomUncommittedResponse(int64 id
);
139 // Compares only the response bodies.
140 void CompareScriptResources(int64 lhs_id
, int64 rhs_id
,
141 const CompareCallback
& callback
);
143 // Provide a storage mechanism to read/write arbitrary data associated with
144 // a registration. Each registration has its own key namespace. Stored data
145 // is deleted when the associated registraton is deleted.
146 void GetUserData(int64 registration_id
,
147 const std::string
& key
,
148 const GetUserDataCallback
& callback
);
149 void StoreUserData(int64 registration_id
,
151 const std::string
& key
,
152 const std::string
& data
,
153 const StatusCallback
& callback
);
154 void ClearUserData(int64 registration_id
,
155 const std::string
& key
,
156 const StatusCallback
& callback
);
158 // Deletes the storage and starts over.
159 void DeleteAndStartOver(const StatusCallback
& callback
);
161 // Returns new IDs which are guaranteed to be unique in the storage.
162 int64
NewRegistrationId();
163 int64
NewVersionId();
164 int64
NewResourceId();
166 // Intended for use only by ServiceWorkerRegisterJob and
167 // ServiceWorkerRegistration.
168 void NotifyInstallingRegistration(
169 ServiceWorkerRegistration
* registration
);
170 void NotifyDoneInstallingRegistration(
171 ServiceWorkerRegistration
* registration
,
172 ServiceWorkerVersion
* version
,
173 ServiceWorkerStatusCode status
);
174 void NotifyUninstallingRegistration(ServiceWorkerRegistration
* registration
);
175 void NotifyDoneUninstallingRegistration(
176 ServiceWorkerRegistration
* registration
);
179 bool IsDisabled() const;
181 // |resources| must already be on the purgeable list.
182 void PurgeResources(const ResourceList
& resources
);
185 friend class ServiceWorkerStorageTest
;
186 friend class ServiceWorkerResourceStorageTest
;
187 friend class ServiceWorkerControlleeRequestHandlerTest
;
188 friend class ServiceWorkerContextRequestHandlerTest
;
189 friend class ServiceWorkerRequestHandlerTest
;
190 friend class ServiceWorkerWriteToCacheJobTest
;
191 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
192 DeleteRegistration_NoLiveVersion
);
193 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
194 DeleteRegistration_WaitingVersion
);
195 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
196 DeleteRegistration_ActiveVersion
);
197 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
199 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
201 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
205 int64 next_registration_id
;
206 int64 next_version_id
;
207 int64 next_resource_id
;
208 std::set
<GURL
> origins
;
214 // Because there are too many params for base::Bind to wrap a closure around.
215 struct DidDeleteRegistrationParams
{
216 int64 registration_id
;
218 StatusCallback callback
;
220 DidDeleteRegistrationParams();
221 ~DidDeleteRegistrationParams();
224 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
225 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
226 RegistrationRefsById
;
227 typedef base::Callback
<void(
229 ServiceWorkerDatabase::Status status
)> InitializeCallback
;
230 typedef base::Callback
<void(
232 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
233 const std::vector
<int64
>& newly_purgeable_resources
,
234 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
235 typedef base::Callback
<void(
236 bool origin_is_deletable
,
237 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
238 const std::vector
<int64
>& newly_purgeable_resources
,
239 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
240 typedef base::Callback
<void(
241 const ServiceWorkerDatabase::RegistrationData
& data
,
242 const ResourceList
& resources
,
243 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
244 typedef base::Callback
<void(
245 const std::string
& data
,
246 ServiceWorkerDatabase::Status
)> GetUserDataInDBCallback
;
247 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
248 ServiceWorkerDatabase::Status status
)>
249 GetResourcesCallback
;
251 ServiceWorkerStorage(
252 const base::FilePath
& path
,
253 base::WeakPtr
<ServiceWorkerContextCore
> context
,
254 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
255 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
256 storage::QuotaManagerProxy
* quota_manager_proxy
,
257 storage::SpecialStoragePolicy
* special_storage_policy
);
259 base::FilePath
GetDatabasePath();
260 base::FilePath
GetDiskCachePath();
263 const base::Closure
& callback
);
264 void DidReadInitialData(
266 ServiceWorkerDatabase::Status status
);
267 void DidFindRegistrationForDocument(
268 const GURL
& document_url
,
269 const FindRegistrationCallback
& callback
,
271 const ServiceWorkerDatabase::RegistrationData
& data
,
272 const ResourceList
& resources
,
273 ServiceWorkerDatabase::Status status
);
274 void DidFindRegistrationForPattern(
276 const FindRegistrationCallback
& callback
,
277 const ServiceWorkerDatabase::RegistrationData
& data
,
278 const ResourceList
& resources
,
279 ServiceWorkerDatabase::Status status
);
280 void DidFindRegistrationForId(
281 const FindRegistrationCallback
& callback
,
282 const ServiceWorkerDatabase::RegistrationData
& data
,
283 const ResourceList
& resources
,
284 ServiceWorkerDatabase::Status status
);
285 void DidGetAllRegistrations(
286 const GetAllRegistrationInfosCallback
& callback
,
287 RegistrationList
* registrations
,
288 ServiceWorkerDatabase::Status status
);
289 void DidStoreRegistration(
290 const StatusCallback
& callback
,
291 const ServiceWorkerDatabase::RegistrationData
& new_version
,
293 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
294 const std::vector
<int64
>& newly_purgeable_resources
,
295 ServiceWorkerDatabase::Status status
);
296 void DidUpdateToActiveState(
297 const StatusCallback
& callback
,
298 ServiceWorkerDatabase::Status status
);
299 void DidDeleteRegistration(
300 const DidDeleteRegistrationParams
& params
,
301 bool origin_is_deletable
,
302 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
303 const std::vector
<int64
>& newly_purgeable_resources
,
304 ServiceWorkerDatabase::Status status
);
305 void DidStoreUserData(
306 const StatusCallback
& callback
,
307 ServiceWorkerDatabase::Status status
);
309 const GetUserDataCallback
& callback
,
310 const std::string
& data
,
311 ServiceWorkerDatabase::Status status
);
312 void DidDeleteUserData(
313 const StatusCallback
& callback
,
314 ServiceWorkerDatabase::Status status
);
315 void ReturnFoundRegistration(
316 const FindRegistrationCallback
& callback
,
317 const ServiceWorkerDatabase::RegistrationData
& data
,
318 const ResourceList
& resources
);
320 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
321 const ServiceWorkerDatabase::RegistrationData
& data
,
322 const ResourceList
& resources
);
323 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
324 const GURL
& document_url
);
325 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
327 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
328 int64 registration_id
);
330 // Lazy disk_cache getter.
331 ServiceWorkerDiskCache
* disk_cache();
332 void OnDiskCacheInitialized(int rv
);
334 void StartPurgingResources(const std::vector
<int64
>& ids
);
335 void StartPurgingResources(const ResourceList
& resources
);
336 void ContinuePurgingResources();
337 void PurgeResource(int64 id
);
338 void OnResourcePurged(int64 id
, int rv
);
340 // Deletes purgeable and uncommitted resources left over from the previous
341 // browser session. This must be called once per session before any database
342 // operation that may mutate the purgeable or uncommitted resource lists.
343 void DeleteStaleResources();
344 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
345 ServiceWorkerDatabase::Status status
);
347 void ClearSessionOnlyOrigins();
349 // Static cross-thread helpers.
350 static void CollectStaleResourcesFromDB(
351 ServiceWorkerDatabase
* database
,
352 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
353 const GetResourcesCallback
& callback
);
354 static void ReadInitialDataFromDB(
355 ServiceWorkerDatabase
* database
,
356 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
357 const InitializeCallback
& callback
);
358 static void DeleteRegistrationFromDB(
359 ServiceWorkerDatabase
* database
,
360 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
361 int64 registration_id
,
363 const DeleteRegistrationCallback
& callback
);
364 static void WriteRegistrationInDB(
365 ServiceWorkerDatabase
* database
,
366 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
367 const ServiceWorkerDatabase::RegistrationData
& registration
,
368 const ResourceList
& resources
,
369 const WriteRegistrationCallback
& callback
);
370 static void FindForDocumentInDB(
371 ServiceWorkerDatabase
* database
,
372 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
373 const GURL
& document_url
,
374 const FindInDBCallback
& callback
);
375 static void FindForPatternInDB(
376 ServiceWorkerDatabase
* database
,
377 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
379 const FindInDBCallback
& callback
);
380 static void FindForIdInDB(
381 ServiceWorkerDatabase
* database
,
382 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
383 int64 registration_id
,
385 const FindInDBCallback
& callback
);
386 static void GetUserDataInDB(
387 ServiceWorkerDatabase
* database
,
388 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
389 int64 registration_id
,
390 const std::string
& key
,
391 const GetUserDataInDBCallback
& callback
);
392 static void DeleteAllDataForOriginsFromDB(
393 ServiceWorkerDatabase
* database
,
394 const std::set
<GURL
>& origins
);
396 void ScheduleDeleteAndStartOver();
397 void DidDeleteDatabase(
398 const StatusCallback
& callback
,
399 ServiceWorkerDatabase::Status status
);
400 void DidDeleteDiskCache(
401 const StatusCallback
& callback
,
404 // For finding registrations being installed or uninstalled.
405 RegistrationRefsById installing_registrations_
;
406 RegistrationRefsById uninstalling_registrations_
;
408 // Origins having registations.
409 std::set
<GURL
> registered_origins_
;
411 // Pending database tasks waiting for initialization.
412 std::vector
<base::Closure
> pending_tasks_
;
414 int64 next_registration_id_
;
415 int64 next_version_id_
;
416 int64 next_resource_id_
;
426 base::FilePath path_
;
427 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
429 // Only accessed using |database_task_manager_|.
430 scoped_ptr
<ServiceWorkerDatabase
> database_
;
432 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager_
;
433 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
434 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
435 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
436 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
437 std::deque
<int64
> purgeable_resource_ids_
;
438 bool is_purge_pending_
;
439 bool has_checked_for_stale_resources_
;
440 std::set
<int64
> pending_deletions_
;
442 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
444 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
447 } // namespace content
449 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_