Roll ANGLE e754fb8..6ffeb74
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_storage.h
blob0b4e96310c73a5490466769b1b4acb8f40463d7a
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_version.h"
22 #include "content/common/content_export.h"
23 #include "content/common/service_worker/service_worker_status_code.h"
24 #include "url/gurl.h"
26 namespace base {
27 class SequencedTaskRunner;
28 class SingleThreadTaskRunner;
31 namespace storage {
32 class QuotaManagerProxy;
33 class SpecialStoragePolicy;
36 namespace content {
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
47 // registration data.
48 class CONTENT_EXPORT ServiceWorkerStorage
49 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) {
50 public:
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<void(
57 const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
58 registrations)> GetRegistrationsCallback;
59 typedef base::Callback<void(const std::vector<ServiceWorkerRegistrationInfo>&
60 registrations)> GetRegistrationsInfosCallback;
61 typedef base::Callback<
62 void(ServiceWorkerStatusCode status, bool are_equal)>
63 CompareCallback;
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 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 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 // Compares only the response bodies.
161 void CompareScriptResources(int64 lhs_id, int64 rhs_id,
162 const CompareCallback& callback);
164 // Provide a storage mechanism to read/write arbitrary data associated with
165 // a registration. Each registration has its own key namespace. Stored data
166 // is deleted when the associated registraton is deleted.
167 void GetUserData(int64 registration_id,
168 const std::string& key,
169 const GetUserDataCallback& callback);
170 void StoreUserData(int64 registration_id,
171 const GURL& origin,
172 const std::string& key,
173 const std::string& data,
174 const StatusCallback& callback);
175 void ClearUserData(int64 registration_id,
176 const std::string& key,
177 const StatusCallback& callback);
178 // Returns all registrations that have user data with a particular key, as
179 // well as that user data.
180 void GetUserDataForAllRegistrations(
181 const std::string& key,
182 const GetUserDataForAllRegistrationsCallback& callback);
184 // Deletes the storage and starts over.
185 void DeleteAndStartOver(const StatusCallback& callback);
187 // Returns new IDs which are guaranteed to be unique in the storage.
188 int64 NewRegistrationId();
189 int64 NewVersionId();
190 int64 NewResourceId();
192 // Intended for use only by ServiceWorkerRegisterJob and
193 // ServiceWorkerRegistration.
194 void NotifyInstallingRegistration(
195 ServiceWorkerRegistration* registration);
196 void NotifyDoneInstallingRegistration(
197 ServiceWorkerRegistration* registration,
198 ServiceWorkerVersion* version,
199 ServiceWorkerStatusCode status);
200 void NotifyUninstallingRegistration(ServiceWorkerRegistration* registration);
201 void NotifyDoneUninstallingRegistration(
202 ServiceWorkerRegistration* registration);
204 void Disable();
205 bool IsDisabled() const;
207 // |resources| must already be on the purgeable list.
208 void PurgeResources(const ResourceList& resources);
210 private:
211 friend class ServiceWorkerHandleTest;
212 friend class ServiceWorkerStorageTest;
213 friend class ServiceWorkerResourceStorageTest;
214 friend class ServiceWorkerControlleeRequestHandlerTest;
215 friend class ServiceWorkerContextRequestHandlerTest;
216 friend class ServiceWorkerRequestHandlerTest;
217 friend class ServiceWorkerURLRequestJobTest;
218 friend class ServiceWorkerVersionBrowserTest;
219 friend class ServiceWorkerVersionTest;
220 friend class ServiceWorkerWriteToCacheJobTest;
221 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest,
222 CleanupOnRendererCrash);
223 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
224 DeleteRegistration_NoLiveVersion);
225 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
226 DeleteRegistration_WaitingVersion);
227 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
228 DeleteRegistration_ActiveVersion);
229 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
230 UpdateRegistration);
231 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
232 CleanupOnRestart);
233 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
234 ClearOnExit);
236 struct InitialData {
237 int64 next_registration_id;
238 int64 next_version_id;
239 int64 next_resource_id;
240 std::set<GURL> origins;
242 InitialData();
243 ~InitialData();
246 // Because there are too many params for base::Bind to wrap a closure around.
247 struct DidDeleteRegistrationParams {
248 int64 registration_id;
249 GURL origin;
250 StatusCallback callback;
252 DidDeleteRegistrationParams();
253 ~DidDeleteRegistrationParams();
256 typedef std::vector<ServiceWorkerDatabase::RegistrationData> RegistrationList;
257 typedef std::map<int64, scoped_refptr<ServiceWorkerRegistration> >
258 RegistrationRefsById;
259 typedef base::Callback<void(
260 InitialData* data,
261 ServiceWorkerDatabase::Status status)> InitializeCallback;
262 typedef base::Callback<void(
263 const GURL& origin,
264 const ServiceWorkerDatabase::RegistrationData& deleted_version_data,
265 const std::vector<int64>& newly_purgeable_resources,
266 ServiceWorkerDatabase::Status status)> WriteRegistrationCallback;
267 typedef base::Callback<void(
268 bool origin_is_deletable,
269 const ServiceWorkerDatabase::RegistrationData& deleted_version_data,
270 const std::vector<int64>& newly_purgeable_resources,
271 ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback;
272 typedef base::Callback<void(
273 const ServiceWorkerDatabase::RegistrationData& data,
274 const ResourceList& resources,
275 ServiceWorkerDatabase::Status status)> FindInDBCallback;
276 typedef base::Callback<void(
277 const std::string& data,
278 ServiceWorkerDatabase::Status)> GetUserDataInDBCallback;
279 typedef base::Callback<void(
280 const std::vector<std::pair<int64, std::string>>& user_data,
281 ServiceWorkerDatabase::Status)>
282 GetUserDataForAllRegistrationsInDBCallback;
283 typedef base::Callback<void(const std::vector<int64>& resource_ids,
284 ServiceWorkerDatabase::Status status)>
285 GetResourcesCallback;
287 ServiceWorkerStorage(
288 const base::FilePath& path,
289 base::WeakPtr<ServiceWorkerContextCore> context,
290 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager,
291 const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread,
292 storage::QuotaManagerProxy* quota_manager_proxy,
293 storage::SpecialStoragePolicy* special_storage_policy);
295 base::FilePath GetDatabasePath();
296 base::FilePath GetDiskCachePath();
298 // Loads the registration data from backend storage. This must be called
299 // before any method that requires registration data.
300 bool LazyInitialize(
301 const base::Closure& callback);
302 void DidReadInitialData(
303 InitialData* data,
304 ServiceWorkerDatabase::Status status);
305 void DidFindRegistrationForDocument(
306 const GURL& document_url,
307 const FindRegistrationCallback& callback,
308 int64 callback_id,
309 const ServiceWorkerDatabase::RegistrationData& data,
310 const ResourceList& resources,
311 ServiceWorkerDatabase::Status status);
312 void DidFindRegistrationForPattern(
313 const GURL& scope,
314 const FindRegistrationCallback& callback,
315 const ServiceWorkerDatabase::RegistrationData& data,
316 const ResourceList& resources,
317 ServiceWorkerDatabase::Status status);
318 void DidFindRegistrationForId(
319 const FindRegistrationCallback& callback,
320 const ServiceWorkerDatabase::RegistrationData& data,
321 const ResourceList& resources,
322 ServiceWorkerDatabase::Status status);
323 void DidGetRegistrations(const GetRegistrationsCallback& callback,
324 RegistrationList* registration_data_list,
325 std::vector<ResourceList>* resources_list,
326 const GURL& origin_filter,
327 ServiceWorkerDatabase::Status status);
328 void DidGetRegistrationsInfos(const GetRegistrationsInfosCallback& callback,
329 RegistrationList* registration_data_list,
330 const GURL& origin_filter,
331 ServiceWorkerDatabase::Status status);
332 void DidStoreRegistration(
333 const StatusCallback& callback,
334 const ServiceWorkerDatabase::RegistrationData& new_version,
335 const GURL& origin,
336 const ServiceWorkerDatabase::RegistrationData& deleted_version,
337 const std::vector<int64>& newly_purgeable_resources,
338 ServiceWorkerDatabase::Status status);
339 void DidUpdateToActiveState(
340 const StatusCallback& callback,
341 ServiceWorkerDatabase::Status status);
342 void DidDeleteRegistration(
343 const DidDeleteRegistrationParams& params,
344 bool origin_is_deletable,
345 const ServiceWorkerDatabase::RegistrationData& deleted_version,
346 const std::vector<int64>& newly_purgeable_resources,
347 ServiceWorkerDatabase::Status status);
348 void DidStoreUserData(
349 const StatusCallback& callback,
350 ServiceWorkerDatabase::Status status);
351 void DidGetUserData(
352 const GetUserDataCallback& callback,
353 const std::string& data,
354 ServiceWorkerDatabase::Status status);
355 void DidDeleteUserData(
356 const StatusCallback& callback,
357 ServiceWorkerDatabase::Status status);
358 void DidGetUserDataForAllRegistrations(
359 const GetUserDataForAllRegistrationsCallback& callback,
360 const std::vector<std::pair<int64, std::string>>& user_data,
361 ServiceWorkerDatabase::Status status);
362 void ReturnFoundRegistration(
363 const FindRegistrationCallback& callback,
364 const ServiceWorkerDatabase::RegistrationData& data,
365 const ResourceList& resources);
367 scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration(
368 const ServiceWorkerDatabase::RegistrationData& data,
369 const ResourceList& resources);
370 ServiceWorkerRegistration* FindInstallingRegistrationForDocument(
371 const GURL& document_url);
372 ServiceWorkerRegistration* FindInstallingRegistrationForPattern(
373 const GURL& scope);
374 ServiceWorkerRegistration* FindInstallingRegistrationForId(
375 int64 registration_id);
377 // Lazy disk_cache getter.
378 ServiceWorkerDiskCache* disk_cache();
379 void OnDiskCacheInitialized(int rv);
381 void StartPurgingResources(const std::vector<int64>& ids);
382 void StartPurgingResources(const ResourceList& resources);
383 void ContinuePurgingResources();
384 void PurgeResource(int64 id);
385 void OnResourcePurged(int64 id, int rv);
387 // Deletes purgeable and uncommitted resources left over from the previous
388 // browser session. This must be called once per session before any database
389 // operation that may mutate the purgeable or uncommitted resource lists.
390 void DeleteStaleResources();
391 void DidCollectStaleResources(const std::vector<int64>& stale_resource_ids,
392 ServiceWorkerDatabase::Status status);
394 void ClearSessionOnlyOrigins();
396 // Static cross-thread helpers.
397 static void CollectStaleResourcesFromDB(
398 ServiceWorkerDatabase* database,
399 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
400 const GetResourcesCallback& callback);
401 static void ReadInitialDataFromDB(
402 ServiceWorkerDatabase* database,
403 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
404 const InitializeCallback& callback);
405 static void DeleteRegistrationFromDB(
406 ServiceWorkerDatabase* database,
407 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
408 int64 registration_id,
409 const GURL& origin,
410 const DeleteRegistrationCallback& callback);
411 static void WriteRegistrationInDB(
412 ServiceWorkerDatabase* database,
413 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
414 const ServiceWorkerDatabase::RegistrationData& registration,
415 const ResourceList& resources,
416 const WriteRegistrationCallback& callback);
417 static void FindForDocumentInDB(
418 ServiceWorkerDatabase* database,
419 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
420 const GURL& document_url,
421 const FindInDBCallback& callback);
422 static void FindForPatternInDB(
423 ServiceWorkerDatabase* database,
424 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
425 const GURL& scope,
426 const FindInDBCallback& callback);
427 static void FindForIdInDB(
428 ServiceWorkerDatabase* database,
429 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
430 int64 registration_id,
431 const GURL& origin,
432 const FindInDBCallback& callback);
433 static void FindForIdOnlyInDB(
434 ServiceWorkerDatabase* database,
435 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
436 int64 registration_id,
437 const FindInDBCallback& callback);
438 static void GetUserDataInDB(
439 ServiceWorkerDatabase* database,
440 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
441 int64 registration_id,
442 const std::string& key,
443 const GetUserDataInDBCallback& callback);
444 static void GetUserDataForAllRegistrationsInDB(
445 ServiceWorkerDatabase* database,
446 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
447 const std::string& key,
448 const GetUserDataForAllRegistrationsInDBCallback& callback);
449 static void DeleteAllDataForOriginsFromDB(
450 ServiceWorkerDatabase* database,
451 const std::set<GURL>& origins);
453 void ScheduleDeleteAndStartOver();
454 void DidDeleteDatabase(
455 const StatusCallback& callback,
456 ServiceWorkerDatabase::Status status);
457 void DidDeleteDiskCache(
458 const StatusCallback& callback,
459 bool result);
461 // For finding registrations being installed or uninstalled.
462 RegistrationRefsById installing_registrations_;
463 RegistrationRefsById uninstalling_registrations_;
465 // Origins having registations.
466 std::set<GURL> registered_origins_;
468 // Pending database tasks waiting for initialization.
469 std::vector<base::Closure> pending_tasks_;
471 int64 next_registration_id_;
472 int64 next_version_id_;
473 int64 next_resource_id_;
475 enum State {
476 UNINITIALIZED,
477 INITIALIZING,
478 INITIALIZED,
479 DISABLED,
481 State state_;
483 base::FilePath path_;
484 base::WeakPtr<ServiceWorkerContextCore> context_;
486 // Only accessed using |database_task_manager_|.
487 scoped_ptr<ServiceWorkerDatabase> database_;
489 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager_;
490 scoped_refptr<base::SingleThreadTaskRunner> disk_cache_thread_;
491 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
492 scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
493 scoped_ptr<ServiceWorkerDiskCache> disk_cache_;
494 std::deque<int64> purgeable_resource_ids_;
495 bool is_purge_pending_;
496 bool has_checked_for_stale_resources_;
497 std::set<int64> pending_deletions_;
499 base::WeakPtrFactory<ServiceWorkerStorage> weak_factory_;
501 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage);
504 } // namespace content
506 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_