chromium/content/browser/service_worker/service_worker_registry.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

// When this is enabled, the browser will schedule
// ServiceWorkerStorageControl's response in a kHighest priority
// queue during startup. After startup, it has a normal priority.
BASE_FEATURE();

// A hard limit of the ServiceWorkerScopeCacheLimitPerKey feature param.
// (https://crbug.com/1411197)
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) {}

// Notifies quota manager that a disk write operation failed so that it can
// check for storage pressure.
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) {}

}  // namespace

// Enables merging duplicate calls of FindRegistrationForClientUrl.
BASE_FEATURE();

// Enable registration cache to skip calling FindRegistrationForClientUrl while
// there is a live registration. (https://crbug.com/1446216)
BASE_FEATURE();

const base::FeatureParam<int> kServiceWorkerRegistrationCacheSize{};

BASE_FEATURE();

// The cache size for kServiceWorkerScopeCache.
// (https://crbug.com/1411197)
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 {};

// Specialization for vectors with move-only types, since STL does not SFINAE
// disable the copy constructor.
RequiresCloneTraits<std::vector<T>>;

template <typename T,
          bool is_copy_constructible = RequiresCloneTraits<T>::kValue>
struct CloneTraits;

CloneTraits<T, true>;

CloneTraits<T, false>;

}  // namespace

template <typename Functor, typename... Args, typename... ReplyArgs>
void ServiceWorkerRegistry::CreateInvokerAndStartRemoteCall(
    Functor&& f,
    base::OnceCallback<void(ReplyArgs...)> reply_callback,
    Args&&... args) {}

}  // namespace content