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