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_
13 #include "base/bind.h"
14 #include "base/files/file_path.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/scoped_vector.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_version.h"
21 #include "content/common/content_export.h"
22 #include "content/common/service_worker/service_worker_status_code.h"
26 class SequencedTaskRunner
;
27 class SingleThreadTaskRunner
;
31 class QuotaManagerProxy
;
32 class SpecialStoragePolicy
;
37 class ServiceWorkerContextCore
;
38 class ServiceWorkerDiskCache
;
39 class ServiceWorkerRegistration
;
40 class ServiceWorkerRegistrationInfo
;
41 class ServiceWorkerResponseReader
;
42 class ServiceWorkerResponseWriter
;
44 // This class provides an interface to store and retrieve ServiceWorker
46 class CONTENT_EXPORT ServiceWorkerStorage
47 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener
) {
49 typedef std::vector
<ServiceWorkerDatabase::ResourceRecord
> ResourceList
;
50 typedef base::Callback
<void(ServiceWorkerStatusCode status
)> StatusCallback
;
51 typedef base::Callback
<void(ServiceWorkerStatusCode status
,
52 const scoped_refptr
<ServiceWorkerRegistration
>&
53 registration
)> FindRegistrationCallback
;
54 typedef base::Callback
<
55 void(const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
)>
56 GetAllRegistrationInfosCallback
;
57 typedef base::Callback
<
58 void(ServiceWorkerStatusCode status
, bool are_equal
)>
61 ~ServiceWorkerStorage() override
;
63 static scoped_ptr
<ServiceWorkerStorage
> Create(
64 const base::FilePath
& path
,
65 base::WeakPtr
<ServiceWorkerContextCore
> context
,
66 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
67 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
68 storage::QuotaManagerProxy
* quota_manager_proxy
,
69 storage::SpecialStoragePolicy
* special_storage_policy
);
71 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
72 static scoped_ptr
<ServiceWorkerStorage
> Create(
73 base::WeakPtr
<ServiceWorkerContextCore
> context
,
74 ServiceWorkerStorage
* old_storage
);
76 // Finds registration for |document_url| or |pattern| or |registration_id|.
77 // The Find methods will find stored and initially installing registrations.
78 // Returns SERVICE_WORKER_OK with non-null registration if registration
79 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
80 // registration is found. The FindRegistrationForPattern method is
81 // guaranteed to return asynchronously. However, the methods to find
82 // for |document_url| or |registration_id| may complete immediately
83 // (the callback may be called prior to the method returning) or
85 void FindRegistrationForDocument(const GURL
& document_url
,
86 const FindRegistrationCallback
& callback
);
87 void FindRegistrationForPattern(const GURL
& scope
,
88 const FindRegistrationCallback
& callback
);
89 void FindRegistrationForId(int64 registration_id
,
91 const FindRegistrationCallback
& callback
);
93 ServiceWorkerRegistration
* GetUninstallingRegistration(const GURL
& scope
);
95 // Returns info about all stored and initially installing registrations.
96 void GetAllRegistrations(const GetAllRegistrationInfosCallback
& callback
);
98 // Commits |registration| with the installed but not activated |version|
99 // to storage, overwritting any pre-existing registration data for the scope.
100 // A pre-existing version's script resources remain available if that version
101 // is live. PurgeResources should be called when it's OK to delete them.
102 void StoreRegistration(ServiceWorkerRegistration
* registration
,
103 ServiceWorkerVersion
* version
,
104 const StatusCallback
& callback
);
106 // Updates the state of the registration's stored version to active.
107 void UpdateToActiveState(
108 ServiceWorkerRegistration
* registration
,
109 const StatusCallback
& callback
);
111 // Updates the stored time to match the value of
112 // registration->last_update_check().
113 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
);
115 // Deletes the registration data for |registration_id|. If the registration's
116 // version is live, its script resources will remain available.
117 // PurgeResources should be called when it's OK to delete them.
118 void DeleteRegistration(int64 registration_id
,
120 const StatusCallback
& callback
);
122 scoped_ptr
<ServiceWorkerResponseReader
> CreateResponseReader(
124 scoped_ptr
<ServiceWorkerResponseWriter
> CreateResponseWriter(
127 // Adds |id| to the set of resources ids that are in the disk
128 // cache but not yet stored with a registration.
129 void StoreUncommittedResponseId(int64 id
);
131 // Removes |id| from uncommitted list, adds it to the
132 // purgeable list and purges it.
133 void DoomUncommittedResponse(int64 id
);
135 // Compares only the response bodies.
136 void CompareScriptResources(int64 lhs_id
, int64 rhs_id
,
137 const CompareCallback
& callback
);
139 // Deletes the storage and starts over.
140 void DeleteAndStartOver(const StatusCallback
& callback
);
142 // Returns new IDs which are guaranteed to be unique in the storage.
143 int64
NewRegistrationId();
144 int64
NewVersionId();
145 int64
NewResourceId();
147 // Intended for use only by ServiceWorkerRegisterJob and
148 // ServiceWorkerRegistration.
149 void NotifyInstallingRegistration(
150 ServiceWorkerRegistration
* registration
);
151 void NotifyDoneInstallingRegistration(
152 ServiceWorkerRegistration
* registration
,
153 ServiceWorkerVersion
* version
,
154 ServiceWorkerStatusCode status
);
155 void NotifyUninstallingRegistration(ServiceWorkerRegistration
* registration
);
156 void NotifyDoneUninstallingRegistration(
157 ServiceWorkerRegistration
* registration
);
160 bool IsDisabled() const;
162 // |resources| must already be on the purgeable list.
163 void PurgeResources(const ResourceList
& resources
);
166 friend class ServiceWorkerResourceStorageTest
;
167 friend class ServiceWorkerControlleeRequestHandlerTest
;
168 friend class ServiceWorkerContextRequestHandlerTest
;
169 friend class ServiceWorkerRequestHandlerTest
;
170 friend class ServiceWorkerWriteToCacheJobTest
;
171 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
172 DeleteRegistration_NoLiveVersion
);
173 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
174 DeleteRegistration_WaitingVersion
);
175 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
176 DeleteRegistration_ActiveVersion
);
177 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest
,
179 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
181 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest
,
185 int64 next_registration_id
;
186 int64 next_version_id
;
187 int64 next_resource_id
;
188 std::set
<GURL
> origins
;
194 // Because there are too many params for base::Bind to wrap a closure around.
195 struct DidDeleteRegistrationParams
{
196 int64 registration_id
;
198 StatusCallback callback
;
200 DidDeleteRegistrationParams();
201 ~DidDeleteRegistrationParams();
204 typedef std::vector
<ServiceWorkerDatabase::RegistrationData
> RegistrationList
;
205 typedef std::map
<int64
, scoped_refptr
<ServiceWorkerRegistration
> >
206 RegistrationRefsById
;
207 typedef base::Callback
<void(
209 ServiceWorkerDatabase::Status status
)> InitializeCallback
;
210 typedef base::Callback
<void(
212 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
213 const std::vector
<int64
>& newly_purgeable_resources
,
214 ServiceWorkerDatabase::Status status
)> WriteRegistrationCallback
;
215 typedef base::Callback
<void(
216 bool origin_is_deletable
,
217 const ServiceWorkerDatabase::RegistrationData
& deleted_version_data
,
218 const std::vector
<int64
>& newly_purgeable_resources
,
219 ServiceWorkerDatabase::Status status
)> DeleteRegistrationCallback
;
220 typedef base::Callback
<void(
221 const ServiceWorkerDatabase::RegistrationData
& data
,
222 const ResourceList
& resources
,
223 ServiceWorkerDatabase::Status status
)> FindInDBCallback
;
224 typedef base::Callback
<void(const std::vector
<int64
>& resource_ids
,
225 ServiceWorkerDatabase::Status status
)>
226 GetResourcesCallback
;
228 ServiceWorkerStorage(
229 const base::FilePath
& path
,
230 base::WeakPtr
<ServiceWorkerContextCore
> context
,
231 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
232 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
233 storage::QuotaManagerProxy
* quota_manager_proxy
,
234 storage::SpecialStoragePolicy
* special_storage_policy
);
236 base::FilePath
GetDatabasePath();
237 base::FilePath
GetDiskCachePath();
240 const base::Closure
& callback
);
241 void DidReadInitialData(
243 ServiceWorkerDatabase::Status status
);
244 void DidFindRegistrationForDocument(
245 const GURL
& document_url
,
246 const FindRegistrationCallback
& callback
,
248 const ServiceWorkerDatabase::RegistrationData
& data
,
249 const ResourceList
& resources
,
250 ServiceWorkerDatabase::Status status
);
251 void DidFindRegistrationForPattern(
253 const FindRegistrationCallback
& callback
,
254 const ServiceWorkerDatabase::RegistrationData
& data
,
255 const ResourceList
& resources
,
256 ServiceWorkerDatabase::Status status
);
257 void DidFindRegistrationForId(
258 const FindRegistrationCallback
& callback
,
259 const ServiceWorkerDatabase::RegistrationData
& data
,
260 const ResourceList
& resources
,
261 ServiceWorkerDatabase::Status status
);
262 void DidGetAllRegistrations(
263 const GetAllRegistrationInfosCallback
& callback
,
264 RegistrationList
* registrations
,
265 ServiceWorkerDatabase::Status status
);
266 void DidStoreRegistration(
267 const StatusCallback
& callback
,
268 const ServiceWorkerDatabase::RegistrationData
& new_version
,
270 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
271 const std::vector
<int64
>& newly_purgeable_resources
,
272 ServiceWorkerDatabase::Status status
);
273 void DidUpdateToActiveState(
274 const StatusCallback
& callback
,
275 ServiceWorkerDatabase::Status status
);
276 void DidDeleteRegistration(
277 const DidDeleteRegistrationParams
& params
,
278 bool origin_is_deletable
,
279 const ServiceWorkerDatabase::RegistrationData
& deleted_version
,
280 const std::vector
<int64
>& newly_purgeable_resources
,
281 ServiceWorkerDatabase::Status status
);
282 void ReturnFoundRegistration(
283 const FindRegistrationCallback
& callback
,
284 const ServiceWorkerDatabase::RegistrationData
& data
,
285 const ResourceList
& resources
);
287 scoped_refptr
<ServiceWorkerRegistration
> GetOrCreateRegistration(
288 const ServiceWorkerDatabase::RegistrationData
& data
,
289 const ResourceList
& resources
);
290 ServiceWorkerRegistration
* FindInstallingRegistrationForDocument(
291 const GURL
& document_url
);
292 ServiceWorkerRegistration
* FindInstallingRegistrationForPattern(
294 ServiceWorkerRegistration
* FindInstallingRegistrationForId(
295 int64 registration_id
);
297 // Lazy disk_cache getter.
298 ServiceWorkerDiskCache
* disk_cache();
299 void OnDiskCacheInitialized(int rv
);
301 void StartPurgingResources(const std::vector
<int64
>& ids
);
302 void StartPurgingResources(const ResourceList
& resources
);
303 void ContinuePurgingResources();
304 void PurgeResource(int64 id
);
305 void OnResourcePurged(int64 id
, int rv
);
307 // Deletes purgeable and uncommitted resources left over from the previous
308 // browser session. This must be called once per session before any database
309 // operation that may mutate the purgeable or uncommitted resource lists.
310 void DeleteStaleResources();
311 void DidCollectStaleResources(const std::vector
<int64
>& stale_resource_ids
,
312 ServiceWorkerDatabase::Status status
);
314 void ClearSessionOnlyOrigins();
316 // Static cross-thread helpers.
317 static void CollectStaleResourcesFromDB(
318 ServiceWorkerDatabase
* database
,
319 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
320 const GetResourcesCallback
& callback
);
321 static void ReadInitialDataFromDB(
322 ServiceWorkerDatabase
* database
,
323 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
324 const InitializeCallback
& callback
);
325 static void DeleteRegistrationFromDB(
326 ServiceWorkerDatabase
* database
,
327 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
328 int64 registration_id
,
330 const DeleteRegistrationCallback
& callback
);
331 static void WriteRegistrationInDB(
332 ServiceWorkerDatabase
* database
,
333 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
334 const ServiceWorkerDatabase::RegistrationData
& registration
,
335 const ResourceList
& resources
,
336 const WriteRegistrationCallback
& callback
);
337 static void FindForDocumentInDB(
338 ServiceWorkerDatabase
* database
,
339 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
340 const GURL
& document_url
,
341 const FindInDBCallback
& callback
);
342 static void FindForPatternInDB(
343 ServiceWorkerDatabase
* database
,
344 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
346 const FindInDBCallback
& callback
);
347 static void FindForIdInDB(
348 ServiceWorkerDatabase
* database
,
349 scoped_refptr
<base::SequencedTaskRunner
> original_task_runner
,
350 int64 registration_id
,
352 const FindInDBCallback
& callback
);
353 static void DeleteAllDataForOriginsFromDB(
354 ServiceWorkerDatabase
* database
,
355 const std::set
<GURL
>& origins
);
357 void ScheduleDeleteAndStartOver();
358 void DidDeleteDatabase(
359 const StatusCallback
& callback
,
360 ServiceWorkerDatabase::Status status
);
361 void DidDeleteDiskCache(
362 const StatusCallback
& callback
,
365 // For finding registrations being installed or uninstalled.
366 RegistrationRefsById installing_registrations_
;
367 RegistrationRefsById uninstalling_registrations_
;
369 // Origins having registations.
370 std::set
<GURL
> registered_origins_
;
372 // Pending database tasks waiting for initialization.
373 std::vector
<base::Closure
> pending_tasks_
;
375 int64 next_registration_id_
;
376 int64 next_version_id_
;
377 int64 next_resource_id_
;
387 base::FilePath path_
;
388 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
390 // Only accessed using |database_task_manager_|.
391 scoped_ptr
<ServiceWorkerDatabase
> database_
;
393 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager_
;
394 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread_
;
395 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
396 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
397 scoped_ptr
<ServiceWorkerDiskCache
> disk_cache_
;
398 std::deque
<int64
> purgeable_resource_ids_
;
399 bool is_purge_pending_
;
400 bool has_checked_for_stale_resources_
;
401 std::set
<int64
> pending_deletions_
;
403 base::WeakPtrFactory
<ServiceWorkerStorage
> weak_factory_
;
405 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage
);
408 } // namespace content
410 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_