Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: content/browser/service_worker/service_worker_storage.cc

Issue 293483002: Store the service worker script and its imports on first load... really (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/service_worker/service_worker_storage.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_storage.h" 5 #include "content/browser/service_worker/service_worker_storage.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind_helpers.h" 9 #include "base/bind_helpers.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/sequenced_task_runner.h" 11 #include "base/sequenced_task_runner.h"
12 #include "base/task_runner_util.h" 12 #include "base/task_runner_util.h"
13 #include "content/browser/service_worker/service_worker_context_core.h" 13 #include "content/browser/service_worker/service_worker_context_core.h"
14 #include "content/browser/service_worker/service_worker_disk_cache.h" 14 #include "content/browser/service_worker/service_worker_disk_cache.h"
15 #include "content/browser/service_worker/service_worker_info.h" 15 #include "content/browser/service_worker/service_worker_info.h"
16 #include "content/browser/service_worker/service_worker_registration.h" 16 #include "content/browser/service_worker/service_worker_registration.h"
17 #include "content/browser/service_worker/service_worker_utils.h" 17 #include "content/browser/service_worker/service_worker_utils.h"
18 #include "content/browser/service_worker/service_worker_version.h" 18 #include "content/browser/service_worker/service_worker_version.h"
19 #include "content/common/service_worker/service_worker_types.h" 19 #include "content/common/service_worker/service_worker_types.h"
20 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
21 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
22 #include "webkit/browser/quota/quota_manager_proxy.h" 22 #include "webkit/browser/quota/quota_manager_proxy.h"
23 23
24 namespace content { 24 namespace content {
25 25
26 namespace { 26 namespace {
27 27
28 typedef base::Callback<void(
29 ServiceWorkerStorage::InitialData* data,
30 ServiceWorkerDatabase::Status status)> InitializeCallback;
31 typedef base::Callback<void(
32 const ServiceWorkerDatabase::RegistrationData& data,
33 const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources,
34 ServiceWorkerDatabase::Status status)> ReadRegistrationCallback;
35 typedef base::Callback<void(
36 bool origin_is_deletable,
37 ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback;
38
39 void RunSoon(const tracked_objects::Location& from_here, 28 void RunSoon(const tracked_objects::Location& from_here,
40 const base::Closure& closure) { 29 const base::Closure& closure) {
41 base::MessageLoop::current()->PostTask(from_here, closure); 30 base::MessageLoop::current()->PostTask(from_here, closure);
42 } 31 }
43 32
44 void CompleteFindNow( 33 void CompleteFindNow(
45 const scoped_refptr<ServiceWorkerRegistration>& registration, 34 const scoped_refptr<ServiceWorkerRegistration>& registration,
46 ServiceWorkerStatusCode status, 35 ServiceWorkerStatusCode status,
47 const ServiceWorkerStorage::FindRegistrationCallback& callback) { 36 const ServiceWorkerStorage::FindRegistrationCallback& callback) {
48 callback.Run(status, registration); 37 callback.Run(status, registration);
49 } 38 }
50 39
51 void CompleteFindSoon( 40 void CompleteFindSoon(
52 const tracked_objects::Location& from_here, 41 const tracked_objects::Location& from_here,
53 const scoped_refptr<ServiceWorkerRegistration>& registration, 42 const scoped_refptr<ServiceWorkerRegistration>& registration,
54 ServiceWorkerStatusCode status, 43 ServiceWorkerStatusCode status,
55 const ServiceWorkerStorage::FindRegistrationCallback& callback) { 44 const ServiceWorkerStorage::FindRegistrationCallback& callback) {
56 RunSoon(from_here, base::Bind(callback, status, registration)); 45 RunSoon(from_here, base::Bind(callback, status, registration));
57 } 46 }
58 47
59 const base::FilePath::CharType kServiceWorkerDirectory[] = 48 const base::FilePath::CharType kServiceWorkerDirectory[] =
60 FILE_PATH_LITERAL("Service Worker"); 49 FILE_PATH_LITERAL("Service Worker");
61 const base::FilePath::CharType kDatabaseName[] = 50 const base::FilePath::CharType kDatabaseName[] =
62 FILE_PATH_LITERAL("Database"); 51 FILE_PATH_LITERAL("Database");
52 const base::FilePath::CharType kDiskCacheName[] =
53 FILE_PATH_LITERAL("Cache");
63 54
64 const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; 55 const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
56 const int kMaxDiskCacheSize = 250 * 1024 * 1024;
65 57
66 void EmptyCompletionCallback(int) {} 58 void EmptyCompletionCallback(int) {}
67 59
68 ServiceWorkerStatusCode DatabaseStatusToStatusCode( 60 ServiceWorkerStatusCode DatabaseStatusToStatusCode(
69 ServiceWorkerDatabase::Status status) { 61 ServiceWorkerDatabase::Status status) {
70 switch (status) { 62 switch (status) {
71 case ServiceWorkerDatabase::STATUS_OK: 63 case ServiceWorkerDatabase::STATUS_OK:
72 return SERVICE_WORKER_OK; 64 return SERVICE_WORKER_OK;
73 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND: 65 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND:
74 return SERVICE_WORKER_ERROR_NOT_FOUND; 66 return SERVICE_WORKER_ERROR_NOT_FOUND;
75 default: 67 default:
76 return SERVICE_WORKER_ERROR_FAILED; 68 return SERVICE_WORKER_ERROR_FAILED;
77 } 69 }
78 } 70 }
79 71
80 void ReadInitialDataFromDB(
81 ServiceWorkerDatabase* database,
82 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
83 const InitializeCallback& callback) {
84 DCHECK(database);
85 scoped_ptr<ServiceWorkerStorage::InitialData> data(
86 new ServiceWorkerStorage::InitialData());
87
88 ServiceWorkerDatabase::Status status =
89 database->GetNextAvailableIds(&data->next_registration_id,
90 &data->next_version_id,
91 &data->next_resource_id);
92 if (status != ServiceWorkerDatabase::STATUS_OK) {
93 original_task_runner->PostTask(
94 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
95 return;
96 }
97
98 status = database->GetOriginsWithRegistrations(&data->origins);
99 original_task_runner->PostTask(
100 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
101 }
102
103 void DeleteRegistrationFromDB(
104 ServiceWorkerDatabase* database,
105 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
106 int64 registration_id,
107 const GURL& origin,
108 const DeleteRegistrationCallback& callback) {
109 DCHECK(database);
110 ServiceWorkerDatabase::Status status =
111 database->DeleteRegistration(registration_id, origin);
112 if (status != ServiceWorkerDatabase::STATUS_OK) {
113 original_task_runner->PostTask(
114 FROM_HERE, base::Bind(callback, false, status));
115 return;
116 }
117
118 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the
119 // unique origin list.
120 std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
121 status = database->GetRegistrationsForOrigin(origin, &registrations);
122 if (status != ServiceWorkerDatabase::STATUS_OK) {
123 original_task_runner->PostTask(
124 FROM_HERE, base::Bind(callback, false, status));
125 return;
126 }
127
128 bool deletable = registrations.empty();
129 original_task_runner->PostTask(
130 FROM_HERE, base::Bind(callback, deletable, status));
131 }
132
133 } // namespace 72 } // namespace
134 73
135 ServiceWorkerStorage::InitialData::InitialData() 74 ServiceWorkerStorage::InitialData::InitialData()
136 : next_registration_id(kInvalidServiceWorkerRegistrationId), 75 : next_registration_id(kInvalidServiceWorkerRegistrationId),
137 next_version_id(kInvalidServiceWorkerVersionId), 76 next_version_id(kInvalidServiceWorkerVersionId),
138 next_resource_id(kInvalidServiceWorkerResourceId) { 77 next_resource_id(kInvalidServiceWorkerResourceId) {
139 } 78 }
140 79
141 ServiceWorkerStorage::InitialData::~InitialData() { 80 ServiceWorkerStorage::InitialData::~InitialData() {
142 } 81 }
143 82
144 ServiceWorkerStorage::ServiceWorkerStorage( 83 ServiceWorkerStorage::ServiceWorkerStorage(
145 const base::FilePath& path, 84 const base::FilePath& path,
146 base::WeakPtr<ServiceWorkerContextCore> context, 85 base::WeakPtr<ServiceWorkerContextCore> context,
147 base::SequencedTaskRunner* database_task_runner, 86 base::SequencedTaskRunner* database_task_runner,
148 base::MessageLoopProxy* disk_cache_thread, 87 base::MessageLoopProxy* disk_cache_thread,
149 quota::QuotaManagerProxy* quota_manager_proxy) 88 quota::QuotaManagerProxy* quota_manager_proxy)
150 : next_registration_id_(kInvalidServiceWorkerRegistrationId), 89 : next_registration_id_(kInvalidServiceWorkerRegistrationId),
151 next_version_id_(kInvalidServiceWorkerVersionId), 90 next_version_id_(kInvalidServiceWorkerVersionId),
152 next_resource_id_(kInvalidServiceWorkerResourceId), 91 next_resource_id_(kInvalidServiceWorkerResourceId),
153 state_(UNINITIALIZED), 92 state_(UNINITIALIZED),
154 context_(context), 93 context_(context),
155 database_task_runner_(database_task_runner), 94 database_task_runner_(database_task_runner),
156 disk_cache_thread_(disk_cache_thread), 95 disk_cache_thread_(disk_cache_thread),
157 quota_manager_proxy_(quota_manager_proxy), 96 quota_manager_proxy_(quota_manager_proxy),
97 is_purge_pending_(false),
158 weak_factory_(this) { 98 weak_factory_(this) {
159 if (!path.empty()) { 99 if (!path.empty())
160 path_ = path.Append(kServiceWorkerDirectory); 100 path_ = path.Append(kServiceWorkerDirectory);
161 database_.reset(new ServiceWorkerDatabase(path_.Append(kDatabaseName))); 101 database_.reset(new ServiceWorkerDatabase(GetDatabasePath()));
162 } else {
163 // Create an in-memory database.
164 database_.reset(new ServiceWorkerDatabase(base::FilePath()));
165 }
166 } 102 }
167 103
168 ServiceWorkerStorage::~ServiceWorkerStorage() { 104 ServiceWorkerStorage::~ServiceWorkerStorage() {
169 weak_factory_.InvalidateWeakPtrs(); 105 weak_factory_.InvalidateWeakPtrs();
170 database_task_runner_->DeleteSoon(FROM_HERE, database_.release()); 106 database_task_runner_->DeleteSoon(FROM_HERE, database_.release());
171 } 107 }
172 108
109 void ServiceWorkerStorage::FindRegistrationForDocument(
110 const GURL& document_url,
111 const FindRegistrationCallback& callback) {
112 if (!LazyInitialize(base::Bind(
113 &ServiceWorkerStorage::FindRegistrationForDocument,
114 weak_factory_.GetWeakPtr(), document_url, callback))) {
115 if (state_ != INITIALIZING || !context_) {
116 CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
117 SERVICE_WORKER_ERROR_FAILED, callback);
118 }
119 return;
120 }
121 DCHECK_EQ(INITIALIZED, state_);
122
123 // See if there are any stored registrations for the origin.
124 if (!ContainsKey(registered_origins_, document_url.GetOrigin())) {
125 // Look for something currently being installed.
126 scoped_refptr<ServiceWorkerRegistration> installing_registration =
127 FindInstallingRegistrationForDocument(document_url);
128 CompleteFindNow(
129 installing_registration,
130 installing_registration ?
131 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
132 callback);
133 return;
134 }
135
136 database_task_runner_->PostTask(
137 FROM_HERE,
138 base::Bind(
139 &FindForDocumentInDB,
140 database_.get(),
141 base::MessageLoopProxy::current(),
142 document_url,
143 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForDocument,
144 weak_factory_.GetWeakPtr(), document_url, callback)));
145 }
146
173 void ServiceWorkerStorage::FindRegistrationForPattern( 147 void ServiceWorkerStorage::FindRegistrationForPattern(
174 const GURL& scope, 148 const GURL& scope,
175 const FindRegistrationCallback& callback) { 149 const FindRegistrationCallback& callback) {
176 scoped_refptr<ServiceWorkerRegistration> null_registration;
177 if (!LazyInitialize(base::Bind( 150 if (!LazyInitialize(base::Bind(
178 &ServiceWorkerStorage::FindRegistrationForPattern, 151 &ServiceWorkerStorage::FindRegistrationForPattern,
179 weak_factory_.GetWeakPtr(), scope, callback))) { 152 weak_factory_.GetWeakPtr(), scope, callback))) {
180 if (state_ != INITIALIZING || !context_) { 153 if (state_ != INITIALIZING || !context_) {
181 CompleteFindSoon(FROM_HERE, null_registration, 154 CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(),
182 SERVICE_WORKER_ERROR_FAILED, callback); 155 SERVICE_WORKER_ERROR_FAILED, callback);
183 } 156 }
184 return; 157 return;
185 } 158 }
186 DCHECK_EQ(INITIALIZED, state_); 159 DCHECK_EQ(INITIALIZED, state_);
187 160
188 // See if there are any stored registrations for the origin. 161 // See if there are any stored registrations for the origin.
189 if (!ContainsKey(registered_origins_, scope.GetOrigin())) { 162 if (!ContainsKey(registered_origins_, scope.GetOrigin())) {
190 // Look for something currently being installed. 163 // Look for something currently being installed.
191 scoped_refptr<ServiceWorkerRegistration> installing_registration = 164 scoped_refptr<ServiceWorkerRegistration> installing_registration =
192 FindInstallingRegistrationForPattern(scope); 165 FindInstallingRegistrationForPattern(scope);
193 if (installing_registration) {
194 CompleteFindSoon(
195 FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
196 return;
197 }
198 CompleteFindSoon( 166 CompleteFindSoon(
199 FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback); 167 FROM_HERE, installing_registration,
168 installing_registration ?
169 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
170 callback);
200 return; 171 return;
201 } 172 }
202 173
203 RegistrationList* registrations = new RegistrationList(); 174 database_task_runner_->PostTask(
204 PostTaskAndReplyWithResult(
205 database_task_runner_,
206 FROM_HERE, 175 FROM_HERE,
207 base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin, 176 base::Bind(
208 base::Unretained(database_.get()), 177 &FindForPatternInDB,
209 scope.GetOrigin(), base::Unretained(registrations)), 178 database_.get(),
210 base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForPattern, 179 base::MessageLoopProxy::current(),
211 weak_factory_.GetWeakPtr(), scope, callback, 180 scope,
212 base::Owned(registrations))); 181 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForPattern,
213 } 182 weak_factory_.GetWeakPtr(), scope, callback)));
214
215 void ServiceWorkerStorage::FindRegistrationForDocument(
216 const GURL& document_url,
217 const FindRegistrationCallback& callback) {
218 scoped_refptr<ServiceWorkerRegistration> null_registration;
219 if (!LazyInitialize(base::Bind(
220 &ServiceWorkerStorage::FindRegistrationForDocument,
221 weak_factory_.GetWeakPtr(), document_url, callback))) {
222 if (state_ != INITIALIZING || !context_)
223 CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
224 return;
225 }
226 DCHECK_EQ(INITIALIZED, state_);
227
228 // See if there are any stored registrations for the origin.
229 if (!ContainsKey(registered_origins_, document_url.GetOrigin())) {
230 // Look for something currently being installed.
231 scoped_refptr<ServiceWorkerRegistration> installing_registration =
232 FindInstallingRegistrationForDocument(document_url);
233 if (installing_registration) {
234 CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
235 return;
236 }
237 CompleteFindNow(
238 null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
239 return;
240 }
241
242 RegistrationList* registrations = new RegistrationList();
243 PostTaskAndReplyWithResult(
244 database_task_runner_,
245 FROM_HERE,
246 base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin,
247 base::Unretained(database_.get()),
248 document_url.GetOrigin(), base::Unretained(registrations)),
249 base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForDocument,
250 weak_factory_.GetWeakPtr(), document_url, callback,
251 base::Owned(registrations)));
252 } 183 }
253 184
254 void ServiceWorkerStorage::FindRegistrationForId( 185 void ServiceWorkerStorage::FindRegistrationForId(
255 int64 registration_id, 186 int64 registration_id,
256 const GURL& origin, 187 const GURL& origin,
257 const FindRegistrationCallback& callback) { 188 const FindRegistrationCallback& callback) {
258 scoped_refptr<ServiceWorkerRegistration> null_registration;
259 if (!LazyInitialize(base::Bind( 189 if (!LazyInitialize(base::Bind(
260 &ServiceWorkerStorage::FindRegistrationForId, 190 &ServiceWorkerStorage::FindRegistrationForId,
261 weak_factory_.GetWeakPtr(), registration_id, origin, callback))) { 191 weak_factory_.GetWeakPtr(), registration_id, origin, callback))) {
262 if (state_ != INITIALIZING || !context_) 192 if (state_ != INITIALIZING || !context_) {
263 CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback); 193 CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
194 SERVICE_WORKER_ERROR_FAILED, callback);
195 }
264 return; 196 return;
265 } 197 }
266 DCHECK_EQ(INITIALIZED, state_); 198 DCHECK_EQ(INITIALIZED, state_);
267 199
268 // See if there are any stored registrations for the origin. 200 // See if there are any stored registrations for the origin.
269 if (!ContainsKey(registered_origins_, origin)) { 201 if (!ContainsKey(registered_origins_, origin)) {
270 // Look for somthing currently being installed. 202 // Look for something currently being installed.
271 scoped_refptr<ServiceWorkerRegistration> installing_registration = 203 scoped_refptr<ServiceWorkerRegistration> installing_registration =
272 FindInstallingRegistrationForId(registration_id); 204 FindInstallingRegistrationForId(registration_id);
273 if (installing_registration) {
274 CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
275 return;
276 }
277 CompleteFindNow( 205 CompleteFindNow(
278 null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback); 206 installing_registration,
207 installing_registration ?
208 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
209 callback);
279 return; 210 return;
280 } 211 }
281 212
282 scoped_refptr<ServiceWorkerRegistration> registration = 213 scoped_refptr<ServiceWorkerRegistration> registration =
283 context_->GetLiveRegistration(registration_id); 214 context_->GetLiveRegistration(registration_id);
284 if (registration) { 215 if (registration) {
285 CompleteFindNow(registration, SERVICE_WORKER_OK, callback); 216 CompleteFindNow(registration, SERVICE_WORKER_OK, callback);
286 return; 217 return;
287 } 218 }
288 219
289 ServiceWorkerDatabase::RegistrationData* data = 220 database_task_runner_->PostTask(
290 new ServiceWorkerDatabase::RegistrationData;
291 ResourceList* resources = new ResourceList;
292 PostTaskAndReplyWithResult(
293 database_task_runner_,
294 FROM_HERE, 221 FROM_HERE,
295 base::Bind(&ServiceWorkerDatabase::ReadRegistration, 222 base::Bind(&FindForIdInDB,
296 base::Unretained(database_.get()), 223 database_.get(),
224 base::MessageLoopProxy::current(),
297 registration_id, origin, 225 registration_id, origin,
298 base::Unretained(data), 226 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId,
299 base::Unretained(resources)), 227 weak_factory_.GetWeakPtr(), callback)));
300 base::Bind(&ServiceWorkerStorage::DidReadRegistrationForId,
301 weak_factory_.GetWeakPtr(),
302 callback, base::Owned(data), base::Owned(resources)));
303 } 228 }
304 229
305 void ServiceWorkerStorage::GetAllRegistrations( 230 void ServiceWorkerStorage::GetAllRegistrations(
306 const GetAllRegistrationInfosCallback& callback) { 231 const GetAllRegistrationInfosCallback& callback) {
307 if (!LazyInitialize(base::Bind( 232 if (!LazyInitialize(base::Bind(
308 &ServiceWorkerStorage::GetAllRegistrations, 233 &ServiceWorkerStorage::GetAllRegistrations,
309 weak_factory_.GetWeakPtr(), callback))) { 234 weak_factory_.GetWeakPtr(), callback))) {
310 if (state_ != INITIALIZING || !context_) { 235 if (state_ != INITIALIZING || !context_) {
311 RunSoon(FROM_HERE, base::Bind( 236 RunSoon(FROM_HERE, base::Bind(
312 callback, std::vector<ServiceWorkerRegistrationInfo>())); 237 callback, std::vector<ServiceWorkerRegistrationInfo>()));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 ServiceWorkerDatabase::RegistrationData data; 269 ServiceWorkerDatabase::RegistrationData data;
345 data.registration_id = registration->id(); 270 data.registration_id = registration->id();
346 data.scope = registration->pattern(); 271 data.scope = registration->pattern();
347 data.script = registration->script_url(); 272 data.script = registration->script_url();
348 data.has_fetch_handler = true; 273 data.has_fetch_handler = true;
349 data.version_id = version->version_id(); 274 data.version_id = version->version_id();
350 data.last_update_check = base::Time::Now(); 275 data.last_update_check = base::Time::Now();
351 data.is_active = false; // initially stored in the waiting state 276 data.is_active = false; // initially stored in the waiting state
352 277
353 ResourceList resources; 278 ResourceList resources;
354 PostTaskAndReplyWithResult( 279 version->script_cache_map()->GetResources(&resources);
355 database_task_runner_, 280
281 database_task_runner_->PostTask(
356 FROM_HERE, 282 FROM_HERE,
357 base::Bind(&ServiceWorkerDatabase::WriteRegistration, 283 base::Bind(&WriteRegistrationInDB,
358 base::Unretained(database_.get()), data, resources), 284 database_.get(),
359 base::Bind(&ServiceWorkerStorage::DidStoreRegistration, 285 base::MessageLoopProxy::current(),
360 weak_factory_.GetWeakPtr(), 286 data, resources,
361 registration->script_url().GetOrigin(), 287 base::Bind(&ServiceWorkerStorage::DidStoreRegistration,
362 callback)); 288 weak_factory_.GetWeakPtr(),
289 callback)));
363 } 290 }
364 291
365 void ServiceWorkerStorage::UpdateToActiveState( 292 void ServiceWorkerStorage::UpdateToActiveState(
366 ServiceWorkerRegistration* registration, 293 ServiceWorkerRegistration* registration,
367 const StatusCallback& callback) { 294 const StatusCallback& callback) {
368 DCHECK(registration); 295 DCHECK(registration);
369 296
370 DCHECK(state_ == INITIALIZED || state_ == DISABLED); 297 DCHECK(state_ == INITIALIZED || state_ == DISABLED);
371 if (state_ != INITIALIZED || !context_) { 298 if (state_ != INITIALIZED || !context_) {
372 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 299 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 void ServiceWorkerStorage::NotifyInstallingRegistration( 373 void ServiceWorkerStorage::NotifyInstallingRegistration(
447 ServiceWorkerRegistration* registration) { 374 ServiceWorkerRegistration* registration) {
448 installing_registrations_[registration->id()] = registration; 375 installing_registrations_[registration->id()] = registration;
449 } 376 }
450 377
451 void ServiceWorkerStorage::NotifyDoneInstallingRegistration( 378 void ServiceWorkerStorage::NotifyDoneInstallingRegistration(
452 ServiceWorkerRegistration* registration) { 379 ServiceWorkerRegistration* registration) {
453 installing_registrations_.erase(registration->id()); 380 installing_registrations_.erase(registration->id());
454 } 381 }
455 382
383 base::FilePath ServiceWorkerStorage::GetDatabasePath() {
384 if (path_.empty())
385 return base::FilePath();
386 return path_.Append(kDatabaseName);
387 }
388
389 base::FilePath ServiceWorkerStorage::GetDiskCachePath() {
390 if (path_.empty())
391 return base::FilePath();
392 return path_.Append(kDiskCacheName);
393 }
394
456 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { 395 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
457 if (!context_) 396 if (!context_)
458 return false; 397 return false;
459 398
460 switch (state_) { 399 switch (state_) {
461 case INITIALIZED: 400 case INITIALIZED:
462 return true; 401 return true;
463 case DISABLED: 402 case DISABLED:
464 return false; 403 return false;
465 case INITIALIZING: 404 case INITIALIZING:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 state_ = DISABLED; 439 state_ = DISABLED;
501 } 440 }
502 441
503 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); 442 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin();
504 it != pending_tasks_.end(); ++it) { 443 it != pending_tasks_.end(); ++it) {
505 RunSoon(FROM_HERE, *it); 444 RunSoon(FROM_HERE, *it);
506 } 445 }
507 pending_tasks_.clear(); 446 pending_tasks_.clear();
508 } 447 }
509 448
510 void ServiceWorkerStorage::DidGetRegistrationsForPattern( 449 void ServiceWorkerStorage::DidFindRegistrationForDocument(
511 const GURL& scope,
512 const FindRegistrationCallback& callback,
513 RegistrationList* registrations,
514 ServiceWorkerDatabase::Status status) {
515 DCHECK(registrations);
516 if (status != ServiceWorkerDatabase::STATUS_OK) {
517 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
518 callback.Run(SERVICE_WORKER_ERROR_FAILED,
519 scoped_refptr<ServiceWorkerRegistration>());
520 return;
521 }
522
523 // Find one with a matching scope.
524 for (RegistrationList::const_iterator it = registrations->begin();
525 it != registrations->end(); ++it) {
526 if (scope == it->scope) {
527 scoped_refptr<ServiceWorkerRegistration> registration =
528 context_->GetLiveRegistration(it->registration_id);
529 if (!registration)
530 registration = CreateRegistration(*it);
531 callback.Run(SERVICE_WORKER_OK, registration);
532 return;
533 }
534 }
535
536 // Look for something currently being installed.
537 scoped_refptr<ServiceWorkerRegistration> installing_registration =
538 FindInstallingRegistrationForPattern(scope);
539 if (installing_registration) {
540 callback.Run(SERVICE_WORKER_OK, installing_registration);
541 return;
542 }
543
544 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
545 scoped_refptr<ServiceWorkerRegistration>());
546 }
547
548 void ServiceWorkerStorage::DidGetRegistrationsForDocument(
549 const GURL& document_url, 450 const GURL& document_url,
550 const FindRegistrationCallback& callback, 451 const FindRegistrationCallback& callback,
551 RegistrationList* registrations, 452 const ServiceWorkerDatabase::RegistrationData& data,
453 const ResourceList& resources,
552 ServiceWorkerDatabase::Status status) { 454 ServiceWorkerDatabase::Status status) {
553 DCHECK(registrations);
554 if (status != ServiceWorkerDatabase::STATUS_OK) {
555 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
556 callback.Run(SERVICE_WORKER_ERROR_FAILED,
557 scoped_refptr<ServiceWorkerRegistration>());
558 return;
559 }
560
561 // Find one with a pattern match.
562 for (RegistrationList::const_iterator it = registrations->begin();
563 it != registrations->end(); ++it) {
564 // TODO(michaeln): if there are multiple matches the one with
565 // the longest scope should win.
566 if (ServiceWorkerUtils::ScopeMatches(it->scope, document_url)) {
567 scoped_refptr<ServiceWorkerRegistration> registration =
568 context_->GetLiveRegistration(it->registration_id);
569 if (registration) {
570 callback.Run(SERVICE_WORKER_OK, registration);
571 return;
572 }
573 callback.Run(SERVICE_WORKER_OK, CreateRegistration(*it));
574 return;
575 }
576 }
577
578 // Look for something currently being installed.
579 // TODO(michaeln): Should be mixed in with the stored registrations
580 // for this test.
581 scoped_refptr<ServiceWorkerRegistration> installing_registration =
582 FindInstallingRegistrationForDocument(document_url);
583 if (installing_registration) {
584 callback.Run(SERVICE_WORKER_OK, installing_registration);
585 return;
586 }
587
588 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
589 scoped_refptr<ServiceWorkerRegistration>());
590 }
591
592 void ServiceWorkerStorage::DidReadRegistrationForId(
593 const FindRegistrationCallback& callback,
594 ServiceWorkerDatabase::RegistrationData* registration,
595 ResourceList* resources,
596 ServiceWorkerDatabase::Status status) {
597 DCHECK(registration);
598 DCHECK(resources);
599
600 if (status == ServiceWorkerDatabase::STATUS_OK) { 455 if (status == ServiceWorkerDatabase::STATUS_OK) {
601 callback.Run(SERVICE_WORKER_OK, CreateRegistration(*registration)); 456 callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources));
602 return; 457 return;
603 } 458 }
604 459
605 if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { 460 if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
606 // Look for somthing currently being installed. 461 // Look for something currently being installed.
607 scoped_refptr<ServiceWorkerRegistration> installing_registration = 462 scoped_refptr<ServiceWorkerRegistration> installing_registration =
608 FindInstallingRegistrationForId(registration->registration_id); 463 FindInstallingRegistrationForDocument(document_url);
609 if (installing_registration) { 464 callback.Run(installing_registration ?
610 callback.Run(SERVICE_WORKER_OK, installing_registration); 465 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
611 return; 466 installing_registration);
612 }
613 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
614 scoped_refptr<ServiceWorkerRegistration>());
615 return; 467 return;
616 } 468 }
617 469
618 // TODO(nhiroki): Handle database error (http://crbug.com/371675). 470 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
619 callback.Run(DatabaseStatusToStatusCode(status), 471 callback.Run(DatabaseStatusToStatusCode(status),
620 scoped_refptr<ServiceWorkerRegistration>()); 472 scoped_refptr<ServiceWorkerRegistration>());
621 return; 473 }
474
475 void ServiceWorkerStorage::DidFindRegistrationForPattern(
476 const GURL& scope,
477 const FindRegistrationCallback& callback,
478 const ServiceWorkerDatabase::RegistrationData& data,
479 const ResourceList& resources,
480 ServiceWorkerDatabase::Status status) {
481 if (status == ServiceWorkerDatabase::STATUS_OK) {
482 callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources));
483 return;
484 }
485
486 if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
487 scoped_refptr<ServiceWorkerRegistration> installing_registration =
488 FindInstallingRegistrationForPattern(scope);
489 callback.Run(installing_registration ?
490 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
491 installing_registration);
492 return;
493 }
494
495 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
496 callback.Run(DatabaseStatusToStatusCode(status),
497 scoped_refptr<ServiceWorkerRegistration>());
498 }
499
500 void ServiceWorkerStorage::DidFindRegistrationForId(
501 const FindRegistrationCallback& callback,
502 const ServiceWorkerDatabase::RegistrationData& data,
503 const ResourceList& resources,
504 ServiceWorkerDatabase::Status status) {
505 if (status == ServiceWorkerDatabase::STATUS_OK) {
506 callback.Run(SERVICE_WORKER_OK,
507 GetOrCreateRegistration(data, resources));
508 return;
509 }
510 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
511 callback.Run(DatabaseStatusToStatusCode(status),
512 scoped_refptr<ServiceWorkerRegistration>());
nhiroki 2014/05/21 04:01:01 nit: indent
622 } 513 }
623 514
624 void ServiceWorkerStorage::DidGetAllRegistrations( 515 void ServiceWorkerStorage::DidGetAllRegistrations(
625 const GetAllRegistrationInfosCallback& callback, 516 const GetAllRegistrationInfosCallback& callback,
626 RegistrationList* registrations, 517 RegistrationList* registrations,
627 ServiceWorkerDatabase::Status status) { 518 ServiceWorkerDatabase::Status status) {
628 DCHECK(registrations); 519 DCHECK(registrations);
629 if (status != ServiceWorkerDatabase::STATUS_OK) { 520 if (status != ServiceWorkerDatabase::STATUS_OK) {
630 // TODO(nhiroki): Handle database error (http://crbug.com/371675). 521 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
631 callback.Run(std::vector<ServiceWorkerRegistrationInfo>()); 522 callback.Run(std::vector<ServiceWorkerRegistrationInfo>());
(...skipping 29 matching lines...) Expand all
661 installing_registrations_.begin(); 552 installing_registrations_.begin();
662 it != installing_registrations_.end(); ++it) { 553 it != installing_registrations_.end(); ++it) {
663 if (pushed_registrations.insert(it->first).second) 554 if (pushed_registrations.insert(it->first).second)
664 infos.push_back(it->second->GetInfo()); 555 infos.push_back(it->second->GetInfo());
665 } 556 }
666 557
667 callback.Run(infos); 558 callback.Run(infos);
668 } 559 }
669 560
670 void ServiceWorkerStorage::DidStoreRegistration( 561 void ServiceWorkerStorage::DidStoreRegistration(
562 const StatusCallback& callback,
671 const GURL& origin, 563 const GURL& origin,
672 const StatusCallback& callback, 564 const std::vector<int64>& newly_purgeable_resources,
673 ServiceWorkerDatabase::Status status) { 565 ServiceWorkerDatabase::Status status) {
674 if (status != ServiceWorkerDatabase::STATUS_OK) { 566 if (status != ServiceWorkerDatabase::STATUS_OK) {
675 // TODO(nhiroki): Handle database error (http://crbug.com/371675). 567 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
676 callback.Run(DatabaseStatusToStatusCode(status)); 568 callback.Run(DatabaseStatusToStatusCode(status));
677 return; 569 return;
678 } 570 }
679 registered_origins_.insert(origin); 571 registered_origins_.insert(origin);
680 callback.Run(SERVICE_WORKER_OK); 572 callback.Run(SERVICE_WORKER_OK);
573 StartPurgingResources(newly_purgeable_resources);
681 } 574 }
682 575
683 void ServiceWorkerStorage::DidUpdateToActiveState( 576 void ServiceWorkerStorage::DidUpdateToActiveState(
684 const StatusCallback& callback, 577 const StatusCallback& callback,
685 ServiceWorkerDatabase::Status status) { 578 ServiceWorkerDatabase::Status status) {
686 // TODO(nhiroki): Handle database error (http://crbug.com/371675). 579 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
687 callback.Run(DatabaseStatusToStatusCode(status)); 580 callback.Run(DatabaseStatusToStatusCode(status));
688 } 581 }
689 582
690 void ServiceWorkerStorage::DidDeleteRegistration( 583 void ServiceWorkerStorage::DidDeleteRegistration(
691 const GURL& origin, 584 const GURL& origin,
692 const StatusCallback& callback, 585 const StatusCallback& callback,
693 bool origin_is_deletable, 586 bool origin_is_deletable,
587 const std::vector<int64>& newly_purgeable_resources,
694 ServiceWorkerDatabase::Status status) { 588 ServiceWorkerDatabase::Status status) {
695 if (status != ServiceWorkerDatabase::STATUS_OK) { 589 if (status != ServiceWorkerDatabase::STATUS_OK) {
696 // TODO(nhiroki): Handle database error (http://crbug.com/371675). 590 // TODO(nhiroki): Handle database error (http://crbug.com/371675).
697 callback.Run(DatabaseStatusToStatusCode(status)); 591 callback.Run(DatabaseStatusToStatusCode(status));
698 return; 592 return;
699 } 593 }
700 if (origin_is_deletable) 594 if (origin_is_deletable)
701 registered_origins_.erase(origin); 595 registered_origins_.erase(origin);
702 callback.Run(SERVICE_WORKER_OK); 596 callback.Run(SERVICE_WORKER_OK);
597 StartPurgingResources(newly_purgeable_resources);
703 } 598 }
704 599
705 scoped_refptr<ServiceWorkerRegistration> 600 scoped_refptr<ServiceWorkerRegistration>
706 ServiceWorkerStorage::CreateRegistration( 601 ServiceWorkerStorage::GetOrCreateRegistration(
707 const ServiceWorkerDatabase::RegistrationData& data) { 602 const ServiceWorkerDatabase::RegistrationData& data,
708 scoped_refptr<ServiceWorkerRegistration> registration( 603 const ResourceList& resources) {
709 new ServiceWorkerRegistration( 604 scoped_refptr<ServiceWorkerRegistration> registration =
710 data.scope, data.script, data.registration_id, context_)); 605 context_->GetLiveRegistration(data.registration_id);
606 if (registration)
607 return registration;
711 608
609 registration = new ServiceWorkerRegistration(
nhiroki 2014/05/21 04:01:01 nit: There is an extra whitespace before "new".
610 data.scope, data.script, data.registration_id, context_);
712 scoped_refptr<ServiceWorkerVersion> version = 611 scoped_refptr<ServiceWorkerVersion> version =
713 context_->GetLiveVersion(data.version_id); 612 context_->GetLiveVersion(data.version_id);
714 if (!version) { 613 if (!version) {
715 version = new ServiceWorkerVersion(registration, data.version_id, context_); 614 version = new ServiceWorkerVersion(registration, data.version_id, context_);
716 version->SetStatus(data.is_active ? 615 version->SetStatus(data.is_active ?
717 ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED); 616 ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED);
617 version->script_cache_map()->SetResources(resources);
718 } 618 }
719 619
720 if (version->status() == ServiceWorkerVersion::ACTIVE) 620 if (version->status() == ServiceWorkerVersion::ACTIVE)
721 registration->set_active_version(version); 621 registration->set_active_version(version);
722 else if (version->status() == ServiceWorkerVersion::INSTALLED) 622 else if (version->status() == ServiceWorkerVersion::INSTALLED)
723 registration->set_pending_version(version); 623 registration->set_pending_version(version);
724 else 624 else
725 NOTREACHED(); 625 NOTREACHED();
726 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after 626 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after
727 // the Find result we're returning here? NOTREACHED condition? 627 // the Find result we're returning here? NOTREACHED condition?
728
729 return registration; 628 return registration;
730 } 629 }
731 630
732 ServiceWorkerRegistration* 631 ServiceWorkerRegistration*
733 ServiceWorkerStorage::FindInstallingRegistrationForDocument( 632 ServiceWorkerStorage::FindInstallingRegistrationForDocument(
734 const GURL& document_url) { 633 const GURL& document_url) {
735 // TODO(michaeln): if there are multiple matches the one with 634 // TODO(michaeln): if there are multiple matches the one with
736 // the longest scope should win, and these should on equal footing 635 // the longest scope should win.
737 // with the stored registrations in FindRegistrationForDocument().
738 for (RegistrationRefsById::const_iterator it = 636 for (RegistrationRefsById::const_iterator it =
739 installing_registrations_.begin(); 637 installing_registrations_.begin();
740 it != installing_registrations_.end(); ++it) { 638 it != installing_registrations_.end(); ++it) {
741 if (ServiceWorkerUtils::ScopeMatches( 639 if (ServiceWorkerUtils::ScopeMatches(
742 it->second->pattern(), document_url)) { 640 it->second->pattern(), document_url)) {
743 return it->second; 641 return it->second;
744 } 642 }
745 } 643 }
746 return NULL; 644 return NULL;
747 } 645 }
(...skipping 17 matching lines...) Expand all
765 installing_registrations_.find(registration_id); 663 installing_registrations_.find(registration_id);
766 if (found == installing_registrations_.end()) 664 if (found == installing_registrations_.end())
767 return NULL; 665 return NULL;
768 return found->second; 666 return found->second;
769 } 667 }
770 668
771 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { 669 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
772 if (disk_cache_) 670 if (disk_cache_)
773 return disk_cache_.get(); 671 return disk_cache_.get();
774 672
775 // TODO(michaeln): Store data on disk and do error checking.
776 disk_cache_.reset(new ServiceWorkerDiskCache); 673 disk_cache_.reset(new ServiceWorkerDiskCache);
777 int rv = disk_cache_->InitWithMemBackend( 674
778 kMaxMemDiskCacheSize, 675 base::FilePath path = GetDiskCachePath();
779 base::Bind(&EmptyCompletionCallback)); 676 if (path.empty()) {
780 DCHECK_EQ(net::OK, rv); 677 int rv = disk_cache_->InitWithMemBackend(
678 kMaxMemDiskCacheSize,
679 base::Bind(&EmptyCompletionCallback));
680 DCHECK_EQ(net::OK, rv);
681 return disk_cache_.get();
682 }
683
684 int rv = disk_cache_->InitWithDiskBackend(
685 path, kMaxDiskCacheSize, false,
686 disk_cache_thread_.get(),
687 base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized,
688 weak_factory_.GetWeakPtr()));
689 if (rv != net::ERR_IO_PENDING)
690 OnDiskCacheInitialized(rv);
691
781 return disk_cache_.get(); 692 return disk_cache_.get();
782 } 693 }
783 694
695 void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) {
696 if (rv != net::OK) {
697 LOG(ERROR) << "Failed to open the serviceworker diskcache.";
698 // TODO(michaeln): DeleteAndStartOver()
699 disk_cache_->Disable();
700 state_ = DISABLED;
701 }
702 }
703
704 void ServiceWorkerStorage::StartPurgingResources(
705 const std::vector<int64>& ids) {
706 for (size_t i = 0; i < ids.size(); ++i)
707 purgeable_reource_ids_.push_back(ids[i]);
708
709 if (purgeable_reource_ids_.empty() || is_purge_pending_)
710 return;
711
712 // Do one at a time until we're done, use RunSoon to avoid recursion when
713 // DoomEntry returns immediately.
714 is_purge_pending_ = true;
715 int64 id = purgeable_reource_ids_.front();
716 purgeable_reource_ids_.pop_front();
717 RunSoon(FROM_HERE,
718 base::Bind(&ServiceWorkerStorage::PurgeResource,
719 weak_factory_.GetWeakPtr(), id));
720 }
721
722 void ServiceWorkerStorage::PurgeResource(int64 id) {
723 DCHECK(is_purge_pending_);
724 disk_cache()->DoomEntry(
725 id, base::Bind(&ServiceWorkerStorage::OnResourcePurged,
726 weak_factory_.GetWeakPtr(), id));
727 }
728
729 void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) {
730 DCHECK(is_purge_pending_);
731 is_purge_pending_ = false;
732
733 database_task_runner_->PostTask(
734 FROM_HERE,
735 base::Bind(base::IgnoreResult(
736 &ServiceWorkerDatabase::ClearPurgeableResourceIds),
737 base::Unretained(database_.get()),
738 std::set<int64>(&id, &id + 1)));
739
740 // Continue purging the remaining resources.
741 StartPurgingResources(std::vector<int64>());
742 }
743
744 void ServiceWorkerStorage::ReadInitialDataFromDB(
745 ServiceWorkerDatabase* database,
746 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
747 const InitializeCallback& callback) {
748 DCHECK(database);
749 scoped_ptr<ServiceWorkerStorage::InitialData> data(
750 new ServiceWorkerStorage::InitialData());
751
752 ServiceWorkerDatabase::Status status =
753 database->GetNextAvailableIds(&data->next_registration_id,
754 &data->next_version_id,
755 &data->next_resource_id);
756 if (status != ServiceWorkerDatabase::STATUS_OK) {
757 original_task_runner->PostTask(
758 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
759 return;
760 }
761
762 status = database->GetOriginsWithRegistrations(&data->origins);
763 original_task_runner->PostTask(
764 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
765 }
766
767 void ServiceWorkerStorage::DeleteRegistrationFromDB(
768 ServiceWorkerDatabase* database,
769 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
770 int64 registration_id,
771 const GURL& origin,
772 const DeleteRegistrationCallback& callback) {
773 DCHECK(database);
774
775 std::vector<int64> newly_purgeable_resources;
776 ServiceWorkerDatabase::Status status =
777 database->DeleteRegistration(registration_id, origin,
778 &newly_purgeable_resources);
779 if (status != ServiceWorkerDatabase::STATUS_OK) {
780 original_task_runner->PostTask(
781 FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status));
782 return;
783 }
784
785 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the
786 // unique origin list.
787 std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
788 status = database->GetRegistrationsForOrigin(origin, &registrations);
789 if (status != ServiceWorkerDatabase::STATUS_OK) {
790 original_task_runner->PostTask(
791 FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status));
792 return;
793 }
794
795 bool deletable = registrations.empty();
796 original_task_runner->PostTask(
797 FROM_HERE, base::Bind(callback, deletable,
798 newly_purgeable_resources, status));
799 }
800
801 void ServiceWorkerStorage::WriteRegistrationInDB(
802 ServiceWorkerDatabase* database,
803 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
804 const ServiceWorkerDatabase::RegistrationData& data,
805 const ResourceList& resources,
806 const WriteRegistrationCallback& callback) {
807 DCHECK(database);
808 std::vector<int64> newly_purgeable_resources;
809 ServiceWorkerDatabase::Status status =
810 database->WriteRegistration(data, resources, &newly_purgeable_resources);
811 original_task_runner->PostTask(
812 FROM_HERE,
813 base::Bind(callback, data.script.GetOrigin(),
814 newly_purgeable_resources, status));
815 }
816
817 void ServiceWorkerStorage::FindForDocumentInDB(
818 ServiceWorkerDatabase* database,
819 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
820 const GURL& document_url,
821 const FindInDBCallback& callback) {
822 GURL origin = document_url.GetOrigin();
823 RegistrationList registrations;
824 ServiceWorkerDatabase::Status status =
825 database->GetRegistrationsForOrigin(origin, &registrations);
826 if (status != ServiceWorkerDatabase::STATUS_OK) {
827 original_task_runner->PostTask(
828 FROM_HERE,
829 base::Bind(callback,
830 ServiceWorkerDatabase::RegistrationData(),
831 ResourceList(),
832 status));
833 return;
834 }
835
836 // Find one with a pattern match.
837 // TODO(michaeln): if there are multiple matches the one with
838 // the longest scope should win.
839 ServiceWorkerDatabase::RegistrationData data;
840 ResourceList resources;
841 status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND;
842 for (RegistrationList::const_iterator it = registrations.begin();
843 it != registrations.end(); ++it) {
844 if (!ServiceWorkerUtils::ScopeMatches(it->scope, document_url))
845 continue;
846 status = database->ReadRegistration(it->registration_id, origin,
847 &data, &resources);
848 break; // We're done looping.
849 }
850
851 original_task_runner->PostTask(
852 FROM_HERE,
853 base::Bind(callback, data, resources, status));
854 }
855
856 void ServiceWorkerStorage::FindForPatternInDB(
857 ServiceWorkerDatabase* database,
858 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
859 const GURL& scope,
860 const FindInDBCallback& callback) {
861 GURL origin = scope.GetOrigin();
862 std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
863 ServiceWorkerDatabase::Status status =
864 database->GetRegistrationsForOrigin(origin, &registrations);
865 if (status != ServiceWorkerDatabase::STATUS_OK) {
866 original_task_runner->PostTask(
867 FROM_HERE,
868 base::Bind(callback,
869 ServiceWorkerDatabase::RegistrationData(),
870 ResourceList(),
871 status));
872 return;
873 }
874
875 // Find one with an exact matching scope.
876 ServiceWorkerDatabase::RegistrationData data;
877 ResourceList resources;
878 status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND;
879 for (RegistrationList::const_iterator it = registrations.begin();
880 it != registrations.end(); ++it) {
881 if (scope != it->scope)
882 continue;
883 status = database->ReadRegistration(it->registration_id, origin,
884 &data, &resources);
885 break; // We're done looping.
886 }
887
888 original_task_runner->PostTask(
889 FROM_HERE,
890 base::Bind(callback, data, resources, status));
891 }
892
893 void ServiceWorkerStorage::FindForIdInDB(
894 ServiceWorkerDatabase* database,
895 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
896 int64 registration_id,
897 const GURL& origin,
898 const FindInDBCallback& callback) {
899 ServiceWorkerDatabase::RegistrationData data;
900 ResourceList resources;
901 ServiceWorkerDatabase::Status status =
902 database->ReadRegistration(registration_id, origin, &data, &resources);
903 original_task_runner->PostTask(
904 FROM_HERE, base::Bind(callback, data, resources, status));
905 }
906
784 } // namespace content 907 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_storage.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698