| 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 "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "content/browser/service_worker/service_worker_database.pb.h" | 17 #include "content/browser/service_worker/service_worker_database.pb.h" |
| 18 #include "content/browser/service_worker/service_worker_metrics.h" | 18 #include "content/browser/service_worker/service_worker_metrics.h" |
| 19 #include "content/common/service_worker/service_worker_types.h" | 19 #include "content/common/service_worker/service_worker_types.h" |
| 20 #include "content/common/service_worker/service_worker_utils.h" |
| 20 #include "third_party/leveldatabase/env_chromium.h" | 21 #include "third_party/leveldatabase/env_chromium.h" |
| 21 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" | 22 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" |
| 22 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 23 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
| 23 #include "third_party/leveldatabase/src/include/leveldb/env.h" | 24 #include "third_party/leveldatabase/src/include/leveldb/env.h" |
| 24 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 25 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
| 25 | 26 |
| 26 // LevelDB database schema | 27 // LevelDB database schema |
| 27 // ======================= | 28 // ======================= |
| 28 // | 29 // |
| 29 // NOTE | 30 // NOTE |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 // | 77 // |
| 77 // key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED" | 78 // key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED" |
| 78 // value: <empty> | 79 // value: <empty> |
| 79 // - This entry represents that the diskcache uses the Simple backend and | 80 // - This entry represents that the diskcache uses the Simple backend and |
| 80 // does not have to do diskcache migration (http://crbug.com/487482). | 81 // does not have to do diskcache migration (http://crbug.com/487482). |
| 81 // | 82 // |
| 82 // key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED" | 83 // key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED" |
| 83 // value: <empty> | 84 // value: <empty> |
| 84 // - This entry represents that the old BlockFile diskcache was deleted | 85 // - This entry represents that the old BlockFile diskcache was deleted |
| 85 // after diskcache migration (http://crbug.com/487482). | 86 // after diskcache migration (http://crbug.com/487482). |
| 87 // |
| 88 // key: "INITDATA_FOREIGN_FETCH_ORIGIN:" + <GURL 'origin'> |
| 89 // value: <empty> |
| 86 namespace content { | 90 namespace content { |
| 87 | 91 |
| 88 namespace { | 92 namespace { |
| 89 | 93 |
| 90 const char kDatabaseVersionKey[] = "INITDATA_DB_VERSION"; | 94 const char kDatabaseVersionKey[] = "INITDATA_DB_VERSION"; |
| 91 const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID"; | 95 const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID"; |
| 92 const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID"; | 96 const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID"; |
| 93 const char kNextVerIdKey[] = "INITDATA_NEXT_VERSION_ID"; | 97 const char kNextVerIdKey[] = "INITDATA_NEXT_VERSION_ID"; |
| 94 const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:"; | 98 const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:"; |
| 95 const char kDiskCacheMigrationNotNeededKey[] = | 99 const char kDiskCacheMigrationNotNeededKey[] = |
| 96 "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"; | 100 "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"; |
| 97 const char kOldDiskCacheDeletionNotNeededKey[] = | 101 const char kOldDiskCacheDeletionNotNeededKey[] = |
| 98 "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"; | 102 "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"; |
| 103 const char kForeignFetchOriginKey[] = "INITDATA_FOREIGN_FETCH_ORIGIN:"; |
| 99 | 104 |
| 100 const char kRegKeyPrefix[] = "REG:"; | 105 const char kRegKeyPrefix[] = "REG:"; |
| 101 const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:"; | 106 const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:"; |
| 102 const char kRegHasUserDataKeyPrefix[] = "REG_HAS_USER_DATA:"; | 107 const char kRegHasUserDataKeyPrefix[] = "REG_HAS_USER_DATA:"; |
| 103 const char kRegIdToOriginKeyPrefix[] = "REGID_TO_ORIGIN:"; | 108 const char kRegIdToOriginKeyPrefix[] = "REGID_TO_ORIGIN:"; |
| 104 const char kResKeyPrefix[] = "RES:"; | 109 const char kResKeyPrefix[] = "RES:"; |
| 105 const char kKeySeparator = '\x00'; | 110 const char kKeySeparator = '\x00'; |
| 106 const char kEmptyValue[] = ""; | 111 const char kEmptyValue[] = ""; |
| 107 | 112 |
| 108 const char kUncommittedResIdKeyPrefix[] = "URES:"; | 113 const char kUncommittedResIdKeyPrefix[] = "URES:"; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 int64 resource_id) { | 156 int64 resource_id) { |
| 152 return CreateResourceRecordKeyPrefix(version_id).append( | 157 return CreateResourceRecordKeyPrefix(version_id).append( |
| 153 base::Int64ToString(resource_id)); | 158 base::Int64ToString(resource_id)); |
| 154 } | 159 } |
| 155 | 160 |
| 156 std::string CreateUniqueOriginKey(const GURL& origin) { | 161 std::string CreateUniqueOriginKey(const GURL& origin) { |
| 157 return base::StringPrintf("%s%s", kUniqueOriginKey, | 162 return base::StringPrintf("%s%s", kUniqueOriginKey, |
| 158 origin.GetOrigin().spec().c_str()); | 163 origin.GetOrigin().spec().c_str()); |
| 159 } | 164 } |
| 160 | 165 |
| 166 std::string CreateForeignFetchOriginKey(const GURL& origin) { |
| 167 return base::StringPrintf("%s%s", kForeignFetchOriginKey, |
| 168 origin.GetOrigin().spec().c_str()); |
| 169 } |
| 170 |
| 161 std::string CreateResourceIdKey(const char* key_prefix, int64 resource_id) { | 171 std::string CreateResourceIdKey(const char* key_prefix, int64 resource_id) { |
| 162 return base::StringPrintf( | 172 return base::StringPrintf( |
| 163 "%s%s", key_prefix, base::Int64ToString(resource_id).c_str()); | 173 "%s%s", key_prefix, base::Int64ToString(resource_id).c_str()); |
| 164 } | 174 } |
| 165 | 175 |
| 166 std::string CreateUserDataKeyPrefix(int64 registration_id) { | 176 std::string CreateUserDataKeyPrefix(int64 registration_id) { |
| 167 return base::StringPrintf("%s%s%c", | 177 return base::StringPrintf("%s%s%c", |
| 168 kRegUserDataKeyPrefix, | 178 kRegUserDataKeyPrefix, |
| 169 base::Int64ToString(registration_id).c_str(), | 179 base::Int64ToString(registration_id).c_str(), |
| 170 kKeySeparator); | 180 kKeySeparator); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 199 // Convert RegistrationData to ServiceWorkerRegistrationData. | 209 // Convert RegistrationData to ServiceWorkerRegistrationData. |
| 200 ServiceWorkerRegistrationData data; | 210 ServiceWorkerRegistrationData data; |
| 201 data.set_registration_id(input.registration_id); | 211 data.set_registration_id(input.registration_id); |
| 202 data.set_scope_url(input.scope.spec()); | 212 data.set_scope_url(input.scope.spec()); |
| 203 data.set_script_url(input.script.spec()); | 213 data.set_script_url(input.script.spec()); |
| 204 data.set_version_id(input.version_id); | 214 data.set_version_id(input.version_id); |
| 205 data.set_is_active(input.is_active); | 215 data.set_is_active(input.is_active); |
| 206 data.set_has_fetch_handler(input.has_fetch_handler); | 216 data.set_has_fetch_handler(input.has_fetch_handler); |
| 207 data.set_last_update_check_time(input.last_update_check.ToInternalValue()); | 217 data.set_last_update_check_time(input.last_update_check.ToInternalValue()); |
| 208 data.set_resources_total_size_bytes(input.resources_total_size_bytes); | 218 data.set_resources_total_size_bytes(input.resources_total_size_bytes); |
| 219 for (const GURL& url : input.foreign_fetch_scopes) { |
| 220 DCHECK(ServiceWorkerUtils::ScopeMatches(input.scope, url)) |
| 221 << "Foreign fetch scope '" << url |
| 222 << "' does not match service worker scope '" << input.scope << "'."; |
| 223 data.add_foreign_fetch_scope(url.spec()); |
| 224 } |
| 209 | 225 |
| 210 std::string value; | 226 std::string value; |
| 211 bool success = data.SerializeToString(&value); | 227 bool success = data.SerializeToString(&value); |
| 212 DCHECK(success); | 228 DCHECK(success); |
| 213 GURL origin = input.scope.GetOrigin(); | 229 GURL origin = input.scope.GetOrigin(); |
| 214 batch->Put(CreateRegistrationKey(data.registration_id(), origin), value); | 230 batch->Put(CreateRegistrationKey(data.registration_id(), origin), value); |
| 215 } | 231 } |
| 216 | 232 |
| 217 void PutResourceRecordToBatch( | 233 void PutResourceRecordToBatch( |
| 218 const ServiceWorkerDatabase::ResourceRecord& input, | 234 const ServiceWorkerDatabase::ResourceRecord& input, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 238 // Value should be empty. | 254 // Value should be empty. |
| 239 batch->Put(CreateUniqueOriginKey(origin), ""); | 255 batch->Put(CreateUniqueOriginKey(origin), ""); |
| 240 } | 256 } |
| 241 | 257 |
| 242 void PutPurgeableResourceIdToBatch(int64 resource_id, | 258 void PutPurgeableResourceIdToBatch(int64 resource_id, |
| 243 leveldb::WriteBatch* batch) { | 259 leveldb::WriteBatch* batch) { |
| 244 // Value should be empty. | 260 // Value should be empty. |
| 245 batch->Put(CreateResourceIdKey(kPurgeableResIdKeyPrefix, resource_id), ""); | 261 batch->Put(CreateResourceIdKey(kPurgeableResIdKeyPrefix, resource_id), ""); |
| 246 } | 262 } |
| 247 | 263 |
| 264 void PutForeignFetchOriginToBatch(const GURL& origin, |
| 265 leveldb::WriteBatch* batch) { |
| 266 // Value should be empty. |
| 267 batch->Put(CreateForeignFetchOriginKey(origin), ""); |
| 268 } |
| 269 |
| 248 ServiceWorkerDatabase::Status ParseId( | 270 ServiceWorkerDatabase::Status ParseId( |
| 249 const std::string& serialized, | 271 const std::string& serialized, |
| 250 int64* out) { | 272 int64* out) { |
| 251 DCHECK(out); | 273 DCHECK(out); |
| 252 int64 id; | 274 int64 id; |
| 253 if (!base::StringToInt64(serialized, &id) || id < 0) | 275 if (!base::StringToInt64(serialized, &id) || id < 0) |
| 254 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; | 276 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; |
| 255 *out = id; | 277 *out = id; |
| 256 return ServiceWorkerDatabase::STATUS_OK; | 278 return ServiceWorkerDatabase::STATUS_OK; |
| 257 } | 279 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 // Convert ServiceWorkerRegistrationData to RegistrationData. | 320 // Convert ServiceWorkerRegistrationData to RegistrationData. |
| 299 out->registration_id = data.registration_id(); | 321 out->registration_id = data.registration_id(); |
| 300 out->scope = scope_url; | 322 out->scope = scope_url; |
| 301 out->script = script_url; | 323 out->script = script_url; |
| 302 out->version_id = data.version_id(); | 324 out->version_id = data.version_id(); |
| 303 out->is_active = data.is_active(); | 325 out->is_active = data.is_active(); |
| 304 out->has_fetch_handler = data.has_fetch_handler(); | 326 out->has_fetch_handler = data.has_fetch_handler(); |
| 305 out->last_update_check = | 327 out->last_update_check = |
| 306 base::Time::FromInternalValue(data.last_update_check_time()); | 328 base::Time::FromInternalValue(data.last_update_check_time()); |
| 307 out->resources_total_size_bytes = data.resources_total_size_bytes(); | 329 out->resources_total_size_bytes = data.resources_total_size_bytes(); |
| 330 for (int i = 0; i < data.foreign_fetch_scope_size(); ++i) { |
| 331 GURL sub_scope_url(data.foreign_fetch_scope(i)); |
| 332 if (!sub_scope_url.is_valid() || |
| 333 !ServiceWorkerUtils::ScopeMatches(scope_url, sub_scope_url)) { |
| 334 DLOG(ERROR) << "Foreign fetch scope '" << data.foreign_fetch_scope(i) |
| 335 << "' is not valid or does not match Scope URL '" << scope_url |
| 336 << "'."; |
| 337 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; |
| 338 } |
| 339 out->foreign_fetch_scopes.push_back(sub_scope_url); |
| 340 } |
| 308 | 341 |
| 309 return ServiceWorkerDatabase::STATUS_OK; | 342 return ServiceWorkerDatabase::STATUS_OK; |
| 310 } | 343 } |
| 311 | 344 |
| 312 ServiceWorkerDatabase::Status ParseResourceRecord( | 345 ServiceWorkerDatabase::Status ParseResourceRecord( |
| 313 const std::string& serialized, | 346 const std::string& serialized, |
| 314 ServiceWorkerDatabase::ResourceRecord* out) { | 347 ServiceWorkerDatabase::ResourceRecord* out) { |
| 315 DCHECK(out); | 348 DCHECK(out); |
| 316 ServiceWorkerResourceRecord record; | 349 ServiceWorkerResourceRecord record; |
| 317 if (!record.ParseFromString(serialized)) | 350 if (!record.ParseFromString(serialized)) |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 return status; | 585 return status; |
| 553 } | 586 } |
| 554 | 587 |
| 555 origins->insert(origin); | 588 origins->insert(origin); |
| 556 } | 589 } |
| 557 | 590 |
| 558 HandleReadResult(FROM_HERE, status); | 591 HandleReadResult(FROM_HERE, status); |
| 559 return status; | 592 return status; |
| 560 } | 593 } |
| 561 | 594 |
| 595 ServiceWorkerDatabase::Status |
| 596 ServiceWorkerDatabase::GetOriginsWithForeignFetchRegistrations( |
| 597 std::set<GURL>* origins) { |
| 598 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 599 DCHECK(origins->empty()); |
| 600 |
| 601 Status status = LazyOpen(false); |
| 602 if (IsNewOrNonexistentDatabase(status)) |
| 603 return STATUS_OK; |
| 604 if (status != STATUS_OK) |
| 605 return status; |
| 606 |
| 607 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
| 608 for (itr->Seek(kForeignFetchOriginKey); itr->Valid(); itr->Next()) { |
| 609 status = LevelDBStatusToStatus(itr->status()); |
| 610 if (status != STATUS_OK) { |
| 611 HandleReadResult(FROM_HERE, status); |
| 612 origins->clear(); |
| 613 return status; |
| 614 } |
| 615 |
| 616 std::string origin_str; |
| 617 if (!RemovePrefix(itr->key().ToString(), kForeignFetchOriginKey, |
| 618 &origin_str)) |
| 619 break; |
| 620 |
| 621 GURL origin(origin_str); |
| 622 if (!origin.is_valid()) { |
| 623 status = STATUS_ERROR_CORRUPTED; |
| 624 HandleReadResult(FROM_HERE, status); |
| 625 origins->clear(); |
| 626 return status; |
| 627 } |
| 628 |
| 629 origins->insert(origin); |
| 630 } |
| 631 |
| 632 HandleReadResult(FROM_HERE, status); |
| 633 return status; |
| 634 } |
| 635 |
| 562 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetRegistrationsForOrigin( | 636 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetRegistrationsForOrigin( |
| 563 const GURL& origin, | 637 const GURL& origin, |
| 564 std::vector<RegistrationData>* registrations, | 638 std::vector<RegistrationData>* registrations, |
| 565 std::vector<std::vector<ResourceRecord>>* opt_resources_list) { | 639 std::vector<std::vector<ResourceRecord>>* opt_resources_list) { |
| 566 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 640 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 567 DCHECK(registrations->empty()); | 641 DCHECK(registrations->empty()); |
| 568 | 642 |
| 569 Status status = LazyOpen(false); | 643 Status status = LazyOpen(false); |
| 570 if (IsNewOrNonexistentDatabase(status)) | 644 if (IsNewOrNonexistentDatabase(status)) |
| 571 return STATUS_OK; | 645 return STATUS_OK; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 old_registration->version_id = kInvalidServiceWorkerVersionId; | 804 old_registration->version_id = kInvalidServiceWorkerVersionId; |
| 731 if (status != STATUS_OK) | 805 if (status != STATUS_OK) |
| 732 return status; | 806 return status; |
| 733 | 807 |
| 734 leveldb::WriteBatch batch; | 808 leveldb::WriteBatch batch; |
| 735 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch); | 809 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch); |
| 736 BumpNextVersionIdIfNeeded(registration.version_id, &batch); | 810 BumpNextVersionIdIfNeeded(registration.version_id, &batch); |
| 737 | 811 |
| 738 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch); | 812 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch); |
| 739 | 813 |
| 814 if (!registration.foreign_fetch_scopes.empty()) |
| 815 PutForeignFetchOriginToBatch(registration.scope.GetOrigin(), &batch); |
| 816 |
| 740 DCHECK_EQ(AccumulateResourceSizeInBytes(resources), | 817 DCHECK_EQ(AccumulateResourceSizeInBytes(resources), |
| 741 registration.resources_total_size_bytes) | 818 registration.resources_total_size_bytes) |
| 742 << "The total size in the registration must match the cumulative " | 819 << "The total size in the registration must match the cumulative " |
| 743 << "sizes of the resources."; | 820 << "sizes of the resources."; |
| 744 | 821 |
| 745 PutRegistrationDataToBatch(registration, &batch); | 822 PutRegistrationDataToBatch(registration, &batch); |
| 746 batch.Put(CreateRegistrationIdToOriginKey(registration.registration_id), | 823 batch.Put(CreateRegistrationIdToOriginKey(registration.registration_id), |
| 747 registration.scope.GetOrigin().spec()); | 824 registration.scope.GetOrigin().spec()); |
| 748 | 825 |
| 749 // Used for avoiding multiple writes for the same resource id or url. | 826 // Used for avoiding multiple writes for the same resource id or url. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 if (status != STATUS_OK) | 858 if (status != STATUS_OK) |
| 782 return status; | 859 return status; |
| 783 | 860 |
| 784 // Currently resource sharing across versions and registrations is not | 861 // Currently resource sharing across versions and registrations is not |
| 785 // supported, so resource ids should not be overlapped between | 862 // supported, so resource ids should not be overlapped between |
| 786 // |registration| and |old_registration|. | 863 // |registration| and |old_registration|. |
| 787 std::set<int64> deleted_resources(newly_purgeable_resources->begin(), | 864 std::set<int64> deleted_resources(newly_purgeable_resources->begin(), |
| 788 newly_purgeable_resources->end()); | 865 newly_purgeable_resources->end()); |
| 789 DCHECK(base::STLSetIntersection<std::set<int64> >( | 866 DCHECK(base::STLSetIntersection<std::set<int64> >( |
| 790 pushed_resources, deleted_resources).empty()); | 867 pushed_resources, deleted_resources).empty()); |
| 868 |
| 869 // If old registration had foreign fetch scopes, but new registration |
| 870 // doesn't, the origin might have to be removed from the list of origins |
| 871 // with foreign fetch scopes. |
| 872 // TODO(mek): Like the similar check in DeleteRegistration, ideally this |
| 873 // could be done more efficiently. |
| 874 if (!old_registration->foreign_fetch_scopes.empty() && |
| 875 registration.foreign_fetch_scopes.empty()) { |
| 876 std::vector<RegistrationData> registrations; |
| 877 status = GetRegistrationsForOrigin(registration.scope.GetOrigin(), |
| 878 ®istrations, nullptr); |
| 879 if (status != STATUS_OK) |
| 880 return status; |
| 881 bool remaining_ff_scopes = false; |
| 882 for (const auto& existing_reg : registrations) { |
| 883 if (existing_reg.registration_id != registration.registration_id && |
| 884 !existing_reg.foreign_fetch_scopes.empty()) { |
| 885 remaining_ff_scopes = true; |
| 886 break; |
| 887 } |
| 888 } |
| 889 if (!remaining_ff_scopes) |
| 890 batch.Delete( |
| 891 CreateForeignFetchOriginKey(registration.scope.GetOrigin())); |
| 892 } |
| 791 } | 893 } |
| 792 | 894 |
| 793 return WriteBatch(&batch); | 895 return WriteBatch(&batch); |
| 794 } | 896 } |
| 795 | 897 |
| 796 ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateVersionToActive( | 898 ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateVersionToActive( |
| 797 int64 registration_id, | 899 int64 registration_id, |
| 798 const GURL& origin) { | 900 const GURL& origin) { |
| 799 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 901 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 800 Status status = LazyOpen(false); | 902 Status status = LazyOpen(false); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 std::vector<RegistrationData> registrations; | 968 std::vector<RegistrationData> registrations; |
| 867 status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); | 969 status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); |
| 868 if (status != STATUS_OK) | 970 if (status != STATUS_OK) |
| 869 return status; | 971 return status; |
| 870 | 972 |
| 871 if (registrations.size() == 1 && | 973 if (registrations.size() == 1 && |
| 872 registrations[0].registration_id == registration_id) { | 974 registrations[0].registration_id == registration_id) { |
| 873 batch.Delete(CreateUniqueOriginKey(origin)); | 975 batch.Delete(CreateUniqueOriginKey(origin)); |
| 874 } | 976 } |
| 875 | 977 |
| 978 // Remove |origin| from foreign fetch origins if a registration specified by |
| 979 // |registration_id| is the only one with foreign fetch scopes for |origin|. |
| 980 bool remaining_ff_scopes = false; |
| 981 for (const auto& registration : registrations) { |
| 982 if (registration.registration_id != registration_id && |
| 983 !registration.foreign_fetch_scopes.empty()) { |
| 984 remaining_ff_scopes = true; |
| 985 break; |
| 986 } |
| 987 } |
| 988 if (!remaining_ff_scopes) |
| 989 batch.Delete(CreateForeignFetchOriginKey(origin)); |
| 990 |
| 876 // Delete a registration specified by |registration_id|. | 991 // Delete a registration specified by |registration_id|. |
| 877 batch.Delete(CreateRegistrationKey(registration_id, origin)); | 992 batch.Delete(CreateRegistrationKey(registration_id, origin)); |
| 878 batch.Delete(CreateRegistrationIdToOriginKey(registration_id)); | 993 batch.Delete(CreateRegistrationIdToOriginKey(registration_id)); |
| 879 | 994 |
| 880 // Delete resource records and user data associated with the registration. | 995 // Delete resource records and user data associated with the registration. |
| 881 for (const auto& registration : registrations) { | 996 for (const auto& registration : registrations) { |
| 882 if (registration.registration_id == registration_id) { | 997 if (registration.registration_id == registration_id) { |
| 883 *deleted_version = registration; | 998 *deleted_version = registration; |
| 884 status = DeleteResourceRecords( | 999 status = DeleteResourceRecords( |
| 885 registration.version_id, newly_purgeable_resources, &batch); | 1000 registration.version_id, newly_purgeable_resources, &batch); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 return status; | 1188 return status; |
| 1074 leveldb::WriteBatch batch; | 1189 leveldb::WriteBatch batch; |
| 1075 | 1190 |
| 1076 for (const GURL& origin : origins) { | 1191 for (const GURL& origin : origins) { |
| 1077 if (!origin.is_valid()) | 1192 if (!origin.is_valid()) |
| 1078 return STATUS_ERROR_FAILED; | 1193 return STATUS_ERROR_FAILED; |
| 1079 | 1194 |
| 1080 // Delete from the unique origin list. | 1195 // Delete from the unique origin list. |
| 1081 batch.Delete(CreateUniqueOriginKey(origin)); | 1196 batch.Delete(CreateUniqueOriginKey(origin)); |
| 1082 | 1197 |
| 1198 // Delete from the foreign fetch origin list. |
| 1199 batch.Delete(CreateForeignFetchOriginKey(origin)); |
| 1200 |
| 1083 std::vector<RegistrationData> registrations; | 1201 std::vector<RegistrationData> registrations; |
| 1084 status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); | 1202 status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); |
| 1085 if (status != STATUS_OK) | 1203 if (status != STATUS_OK) |
| 1086 return status; | 1204 return status; |
| 1087 | 1205 |
| 1088 // Delete registrations, resource records and user data. | 1206 // Delete registrations, resource records and user data. |
| 1089 for (const RegistrationData& data : registrations) { | 1207 for (const RegistrationData& data : registrations) { |
| 1090 batch.Delete(CreateRegistrationKey(data.registration_id, origin)); | 1208 batch.Delete(CreateRegistrationKey(data.registration_id, origin)); |
| 1091 batch.Delete(CreateRegistrationIdToOriginKey(data.registration_id)); | 1209 batch.Delete(CreateRegistrationIdToOriginKey(data.registration_id)); |
| 1092 | 1210 |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 if (status != STATUS_OK) | 1697 if (status != STATUS_OK) |
| 1580 Disable(from_here, status); | 1698 Disable(from_here, status); |
| 1581 ServiceWorkerMetrics::CountWriteDatabaseResult(status); | 1699 ServiceWorkerMetrics::CountWriteDatabaseResult(status); |
| 1582 } | 1700 } |
| 1583 | 1701 |
| 1584 bool ServiceWorkerDatabase::IsDatabaseInMemory() const { | 1702 bool ServiceWorkerDatabase::IsDatabaseInMemory() const { |
| 1585 return path_.empty(); | 1703 return path_.empty(); |
| 1586 } | 1704 } |
| 1587 | 1705 |
| 1588 } // namespace content | 1706 } // namespace content |
| OLD | NEW |