OLD | NEW |
---|---|
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, ®istrations); | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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>()); | |
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 Loading... | |
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( | |
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 Loading... | |
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 int rv = disk_cache()->DoomEntry( | |
725 id, base::Bind(&ServiceWorkerStorage::OnResourcePurged, | |
726 weak_factory_.GetWeakPtr(), id)); | |
727 if (rv != net::ERR_IO_PENDING) | |
728 OnResourcePurged(id, rv); | |
nhiroki
2014/05/22 01:20:13
I see... DoomEntry() will run the callback only wh
michaeln
2014/05/22 02:02:37
yes, that flavor of async or not completion is com
| |
729 } | |
730 | |
731 void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) { | |
732 DCHECK(is_purge_pending_); | |
733 is_purge_pending_ = false; | |
734 | |
735 database_task_runner_->PostTask( | |
736 FROM_HERE, | |
737 base::Bind(base::IgnoreResult( | |
738 &ServiceWorkerDatabase::ClearPurgeableResourceIds), | |
739 base::Unretained(database_.get()), | |
740 std::set<int64>(&id, &id + 1))); | |
741 | |
742 // Continue purging the remaining resources. | |
743 StartPurgingResources(std::vector<int64>()); | |
744 } | |
745 | |
746 void ServiceWorkerStorage::ReadInitialDataFromDB( | |
747 ServiceWorkerDatabase* database, | |
748 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
749 const InitializeCallback& callback) { | |
750 DCHECK(database); | |
751 scoped_ptr<ServiceWorkerStorage::InitialData> data( | |
752 new ServiceWorkerStorage::InitialData()); | |
753 | |
754 ServiceWorkerDatabase::Status status = | |
755 database->GetNextAvailableIds(&data->next_registration_id, | |
756 &data->next_version_id, | |
757 &data->next_resource_id); | |
758 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
759 original_task_runner->PostTask( | |
760 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); | |
761 return; | |
762 } | |
763 | |
764 status = database->GetOriginsWithRegistrations(&data->origins); | |
765 original_task_runner->PostTask( | |
766 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); | |
767 } | |
768 | |
769 void ServiceWorkerStorage::DeleteRegistrationFromDB( | |
770 ServiceWorkerDatabase* database, | |
771 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
772 int64 registration_id, | |
773 const GURL& origin, | |
774 const DeleteRegistrationCallback& callback) { | |
775 DCHECK(database); | |
776 | |
777 std::vector<int64> newly_purgeable_resources; | |
778 ServiceWorkerDatabase::Status status = | |
779 database->DeleteRegistration(registration_id, origin, | |
780 &newly_purgeable_resources); | |
781 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
782 original_task_runner->PostTask( | |
783 FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status)); | |
784 return; | |
785 } | |
786 | |
787 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the | |
788 // unique origin list. | |
789 std::vector<ServiceWorkerDatabase::RegistrationData> registrations; | |
790 status = database->GetRegistrationsForOrigin(origin, ®istrations); | |
791 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
792 original_task_runner->PostTask( | |
793 FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status)); | |
794 return; | |
795 } | |
796 | |
797 bool deletable = registrations.empty(); | |
798 original_task_runner->PostTask( | |
799 FROM_HERE, base::Bind(callback, deletable, | |
800 newly_purgeable_resources, status)); | |
801 } | |
802 | |
803 void ServiceWorkerStorage::WriteRegistrationInDB( | |
804 ServiceWorkerDatabase* database, | |
805 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
806 const ServiceWorkerDatabase::RegistrationData& data, | |
807 const ResourceList& resources, | |
808 const WriteRegistrationCallback& callback) { | |
809 DCHECK(database); | |
810 std::vector<int64> newly_purgeable_resources; | |
811 ServiceWorkerDatabase::Status status = | |
812 database->WriteRegistration(data, resources, &newly_purgeable_resources); | |
813 original_task_runner->PostTask( | |
814 FROM_HERE, | |
815 base::Bind(callback, data.script.GetOrigin(), | |
816 newly_purgeable_resources, status)); | |
817 } | |
818 | |
819 void ServiceWorkerStorage::FindForDocumentInDB( | |
820 ServiceWorkerDatabase* database, | |
821 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
822 const GURL& document_url, | |
823 const FindInDBCallback& callback) { | |
824 GURL origin = document_url.GetOrigin(); | |
825 RegistrationList registrations; | |
826 ServiceWorkerDatabase::Status status = | |
827 database->GetRegistrationsForOrigin(origin, ®istrations); | |
828 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
829 original_task_runner->PostTask( | |
830 FROM_HERE, | |
831 base::Bind(callback, | |
832 ServiceWorkerDatabase::RegistrationData(), | |
833 ResourceList(), | |
834 status)); | |
835 return; | |
836 } | |
837 | |
838 // Find one with a pattern match. | |
839 // TODO(michaeln): if there are multiple matches the one with | |
840 // the longest scope should win. | |
841 ServiceWorkerDatabase::RegistrationData data; | |
842 ResourceList resources; | |
843 status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND; | |
844 for (RegistrationList::const_iterator it = registrations.begin(); | |
845 it != registrations.end(); ++it) { | |
846 if (!ServiceWorkerUtils::ScopeMatches(it->scope, document_url)) | |
847 continue; | |
848 status = database->ReadRegistration(it->registration_id, origin, | |
849 &data, &resources); | |
850 break; // We're done looping. | |
851 } | |
852 | |
853 original_task_runner->PostTask( | |
854 FROM_HERE, | |
855 base::Bind(callback, data, resources, status)); | |
856 } | |
857 | |
858 void ServiceWorkerStorage::FindForPatternInDB( | |
859 ServiceWorkerDatabase* database, | |
860 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
861 const GURL& scope, | |
862 const FindInDBCallback& callback) { | |
863 GURL origin = scope.GetOrigin(); | |
864 std::vector<ServiceWorkerDatabase::RegistrationData> registrations; | |
865 ServiceWorkerDatabase::Status status = | |
866 database->GetRegistrationsForOrigin(origin, ®istrations); | |
867 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
868 original_task_runner->PostTask( | |
869 FROM_HERE, | |
870 base::Bind(callback, | |
871 ServiceWorkerDatabase::RegistrationData(), | |
872 ResourceList(), | |
873 status)); | |
874 return; | |
875 } | |
876 | |
877 // Find one with an exact matching scope. | |
878 ServiceWorkerDatabase::RegistrationData data; | |
879 ResourceList resources; | |
880 status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND; | |
881 for (RegistrationList::const_iterator it = registrations.begin(); | |
882 it != registrations.end(); ++it) { | |
883 if (scope != it->scope) | |
884 continue; | |
885 status = database->ReadRegistration(it->registration_id, origin, | |
886 &data, &resources); | |
887 break; // We're done looping. | |
888 } | |
889 | |
890 original_task_runner->PostTask( | |
891 FROM_HERE, | |
892 base::Bind(callback, data, resources, status)); | |
893 } | |
894 | |
895 void ServiceWorkerStorage::FindForIdInDB( | |
896 ServiceWorkerDatabase* database, | |
897 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
898 int64 registration_id, | |
899 const GURL& origin, | |
900 const FindInDBCallback& callback) { | |
901 ServiceWorkerDatabase::RegistrationData data; | |
902 ResourceList resources; | |
903 ServiceWorkerDatabase::Status status = | |
904 database->ReadRegistration(registration_id, origin, &data, &resources); | |
905 original_task_runner->PostTask( | |
906 FROM_HERE, base::Bind(callback, data, resources, status)); | |
907 } | |
908 | |
784 } // namespace content | 909 } // namespace content |
OLD | NEW |