After 24 hours, bust the browser cache when checking for ServiceWorker updates and...
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_storage.h
blob0180cba4486a7502c5d91ec4052affe22d3bacca
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 <vector>
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_version.h"
20 #include "content/common/content_export.h"
21 #include "content/common/service_worker/service_worker_status_code.h"
22 #include "url/gurl.h"
24 namespace base {
25 class MessageLoopProxy;
26 class SequencedTaskRunner;
29 namespace quota {
30 class QuotaManagerProxy;
33 namespace content {
35 class ServiceWorkerContextCore;
36 class ServiceWorkerDiskCache;
37 class ServiceWorkerRegistration;
38 class ServiceWorkerRegistrationInfo;
39 class ServiceWorkerResponseReader;
40 class ServiceWorkerResponseWriter;
42 // This class provides an interface to store and retrieve ServiceWorker
43 // registration data.
44 class CONTENT_EXPORT ServiceWorkerStorage
45 : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) {
46 public:
47 typedef std::vector<ServiceWorkerDatabase::ResourceRecord> ResourceList;
48 typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
49 typedef base::Callback<void(ServiceWorkerStatusCode status,
50 const scoped_refptr<ServiceWorkerRegistration>&
51 registration)> FindRegistrationCallback;
52 typedef base::Callback<
53 void(const std::vector<ServiceWorkerRegistrationInfo>& registrations)>
54 GetAllRegistrationInfosCallback;
55 typedef base::Callback<
56 void(ServiceWorkerStatusCode status, bool are_equal)>
57 CompareCallback;
59 virtual ~ServiceWorkerStorage();
61 static scoped_ptr<ServiceWorkerStorage> Create(
62 const base::FilePath& path,
63 base::WeakPtr<ServiceWorkerContextCore> context,
64 base::SequencedTaskRunner* database_task_runner,
65 base::MessageLoopProxy* disk_cache_thread,
66 quota::QuotaManagerProxy* quota_manager_proxy);
68 // Used for DeleteAndStartOver. Creates new storage based on |old_storage|.
69 static scoped_ptr<ServiceWorkerStorage> Create(
70 base::WeakPtr<ServiceWorkerContextCore> context,
71 ServiceWorkerStorage* old_storage);
73 // Finds registration for |document_url| or |pattern| or |registration_id|.
74 // The Find methods will find stored and initially installing registrations.
75 // Returns SERVICE_WORKER_OK with non-null registration if registration
76 // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
77 // registration is found. The FindRegistrationForPattern method is
78 // guaranteed to return asynchronously. However, the methods to find
79 // for |document_url| or |registration_id| may complete immediately
80 // (the callback may be called prior to the method returning) or
81 // asynchronously.
82 void FindRegistrationForDocument(const GURL& document_url,
83 const FindRegistrationCallback& callback);
84 void FindRegistrationForPattern(const GURL& scope,
85 const FindRegistrationCallback& callback);
86 void FindRegistrationForId(int64 registration_id,
87 const GURL& origin,
88 const FindRegistrationCallback& callback);
90 ServiceWorkerRegistration* GetUninstallingRegistration(const GURL& scope);
92 // Returns info about all stored and initially installing registrations.
93 void GetAllRegistrations(const GetAllRegistrationInfosCallback& callback);
95 // Commits |registration| with the installed but not activated |version|
96 // to storage, overwritting any pre-existing registration data for the scope.
97 // A pre-existing version's script resources remain available if that version
98 // is live. PurgeResources should be called when it's OK to delete them.
99 void StoreRegistration(
100 ServiceWorkerRegistration* registration,
101 ServiceWorkerVersion* version,
102 const StatusCallback& callback);
104 // Updates the state of the registration's stored version to active.
105 void UpdateToActiveState(
106 ServiceWorkerRegistration* registration,
107 const StatusCallback& callback);
109 // Updates the stored time to match the value of
110 // registration->last_update_check().
111 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration* registration);
113 // Deletes the registration data for |registration_id|. If the registration's
114 // version is live, its script resources will remain available.
115 // PurgeResources should be called when it's OK to delete them.
116 void DeleteRegistration(int64 registration_id,
117 const GURL& origin,
118 const StatusCallback& callback);
120 scoped_ptr<ServiceWorkerResponseReader> CreateResponseReader(
121 int64 response_id);
122 scoped_ptr<ServiceWorkerResponseWriter> CreateResponseWriter(
123 int64 response_id);
125 // Adds |id| to the set of resources ids that are in the disk
126 // cache but not yet stored with a registration.
127 void StoreUncommittedResponseId(int64 id);
129 // Removes |id| from uncommitted list, adds it to the
130 // purgeable list and purges it.
131 void DoomUncommittedResponse(int64 id);
133 // Compares only the response bodies.
134 void CompareScriptResources(int64 lhs_id, int64 rhs_id,
135 const CompareCallback& callback);
137 // Deletes the storage and starts over.
138 void DeleteAndStartOver(const StatusCallback& callback);
140 // Returns new IDs which are guaranteed to be unique in the storage.
141 int64 NewRegistrationId();
142 int64 NewVersionId();
143 int64 NewResourceId();
145 // Intended for use only by ServiceWorkerRegisterJob and
146 // ServiceWorkerRegistration.
147 void NotifyInstallingRegistration(
148 ServiceWorkerRegistration* registration);
149 void NotifyDoneInstallingRegistration(
150 ServiceWorkerRegistration* registration,
151 ServiceWorkerVersion* version,
152 ServiceWorkerStatusCode status);
153 void NotifyUninstallingRegistration(ServiceWorkerRegistration* registration);
154 void NotifyDoneUninstallingRegistration(
155 ServiceWorkerRegistration* registration);
157 void Disable();
158 bool IsDisabled() const;
160 // |resources| must already be on the purgeable list.
161 void PurgeResources(const ResourceList& resources);
163 private:
164 friend class ServiceWorkerResourceStorageTest;
165 friend class ServiceWorkerControlleeRequestHandlerTest;
166 friend class ServiceWorkerContextRequestHandlerTest;
167 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
168 DeleteRegistration_NoLiveVersion);
169 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
170 DeleteRegistration_WaitingVersion);
171 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
172 DeleteRegistration_ActiveVersion);
173 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
174 UpdateRegistration);
175 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageDiskTest,
176 CleanupOnRestart);
178 struct InitialData {
179 int64 next_registration_id;
180 int64 next_version_id;
181 int64 next_resource_id;
182 std::set<GURL> origins;
184 InitialData();
185 ~InitialData();
188 // Because there are too many params for base::Bind to wrap a closure around.
189 struct DidDeleteRegistrationParams {
190 int64 registration_id;
191 GURL origin;
192 StatusCallback callback;
194 DidDeleteRegistrationParams();
195 ~DidDeleteRegistrationParams();
198 typedef std::vector<ServiceWorkerDatabase::RegistrationData> RegistrationList;
199 typedef std::map<int64, scoped_refptr<ServiceWorkerRegistration> >
200 RegistrationRefsById;
201 typedef base::Callback<void(
202 InitialData* data,
203 ServiceWorkerDatabase::Status status)> InitializeCallback;
204 typedef base::Callback<
205 void(const GURL& origin,
206 int64 deleted_version_id,
207 const std::vector<int64>& newly_purgeable_resources,
208 ServiceWorkerDatabase::Status status)> WriteRegistrationCallback;
209 typedef base::Callback<
210 void(bool origin_is_deletable,
211 int64 version_id,
212 const std::vector<int64>& newly_purgeable_resources,
213 ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback;
214 typedef base::Callback<void(
215 const ServiceWorkerDatabase::RegistrationData& data,
216 const ResourceList& resources,
217 ServiceWorkerDatabase::Status status)> FindInDBCallback;
218 typedef base::Callback<void(const std::vector<int64>& resource_ids,
219 ServiceWorkerDatabase::Status status)>
220 GetResourcesCallback;
222 ServiceWorkerStorage(const base::FilePath& path,
223 base::WeakPtr<ServiceWorkerContextCore> context,
224 base::SequencedTaskRunner* database_task_runner,
225 base::MessageLoopProxy* disk_cache_thread,
226 quota::QuotaManagerProxy* quota_manager_proxy);
228 base::FilePath GetDatabasePath();
229 base::FilePath GetDiskCachePath();
231 bool LazyInitialize(
232 const base::Closure& callback);
233 void DidReadInitialData(
234 InitialData* data,
235 ServiceWorkerDatabase::Status status);
236 void DidFindRegistrationForDocument(
237 const GURL& document_url,
238 const FindRegistrationCallback& callback,
239 const ServiceWorkerDatabase::RegistrationData& data,
240 const ResourceList& resources,
241 ServiceWorkerDatabase::Status status);
242 void DidFindRegistrationForPattern(
243 const GURL& scope,
244 const FindRegistrationCallback& callback,
245 const ServiceWorkerDatabase::RegistrationData& data,
246 const ResourceList& resources,
247 ServiceWorkerDatabase::Status status);
248 void DidFindRegistrationForId(
249 const FindRegistrationCallback& callback,
250 const ServiceWorkerDatabase::RegistrationData& data,
251 const ResourceList& resources,
252 ServiceWorkerDatabase::Status status);
253 void DidGetAllRegistrations(
254 const GetAllRegistrationInfosCallback& callback,
255 RegistrationList* registrations,
256 ServiceWorkerDatabase::Status status);
257 void DidStoreRegistration(const StatusCallback& callback,
258 const GURL& origin,
259 int64 deleted_version_id,
260 const std::vector<int64>& newly_purgeable_resources,
261 ServiceWorkerDatabase::Status status);
262 void DidUpdateToActiveState(
263 const StatusCallback& callback,
264 ServiceWorkerDatabase::Status status);
265 void DidDeleteRegistration(
266 const DidDeleteRegistrationParams& params,
267 bool origin_is_deletable,
268 int64 version_id,
269 const std::vector<int64>& newly_purgeable_resources,
270 ServiceWorkerDatabase::Status status);
271 void ReturnFoundRegistration(
272 const FindRegistrationCallback& callback,
273 const ServiceWorkerDatabase::RegistrationData& data,
274 const ResourceList& resources);
276 scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration(
277 const ServiceWorkerDatabase::RegistrationData& data,
278 const ResourceList& resources);
279 ServiceWorkerRegistration* FindInstallingRegistrationForDocument(
280 const GURL& document_url);
281 ServiceWorkerRegistration* FindInstallingRegistrationForPattern(
282 const GURL& scope);
283 ServiceWorkerRegistration* FindInstallingRegistrationForId(
284 int64 registration_id);
286 // Lazy disk_cache getter.
287 ServiceWorkerDiskCache* disk_cache();
288 void OnDiskCacheInitialized(int rv);
290 void StartPurgingResources(const std::vector<int64>& ids);
291 void StartPurgingResources(const ResourceList& resources);
292 void ContinuePurgingResources();
293 void PurgeResource(int64 id);
294 void OnResourcePurged(int64 id, int rv);
296 // Deletes purgeable and uncommitted resources left over from the previous
297 // browser session. This must be called once per session before any database
298 // operation that may mutate the purgeable or uncommitted resource lists.
299 void DeleteStaleResources();
300 void DidCollectStaleResources(const std::vector<int64>& stale_resource_ids,
301 ServiceWorkerDatabase::Status status);
303 // Static cross-thread helpers.
304 static void CollectStaleResourcesFromDB(
305 ServiceWorkerDatabase* database,
306 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
307 const GetResourcesCallback& callback);
308 static void ReadInitialDataFromDB(
309 ServiceWorkerDatabase* database,
310 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
311 const InitializeCallback& callback);
312 static void DeleteRegistrationFromDB(
313 ServiceWorkerDatabase* database,
314 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
315 int64 registration_id,
316 const GURL& origin,
317 const DeleteRegistrationCallback& callback);
318 static void WriteRegistrationInDB(
319 ServiceWorkerDatabase* database,
320 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
321 const ServiceWorkerDatabase::RegistrationData& registration,
322 const ResourceList& resources,
323 const WriteRegistrationCallback& callback);
324 static void FindForDocumentInDB(
325 ServiceWorkerDatabase* database,
326 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
327 const GURL& document_url,
328 const FindInDBCallback& callback);
329 static void FindForPatternInDB(
330 ServiceWorkerDatabase* database,
331 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
332 const GURL& scope,
333 const FindInDBCallback& callback);
334 static void FindForIdInDB(
335 ServiceWorkerDatabase* database,
336 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
337 int64 registration_id,
338 const GURL& origin,
339 const FindInDBCallback& callback);
341 void ScheduleDeleteAndStartOver();
342 void DidDeleteDatabase(
343 const StatusCallback& callback,
344 ServiceWorkerDatabase::Status status);
345 void DidDeleteDiskCache(
346 const StatusCallback& callback,
347 bool result);
349 // For finding registrations being installed or uninstalled.
350 RegistrationRefsById installing_registrations_;
351 RegistrationRefsById uninstalling_registrations_;
353 // Origins having registations.
354 std::set<GURL> registered_origins_;
356 // Pending database tasks waiting for initialization.
357 std::vector<base::Closure> pending_tasks_;
359 int64 next_registration_id_;
360 int64 next_version_id_;
361 int64 next_resource_id_;
363 enum State {
364 UNINITIALIZED,
365 INITIALIZING,
366 INITIALIZED,
367 DISABLED,
369 State state_;
371 base::FilePath path_;
372 base::WeakPtr<ServiceWorkerContextCore> context_;
374 // Only accessed on |database_task_runner_|.
375 scoped_ptr<ServiceWorkerDatabase> database_;
377 scoped_refptr<base::SequencedTaskRunner> database_task_runner_;
378 scoped_refptr<base::MessageLoopProxy> disk_cache_thread_;
379 scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
380 scoped_ptr<ServiceWorkerDiskCache> disk_cache_;
381 std::deque<int64> purgeable_resource_ids_;
382 bool is_purge_pending_;
383 bool has_checked_for_stale_resources_;
384 std::set<int64> pending_deletions_;
386 base::WeakPtrFactory<ServiceWorkerStorage> weak_factory_;
388 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage);
391 } // namespace content
393 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_