#include "content/browser/service_worker/service_worker_registry.h"
#include <type_traits>
#include <utility>
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/not_fatal_until.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
#include "components/services/storage/public/cpp/buckets/constants.h"
#include "components/services/storage/public/cpp/quota_error_or.h"
#include "components/services/storage/public/mojom/storage_policy_update.mojom.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_router_evaluator.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/special_storage_policy.h"
#include "third_party/blink/public/common/service_worker/service_worker_scope_match.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration_options.mojom.h"
#include "url/origin.h"
namespace content {
namespace {
BASE_FEATURE(…);
const int kServiceWorkerScopeCacheHardLimitPerKey = …;
blink::ServiceWorkerStatusCode DatabaseStatusToStatusCode(
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void RunSoon(const base::Location& from_here, base::OnceClosure closure) { … }
void CompleteFindNow(scoped_refptr<ServiceWorkerRegistration> registration,
blink::ServiceWorkerStatusCode status,
ServiceWorkerRegistry::FindRegistrationCallback callback) { … }
void CompleteFindSoon(
const base::Location& from_here,
scoped_refptr<ServiceWorkerRegistration> registration,
blink::ServiceWorkerStatusCode status,
ServiceWorkerRegistry::FindRegistrationCallback callback) { … }
void RecordRetryCount(size_t retries, size_t queue_size) { … }
void CheckForClientWriteFailure(
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
storage::mojom::ServiceWorkerDatabaseStatus status,
const blink::StorageKey& key) { … }
void EraseRegistrationIdCacheEntry(
base::LRUCache<std::tuple<GURL, blink::StorageKey>, int64_t>&
registration_id_cache,
const GURL& scope,
const blink::StorageKey& key) { … }
void FindRegistrationForClientUrlTraceEventBegin(int64_t trace_event_id,
const GURL& client_url) { … }
void FindRegistrationForClientUrlTraceEventEnd(
int64_t trace_event_id,
blink::ServiceWorkerStatusCode status,
std::optional<std::string> info) { … }
std::string RouterRulesToString(blink::ServiceWorkerRouterRules rules) { … }
}
BASE_FEATURE(…);
BASE_FEATURE(…);
const base::FeatureParam<int> kServiceWorkerRegistrationCacheSize{ … };
BASE_FEATURE(…);
const base::FeatureParam<int> kServiceWorkerScopeCacheLimitSize{ … };
template <typename... ReplyArgs>
class InflightCallWithInvoker final
: public ServiceWorkerRegistry::InflightCall { … };
ServiceWorkerRegistry::ServiceWorkerRegistry(
ServiceWorkerContextCore* context,
storage::QuotaManagerProxy* quota_manager_proxy,
storage::SpecialStoragePolicy* special_storage_policy)
: … { … }
ServiceWorkerRegistry::ServiceWorkerRegistry(
ServiceWorkerContextCore* context,
ServiceWorkerRegistry* old_registry)
: … { … }
ServiceWorkerRegistry::~ServiceWorkerRegistry() = default;
void ServiceWorkerRegistry::CreateNewRegistration(
blink::mojom::ServiceWorkerRegistrationOptions options,
const blink::StorageKey& key,
blink::mojom::AncestorFrameType ancestor_frame_type,
NewRegistrationCallback callback) { … }
void ServiceWorkerRegistry::CreateNewRegistrationWithBucketInfo(
blink::mojom::ServiceWorkerRegistrationOptions options,
const blink::StorageKey& key,
blink::mojom::AncestorFrameType ancestor_frame_type,
NewRegistrationCallback callback,
storage::QuotaErrorOr<storage::BucketInfo> result) { … }
void ServiceWorkerRegistry::CreateNewVersion(
scoped_refptr<ServiceWorkerRegistration> registration,
const GURL& script_url,
blink::mojom::ScriptType script_type,
NewVersionCallback callback) { … }
void ServiceWorkerRegistry::FindRegistrationForClientUrl(
Purpose purpose,
const GURL& client_url,
const blink::StorageKey& key,
FindRegistrationCallback callback) { … }
void ServiceWorkerRegistry::FindRegistrationForScope(
const GURL& scope,
const blink::StorageKey& key,
FindRegistrationCallback callback) { … }
void ServiceWorkerRegistry::FindRegistrationForId(
int64_t registration_id,
const blink::StorageKey& key,
FindRegistrationCallback callback) { … }
void ServiceWorkerRegistry::FindRegistrationForIdOnly(
int64_t registration_id,
FindRegistrationCallback callback) { … }
void ServiceWorkerRegistry::GetRegistrationsForStorageKey(
const blink::StorageKey& key,
GetRegistrationsCallback callback) { … }
void ServiceWorkerRegistry::GetStorageUsageForStorageKey(
const blink::StorageKey& key,
GetStorageUsageForStorageKeyCallback callback) { … }
void ServiceWorkerRegistry::GetAllRegistrationsInfos(
GetRegistrationsInfosCallback callback) { … }
ServiceWorkerRegistration* ServiceWorkerRegistry::GetUninstallingRegistration(
const GURL& scope,
const blink::StorageKey& key) { … }
std::vector<scoped_refptr<ServiceWorkerRegistration>>
ServiceWorkerRegistry::GetUninstallingRegistrationsForStorageKey(
const blink::StorageKey& key) { … }
void ServiceWorkerRegistry::StoreRegistration(
ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version,
StatusCallback callback) { … }
void ServiceWorkerRegistry::DeleteRegistration(
scoped_refptr<ServiceWorkerRegistration> registration,
StatusCallback callback) { … }
void ServiceWorkerRegistry::NotifyInstallingRegistration(
ServiceWorkerRegistration* registration) { … }
void ServiceWorkerRegistry::NotifyDoneInstallingRegistration(
ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version,
blink::ServiceWorkerStatusCode status) { … }
void ServiceWorkerRegistry::NotifyDoneUninstallingRegistration(
ServiceWorkerRegistration* registration,
ServiceWorkerRegistration::Status new_status) { … }
void ServiceWorkerRegistry::UpdateToActiveState(int64_t registration_id,
const blink::StorageKey& key,
StatusCallback callback) { … }
void ServiceWorkerRegistry::UpdateLastUpdateCheckTime(
int64_t registration_id,
const blink::StorageKey& key,
base::Time last_update_check_time,
StatusCallback callback) { … }
void ServiceWorkerRegistry::UpdateNavigationPreloadEnabled(
int64_t registration_id,
const blink::StorageKey& key,
bool enable,
StatusCallback callback) { … }
void ServiceWorkerRegistry::UpdateNavigationPreloadHeader(
int64_t registration_id,
const blink::StorageKey& key,
const std::string& value,
StatusCallback callback) { … }
void ServiceWorkerRegistry::UpdateFetchHandlerType(
int64_t registration_id,
const blink::StorageKey& key,
blink::mojom::ServiceWorkerFetchHandlerType fetch_handler_type,
StatusCallback callback) { … }
void ServiceWorkerRegistry::UpdateResourceSha256Checksums(
int64_t registration_id,
const blink::StorageKey& key,
const base::flat_map<int64_t, std::string>& updated_sha256_checksums,
StatusCallback callback) { … }
void ServiceWorkerRegistry::StoreUncommittedResourceId(
int64_t resource_id,
const blink::StorageKey& key) { … }
void ServiceWorkerRegistry::DoomUncommittedResource(int64_t resource_id) { … }
void ServiceWorkerRegistry::GetUserData(int64_t registration_id,
const std::vector<std::string>& keys,
GetUserDataCallback callback) { … }
void ServiceWorkerRegistry::GetUserDataByKeyPrefix(
int64_t registration_id,
const std::string& key_prefix,
GetUserDataCallback callback) { … }
void ServiceWorkerRegistry::GetUserKeysAndDataByKeyPrefix(
int64_t registration_id,
const std::string& key_prefix,
GetUserKeysAndDataCallback callback) { … }
void ServiceWorkerRegistry::StoreUserData(
int64_t registration_id,
const blink::StorageKey& key,
const std::vector<std::pair<std::string, std::string>>& key_value_pairs,
StatusCallback callback) { … }
void ServiceWorkerRegistry::ClearUserData(int64_t registration_id,
const std::vector<std::string>& keys,
StatusCallback callback) { … }
void ServiceWorkerRegistry::ClearUserDataByKeyPrefixes(
int64_t registration_id,
const std::vector<std::string>& key_prefixes,
StatusCallback callback) { … }
void ServiceWorkerRegistry::ClearUserDataForAllRegistrationsByKeyPrefix(
const std::string& key_prefix,
StatusCallback callback) { … }
void ServiceWorkerRegistry::GetUserDataForAllRegistrations(
const std::string& key,
GetUserDataForAllRegistrationsCallback callback) { … }
void ServiceWorkerRegistry::GetUserDataForAllRegistrationsByKeyPrefix(
const std::string& key_prefix,
GetUserDataForAllRegistrationsCallback callback) { … }
void ServiceWorkerRegistry::GetRegisteredStorageKeys(
GetRegisteredStorageKeysCallback callback) { … }
void ServiceWorkerRegistry::PerformStorageCleanup(base::OnceClosure callback) { … }
void ServiceWorkerRegistry::PrepareForDeleteAndStartOver() { … }
void ServiceWorkerRegistry::DeleteAndStartOver(StatusCallback callback) { … }
void ServiceWorkerRegistry::DisableStorageForTesting(
base::OnceClosure callback) { … }
void ServiceWorkerRegistry::Start() { … }
void ServiceWorkerRegistry::FindRegistrationForIdInternal(
int64_t registration_id,
const std::optional<blink::StorageKey>& key,
FindRegistrationCallback callback) { … }
ServiceWorkerRegistration*
ServiceWorkerRegistry::FindInstallingRegistrationForClientUrl(
const GURL& client_url,
const blink::StorageKey& key) { … }
ServiceWorkerRegistration*
ServiceWorkerRegistry::FindInstallingRegistrationForScope(
const GURL& scope,
const blink::StorageKey& key) { … }
ServiceWorkerRegistration*
ServiceWorkerRegistry::FindInstallingRegistrationForId(
int64_t registration_id) { … }
scoped_refptr<ServiceWorkerRegistration>
ServiceWorkerRegistry::GetOrCreateRegistration(
const storage::mojom::ServiceWorkerRegistrationData& data,
const ResourceList& resources,
mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
version_reference) { … }
std::optional<scoped_refptr<ServiceWorkerRegistration>>
ServiceWorkerRegistry::FindFromLiveRegistrationsForId(int64_t registration_id) { … }
void ServiceWorkerRegistry::DoomUncommittedResources(
const std::vector<int64_t>& resource_ids) { … }
void ServiceWorkerRegistry::DidFindRegistrationForClientUrl(
const GURL& client_url,
const blink::StorageKey& key,
int64_t trace_event_id,
FindRegistrationCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
storage::mojom::ServiceWorkerFindRegistrationResultPtr result,
const std::optional<std::vector<GURL>>& scopes) { … }
void ServiceWorkerRegistry::RunFindRegistrationCallbacks(
const GURL& client_url,
const blink::StorageKey& key,
scoped_refptr<ServiceWorkerRegistration> registration,
blink::ServiceWorkerStatusCode status) { … }
void ServiceWorkerRegistry::DidFindRegistrationForScope(
FindRegistrationCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
storage::mojom::ServiceWorkerFindRegistrationResultPtr result) { … }
void ServiceWorkerRegistry::DidFindRegistrationForId(
int64_t registration_id,
FindRegistrationCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
storage::mojom::ServiceWorkerFindRegistrationResultPtr result) { … }
void ServiceWorkerRegistry::DidGetRegistrationsForStorageKey(
GetRegistrationsCallback callback,
const blink::StorageKey& key_filter,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
std::vector<storage::mojom::ServiceWorkerFindRegistrationResultPtr>
entries) { … }
void ServiceWorkerRegistry::DidGetAllRegistrations(
GetRegistrationsInfosCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
RegistrationList registration_data_list) { … }
void ServiceWorkerRegistry::DidGetStorageUsageForStorageKey(
GetStorageUsageForStorageKeyCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
int64_t usage) { … }
void ServiceWorkerRegistry::DidStoreRegistration(
int64_t stored_registration_id,
uint64_t stored_resources_total_size_bytes,
const GURL& stored_scope,
const blink::StorageKey& key,
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
uint64_t deleted_resources_size) { … }
void ServiceWorkerRegistry::NotifyRegistrationStored(
int64_t stored_registration_id,
uint64_t stored_resources_total_size_bytes,
const GURL& stored_scope,
const blink::StorageKey& key,
StatusCallback callback) { … }
void ServiceWorkerRegistry::DidDeleteRegistration(
int64_t registration_id,
const GURL& stored_scope,
const blink::StorageKey& key,
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
uint64_t deleted_resources_size,
storage::mojom::ServiceWorkerStorageStorageKeyState storage_key_state) { … }
void ServiceWorkerRegistry::NotifyRegistrationDeletedForStorageKey(
int64_t registration_id,
const GURL& stored_scope,
const blink::StorageKey& key,
storage::mojom::ServiceWorkerStorageStorageKeyState storage_key_state,
StatusCallback callback) { … }
void ServiceWorkerRegistry::DidUpdateRegistration(
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidUpdateToActiveState(
const blink::StorageKey& key,
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidWriteUncommittedResourceIds(
const blink::StorageKey& key,
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidDoomUncommittedResourceIds(
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidGetUserData(
GetUserDataCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
const std::vector<std::string>& data) { … }
void ServiceWorkerRegistry::DidGetUserKeysAndData(
GetUserKeysAndDataCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
const base::flat_map<std::string, std::string>& data_map) { … }
void ServiceWorkerRegistry::DidStoreUserData(
StatusCallback callback,
const blink::StorageKey& key,
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidClearUserData(
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidGetUserDataForAllRegistrations(
GetUserDataForAllRegistrationsCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
std::vector<storage::mojom::ServiceWorkerUserDataPtr> entries) { … }
void ServiceWorkerRegistry::DidGetNewRegistrationId(
blink::mojom::ServiceWorkerRegistrationOptions options,
const blink::StorageKey& key,
blink::mojom::AncestorFrameType ancestor_frame_type,
NewRegistrationCallback callback,
int64_t registration_id) { … }
void ServiceWorkerRegistry::DidGetNewVersionId(
scoped_refptr<ServiceWorkerRegistration> registration,
const GURL& script_url,
blink::mojom::ScriptType script_type,
NewVersionCallback callback,
int64_t version_id,
mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
version_reference) { … }
void ServiceWorkerRegistry::ScheduleDeleteAndStartOver() { … }
void ServiceWorkerRegistry::DidDeleteAndStartOver(
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidGetRegisteredStorageKeys(
GetRegisteredStorageKeysCallback callback,
const std::vector<blink::StorageKey>& keys) { … }
void ServiceWorkerRegistry::DidPerformStorageCleanup(
base::OnceClosure callback) { … }
void ServiceWorkerRegistry::DidDisable() { … }
void ServiceWorkerRegistry::DidApplyPolicyUpdates(
storage::mojom::ServiceWorkerDatabaseStatus status) { … }
void ServiceWorkerRegistry::DidGetRegisteredStorageKeysOnStartup(
const std::vector<blink::StorageKey>& storage_keys) { … }
void ServiceWorkerRegistry::ApplyPolicyUpdates(
std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates) { … }
bool ServiceWorkerRegistry::ShouldPurgeOnShutdownForTesting(
const blink::StorageKey& key) { … }
mojo::Remote<storage::mojom::ServiceWorkerStorageControl>&
ServiceWorkerRegistry::GetRemoteStorageControl() { … }
void ServiceWorkerRegistry::OnRemoteStorageDisconnected() { … }
void ServiceWorkerRegistry::DidRecover() { … }
void ServiceWorkerRegistry::StartRemoteCall(
std::unique_ptr<InflightCall> call) { … }
void ServiceWorkerRegistry::FinishRemoteCall(const InflightCall* call) { … }
namespace {
PassingType;
template <typename T>
struct RequiresCloneTraits { … };
RequiresCloneTraits<std::vector<T>>;
template <typename T,
bool is_copy_constructible = RequiresCloneTraits<T>::kValue>
struct CloneTraits;
CloneTraits<T, true>;
CloneTraits<T, false>;
}
template <typename Functor, typename... Args, typename... ReplyArgs>
void ServiceWorkerRegistry::CreateInvokerAndStartRemoteCall(
Functor&& f,
base::OnceCallback<void(ReplyArgs...)> reply_callback,
Args&&... args) { … }
}