blob: 5d5e305bccd8e28e605be552f92aeb91e2e373f5 [file] [log] [blame]
// 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.
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRY_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRY_H_
#include <memory>
#include <optional>
#include "base/containers/flat_set.h"
#include "base/containers/lru_cache.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/feature_list.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/threading/sequence_bound.h"
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
#include "components/services/storage/public/cpp/quota_error_or.h"
#include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h"
#include "components/services/storage/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "storage/browser/quota/storage_policy_observer.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_ancestor_frame_type.mojom.h"
namespace blink {
class StorageKey;
} // namespace blink
namespace storage {
class QuotaManagerProxy;
class SpecialStoragePolicy;
} // namespace storage
namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerVersion;
class ServiceWorkerRegistryTest;
FORWARD_DECLARE_TEST(ServiceWorkerRegistryTest, StoragePolicyChange);
CONTENT_EXPORT BASE_DECLARE_FEATURE(
kServiceWorkerMergeFindRegistrationForClientUrl);
// Manages in-memory representation of service worker registrations
// (i.e., ServiceWorkerRegistration) including installing and uninstalling
// registrations. Owned by ServiceWorkerContextCore and has the same lifetime of
// the owner. Lives on the UI thread.
//
// Communicates with ServiceWorkerStorageControl via a mojo remote to
// store/retrieve registrations to/from persistent storage. Most methods of this
// class call relevant mojo methods. Callbacks passed to these methods are
// invoked after mojo calls complete.
//
// The implementation of ServiceWorkerStorageControl lives in the Storage
// Service. This means that the mojo remote can be disconnected when the
// Storage Service crashes. To avoid a situation where callbacks never get
// invoked this class has a recovery mechanism. Upon detecting a disconnection,
// this tries to reconnect to ServiceWorkerStorageControl then retry all
// inflight mojo calls.
class CONTENT_EXPORT ServiceWorkerRegistry {
public:
using ResourceList =
std::vector<storage::mojom::ServiceWorkerResourceRecordPtr>;
using RegistrationList =
std::vector<storage::mojom::ServiceWorkerRegistrationDataPtr>;
using FindRegistrationCallback = base::OnceCallback<void(
blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration)>;
using GetRegisteredStorageKeysCallback = base::OnceCallback<void(
const std::vector<blink::StorageKey>& storage_keys)>;
using GetRegistrationsCallback = base::OnceCallback<void(
blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
registrations)>;
using GetRegistrationsInfosCallback = base::OnceCallback<void(
blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& registrations)>;
using GetUserDataCallback =
base::OnceCallback<void(const std::vector<std::string>& data,
blink::ServiceWorkerStatusCode status)>;
using GetUserKeysAndDataCallback = base::OnceCallback<void(
blink::ServiceWorkerStatusCode status,
const base::flat_map<std::string, std::string>& data_map)>;
using GetUserDataForAllRegistrationsCallback = base::OnceCallback<void(
const std::vector<std::pair<int64_t, std::string>>& user_data,
blink::ServiceWorkerStatusCode status)>;
using GetStorageUsageForStorageKeyCallback =
base::OnceCallback<void(blink::ServiceWorkerStatusCode status,
int64_t usage)>;
using StatusCallback =
base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
enum class Purpose { kNotForNavigation, kNavigation };
ServiceWorkerRegistry(ServiceWorkerContextCore& context,
storage::QuotaManagerProxy* quota_manager_proxy,
storage::SpecialStoragePolicy* special_storage_policy,
base::TimeTicks start_time);
// For re-creating the registry from the old one. This is called when
// something went wrong during storage access.
ServiceWorkerRegistry(ServiceWorkerContextCore& context,
ServiceWorkerRegistry& old_registry);
~ServiceWorkerRegistry();
// Creates a new in-memory representation of registration. Can be null when
// storage is disabled. This method must be called after storage is
// initialized.
using NewRegistrationCallback = base::OnceCallback<void(
scoped_refptr<ServiceWorkerRegistration> registration)>;
void CreateNewRegistration(
blink::mojom::ServiceWorkerRegistrationOptions options,
const blink::StorageKey& key,
blink::mojom::AncestorFrameType ancestor_frame_type,
NewRegistrationCallback callback);
// Create a new instance of ServiceWorkerVersion which is associated with the
// given |registration|. Can be null when storage is disabled. This method
// must be called after storage is initialized.
using NewVersionCallback =
base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion> version)>;
void CreateNewVersion(scoped_refptr<ServiceWorkerRegistration> registration,
const GURL& script_url,
blink::mojom::ScriptType script_type,
NewVersionCallback callback);
// Finds registration for `client_url`, `scope`, or `registration_id` with the
// associated `key`. The Find methods will find stored and initially
// installing registrations. Returns blink::ServiceWorkerStatusCode::kOk with
// non-null registration if registration is found, or returns
// blink::ServiceWorkerStatusCode::kErrorNotFound if no
// matching registration is found. The FindRegistrationForScope method is
// guaranteed to return asynchronously. However, the methods to find
// for `client_url` or `registration_id` may complete immediately
// (the callback may be called prior to the method returning) or
// asynchronously.
void FindRegistrationForClientUrl(Purpose purpose,
const GURL& client_url,
const blink::StorageKey& key,
FindRegistrationCallback callback);
void FindRegistrationForScope(const GURL& scope,
const blink::StorageKey& key,
FindRegistrationCallback callback);
// These FindRegistrationForId() methods look up live registrations and may
// return a "findable" registration without looking up storage. A registration
// is considered as "findable" when the registration is stored or in the
// installing state.
void FindRegistrationForId(int64_t registration_id,
const blink::StorageKey& key,
FindRegistrationCallback callback);
// Generally |FindRegistrationForId| should be used to look up a registration
// by |registration_id| since it's more efficient. But if a |registration_id|
// is all that is available this method can be used instead.
// Like |FindRegistrationForId| this method may complete immediately (the
// callback may be called prior to the method returning) or asynchronously.
void FindRegistrationForIdOnly(int64_t registration_id,
FindRegistrationCallback callback);
// Returns all stored and installing registrations for a given StorageKey.
void GetRegistrationsForStorageKey(const blink::StorageKey& key,
GetRegistrationsCallback callback);
// Reads the total resource size stored in the storage for a given storage
// key.
void GetStorageUsageForStorageKey(
const blink::StorageKey& key,
GetStorageUsageForStorageKeyCallback callback);
// Returns info about all stored and initially installing registrations.
// TODO(crbug.com/807440,1055677): Consider removing this method. Getting all
// registrations at once might not be a good idea.
void GetAllRegistrationsInfos(GetRegistrationsInfosCallback callback);
ServiceWorkerRegistration* GetUninstallingRegistration(
const GURL& scope,
const blink::StorageKey& key);
std::vector<scoped_refptr<ServiceWorkerRegistration>>
GetUninstallingRegistrationsForStorageKey(const blink::StorageKey& key);
// Commits |registration| with the installed but not activated |version|
// to storage, overwriting any pre-existing registration data for the scope.
// A pre-existing version's script resources remain available if that version
// is live. ServiceWorkerStorage::PurgeResources() should be called when it's
// OK to delete them.
void StoreRegistration(ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version,
StatusCallback callback);
// Deletes the registration data for `registration`. The live registration is
// still findable via GetUninstallingRegistration(), and versions are usable
// because their script resources have not been deleted. After calling this,
// the caller should later:
// - Call NotifyDoneUninstallingRegistration() to let registry know the
// uninstalling operation is done.
// - If it no longer wants versions to be usable, call
// ServiceWorkerStorage::PurgeResources() to delete their script resources.
// If these aren't called, on the next profile session the cleanup occurs.
void DeleteRegistration(scoped_refptr<ServiceWorkerRegistration> registration,
StatusCallback callback);
// Intended for use only by ServiceWorkerRegisterJob and
// ServiceWorkerRegistration.
void NotifyInstallingRegistration(ServiceWorkerRegistration* registration);
void NotifyDoneInstallingRegistration(ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version,
blink::ServiceWorkerStatusCode status);
void NotifyDoneUninstallingRegistration(
ServiceWorkerRegistration* registration,
ServiceWorkerRegistration::Status new_status);
// Wrapper functions of ServiceWorkerStorage. These wrappers provide error
// recovering mechanism when database operations fail.
void UpdateToActiveState(int64_t registration_id,
const blink::StorageKey& key,
StatusCallback callback);
void UpdateLastUpdateCheckTime(int64_t registration_id,
const blink::StorageKey& key,
base::Time last_update_check_time,
StatusCallback callback);
void UpdateNavigationPreloadEnabled(int64_t registration_id,
const blink::StorageKey& key,
bool enable,
StatusCallback callback);
void UpdateNavigationPreloadHeader(int64_t registration_id,
const blink::StorageKey& key,
const std::string& value,
StatusCallback callback);
void UpdateFetchHandlerType(
int64_t registration_id,
const blink::StorageKey& key,
blink::mojom::ServiceWorkerFetchHandlerType fetch_handler_type,
StatusCallback callback);
void UpdateResourceSha256Checksums(
int64_t registration_id,
const blink::StorageKey& key,
const base::flat_map<int64_t, std::string>& updated_sha256_checksums,
StatusCallback callback);
void StoreUncommittedResourceId(int64_t resource_id,
const blink::StorageKey& key);
void DoomUncommittedResource(int64_t resource_id);
void GetUserData(int64_t registration_id,
const std::vector<std::string>& keys,
GetUserDataCallback callback);
void GetUserDataByKeyPrefix(int64_t registration_id,
const std::string& key_prefix,
GetUserDataCallback callback);
void GetUserKeysAndDataByKeyPrefix(int64_t registration_id,
const std::string& key_prefix,
GetUserKeysAndDataCallback callback);
void StoreUserData(
int64_t registration_id,
const blink::StorageKey& key,
const std::vector<std::pair<std::string, std::string>>& key_value_pairs,
StatusCallback callback);
void ClearUserData(int64_t registration_id,
const std::vector<std::string>& keys,
StatusCallback callback);
void ClearUserDataByKeyPrefixes(int64_t registration_id,
const std::vector<std::string>& key_prefixes,
StatusCallback callback);
void ClearUserDataForAllRegistrationsByKeyPrefix(
const std::string& key_prefix,
StatusCallback callback);
void GetUserDataForAllRegistrations(
const std::string& key,
GetUserDataForAllRegistrationsCallback callback);
void GetUserDataForAllRegistrationsByKeyPrefix(
const std::string& key_prefix,
GetUserDataForAllRegistrationsCallback callback);
// Returns a set of storage keys which have at least one stored registration.
// The set doesn't include installing/uninstalling/uninstalled registrations.
void GetRegisteredStorageKeys(GetRegisteredStorageKeysCallback callback);
// Returns false only when we are sure that there's no service worker
// registrations for the given storage key. If we are not sure, this function
// must return true to suggest that we need to check the service worker
// registration specifically (e.g. by calling FindRegistrationForClientUrl()).
// This function is a lot faster than FindRegistrationForClientUrl().
bool MaybeHasRegistrationForStorageKey(const blink::StorageKey& key);
// This method waits for service worker registrations to be initialized, and
// depends on |on_registrations_initialized_| and |registrations_initialized_|
// which are called in InitializeRegisteredOrigins().
void WaitForRegistrationsInitializedForTest();
// Performs internal storage cleanup. Operations to the storage in the past
// (e.g. deletion) are usually recorded in disk for a certain period until
// compaction happens. This method wipes them out to ensure that the deleted
// entries and other traces like log files are removed.
void PerformStorageCleanup(base::OnceClosure callback);
// Disables the internal storage to prepare for error recovery.
void PrepareForDeleteAndStartOver();
// Deletes this registry and internal storage, then starts over for error
// recovery.
void DeleteAndStartOver(StatusCallback callback);
mojo::Remote<storage::mojom::ServiceWorkerStorageControl>&
GetRemoteStorageControl();
// Binds a ServiceWorkerStorageControl.
void BindStorageControl(
mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl>
receiver);
// Call storage::mojom::ServiceWorkerStorageControl::Disable() immediately.
// This method sends an IPC message without using the queuing mechanism.
void DisableStorageForTesting(base::OnceClosure callback);
private:
friend class ServiceWorkerRegistryTest;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerRegistryTest, StoragePolicyChange);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerRegistryTest,
RetryInflightCalls_ApplyPolicyUpdates);
void Start(base::TimeTicks start_time);
void FindRegistrationForIdInternal(
int64_t registration_id,
const std::optional<blink::StorageKey>& key,
FindRegistrationCallback callback);
ServiceWorkerRegistration* FindInstallingRegistrationForClientUrl(
const GURL& client_url,
const blink::StorageKey& key);
ServiceWorkerRegistration* FindInstallingRegistrationForScope(
const GURL& scope,
const blink::StorageKey& key);
ServiceWorkerRegistration* FindInstallingRegistrationForId(
int64_t registration_id);
scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration(
const storage::mojom::ServiceWorkerRegistrationData& data,
const ResourceList& resources,
mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
version_reference);
void CreateNewRegistrationWithBucketInfo(
blink::mojom::ServiceWorkerRegistrationOptions options,
const blink::StorageKey& key,
blink::mojom::AncestorFrameType ancestor_frame_type,
NewRegistrationCallback callback,
storage::QuotaErrorOr<storage::BucketInfo> result);
// Looks up live registrations and returns an optional value which may contain
// a "findable" registration. See the implementation of this method for
// what "findable" means and when a registration is returned.
std::optional<scoped_refptr<ServiceWorkerRegistration>>
FindFromLiveRegistrationsForId(int64_t registration_id);
void DoomUncommittedResources(const std::vector<int64_t>& resource_ids);
void 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 RunFindRegistrationCallbacks(
const GURL& client_url,
const blink::StorageKey& key,
scoped_refptr<ServiceWorkerRegistration> registration,
blink::ServiceWorkerStatusCode status);
void DidFindRegistrationForScope(
FindRegistrationCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
storage::mojom::ServiceWorkerFindRegistrationResultPtr result);
void DidFindRegistrationForId(
int64_t registration_id,
FindRegistrationCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
storage::mojom::ServiceWorkerFindRegistrationResultPtr result);
void DidGetRegistrationsForStorageKey(
GetRegistrationsCallback callback,
const blink::StorageKey& key_filter,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
std::vector<storage::mojom::ServiceWorkerFindRegistrationResultPtr>
entries);
void DidGetAllRegistrations(
GetRegistrationsInfosCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
RegistrationList registration_data_list);
void DidGetStorageUsageForStorageKey(
GetStorageUsageForStorageKeyCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus database_status,
int64_t usage);
void 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 NotifyRegistrationStored(int64_t stored_registration_id,
uint64_t stored_resources_total_size_bytes,
const GURL& stored_scope,
const blink::StorageKey& key,
StatusCallback callback);
void 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 NotifyRegistrationDeletedForStorageKey(
int64_t registration_id,
const GURL& stored_scope,
const blink::StorageKey& key,
storage::mojom::ServiceWorkerStorageStorageKeyState storage_key_state,
StatusCallback callback);
void DidUpdateRegistration(
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidUpdateToActiveState(
const blink::StorageKey& key,
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidWriteUncommittedResourceIds(
const blink::StorageKey& key,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidDoomUncommittedResourceIds(
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidGetUserData(GetUserDataCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
const std::vector<std::string>& data);
void DidGetUserKeysAndData(
GetUserKeysAndDataCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
const base::flat_map<std::string, std::string>& data_map);
void DidStoreUserData(StatusCallback callback,
const blink::StorageKey& key,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidClearUserData(StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidGetUserDataForAllRegistrations(
GetUserDataForAllRegistrationsCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
std::vector<storage::mojom::ServiceWorkerUserDataPtr> entries);
void DidGetNewRegistrationId(
blink::mojom::ServiceWorkerRegistrationOptions options,
const blink::StorageKey& key,
blink::mojom::AncestorFrameType ancestor_frame_type,
NewRegistrationCallback callback,
int64_t registration_id);
void 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 ScheduleDeleteAndStartOver();
void DidDeleteAndStartOver(
StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidGetRegisteredStorageKeys(GetRegisteredStorageKeysCallback callback,
const std::vector<blink::StorageKey>& keys);
void DidPerformStorageCleanup(base::OnceClosure callback);
void DidDisable();
void DidApplyPolicyUpdates(
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidGetRegisteredStorageKeysOnStartup(
base::TimeTicks start_time,
const std::vector<blink::StorageKey>& storage_keys);
// This is used as a callback of GetRegisteredStorageKeys when initialising to
// store a list of storage keys that have registered service workers.
void DidGetRegisteredStorageKeysOnStartupDeprecated(
base::TimeTicks start_time,
const std::vector<blink::StorageKey>& storage_keys);
void SetRegisteredStorageKeys(
const std::vector<blink::StorageKey>& storage_keys);
void ApplyPolicyUpdates(
std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates);
bool ShouldPurgeOnShutdownForTesting(const blink::StorageKey& key);
void OnRemoteStorageDisconnected();
void DidRecover();
// Represents an inflight mojo remote call. Used to support retry.
class InflightCall {
public:
virtual ~InflightCall() = default;
virtual void Run() = 0;
};
template <typename...>
friend class InflightCallWithInvoker;
void StartRemoteCall(std::unique_ptr<InflightCall> call);
void FinishRemoteCall(const InflightCall* call);
void ClearAllInternalCache();
void ClearInternalCacheForStorageKey(const blink::StorageKey& storage_key);
storage::ServiceWorkerStorage::StorageSharedBuffer& storage_shared_buffer() {
// storage_shared_buffer_ always exists.
return *storage_shared_buffer_;
}
// A helper function to call a mojo remote call that will automatically be
// reissued if the mojo::Remote becomes disconnected. To allow the call to be
// dispatched multiple times, all arguments must be either be:
//
// - passed by const reference
// - copyable
// - or clonable via `mojo::Clone()`.
//
// Example:
//
// (in mojom)
// Foo(int64 arg1, int64 arg2) => (ServiceWorkerDatabaseStatus status);
//
// CreateInvokerAndStartRemoteCall(
// &storage::mojom::ServiceWorkerStorageControl::Foo,
// base::BindOnce(&ServiceWorkerRegistry::DidFoo,
// weak_factory_.GetWeakPtr(),
// std::move(callback)),
// arg1, arg2);
//
// void ServiceWorkerRegistry::DidFoo(
// FooCallback callback,
// storage::mojom::ServiceWorkerDatabaseStatus status) {
// // ...
// }
template <typename Functor, typename... Args, typename... CallbackArgs>
void CreateInvokerAndStartRemoteCall(
Functor&& f,
base::OnceCallback<void(CallbackArgs...)> callback,
Args&&... args);
// The ServiceWorkerContextCore object must outlive this.
const raw_ref<ServiceWorkerContextCore> context_;
// This is a direct communication channel between this ServiceWorkerRegistry
// in the UI thread and the ServiceWorkerStorage in the thread pool.
// This must not be null.
scoped_refptr<storage::ServiceWorkerStorage::StorageSharedBuffer>
storage_shared_buffer_;
mojo::Remote<storage::mojom::ServiceWorkerStorageControl>
remote_storage_control_;
bool is_storage_disabled_ = false;
// A set of StorageKeys that have at least one registration.
std::set<blink::StorageKey> registered_storage_keys_;
bool registrations_initialized_ = false;
base::OnceClosure on_registrations_initialized_for_test_;
// TODO(crbug.com/40103974): Consider moving QuotaManagerProxy to
// ServiceWorkerStorage once QuotaManager gets mojofied.
const scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
const scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
std::optional<storage::StoragePolicyObserver> storage_policy_observer_;
// For finding registrations being installed or uninstalled.
using RegistrationRefsById =
std::map<int64_t, scoped_refptr<ServiceWorkerRegistration>>;
RegistrationRefsById installing_registrations_;
RegistrationRefsById uninstalling_registrations_;
// Indicates whether recovery process should be scheduled.
bool should_schedule_delete_and_start_over_ = true;
// Stores in-flight FindRegistrationForClientUrl callbacks to merge duplicate
// requests.
base::flat_map<std::pair<GURL, blink::StorageKey>,
std::vector<FindRegistrationCallback>>
find_registration_callbacks_;
// ServiceWorker registration scope cache to skip calling
// FindRegistrationForClientUrl mojo function (https://crbug.com/1411197).
base::LRUCache<blink::StorageKey, std::set<GURL>> registration_scope_cache_;
// Live registration's `registration_id` cache to skip calling
// FindRegistrationForClientUrl mojo function (https://crbug.com/1446216). The
// key is a pair of {registration_scope, storage_key}.
base::LRUCache<std::pair<GURL, blink::StorageKey>, int64_t>
registration_id_cache_;
enum class ConnectionState {
kNormal,
kRecovering,
};
ConnectionState connection_state_ = ConnectionState::kNormal;
size_t recovery_retry_counts_ = 0;
base::flat_set<std::unique_ptr<InflightCall>, base::UniquePtrComparator>
inflight_calls_;
base::WeakPtrFactory<ServiceWorkerRegistry> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRY_H_