| 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 |