| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_database.h" | 5 #include "content/browser/service_worker/service_worker_database.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 GURL url(record.url()); | 204 GURL url(record.url()); |
| 205 if (!url.is_valid()) | 205 if (!url.is_valid()) |
| 206 return false; | 206 return false; |
| 207 | 207 |
| 208 // Convert ServiceWorkerResourceRecord to ResourceRecord. | 208 // Convert ServiceWorkerResourceRecord to ResourceRecord. |
| 209 out->resource_id = record.resource_id(); | 209 out->resource_id = record.resource_id(); |
| 210 out->url = url; | 210 out->url = url; |
| 211 return true; | 211 return true; |
| 212 } | 212 } |
| 213 | 213 |
| 214 ServiceWorkerStatusCode LevelDBStatusToServiceWorkerStatusCode( |
| 215 const leveldb::Status& status) { |
| 216 if (status.ok()) |
| 217 return SERVICE_WORKER_OK; |
| 218 else if (status.IsNotFound()) |
| 219 return SERVICE_WORKER_ERROR_NOT_FOUND; |
| 220 else if (status.IsCorruption()) |
| 221 return SERVICE_WORKER_ERROR_DB_CORRUPTED; |
| 222 else |
| 223 return SERVICE_WORKER_ERROR_FAILED; |
| 224 } |
| 225 |
| 214 } // namespace | 226 } // namespace |
| 215 | 227 |
| 216 ServiceWorkerDatabase::RegistrationData::RegistrationData() | 228 ServiceWorkerDatabase::RegistrationData::RegistrationData() |
| 217 : registration_id(-1), | 229 : registration_id(-1), |
| 218 version_id(-1), | 230 version_id(-1), |
| 219 is_active(false), | 231 is_active(false), |
| 220 has_fetch_handler(false) { | 232 has_fetch_handler(false) { |
| 221 } | 233 } |
| 222 | 234 |
| 223 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { | 235 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { |
| 224 } | 236 } |
| 225 | 237 |
| 226 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) | 238 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) |
| 227 : path_(path), | 239 : path_(path), |
| 228 next_avail_registration_id_(0), | 240 next_avail_registration_id_(0), |
| 229 next_avail_resource_id_(0), | 241 next_avail_resource_id_(0), |
| 230 next_avail_version_id_(0), | 242 next_avail_version_id_(0), |
| 231 is_disabled_(false), | 243 is_disabled_(false), |
| 232 was_corruption_detected_(false), | 244 was_corruption_detected_(false), |
| 233 is_initialized_(false) { | 245 is_initialized_(false) { |
| 234 sequence_checker_.DetachFromSequence(); | 246 sequence_checker_.DetachFromSequence(); |
| 235 } | 247 } |
| 236 | 248 |
| 237 ServiceWorkerDatabase::~ServiceWorkerDatabase() { | 249 ServiceWorkerDatabase::~ServiceWorkerDatabase() { |
| 238 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 250 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 239 db_.reset(); | 251 db_.reset(); |
| 240 } | 252 } |
| 241 | 253 |
| 242 bool ServiceWorkerDatabase::GetNextAvailableIds( | 254 ServiceWorkerStatusCode ServiceWorkerDatabase::GetNextAvailableIds( |
| 243 int64* next_avail_registration_id, | 255 int64* next_avail_registration_id, |
| 244 int64* next_avail_version_id, | 256 int64* next_avail_version_id, |
| 245 int64* next_avail_resource_id) { | 257 int64* next_avail_resource_id) { |
| 246 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 258 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 247 DCHECK(next_avail_registration_id); | 259 DCHECK(next_avail_registration_id); |
| 248 DCHECK(next_avail_version_id); | 260 DCHECK(next_avail_version_id); |
| 249 DCHECK(next_avail_resource_id); | 261 DCHECK(next_avail_resource_id); |
| 250 | 262 |
| 251 if (!LazyOpen(false)) { | 263 if (!LazyOpen(false)) { |
| 252 if (is_disabled_) | 264 if (is_disabled_) |
| 253 return false; | 265 return SERVICE_WORKER_ERROR_FAILED; |
| 254 // Database has never been used. | 266 // Database has never been used. |
| 255 *next_avail_registration_id = 0; | 267 *next_avail_registration_id = 0; |
| 256 *next_avail_version_id = 0; | 268 *next_avail_version_id = 0; |
| 257 *next_avail_resource_id = 0; | 269 *next_avail_resource_id = 0; |
| 258 return true; | 270 return SERVICE_WORKER_OK; |
| 259 } | 271 } |
| 260 | 272 |
| 261 if (!ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_) || | 273 ServiceWorkerStatusCode status = |
| 262 !ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_) || | 274 ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_); |
| 263 !ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_)) { | 275 if (status != SERVICE_WORKER_OK) |
| 264 return false; | 276 return status; |
| 265 } | 277 status = ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_); |
| 278 if (status != SERVICE_WORKER_OK) |
| 279 return status; |
| 280 status = ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_); |
| 281 if (status != SERVICE_WORKER_OK) |
| 282 return status; |
| 266 | 283 |
| 267 *next_avail_registration_id = next_avail_registration_id_; | 284 *next_avail_registration_id = next_avail_registration_id_; |
| 268 *next_avail_version_id = next_avail_version_id_; | 285 *next_avail_version_id = next_avail_version_id_; |
| 269 *next_avail_resource_id = next_avail_resource_id_; | 286 *next_avail_resource_id = next_avail_resource_id_; |
| 270 return true; | 287 return SERVICE_WORKER_OK; |
| 271 } | 288 } |
| 272 | 289 |
| 273 bool ServiceWorkerDatabase::GetOriginsWithRegistrations( | 290 ServiceWorkerStatusCode ServiceWorkerDatabase::GetOriginsWithRegistrations( |
| 274 std::set<GURL>* origins) { | 291 std::set<GURL>* origins) { |
| 275 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 292 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 276 DCHECK(origins); | 293 DCHECK(origins); |
| 277 | 294 |
| 278 if (!LazyOpen(false)) { | 295 if (!LazyOpen(false)) { |
| 279 if (is_disabled_) | 296 if (is_disabled_) |
| 280 return false; | 297 return SERVICE_WORKER_ERROR_FAILED; |
| 281 // Database has never been used. | 298 // Database has never been used. |
| 282 origins->clear(); | 299 origins->clear(); |
| 283 return true; | 300 return SERVICE_WORKER_OK; |
| 284 } | 301 } |
| 285 | 302 |
| 286 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); | 303 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
| 287 for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) { | 304 for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) { |
| 288 if (!itr->status().ok()) { | 305 if (!itr->status().ok()) { |
| 289 HandleError(FROM_HERE, itr->status()); | 306 HandleError(FROM_HERE, itr->status()); |
| 290 origins->clear(); | 307 origins->clear(); |
| 291 return false; | 308 return LevelDBStatusToServiceWorkerStatusCode(itr->status()); |
| 292 } | 309 } |
| 293 | 310 |
| 294 std::string origin; | 311 std::string origin; |
| 295 if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin)) | 312 if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin)) |
| 296 break; | 313 break; |
| 297 origins->insert(GURL(origin)); | 314 origins->insert(GURL(origin)); |
| 298 } | 315 } |
| 299 return true; | 316 return SERVICE_WORKER_OK; |
| 300 } | 317 } |
| 301 | 318 |
| 302 bool ServiceWorkerDatabase::GetRegistrationsForOrigin( | 319 bool ServiceWorkerDatabase::GetRegistrationsForOrigin( |
| 303 const GURL& origin, | 320 const GURL& origin, |
| 304 std::vector<RegistrationData>* registrations) { | 321 std::vector<RegistrationData>* registrations) { |
| 305 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 322 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 306 DCHECK(registrations); | 323 DCHECK(registrations); |
| 307 | 324 |
| 308 if (!LazyOpen(false)) { | 325 if (!LazyOpen(false)) { |
| 309 if (is_disabled_) | 326 if (is_disabled_) |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 db_.reset(db); | 634 db_.reset(db); |
| 618 | 635 |
| 619 int64 db_version; | 636 int64 db_version; |
| 620 if (!ReadDatabaseVersion(&db_version)) | 637 if (!ReadDatabaseVersion(&db_version)) |
| 621 return false; | 638 return false; |
| 622 if (db_version > 0) | 639 if (db_version > 0) |
| 623 is_initialized_ = true; | 640 is_initialized_ = true; |
| 624 return true; | 641 return true; |
| 625 } | 642 } |
| 626 | 643 |
| 627 bool ServiceWorkerDatabase::ReadNextAvailableId( | 644 ServiceWorkerStatusCode ServiceWorkerDatabase::ReadNextAvailableId( |
| 628 const char* id_key, int64* next_avail_id) { | 645 const char* id_key, |
| 646 int64* next_avail_id) { |
| 629 DCHECK(id_key); | 647 DCHECK(id_key); |
| 630 DCHECK(next_avail_id); | 648 DCHECK(next_avail_id); |
| 631 | 649 |
| 632 std::string value; | 650 std::string value; |
| 633 leveldb::Status status = db_->Get(leveldb::ReadOptions(), id_key, &value); | 651 leveldb::Status status = db_->Get(leveldb::ReadOptions(), id_key, &value); |
| 634 if (status.IsNotFound()) { | 652 if (status.IsNotFound()) { |
| 635 // Nobody has gotten the next resource id for |id_key|. | 653 // Nobody has gotten the next resource id for |id_key|. |
| 636 *next_avail_id = 0; | 654 *next_avail_id = 0; |
| 637 return true; | 655 return SERVICE_WORKER_OK; |
| 638 } | 656 } |
| 639 | 657 |
| 640 if (!status.ok()) { | 658 if (!status.ok()) { |
| 641 HandleError(FROM_HERE, status); | 659 HandleError(FROM_HERE, status); |
| 642 return false; | 660 return LevelDBStatusToServiceWorkerStatusCode(status); |
| 643 } | 661 } |
| 644 | 662 |
| 645 int64 parsed; | 663 int64 parsed; |
| 646 if (!base::StringToInt64(value, &parsed)) { | 664 if (!base::StringToInt64(value, &parsed)) { |
| 647 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse")); | 665 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse")); |
| 648 return false; | 666 return SERVICE_WORKER_ERROR_DB_CORRUPTED; |
| 649 } | 667 } |
| 650 | 668 |
| 651 *next_avail_id = parsed; | 669 *next_avail_id = parsed; |
| 652 return true; | 670 return SERVICE_WORKER_OK; |
| 653 } | 671 } |
| 654 | 672 |
| 655 bool ServiceWorkerDatabase::ReadRegistrationData( | 673 bool ServiceWorkerDatabase::ReadRegistrationData( |
| 656 int64 registration_id, | 674 int64 registration_id, |
| 657 const GURL& origin, | 675 const GURL& origin, |
| 658 RegistrationData* registration) { | 676 RegistrationData* registration) { |
| 659 DCHECK(registration); | 677 DCHECK(registration); |
| 660 | 678 |
| 661 std::string key = CreateRegistrationKey(registration_id, origin); | 679 std::string key = CreateRegistrationKey(registration_id, origin); |
| 662 | 680 |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 // TODO(nhiroki): Add an UMA histogram. | 903 // TODO(nhiroki): Add an UMA histogram. |
| 886 DLOG(ERROR) << "Failed at: " << from_here.ToString() | 904 DLOG(ERROR) << "Failed at: " << from_here.ToString() |
| 887 << " with error: " << status.ToString(); | 905 << " with error: " << status.ToString(); |
| 888 is_disabled_ = true; | 906 is_disabled_ = true; |
| 889 if (status.IsCorruption()) | 907 if (status.IsCorruption()) |
| 890 was_corruption_detected_ = true; | 908 was_corruption_detected_ = true; |
| 891 db_.reset(); | 909 db_.reset(); |
| 892 } | 910 } |
| 893 | 911 |
| 894 } // namespace content | 912 } // namespace content |
| OLD | NEW |