| 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 "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/sequenced_task_runner.h" | 10 #include "base/sequenced_task_runner.h" |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 } | 400 } |
| 401 | 401 |
| 402 ServiceWorkerDatabase::RegistrationData data; | 402 ServiceWorkerDatabase::RegistrationData data; |
| 403 data.registration_id = registration->id(); | 403 data.registration_id = registration->id(); |
| 404 data.scope = registration->pattern(); | 404 data.scope = registration->pattern(); |
| 405 data.script = version->script_url(); | 405 data.script = version->script_url(); |
| 406 data.has_fetch_handler = true; | 406 data.has_fetch_handler = true; |
| 407 data.version_id = version->version_id(); | 407 data.version_id = version->version_id(); |
| 408 data.last_update_check = registration->last_update_check(); | 408 data.last_update_check = registration->last_update_check(); |
| 409 data.is_active = (version == registration->active_version()); | 409 data.is_active = (version == registration->active_version()); |
| 410 data.foreign_fetch_scopes = version->foreign_fetch_scopes(); |
| 410 | 411 |
| 411 ResourceList resources; | 412 ResourceList resources; |
| 412 version->script_cache_map()->GetResources(&resources); | 413 version->script_cache_map()->GetResources(&resources); |
| 413 | 414 |
| 414 if (resources.empty()) { | 415 if (resources.empty()) { |
| 415 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); | 416 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
| 416 return; | 417 return; |
| 417 } | 418 } |
| 418 | 419 |
| 419 uint64 resources_total_size_bytes = 0; | 420 uint64 resources_total_size_bytes = 0; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 base::Bind( | 679 base::Bind( |
| 679 &ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB, | 680 &ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB, |
| 680 database_.get(), | 681 database_.get(), |
| 681 base::ThreadTaskRunnerHandle::Get(), | 682 base::ThreadTaskRunnerHandle::Get(), |
| 682 key, | 683 key, |
| 683 base::Bind(&ServiceWorkerStorage::DidGetUserDataForAllRegistrations, | 684 base::Bind(&ServiceWorkerStorage::DidGetUserDataForAllRegistrations, |
| 684 weak_factory_.GetWeakPtr(), | 685 weak_factory_.GetWeakPtr(), |
| 685 callback))); | 686 callback))); |
| 686 } | 687 } |
| 687 | 688 |
| 689 bool ServiceWorkerStorage::OriginHasForeignFetchRegistrations( |
| 690 const GURL& origin) { |
| 691 return !IsDisabled() && |
| 692 foreign_fetch_origins_.find(origin) != foreign_fetch_origins_.end(); |
| 693 } |
| 694 |
| 688 void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) { | 695 void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) { |
| 689 Disable(); | 696 Disable(); |
| 690 | 697 |
| 691 // Delete the database on the database thread. | 698 // Delete the database on the database thread. |
| 692 PostTaskAndReplyWithResult( | 699 PostTaskAndReplyWithResult( |
| 693 database_task_manager_->GetTaskRunner(), FROM_HERE, | 700 database_task_manager_->GetTaskRunner(), FROM_HERE, |
| 694 base::Bind(&ServiceWorkerDatabase::DestroyDatabase, | 701 base::Bind(&ServiceWorkerDatabase::DestroyDatabase, |
| 695 base::Unretained(database_.get())), | 702 base::Unretained(database_.get())), |
| 696 base::Bind(&ServiceWorkerStorage::DidDeleteDatabase, | 703 base::Bind(&ServiceWorkerStorage::DidDeleteDatabase, |
| 697 weak_factory_.GetWeakPtr(), callback)); | 704 weak_factory_.GetWeakPtr(), callback)); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 DCHECK(data); | 854 DCHECK(data); |
| 848 DCHECK_EQ(INITIALIZING, state_); | 855 DCHECK_EQ(INITIALIZING, state_); |
| 849 | 856 |
| 850 if (status == ServiceWorkerDatabase::STATUS_OK) { | 857 if (status == ServiceWorkerDatabase::STATUS_OK) { |
| 851 next_registration_id_ = data->next_registration_id; | 858 next_registration_id_ = data->next_registration_id; |
| 852 next_version_id_ = data->next_version_id; | 859 next_version_id_ = data->next_version_id; |
| 853 next_resource_id_ = data->next_resource_id; | 860 next_resource_id_ = data->next_resource_id; |
| 854 registered_origins_.swap(data->origins); | 861 registered_origins_.swap(data->origins); |
| 855 disk_cache_migration_needed_ = data->disk_cache_migration_needed; | 862 disk_cache_migration_needed_ = data->disk_cache_migration_needed; |
| 856 old_disk_cache_deletion_needed_ = data->old_disk_cache_deletion_needed; | 863 old_disk_cache_deletion_needed_ = data->old_disk_cache_deletion_needed; |
| 864 foreign_fetch_origins_.swap(data->foreign_fetch_origins); |
| 857 state_ = INITIALIZED; | 865 state_ = INITIALIZED; |
| 858 } else { | 866 } else { |
| 859 DVLOG(2) << "Failed to initialize: " | 867 DVLOG(2) << "Failed to initialize: " |
| 860 << ServiceWorkerDatabase::StatusToString(status); | 868 << ServiceWorkerDatabase::StatusToString(status); |
| 861 ScheduleDeleteAndStartOver(); | 869 ScheduleDeleteAndStartOver(); |
| 862 } | 870 } |
| 863 | 871 |
| 864 for (const auto& task : pending_tasks_) | 872 for (const auto& task : pending_tasks_) |
| 865 RunSoon(FROM_HERE, task); | 873 RunSoon(FROM_HERE, task); |
| 866 pending_tasks_.clear(); | 874 pending_tasks_.clear(); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 const GURL& origin, | 1091 const GURL& origin, |
| 1084 const ServiceWorkerDatabase::RegistrationData& deleted_version, | 1092 const ServiceWorkerDatabase::RegistrationData& deleted_version, |
| 1085 const std::vector<int64>& newly_purgeable_resources, | 1093 const std::vector<int64>& newly_purgeable_resources, |
| 1086 ServiceWorkerDatabase::Status status) { | 1094 ServiceWorkerDatabase::Status status) { |
| 1087 if (status != ServiceWorkerDatabase::STATUS_OK) { | 1095 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 1088 ScheduleDeleteAndStartOver(); | 1096 ScheduleDeleteAndStartOver(); |
| 1089 callback.Run(DatabaseStatusToStatusCode(status)); | 1097 callback.Run(DatabaseStatusToStatusCode(status)); |
| 1090 return; | 1098 return; |
| 1091 } | 1099 } |
| 1092 registered_origins_.insert(origin); | 1100 registered_origins_.insert(origin); |
| 1101 if (!new_version.foreign_fetch_scopes.empty()) |
| 1102 foreign_fetch_origins_.insert(origin); |
| 1093 | 1103 |
| 1094 scoped_refptr<ServiceWorkerRegistration> registration = | 1104 scoped_refptr<ServiceWorkerRegistration> registration = |
| 1095 context_->GetLiveRegistration(new_version.registration_id); | 1105 context_->GetLiveRegistration(new_version.registration_id); |
| 1096 if (registration) { | 1106 if (registration) { |
| 1097 registration->set_resources_total_size_bytes( | 1107 registration->set_resources_total_size_bytes( |
| 1098 new_version.resources_total_size_bytes); | 1108 new_version.resources_total_size_bytes); |
| 1099 } | 1109 } |
| 1100 if (quota_manager_proxy_) { | 1110 if (quota_manager_proxy_) { |
| 1101 // Can be nullptr in tests. | 1111 // Can be nullptr in tests. |
| 1102 quota_manager_proxy_->NotifyStorageModified( | 1112 quota_manager_proxy_->NotifyStorageModified( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1118 ServiceWorkerDatabase::Status status) { | 1128 ServiceWorkerDatabase::Status status) { |
| 1119 if (status != ServiceWorkerDatabase::STATUS_OK && | 1129 if (status != ServiceWorkerDatabase::STATUS_OK && |
| 1120 status != ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { | 1130 status != ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { |
| 1121 ScheduleDeleteAndStartOver(); | 1131 ScheduleDeleteAndStartOver(); |
| 1122 } | 1132 } |
| 1123 callback.Run(DatabaseStatusToStatusCode(status)); | 1133 callback.Run(DatabaseStatusToStatusCode(status)); |
| 1124 } | 1134 } |
| 1125 | 1135 |
| 1126 void ServiceWorkerStorage::DidDeleteRegistration( | 1136 void ServiceWorkerStorage::DidDeleteRegistration( |
| 1127 const DidDeleteRegistrationParams& params, | 1137 const DidDeleteRegistrationParams& params, |
| 1128 bool origin_is_deletable, | 1138 OriginState origin_state, |
| 1129 const ServiceWorkerDatabase::RegistrationData& deleted_version, | 1139 const ServiceWorkerDatabase::RegistrationData& deleted_version, |
| 1130 const std::vector<int64>& newly_purgeable_resources, | 1140 const std::vector<int64>& newly_purgeable_resources, |
| 1131 ServiceWorkerDatabase::Status status) { | 1141 ServiceWorkerDatabase::Status status) { |
| 1132 pending_deletions_.erase(params.registration_id); | 1142 pending_deletions_.erase(params.registration_id); |
| 1133 if (status != ServiceWorkerDatabase::STATUS_OK) { | 1143 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 1134 ScheduleDeleteAndStartOver(); | 1144 ScheduleDeleteAndStartOver(); |
| 1135 params.callback.Run(DatabaseStatusToStatusCode(status)); | 1145 params.callback.Run(DatabaseStatusToStatusCode(status)); |
| 1136 return; | 1146 return; |
| 1137 } | 1147 } |
| 1138 if (quota_manager_proxy_) { | 1148 if (quota_manager_proxy_) { |
| 1139 // Can be nullptr in tests. | 1149 // Can be nullptr in tests. |
| 1140 quota_manager_proxy_->NotifyStorageModified( | 1150 quota_manager_proxy_->NotifyStorageModified( |
| 1141 storage::QuotaClient::kServiceWorker, | 1151 storage::QuotaClient::kServiceWorker, |
| 1142 params.origin, | 1152 params.origin, |
| 1143 storage::StorageType::kStorageTypeTemporary, | 1153 storage::StorageType::kStorageTypeTemporary, |
| 1144 -deleted_version.resources_total_size_bytes); | 1154 -deleted_version.resources_total_size_bytes); |
| 1145 } | 1155 } |
| 1146 if (origin_is_deletable) | 1156 if (origin_state == OriginState::DELETE_FROM_ALL) |
| 1147 registered_origins_.erase(params.origin); | 1157 registered_origins_.erase(params.origin); |
| 1158 if (origin_state == OriginState::DELETE_FROM_ALL || |
| 1159 origin_state == OriginState::DELETE_FROM_FOREIGN_FETCH) |
| 1160 foreign_fetch_origins_.erase(params.origin); |
| 1148 params.callback.Run(SERVICE_WORKER_OK); | 1161 params.callback.Run(SERVICE_WORKER_OK); |
| 1149 | 1162 |
| 1150 if (!context_->GetLiveVersion(deleted_version.version_id)) | 1163 if (!context_->GetLiveVersion(deleted_version.version_id)) |
| 1151 StartPurgingResources(newly_purgeable_resources); | 1164 StartPurgingResources(newly_purgeable_resources); |
| 1152 } | 1165 } |
| 1153 | 1166 |
| 1154 void ServiceWorkerStorage::DidWriteUncommittedResourceIds( | 1167 void ServiceWorkerStorage::DidWriteUncommittedResourceIds( |
| 1155 ServiceWorkerDatabase::Status status) { | 1168 ServiceWorkerDatabase::Status status) { |
| 1156 if (status != ServiceWorkerDatabase::STATUS_OK) | 1169 if (status != ServiceWorkerDatabase::STATUS_OK) |
| 1157 ScheduleDeleteAndStartOver(); | 1170 ScheduleDeleteAndStartOver(); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 registration->set_is_deleted(true); | 1239 registration->set_is_deleted(true); |
| 1227 } | 1240 } |
| 1228 scoped_refptr<ServiceWorkerVersion> version = | 1241 scoped_refptr<ServiceWorkerVersion> version = |
| 1229 context_->GetLiveVersion(data.version_id); | 1242 context_->GetLiveVersion(data.version_id); |
| 1230 if (!version) { | 1243 if (!version) { |
| 1231 version = new ServiceWorkerVersion( | 1244 version = new ServiceWorkerVersion( |
| 1232 registration.get(), data.script, data.version_id, context_); | 1245 registration.get(), data.script, data.version_id, context_); |
| 1233 version->SetStatus(data.is_active ? | 1246 version->SetStatus(data.is_active ? |
| 1234 ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); | 1247 ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); |
| 1235 version->script_cache_map()->SetResources(resources); | 1248 version->script_cache_map()->SetResources(resources); |
| 1249 version->set_foreign_fetch_scopes(data.foreign_fetch_scopes); |
| 1236 } | 1250 } |
| 1237 | 1251 |
| 1238 if (version->status() == ServiceWorkerVersion::ACTIVATED) | 1252 if (version->status() == ServiceWorkerVersion::ACTIVATED) |
| 1239 registration->SetActiveVersion(version); | 1253 registration->SetActiveVersion(version); |
| 1240 else if (version->status() == ServiceWorkerVersion::INSTALLED) | 1254 else if (version->status() == ServiceWorkerVersion::INSTALLED) |
| 1241 registration->SetWaitingVersion(version); | 1255 registration->SetWaitingVersion(version); |
| 1242 else | 1256 else |
| 1243 NOTREACHED(); | 1257 NOTREACHED(); |
| 1244 | 1258 |
| 1245 return registration; | 1259 return registration; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 | 1583 |
| 1570 status = database->IsOldDiskCacheDeletionNeeded( | 1584 status = database->IsOldDiskCacheDeletionNeeded( |
| 1571 &data->old_disk_cache_deletion_needed); | 1585 &data->old_disk_cache_deletion_needed); |
| 1572 if (status != ServiceWorkerDatabase::STATUS_OK) { | 1586 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 1573 original_task_runner->PostTask( | 1587 original_task_runner->PostTask( |
| 1574 FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status)); | 1588 FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status)); |
| 1575 return; | 1589 return; |
| 1576 } | 1590 } |
| 1577 | 1591 |
| 1578 status = database->GetOriginsWithRegistrations(&data->origins); | 1592 status = database->GetOriginsWithRegistrations(&data->origins); |
| 1593 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 1594 original_task_runner->PostTask( |
| 1595 FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status)); |
| 1596 return; |
| 1597 } |
| 1598 |
| 1599 status = database->GetOriginsWithForeignFetchRegistrations( |
| 1600 &data->foreign_fetch_origins); |
| 1579 original_task_runner->PostTask( | 1601 original_task_runner->PostTask( |
| 1580 FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status)); | 1602 FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status)); |
| 1581 } | 1603 } |
| 1582 | 1604 |
| 1583 void ServiceWorkerStorage::DeleteOldDiskCacheInDB( | 1605 void ServiceWorkerStorage::DeleteOldDiskCacheInDB( |
| 1584 ServiceWorkerDatabase* database, | 1606 ServiceWorkerDatabase* database, |
| 1585 const base::FilePath& disk_cache_path) { | 1607 const base::FilePath& disk_cache_path) { |
| 1586 // Ignore a failure. A retry will happen on the next initialization. | 1608 // Ignore a failure. A retry will happen on the next initialization. |
| 1587 if (!base::DeleteFile(disk_cache_path, true)) | 1609 if (!base::DeleteFile(disk_cache_path, true)) |
| 1588 return; | 1610 return; |
| 1589 database->SetOldDiskCacheDeletionNotNeeded(); | 1611 database->SetOldDiskCacheDeletionNotNeeded(); |
| 1590 } | 1612 } |
| 1591 | 1613 |
| 1592 void ServiceWorkerStorage::DeleteRegistrationFromDB( | 1614 void ServiceWorkerStorage::DeleteRegistrationFromDB( |
| 1593 ServiceWorkerDatabase* database, | 1615 ServiceWorkerDatabase* database, |
| 1594 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | 1616 scoped_refptr<base::SequencedTaskRunner> original_task_runner, |
| 1595 int64 registration_id, | 1617 int64 registration_id, |
| 1596 const GURL& origin, | 1618 const GURL& origin, |
| 1597 const DeleteRegistrationCallback& callback) { | 1619 const DeleteRegistrationCallback& callback) { |
| 1598 DCHECK(database); | 1620 DCHECK(database); |
| 1599 | 1621 |
| 1600 ServiceWorkerDatabase::RegistrationData deleted_version; | 1622 ServiceWorkerDatabase::RegistrationData deleted_version; |
| 1601 std::vector<int64> newly_purgeable_resources; | 1623 std::vector<int64> newly_purgeable_resources; |
| 1602 ServiceWorkerDatabase::Status status = database->DeleteRegistration( | 1624 ServiceWorkerDatabase::Status status = database->DeleteRegistration( |
| 1603 registration_id, origin, &deleted_version, &newly_purgeable_resources); | 1625 registration_id, origin, &deleted_version, &newly_purgeable_resources); |
| 1604 if (status != ServiceWorkerDatabase::STATUS_OK) { | 1626 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 1605 original_task_runner->PostTask( | 1627 original_task_runner->PostTask( |
| 1606 FROM_HERE, | 1628 FROM_HERE, base::Bind(callback, OriginState::KEEP_ALL, deleted_version, |
| 1607 base::Bind( | 1629 std::vector<int64>(), status)); |
| 1608 callback, false, deleted_version, std::vector<int64>(), status)); | |
| 1609 return; | 1630 return; |
| 1610 } | 1631 } |
| 1611 | 1632 |
| 1612 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the | 1633 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the |
| 1613 // unique origin list. | 1634 // unique origin list. |
| 1614 RegistrationList registrations; | 1635 RegistrationList registrations; |
| 1615 status = database->GetRegistrationsForOrigin(origin, ®istrations, nullptr); | 1636 status = database->GetRegistrationsForOrigin(origin, ®istrations, nullptr); |
| 1616 if (status != ServiceWorkerDatabase::STATUS_OK) { | 1637 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 1617 original_task_runner->PostTask( | 1638 original_task_runner->PostTask( |
| 1618 FROM_HERE, | 1639 FROM_HERE, base::Bind(callback, OriginState::KEEP_ALL, deleted_version, |
| 1619 base::Bind( | 1640 std::vector<int64>(), status)); |
| 1620 callback, false, deleted_version, std::vector<int64>(), status)); | |
| 1621 return; | 1641 return; |
| 1622 } | 1642 } |
| 1623 | 1643 |
| 1624 bool deletable = registrations.empty(); | 1644 OriginState origin_state = registrations.empty() |
| 1625 original_task_runner->PostTask(FROM_HERE, | 1645 ? OriginState::DELETE_FROM_ALL |
| 1626 base::Bind(callback, | 1646 : OriginState::DELETE_FROM_FOREIGN_FETCH; |
| 1627 deletable, | 1647 |
| 1628 deleted_version, | 1648 // TODO(mek): Add convenient method to ServiceWorkerDatabase to check the |
| 1629 newly_purgeable_resources, | 1649 // foreign fetch scope origin list. |
| 1630 status)); | 1650 for (const auto& registration : registrations) { |
| 1651 if (!registration.foreign_fetch_scopes.empty()) { |
| 1652 origin_state = OriginState::KEEP_ALL; |
| 1653 break; |
| 1654 } |
| 1655 } |
| 1656 original_task_runner->PostTask( |
| 1657 FROM_HERE, base::Bind(callback, origin_state, deleted_version, |
| 1658 newly_purgeable_resources, status)); |
| 1631 } | 1659 } |
| 1632 | 1660 |
| 1633 void ServiceWorkerStorage::WriteRegistrationInDB( | 1661 void ServiceWorkerStorage::WriteRegistrationInDB( |
| 1634 ServiceWorkerDatabase* database, | 1662 ServiceWorkerDatabase* database, |
| 1635 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | 1663 scoped_refptr<base::SequencedTaskRunner> original_task_runner, |
| 1636 const ServiceWorkerDatabase::RegistrationData& data, | 1664 const ServiceWorkerDatabase::RegistrationData& data, |
| 1637 const ResourceList& resources, | 1665 const ResourceList& resources, |
| 1638 const WriteRegistrationCallback& callback) { | 1666 const WriteRegistrationCallback& callback) { |
| 1639 DCHECK(database); | 1667 DCHECK(database); |
| 1640 ServiceWorkerDatabase::RegistrationData deleted_version; | 1668 ServiceWorkerDatabase::RegistrationData deleted_version; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1843 callback.Run(SERVICE_WORKER_ERROR_FAILED); | 1871 callback.Run(SERVICE_WORKER_ERROR_FAILED); |
| 1844 return; | 1872 return; |
| 1845 } | 1873 } |
| 1846 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; | 1874 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; |
| 1847 ServiceWorkerMetrics::RecordDeleteAndStartOverResult( | 1875 ServiceWorkerMetrics::RecordDeleteAndStartOverResult( |
| 1848 ServiceWorkerMetrics::DELETE_OK); | 1876 ServiceWorkerMetrics::DELETE_OK); |
| 1849 callback.Run(SERVICE_WORKER_OK); | 1877 callback.Run(SERVICE_WORKER_OK); |
| 1850 } | 1878 } |
| 1851 | 1879 |
| 1852 } // namespace content | 1880 } // namespace content |
| OLD | NEW |