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 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
9 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
| 11 #include "content/browser/service_worker/service_worker_database.pb.h" |
10 #include "content/browser/service_worker/service_worker_info.h" | 12 #include "content/browser/service_worker/service_worker_info.h" |
11 #include "content/browser/service_worker/service_worker_registration.h" | 13 #include "content/browser/service_worker/service_worker_registration.h" |
12 #include "content/browser/service_worker/service_worker_utils.h" | 14 #include "content/browser/service_worker/service_worker_utils.h" |
13 #include "content/browser/service_worker/service_worker_version.h" | 15 #include "content/browser/service_worker/service_worker_version.h" |
14 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
15 #include "webkit/browser/quota/quota_manager_proxy.h" | 17 #include "webkit/browser/quota/quota_manager_proxy.h" |
16 | 18 |
17 namespace content { | 19 namespace content { |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 void RunSoon(const base::Closure& closure) { | 23 void RunSoon(const base::Closure& closure) { |
22 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | 24 base::MessageLoop::current()->PostTask(FROM_HERE, closure); |
23 } | 25 } |
24 | 26 |
25 const base::FilePath::CharType kServiceWorkerDirectory[] = | 27 const base::FilePath::CharType kServiceWorkerDirectory[] = |
26 FILE_PATH_LITERAL("ServiceWorker"); | 28 FILE_PATH_LITERAL("ServiceWorker"); |
27 | 29 |
| 30 ServiceWorkerVersion::Status GetVersionStatus(bool is_active) { |
| 31 return is_active ? ServiceWorkerVersion::ACTIVE |
| 32 : ServiceWorkerVersion::INSTALLED; |
| 33 } |
| 34 |
28 } // namespace | 35 } // namespace |
29 | 36 |
30 ServiceWorkerStorage::ServiceWorkerStorage( | 37 ServiceWorkerStorage::ServiceWorkerStorage( |
31 const base::FilePath& path, | 38 const base::FilePath& path, |
32 base::WeakPtr<ServiceWorkerContextCore> context, | 39 base::WeakPtr<ServiceWorkerContextCore> context, |
33 quota::QuotaManagerProxy* quota_manager_proxy) | 40 quota::QuotaManagerProxy* quota_manager_proxy) |
34 : last_registration_id_(0), | 41 : last_registration_id_(0), |
35 last_version_id_(0), | 42 last_version_id_(0), |
36 last_resource_id_(0), | 43 last_resource_id_(0), |
37 simulated_lazy_initted_(false), | 44 simulated_lazy_initted_(false), |
(...skipping 24 matching lines...) Expand all Loading... |
62 if (found == stored_registrations_.end()) { | 69 if (found == stored_registrations_.end()) { |
63 RunSoon(base::Bind( | 70 RunSoon(base::Bind( |
64 callback, SERVICE_WORKER_ERROR_NOT_FOUND, | 71 callback, SERVICE_WORKER_ERROR_NOT_FOUND, |
65 null_registration)); | 72 null_registration)); |
66 return; | 73 return; |
67 } | 74 } |
68 | 75 |
69 // Find one with a matching scope. | 76 // Find one with a matching scope. |
70 for (RegistrationsMap::const_iterator it = found->second.begin(); | 77 for (RegistrationsMap::const_iterator it = found->second.begin(); |
71 it != found->second.end(); ++it) { | 78 it != found->second.end(); ++it) { |
72 if (scope == it->second.scope) { | 79 if (scope == GURL(it->second.scope_url())) { |
73 const ServiceWorkerDatabase::RegistrationData* data = &(it->second); | 80 const ServiceWorkerRegistrationData* data = &(it->second); |
74 scoped_refptr<ServiceWorkerRegistration> registration = | 81 scoped_refptr<ServiceWorkerRegistration> registration = |
75 context_->GetLiveRegistration(data->registration_id); | 82 context_->GetLiveRegistration(data->registration_id()); |
76 if (registration) { | 83 if (registration) { |
77 RunSoon(base::Bind( | 84 RunSoon(base::Bind( |
78 callback, SERVICE_WORKER_OK, | 85 callback, SERVICE_WORKER_OK, |
79 registration)); | 86 registration)); |
80 return; | 87 return; |
81 } | 88 } |
82 | 89 |
83 registration = CreateRegistration(data); | 90 registration = CreateRegistration(data); |
84 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); | 91 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); |
85 return; | 92 return; |
(...skipping 23 matching lines...) Expand all Loading... |
109 // origins with registrations. | 116 // origins with registrations. |
110 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, null_registration); | 117 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, null_registration); |
111 return; | 118 return; |
112 } | 119 } |
113 | 120 |
114 // Find one with a pattern match. | 121 // Find one with a pattern match. |
115 for (RegistrationsMap::const_iterator it = found->second.begin(); | 122 for (RegistrationsMap::const_iterator it = found->second.begin(); |
116 it != found->second.end(); ++it) { | 123 it != found->second.end(); ++it) { |
117 // TODO(michaeln): if there are multiple matches the one with | 124 // TODO(michaeln): if there are multiple matches the one with |
118 // the longest scope should win. | 125 // the longest scope should win. |
119 if (ServiceWorkerUtils::ScopeMatches(it->second.scope, document_url)) { | 126 if (ServiceWorkerUtils::ScopeMatches( |
120 const ServiceWorkerDatabase::RegistrationData* data = &(it->second); | 127 GURL(it->second.scope_url()), document_url)) { |
| 128 const ServiceWorkerRegistrationData* data = &(it->second); |
121 | 129 |
122 // If its in the live map, return syncly to simulate this class having | 130 // If its in the live map, return syncly to simulate this class having |
123 // iterated over the values in that map instead of reading the db. | 131 // iterated over the values in that map instead of reading the db. |
124 scoped_refptr<ServiceWorkerRegistration> registration = | 132 scoped_refptr<ServiceWorkerRegistration> registration = |
125 context_->GetLiveRegistration(data->registration_id); | 133 context_->GetLiveRegistration(data->registration_id()); |
126 if (registration) { | 134 if (registration) { |
127 callback.Run(SERVICE_WORKER_OK, registration); | 135 callback.Run(SERVICE_WORKER_OK, registration); |
128 return; | 136 return; |
129 } | 137 } |
130 | 138 |
131 // If we have to create a new instance, return it asyncly to simulate | 139 // If we have to create a new instance, return it asyncly to simulate |
132 // having had to retreive the RegistrationData from the db. | 140 // having had to retreive the RegistrationData from the db. |
133 registration = CreateRegistration(data); | 141 registration = CreateRegistration(data); |
134 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); | 142 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); |
135 return; | 143 return; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 | 187 |
180 for (RegistrationPtrMap::const_iterator it = registrations_by_id_.begin(); | 188 for (RegistrationPtrMap::const_iterator it = registrations_by_id_.begin(); |
181 it != registrations_by_id_.end(); ++it) { | 189 it != registrations_by_id_.end(); ++it) { |
182 ServiceWorkerRegistration* registration = | 190 ServiceWorkerRegistration* registration = |
183 context_->GetLiveRegistration(it->first); | 191 context_->GetLiveRegistration(it->first); |
184 if (registration) { | 192 if (registration) { |
185 registrations.push_back(registration->GetInfo()); | 193 registrations.push_back(registration->GetInfo()); |
186 continue; | 194 continue; |
187 } | 195 } |
188 ServiceWorkerRegistrationInfo info; | 196 ServiceWorkerRegistrationInfo info; |
189 info.pattern = it->second->scope; | 197 info.pattern = GURL(it->second->scope_url()); |
190 info.script_url = it->second->script; | 198 info.script_url = GURL(it->second->script_url()); |
191 info.active_version.is_null = false; | 199 info.active_version.is_null = false; |
192 if (it->second->is_active) | 200 if (it->second->is_active()) |
193 info.active_version.status = ServiceWorkerVersion::ACTIVE; | 201 info.active_version.status = ServiceWorkerVersion::ACTIVE; |
194 else | 202 else |
195 info.active_version.status = ServiceWorkerVersion::INSTALLED; | 203 info.active_version.status = ServiceWorkerVersion::INSTALLED; |
196 registrations.push_back(info); | 204 registrations.push_back(info); |
197 } | 205 } |
198 | 206 |
199 RunSoon(base::Bind(callback, registrations)); | 207 RunSoon(base::Bind(callback, registrations)); |
200 } | 208 } |
201 | 209 |
202 void ServiceWorkerStorage::StoreRegistration( | 210 void ServiceWorkerStorage::StoreRegistration( |
203 ServiceWorkerRegistration* registration, | 211 ServiceWorkerRegistration* registration, |
204 ServiceWorkerVersion* version, | 212 ServiceWorkerVersion* version, |
205 const StatusCallback& callback) { | 213 const StatusCallback& callback) { |
206 DCHECK(registration); | 214 DCHECK(registration); |
207 DCHECK(version); | 215 DCHECK(version); |
208 DCHECK(simulated_lazy_initted_); | 216 DCHECK(simulated_lazy_initted_); |
209 if (!context_) { | 217 if (!context_) { |
210 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); | 218 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
211 return; | 219 return; |
212 } | 220 } |
213 | 221 |
214 // Keep a database struct in the storage map. | 222 // Keep a database struct in the storage map. |
215 RegistrationsMap& storage_map = | 223 RegistrationsMap& storage_map = |
216 stored_registrations_[registration->script_url().GetOrigin()]; | 224 stored_registrations_[registration->script_url().GetOrigin()]; |
217 ServiceWorkerDatabase::RegistrationData& data = | 225 ServiceWorkerRegistrationData& data = storage_map[registration->id()]; |
218 storage_map[registration->id()]; | 226 data.set_registration_id(registration->id()); |
219 data.registration_id = registration->id(); | 227 data.set_scope_url(registration->pattern().spec()); |
220 data.scope = registration->pattern(); | 228 data.set_script_url(registration->script_url().spec()); |
221 data.script = registration->script_url(); | 229 data.set_has_fetch_handler(true); |
222 data.has_fetch_handler = true; | 230 data.set_version_id(version->version_id()); |
223 data.version_id = version->version_id(); | 231 data.set_last_update_check_time(base::Time::Now().ToInternalValue()); |
224 data.last_update_check = base::Time::Now(); | 232 data.set_is_active(false); // initially stored in the waiting state |
225 data.is_active = false; // initially stored in the waiting state | |
226 | 233 |
227 // Keep a seperate map of ptrs keyed by id only. | 234 // Keep a seperate map of ptrs keyed by id only. |
228 registrations_by_id_[registration->id()] = &storage_map[registration->id()]; | 235 registrations_by_id_[registration->id()] = &storage_map[registration->id()]; |
229 | 236 |
230 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 237 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
231 } | 238 } |
232 | 239 |
233 void ServiceWorkerStorage::UpdateToActiveState( | 240 void ServiceWorkerStorage::UpdateToActiveState( |
234 ServiceWorkerRegistration* registration, | 241 ServiceWorkerRegistration* registration, |
235 const StatusCallback& callback) { | 242 const StatusCallback& callback) { |
236 DCHECK(simulated_lazy_initted_); | 243 DCHECK(simulated_lazy_initted_); |
237 if (!context_) { | 244 if (!context_) { |
238 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); | 245 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
239 return; | 246 return; |
240 } | 247 } |
241 | 248 |
242 RegistrationPtrMap::const_iterator | 249 RegistrationPtrMap::const_iterator |
243 found = registrations_by_id_.find(registration->id()); | 250 found = registrations_by_id_.find(registration->id()); |
244 if (found == registrations_by_id_.end()) { | 251 if (found == registrations_by_id_.end()) { |
245 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); | 252 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); |
246 return; | 253 return; |
247 } | 254 } |
248 DCHECK(!found->second->is_active); | 255 DCHECK(!found->second->is_active()); |
249 found->second->is_active = true; | 256 found->second->set_is_active(true); |
250 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 257 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
251 } | 258 } |
252 | 259 |
253 void ServiceWorkerStorage::DeleteRegistration( | 260 void ServiceWorkerStorage::DeleteRegistration( |
254 int64 registration_id, | 261 int64 registration_id, |
255 const StatusCallback& callback) { | 262 const StatusCallback& callback) { |
256 DCHECK(simulated_lazy_initted_); | 263 DCHECK(simulated_lazy_initted_); |
257 RegistrationPtrMap::iterator | 264 RegistrationPtrMap::iterator |
258 found = registrations_by_id_.find(registration_id); | 265 found = registrations_by_id_.find(registration_id); |
259 if (found == registrations_by_id_.end()) { | 266 if (found == registrations_by_id_.end()) { |
260 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); | 267 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); |
261 return; | 268 return; |
262 } | 269 } |
263 | 270 |
264 GURL origin = found->second->script.GetOrigin(); | 271 GURL origin = GURL(found->second->script_url()).GetOrigin(); |
265 stored_registrations_[origin].erase(registration_id); | 272 stored_registrations_[origin].erase(registration_id); |
266 if (stored_registrations_[origin].empty()) | 273 if (stored_registrations_[origin].empty()) |
267 stored_registrations_.erase(origin); | 274 stored_registrations_.erase(origin); |
268 | 275 |
269 registrations_by_id_.erase(found); | 276 registrations_by_id_.erase(found); |
270 | 277 |
271 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 278 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
272 // TODO(michaeln): Either its instance should also be | 279 // TODO(michaeln): Either its instance should also be |
273 // removed from liveregistrations map or the live object | 280 // removed from liveregistrations map or the live object |
274 // should marked as deleted in some way and not 'findable' | 281 // should marked as deleted in some way and not 'findable' |
(...skipping 10 matching lines...) Expand all Loading... |
285 return ++last_version_id_; | 292 return ++last_version_id_; |
286 } | 293 } |
287 | 294 |
288 int64 ServiceWorkerStorage::NewResourceId() { | 295 int64 ServiceWorkerStorage::NewResourceId() { |
289 DCHECK(simulated_lazy_initted_); | 296 DCHECK(simulated_lazy_initted_); |
290 return ++last_resource_id_; | 297 return ++last_resource_id_; |
291 } | 298 } |
292 | 299 |
293 scoped_refptr<ServiceWorkerRegistration> | 300 scoped_refptr<ServiceWorkerRegistration> |
294 ServiceWorkerStorage::CreateRegistration( | 301 ServiceWorkerStorage::CreateRegistration( |
295 const ServiceWorkerDatabase::RegistrationData* data) { | 302 const ServiceWorkerRegistrationData* data) { |
296 scoped_refptr<ServiceWorkerRegistration> registration( | 303 scoped_refptr<ServiceWorkerRegistration> registration( |
297 new ServiceWorkerRegistration( | 304 new ServiceWorkerRegistration( |
298 data->scope, data->script, data->registration_id, context_)); | 305 GURL(data->scope_url()), GURL(data->script_url()), |
| 306 data->registration_id(), context_)); |
299 | 307 |
300 scoped_refptr<ServiceWorkerVersion> version = | 308 scoped_refptr<ServiceWorkerVersion> version = |
301 context_->GetLiveVersion(data->version_id); | 309 context_->GetLiveVersion(data->version_id()); |
302 if (!version) { | 310 if (!version) { |
303 version = new ServiceWorkerVersion( | 311 version = new ServiceWorkerVersion( |
304 registration, data->version_id, context_); | 312 registration, data->version_id(), context_); |
305 version->SetStatus(data->GetVersionStatus()); | 313 version->SetStatus(GetVersionStatus(data->is_active())); |
306 } | 314 } |
307 | 315 |
308 if (version->status() == ServiceWorkerVersion::ACTIVE) | 316 if (version->status() == ServiceWorkerVersion::ACTIVE) |
309 registration->set_active_version(version); | 317 registration->set_active_version(version); |
310 else if (version->status() == ServiceWorkerVersion::INSTALLED) | 318 else if (version->status() == ServiceWorkerVersion::INSTALLED) |
311 registration->set_pending_version(version); | 319 registration->set_pending_version(version); |
312 else | 320 else |
313 NOTREACHED(); | 321 NOTREACHED(); |
314 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after | 322 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after |
315 // the Find result we're returning here? NOTREACHED condition? | 323 // the Find result we're returning here? NOTREACHED condition? |
316 | 324 |
317 return registration; | 325 return registration; |
318 } | 326 } |
319 | 327 |
320 } // namespace content | 328 } // namespace content |
OLD | NEW |