// Copyright 2012 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_STORAGE_PARTITION_IMPL_H_ #define CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_ #include <stdint.h> #include <map> #include <memory> #include <set> #include <string> #include "base/containers/flat_map.h" #include "base/dcheck_is_on.h" #include "base/files/file_path.h" #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "components/services/storage/privileged/mojom/indexed_db_client_state_checker.mojom.h" #include "components/services/storage/public/mojom/partition.mojom.h" #include "components/services/storage/public/mojom/storage_service.mojom-forward.h" #include "content/browser/background_sync/background_sync_context_impl.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/content_index/content_index_context_impl.h" #include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/locks/lock_manager.h" #include "content/browser/notifications/platform_notification_context_impl.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/worker_host/dedicated_worker_service_impl.h" #include "content/common/content_export.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition_config.h" #include "media/media_buildflags.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/unique_receiver_set.h" #include "net/cookies/cookie_setting_override.h" #include "services/network/public/cpp/network_service_buildflags.h" #include "services/network/public/mojom/cert_verifier_service_updater.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_context_client.mojom.h" #include "storage/browser/blob/blob_url_registry.h" #include "storage/browser/quota/quota_client_type.h" #include "storage/browser/quota/quota_settings.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/dom_storage/dom_storage.mojom.h" #include "third_party/blink/public/mojom/frame/remote_frame.mojom.h" namespace leveldb_proto { class ProtoDatabaseProvider; } // namespace leveldb_proto namespace net { class IsolationInfo; } // namespace net namespace network { namespace mojom { class SharedDictionaryAccessObserver; } // namespace mojom } // namespace network namespace storage { struct BucketClientInfo; class SharedStorageManager; } namespace content { namespace indexed_db { class IndexedDBControlWrapper; } class AggregationService; class AttributionManager; class BackgroundFetchContext; class BlobRegistryWrapper; class BluetoothAllowedDevicesMap; class BroadcastChannelService; class BrowsingDataFilterBuilder; class KeepAliveURLLoaderService; class BucketManager; class CacheStorageControlWrapper; #if BUILDFLAG(ENABLE_LIBRARY_CDMS) class CdmStorageDataModel; class CdmStorageManager; class MediaLicenseManager; #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) class CookieDeprecationLabelManagerImpl; class CookieStoreManager; class DevToolsBackgroundServicesContextImpl; class FileSystemAccessEntryFactory; class FileSystemAccessManagerImpl; class FontAccessManager; class GeneratedCodeCacheContext; class HostZoomLevelContext; class InterestGroupManagerImpl; class NavigationStateKeepAlive; class PaymentAppContextImpl; class PrivateAggregationDataModel; class PrivateAggregationManager; class PrivateAggregationManagerImpl; class PushMessagingContext; class QuotaContext; class ReconnectableURLLoaderFactoryForIOThreadWrapper; class SharedStorageHeaderObserver; class SharedStorageWorkletHostManager; class SharedWorkerServiceImpl; class SubresourceProxyingURLLoaderService; class NavigationOrDocumentHandle; class CONTENT_EXPORT StoragePartitionImpl : public StoragePartition, public blink::mojom::DomStorage, public network::mojom::NetworkContextClient, public network::mojom::URLLoaderNetworkServiceObserver { public: StoragePartitionImpl(const StoragePartitionImpl&) = delete; StoragePartitionImpl& operator=(const StoragePartitionImpl&) = delete; // It is guaranteed that storage partitions are destructed before the // browser context starts shutting down its corresponding IO thread residents // (e.g. resource context). ~StoragePartitionImpl() override; // Quota managed data uses a different representation for storage types than // StoragePartition uses. This method generates that representation. static storage::QuotaClientTypes GenerateQuotaClientTypes( uint32_t remove_mask); // Forces Storage Service instances to be run in-process. static void ForceInProcessStorageServiceForTesting(); void OverrideQuotaManagerForTesting(storage::QuotaManager* quota_manager); void OverrideSpecialStoragePolicyForTesting( storage::SpecialStoragePolicy* special_storage_policy); void ShutdownBackgroundSyncContextForTesting(); void OverrideBackgroundSyncContextForTesting( BackgroundSyncContextImpl* background_sync_context); void OverrideSharedWorkerServiceForTesting( std::unique_ptr<SharedWorkerServiceImpl> shared_worker_service); void OverrideSharedStorageWorkletHostManagerForTesting( std::unique_ptr<SharedStorageWorkletHostManager> shared_storage_worklet_host_manager); void OverrideSharedStorageHeaderObserverForTesting( std::unique_ptr<SharedStorageHeaderObserver> shared_storage_header_observer); void OverrideAggregationServiceForTesting( std::unique_ptr<AggregationService> aggregation_service); void OverrideAttributionManagerForTesting( std::unique_ptr<AttributionManager> attribution_manager); void OverridePrivateAggregationManagerForTesting( std::unique_ptr<PrivateAggregationManagerImpl> private_aggregation_manager); // StoragePartition interface. const StoragePartitionConfig& GetConfig() const override; const base::FilePath& GetPath() const override; network::mojom::NetworkContext* GetNetworkContext() override; cert_verifier::mojom::CertVerifierServiceUpdater* GetCertVerifierServiceUpdater() override; network::mojom::URLLoaderFactoryParamsPtr CreateURLLoaderFactoryParams(); scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactoryForBrowserProcess() override; std::unique_ptr<network::PendingSharedURLLoaderFactory> GetURLLoaderFactoryForBrowserProcessIOThread() override; network::mojom::CookieManager* GetCookieManagerForBrowserProcess() override; void CreateTrustTokenQueryAnswerer( mojo::PendingReceiver<network::mojom::TrustTokenQueryAnswerer> receiver, const url::Origin& top_frame_origin) override; mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver> CreateURLLoaderNetworkObserverForFrame(int process_id, int routing_id) override; mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver> CreateURLLoaderNetworkObserverForNavigationRequest( NavigationRequest& navigation_request) override; storage::QuotaManager* GetQuotaManager() override; BackgroundSyncContextImpl* GetBackgroundSyncContext() override; storage::FileSystemContext* GetFileSystemContext() override; storage::DatabaseTracker* GetDatabaseTracker() override; DOMStorageContextWrapper* GetDOMStorageContext() override; storage::mojom::LocalStorageControl* GetLocalStorageControl() override; LockManager<storage::BucketId>* GetLockManager(); // override; TODO: Add to interface // TODO(crbug.com/40185706): Add this method to the StoragePartition // interface, which would also require making SharedStorageWorkletHostManager // an interface accessible in //content/public/. SharedStorageWorkletHostManager* GetSharedStorageWorkletHostManager(); // override; storage::mojom::IndexedDBControl& GetIndexedDBControl() override; FileSystemAccessEntryFactory* GetFileSystemAccessEntryFactory() override; storage::mojom::CacheStorageControl* GetCacheStorageControl() override; ServiceWorkerContextWrapper* GetServiceWorkerContext() override; DedicatedWorkerServiceImpl* GetDedicatedWorkerService() override; SharedWorkerService* GetSharedWorkerService() override; GeneratedCodeCacheContext* GetGeneratedCodeCacheContext() override; DevToolsBackgroundServicesContext* GetDevToolsBackgroundServicesContext() override; ContentIndexContextImpl* GetContentIndexContext() override; HostZoomMap* GetHostZoomMap() override; HostZoomLevelContext* GetHostZoomLevelContext() override; ZoomLevelDelegate* GetZoomLevelDelegate() override; PlatformNotificationContextImpl* GetPlatformNotificationContext() override; InterestGroupManager* GetInterestGroupManager() override; BrowsingTopicsSiteDataManager* GetBrowsingTopicsSiteDataManager() override; leveldb_proto::ProtoDatabaseProvider* GetProtoDatabaseProvider() override; // Use outside content. AttributionDataModel* GetAttributionDataModel() override; PrivateAggregationDataModel* GetPrivateAggregationDataModel() override; CookieDeprecationLabelManager* GetCookieDeprecationLabelManager() override; #if BUILDFLAG(ENABLE_LIBRARY_CDMS) CdmStorageDataModel* GetCdmStorageDataModel() override; #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) void DeleteStaleSessionOnlyCookiesAfterDelay() override; void SetProtoDatabaseProvider( std::unique_ptr<leveldb_proto::ProtoDatabaseProvider> proto_db_provider) override; leveldb_proto::ProtoDatabaseProvider* GetProtoDatabaseProviderForTesting() override; void ClearDataForOrigin(uint32_t remove_mask, uint32_t quota_storage_remove_mask, const GURL& storage_origin, base::OnceClosure callback) override; void ClearDataForBuckets(const blink::StorageKey& storage_key, const std::set<std::string>& storage_buckets, base::OnceClosure callback) override; void ClearData(uint32_t remove_mask, uint32_t quota_storage_remove_mask, const blink::StorageKey& storage_key, const base::Time begin, const base::Time end, base::OnceClosure callback) override; void ClearData(uint32_t remove_mask, uint32_t quota_storage_remove_mask, BrowsingDataFilterBuilder* filter_builder, StorageKeyPolicyMatcherFunction storage_key_policy_matcher, network::mojom::CookieDeletionFilterPtr cookie_deletion_filter, bool perform_storage_cleanup, const base::Time begin, const base::Time end, base::OnceClosure callback) override; void ClearCodeCaches( const base::Time begin, const base::Time end, const base::RepeatingCallback<bool(const GURL&)>& url_matcher, base::OnceClosure callback) override; void Flush() override; void ResetURLLoaderFactories() override; void ClearBluetoothAllowedDevicesMapForTesting() override; void AddObserver(DataRemovalObserver* observer) override; void RemoveObserver(DataRemovalObserver* observer) override; void FlushNetworkInterfaceForTesting() override; void FlushCertVerifierInterfaceForTesting() override; void WaitForDeletionTasksForTesting() override; void WaitForCodeCacheShutdownForTesting() override; void SetNetworkContextForTesting( mojo::PendingRemote<network::mojom::NetworkContext> network_context_remote) override; void OverrideDeleteStaleSessionOnlyCookiesDelayForTesting( const base::TimeDelta& delay) override; // TODO(crbug.com/352651664): Consider merging to // `FlushNetworkInterfaceForTesting()` if possible. void FlushNetworkInterfaceOnIOThreadForTesting(); base::WeakPtr<StoragePartitionImpl> GetWeakPtr(); BackgroundFetchContext* GetBackgroundFetchContext(); PaymentAppContextImpl* GetPaymentAppContext(); BroadcastChannelService* GetBroadcastChannelService(); BluetoothAllowedDevicesMap* GetBluetoothAllowedDevicesMap(); BlobRegistryWrapper* GetBlobRegistry(); storage::BlobUrlRegistry* GetBlobUrlRegistry(); SubresourceProxyingURLLoaderService* GetSubresourceProxyingURLLoaderService(); KeepAliveURLLoaderService* GetKeepAliveURLLoaderService(); CookieStoreManager* GetCookieStoreManager(); FileSystemAccessManagerImpl* GetFileSystemAccessManager(); BucketManager* GetBucketManager(); QuotaContext* GetQuotaContext(); // Use inside content. AttributionManager* GetAttributionManager(); void SetFontAccessManagerForTesting( std::unique_ptr<FontAccessManager> font_access_manager); const std::string& GetPartitionDomain() const; AggregationService* GetAggregationService(); FontAccessManager* GetFontAccessManager(); #if BUILDFLAG(ENABLE_LIBRARY_CDMS) MediaLicenseManager* GetMediaLicenseManager(); #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) storage::SharedStorageManager* GetSharedStorageManager() override; PrivateAggregationManager* GetPrivateAggregationManager(); // blink::mojom::DomStorage interface. void OpenLocalStorage( const blink::StorageKey& storage_key, const blink::LocalFrameToken& local_frame_token, mojo::PendingReceiver<blink::mojom::StorageArea> receiver) override; void BindSessionStorageNamespace( const std::string& namespace_id, mojo::PendingReceiver<blink::mojom::SessionStorageNamespace> receiver) override; void BindSessionStorageArea( const blink::StorageKey& storage_key, const blink::LocalFrameToken& local_frame_token, const std::string& namespace_id, mojo::PendingReceiver<blink::mojom::StorageArea> receiver) override; // network::mojom::NetworkContextClient interface. void OnFileUploadRequested(int32_t process_id, bool async, const std::vector<base::FilePath>& file_paths, const GURL& destination_url, OnFileUploadRequestedCallback callback) override; void OnCanSendReportingReports( const std::vector<url::Origin>& origins, OnCanSendReportingReportsCallback callback) override; void OnCanSendDomainReliabilityUpload( const url::Origin& origin, OnCanSendDomainReliabilityUploadCallback callback) override; #if BUILDFLAG(IS_ANDROID) void OnGenerateHttpNegotiateAuthToken( const std::string& server_auth_token, bool can_delegate, const std::string& auth_negotiate_android_account_type, const std::string& spn, OnGenerateHttpNegotiateAuthTokenCallback callback) override; #endif #if BUILDFLAG(IS_CHROMEOS) void OnTrustAnchorUsed() override; #endif #if BUILDFLAG(IS_CT_SUPPORTED) void OnCanSendSCTAuditingReport( OnCanSendSCTAuditingReportCallback callback) override; void OnNewSCTAuditingReportSent() override; #endif // network::mojom::URLLoaderNetworkServiceObserver interface. void OnSSLCertificateError(const GURL& url, int net_error, const net::SSLInfo& ssl_info, bool fatal, OnSSLCertificateErrorCallback response) override; void OnCertificateRequested( const std::optional<base::UnguessableToken>& window_id, const scoped_refptr<net::SSLCertRequestInfo>& cert_info, mojo::PendingRemote<network::mojom::ClientCertificateResponder> cert_responder) override; void Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> listener) override; void OnWebSocketConnectedToPrivateNetwork( network::mojom::IPAddressSpace ip_address_space) override; void OnAuthRequired( const std::optional<base::UnguessableToken>& window_id, int32_t request_id, const GURL& url, bool first_auth_attempt, const net::AuthChallengeInfo& auth_info, const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; void OnPrivateNetworkAccessPermissionRequired( const GURL& url, const net::IPAddress& ip_address, const std::optional<std::string>& private_network_device_id, const std::optional<std::string>& private_network_device_name, OnPrivateNetworkAccessPermissionRequiredCallback callback) override; void OnClearSiteData( const GURL& url, const std::string& header_value, int load_flags, const std::optional<net::CookiePartitionKey>& cookie_partition_key, bool partitioned_state_allowed_only, OnClearSiteDataCallback callback) override; void OnLoadingStateUpdate(network::mojom::LoadInfoPtr info, OnLoadingStateUpdateCallback callback) override; void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash, int64_t recv_bytes, int64_t sent_bytes) override; void OnSharedStorageHeaderReceived( const url::Origin& request_origin, std::vector<network::mojom::SharedStorageOperationPtr> operations, OnSharedStorageHeaderReceivedCallback callback) override; SharedStorageHeaderObserver* shared_storage_header_observer() { return shared_storage_header_observer_.get(); } // Can return nullptr while `this` is being destroyed. BrowserContext* browser_context() const; // Returns the interface used to control the corresponding remote Partition in // the Storage Service. storage::mojom::Partition* GetStorageServicePartition(); // Exposes the shared top-level connection to the Storage Service, for tests. static mojo::Remote<storage::mojom::StorageService>& GetStorageServiceForTesting(); // Binds the mojo endpoint for an `IDBFactory` (which implements // `window.indexedDB`). void BindIndexedDB( const storage::BucketLocator& bucket_locator, const storage::BucketClientInfo& client_info, mojo::PendingRemote<storage::mojom::IndexedDBClientStateChecker> client_state_checker_remote, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver); // Called by each renderer process to bind its global DomStorage interface. // Returns the id of the created receiver. mojo::ReceiverId BindDomStorage( int process_id, mojo::PendingReceiver<blink::mojom::DomStorage> receiver, mojo::PendingRemote<blink::mojom::DomStorageClient> client); // Remove a receiver created by a previous BindDomStorage() call. void UnbindDomStorage(mojo::ReceiverId receiver_id); auto& dom_storage_receivers_for_testing() { return dom_storage_receivers_; } std::vector<std::string> cors_exempt_header_list() const { return cors_exempt_header_list_; } // Tracks whether this StoragePartition is for guests (e.g., for a <webview> // tag). This is needed to properly create a SiteInstance for a // service worker or a shared worker in a guest. Typically one would use the // script URL of the worker (e.g., "https://example.com/sw.js"), but if this // StoragePartition is for guests, one must create the SiteInstance via // guest-specific helpers that ensure that the worker stays in the same // StoragePartition. void set_is_guest() { is_guest_ = true; } bool is_guest() const { return is_guest_; } // We have to plumb `is_service_worker`, `process_id` and `routing_id` because // they are plumbed to WebView via WillCreateRestrictedCookieManager, which // makes some decision based on that. void CreateRestrictedCookieManager( network::mojom::RestrictedCookieManagerRole role, const url::Origin& origin, const net::IsolationInfo& isolation_info, bool is_service_worker, int process_id, int routing_id, net::CookieSettingOverrides cookie_setting_overrides, mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver, mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer); mojo::PendingRemote<network::mojom::CookieAccessObserver> CreateCookieAccessObserverForServiceWorker(); mojo::PendingRemote<network::mojom::TrustTokenAccessObserver> CreateTrustTokenAccessObserverForServiceWorker(); mojo::PendingRemote<network::mojom::SharedDictionaryAccessObserver> CreateSharedDictionaryAccessObserverForServiceWorker(); mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver> CreateAuthCertObserverForServiceWorker(int process_id); std::vector<std::string> GetCorsExemptHeaderList(); void OpenLocalStorageForProcess( int process_id, const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::StorageArea> receiver); void BindSessionStorageAreaForProcess( int process_id, const blink::StorageKey& storage_key, const std::string& namespace_id, mojo::PendingReceiver<blink::mojom::StorageArea> receiver); storage::QuotaManagerProxy* GetQuotaManagerProxy(); // Called by BrowserContextImpl prior to destruction. void OnBrowserContextWillBeDestroyed(); // Store `receiver` and its corresponding `handle`. These will be kept alive // as long as the remote endpoint of `receiver` is still alive on the renderer // side. The receiver will be automatically deleted when the endpoint is // disconnected. void RegisterKeepAliveHandle( mojo::PendingReceiver<blink::mojom::NavigationStateKeepAliveHandle> receiver, std::unique_ptr<NavigationStateKeepAlive> handle); // Forward the call to `NetworkContext::RevokeNetworkForNonces` and save the // nonces in `StoragePartitionImpl`. Clients should revoke network access for // nonces using this function instead of calling // `NetworkContext::RevokeNetworkForNonces` directly. This is because this // function saves the nonces so that they can be restored in case of a // `NetworkService` crash. void RevokeNetworkForNoncesInNetworkContext( const std::vector<base::UnguessableToken>& nonces, network::mojom::NetworkContext::RevokeNetworkForNoncesCallback callback); // Forward the call to `NetworkContext::ClearNonces` and remove the stored // nonce values in `StoragePartitionImpl`. Clients should clear nonces using // this function instead of calling `NetworkContext::ClearNonces` directly. // This should only be called when the nonces saved by // `RevokeNetworkForNoncesInNetworkContext` are no longer relevant. // The nonces are cleared after a time delay, which will prevent races where // network requests succeed while the fenced frame corresponding to the // nonces is being destroyed. void ClearNoncesInNetworkContextAfterDelay( const std::vector<base::UnguessableToken>& nonces); // Get the NavigationStateKeepAlive associated with `frame_token`. See // `navigation_state_keep_alive_map_`. NavigationStateKeepAlive* GetNavigationStateKeepAlive( blink::LocalFrameToken frame_token); // Removes the NavigationStateKeepAlive associated with `frame_token`. This // should be called when the keep alive is destructed. void RemoveKeepAliveHandleFromMap(blink::LocalFrameToken frame_token, NavigationStateKeepAlive* keep_alive); void SetClearNoncesInNetworkContextParamsForTesting( const base::TimeDelta& delay, base::RepeatingClosure callback); enum class ContextType { kRenderFrameHostContext, kNavigationRequestContext, kServiceWorkerContext, }; private: class DataDeletionHelper; class QuotaManagedDataDeletionHelper; class ServiceWorkerCookieAccessObserver; class ServiceWorkerTrustTokenAccessObserver; class ServiceWorkerSharedDictionaryAccessObserver; struct NetworkContextOwner; friend class BackgroundSyncManagerTest; friend class BackgroundSyncServiceImplTestHarness; friend class CookieStoreManagerTest; friend class PaymentAppContentUnitTestBase; friend class ServiceWorkerRegistrationTest; friend class ServiceWorkerUpdateJobTest; friend class StoragePartitionImplMap; FRIEND_TEST_ALL_PREFIXES(StoragePartitionShaderClearTest, ClearShaderCache); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForeverBoth); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForeverOnlyTemporary); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForeverOnlyPersistent); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForeverNeither); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForeverSpecificOrigin); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForLastHour); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedDataForLastWeek); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedUnprotectedOrigins); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedProtectedSpecificOrigin); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedProtectedOrigins); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveQuotaManagedIgnoreDevTools); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveCookieForever); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveCookieLastHour); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveCookieWithDeleteInfo); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveUnprotectedLocalStorageForever); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveProtectedLocalStorageForever); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest, RemoveLocalStorageForLastWeek); class URLLoaderNetworkContext { public: ~URLLoaderNetworkContext(); // Allow copy and assign. URLLoaderNetworkContext(const URLLoaderNetworkContext& other); URLLoaderNetworkContext& operator=(const URLLoaderNetworkContext& other); // Creates a URLLoaderNetworkContext for the RenderFrameHost. static StoragePartitionImpl::URLLoaderNetworkContext CreateForRenderFrameHost( GlobalRenderFrameHostId global_render_frame_host_id); // Creates a URLLoaderNetworkContext for the navigation request. static StoragePartitionImpl::URLLoaderNetworkContext CreateForNavigation( NavigationRequest& navigation_request); // Used when `type` is `kRenderFrameHostContext`. explicit URLLoaderNetworkContext( GlobalRenderFrameHostId global_render_frame_host_id); // Used when `type` is `kServiceWorkerContext`. explicit URLLoaderNetworkContext(int process_id); // Used when `type` is `kNavigationRequestContext`. explicit URLLoaderNetworkContext(NavigationRequest& navigation_request); // Returns true if `type` is `kNavigationRequestContext`. bool IsNavigationRequestContext() const; ContextType type() const { return type_; } NavigationOrDocumentHandle* navigation_or_document() const { return navigation_or_document_.get(); } int process_id() const { return process_id_; } // If `type_` is kServiceWorkerContext, returns nullptr. Otherwise returns // the WebContents. WebContents* GetWebContents(); // Returns true if the request is the primary main frame navigation. bool IsPrimaryMainFrameRequest(); private: ContextType type_; scoped_refptr<NavigationOrDocumentHandle> navigation_or_document_; // Only valid when `type_` is kServiceWorkerContext. int process_id_ = content::ChildProcessHost::kInvalidUniqueID; }; // `relative_partition_path` is the relative path under `profile_path` to the // StoragePartition's on-disk-storage. // // If `in_memory` is true, the `relative_partition_path` is (ab)used as a way // of distinguishing different in-memory partitions, but nothing is persisted // on to disk. // // Initialize() must be called on the StoragePartitionImpl before using it, // and OnBrowserContextWillBeDestroyed() must be called on it prior to // `context` being destroyed. static std::unique_ptr<StoragePartitionImpl> Create( BrowserContext* context, const StoragePartitionConfig& config, const base::FilePath& relative_partition_path); StoragePartitionImpl(BrowserContext* browser_context, const StoragePartitionConfig& config, const base::FilePath& partition_path, const base::FilePath& relative_partition_path, storage::SpecialStoragePolicy* special_storage_policy); // This must be called before calling any members of the StoragePartitionImpl // except for GetPath and browser_context(). // The purpose of the Create, Initialize sequence is that code that // initializes members of the StoragePartitionImpl and gets a pointer to it // can query properties of the StoragePartitionImpl (notably GetPath()). // If `fallback_for_blob_urls` is not null, blob urls that can't be resolved // in this storage partition will be attempted to be resolved in the fallback // storage partition instead. void Initialize(StoragePartitionImpl* fallback_for_blob_urls = nullptr); // If we're running Storage Service out-of-process and it crashes, this // re-establishes a connection and makes sure the service returns to a usable // state. void OnStorageServiceDisconnected(); // Clears the data specified by the `storage_key` or // `filter_builder`/`storage_key_policy_matcher`. `storage_key` and // `filter_builder`/`storage_key_policy_matcher` will never both be populated. void ClearDataImpl( uint32_t remove_mask, uint32_t quota_storage_remove_mask, const blink::StorageKey& storage_key, BrowsingDataFilterBuilder* filter_builder, StorageKeyPolicyMatcherFunction storage_key_policy_matcher, network::mojom::CookieDeletionFilterPtr cookie_deletion_filter, bool perform_storage_cleanup, const base::Time begin, const base::Time end, base::OnceClosure callback); void ClearDataForBucketsDone( const blink::StorageKey& storage_key, const std::set<std::string>& storage_buckets, base::OnceClosure callback, const std::vector<blink::mojom::QuotaStatusCode>& status_codes); void DeletionHelperDone(base::OnceClosure callback); // Function used by the quota system to ask the embedder for the // storage configuration info. void GetQuotaSettings(storage::OptionalQuotaSettingsCallback callback); // Called to initialize `network_context_` when `GetNetworkContext()` is // first called or there is an error. void InitNetworkContext(); bool is_in_memory() { return config_.in_memory(); } void CreateURLLoaderFactoryForBrowserProcessInternal( mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory); std::optional<blink::StorageKey> CalculateStorageKey( const url::Origin& origin, const base::UnguessableToken* nonce); GlobalRenderFrameHostId GetRenderFrameHostIdFromNetworkContext(); void DeleteStaleSessionOnlyCookiesAfterDelayCallback(); void ClearNoncesInNetworkContextAfterDelayCallback( const std::vector<base::UnguessableToken>& nonces); // Raw pointer that should always be valid. The BrowserContext owns the // StoragePartitionImplMap which then owns StoragePartitionImpl. When the // BrowserContext is destroyed, `this` will be destroyed too. raw_ptr<BrowserContext, DanglingUntriaged> browser_context_; const base::FilePath partition_path_; // `config_` and `relative_partition_path_` are cached from // `StoragePartitionImpl::Create()` in order to re-create `NetworkContext`. const StoragePartitionConfig config_; const base::FilePath relative_partition_path_; // Until a StoragePartitionImpl is initialized using Initialize(), only // querying its path abd BrowserContext is allowed. bool initialized_ = false; mojo::Remote<storage::mojom::Partition> remote_partition_; scoped_refptr<QuotaContext> quota_context_; scoped_refptr<storage::QuotaManager> quota_manager_; scoped_refptr<storage::FileSystemContext> filesystem_context_; scoped_refptr<storage::DatabaseTracker> database_tracker_; scoped_refptr<DOMStorageContextWrapper> dom_storage_context_; std::unique_ptr<LockManager<storage::BucketId>> lock_manager_; std::unique_ptr<indexed_db::IndexedDBControlWrapper> indexed_db_control_wrapper_; std::unique_ptr<CacheStorageControlWrapper> cache_storage_control_wrapper_; scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; std::unique_ptr<DedicatedWorkerServiceImpl> dedicated_worker_service_; std::unique_ptr<SharedWorkerServiceImpl> shared_worker_service_; std::unique_ptr<PushMessagingContext> push_messaging_context_; scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; std::unique_ptr<HostZoomLevelContext, BrowserThread::DeleteOnUIThread> host_zoom_level_context_; scoped_refptr<PlatformNotificationContextImpl> platform_notification_context_; scoped_refptr<BackgroundFetchContext> background_fetch_context_; scoped_refptr<BackgroundSyncContextImpl> background_sync_context_; scoped_refptr<PaymentAppContextImpl> payment_app_context_; std::unique_ptr<BroadcastChannelService> broadcast_channel_service_; std::unique_ptr<BluetoothAllowedDevicesMap> bluetooth_allowed_devices_map_; scoped_refptr<BlobRegistryWrapper> blob_registry_; std::unique_ptr<storage::BlobUrlRegistry> blob_url_registry_; std::unique_ptr<SubresourceProxyingURLLoaderService> subresource_proxying_url_loader_service_; std::unique_ptr<KeepAliveURLLoaderService> keep_alive_url_loader_service_; std::unique_ptr<CookieStoreManager> cookie_store_manager_; std::unique_ptr<BucketManager> bucket_manager_; scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context_; std::unique_ptr<DevToolsBackgroundServicesContextImpl> devtools_background_services_context_; scoped_refptr<FileSystemAccessManagerImpl> file_system_access_manager_; std::unique_ptr<leveldb_proto::ProtoDatabaseProvider> proto_database_provider_; scoped_refptr<ContentIndexContextImpl> content_index_context_; std::unique_ptr<AttributionManager> attribution_manager_; std::unique_ptr<FontAccessManager> font_access_manager_; std::unique_ptr<InterestGroupManagerImpl> interest_group_manager_; std::unique_ptr<BrowsingTopicsSiteDataManager> browsing_topics_site_data_manager_; std::unique_ptr<AggregationService> aggregation_service_; #if BUILDFLAG(ENABLE_LIBRARY_CDMS) std::unique_ptr<CdmStorageManager> cdm_storage_manager_; // TODO(crbug.com/40272342): Remove MediaLicenseManager once migration has // been completed. std::unique_ptr<MediaLicenseManager> media_license_manager_; #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) // Owning pointer to the SharedStorageManager for this partition. std::unique_ptr<storage::SharedStorageManager> shared_storage_manager_; // This needs to be declared after `shared_storage_manager_` because // `shared_storage_worklet_host` (managed by // `shared_storage_worklet_host_manager_`) ultimately stores a raw pointer on // it. std::unique_ptr<SharedStorageWorkletHostManager> shared_storage_worklet_host_manager_; // Owning pointer to the `SharedStorageHeaderObserver` for this partition. std::unique_ptr<SharedStorageHeaderObserver> shared_storage_header_observer_; std::unique_ptr<PrivateAggregationManagerImpl> private_aggregation_manager_; std::unique_ptr<CookieDeprecationLabelManagerImpl> cookie_deprecation_label_manager_; // ReceiverSet for DomStorage, using the // ChildProcessSecurityPolicyImpl::Handle as the binding context type. The // handle can subsequently be used during interface method calls to // enforce security checks. using SecurityPolicyHandle = ChildProcessSecurityPolicyImpl::Handle; mojo::ReceiverSet<blink::mojom::DomStorage, std::unique_ptr<SecurityPolicyHandle>> dom_storage_receivers_; // A client interface for each receiver above. std::map<mojo::ReceiverId, mojo::Remote<blink::mojom::DomStorageClient>> dom_storage_clients_; // Owns the NetworkContext used to make requests for the StoragePartition. // Forward declared so we don't need to include network_context.mojom.h here. std::unique_ptr<NetworkContextOwner> network_context_owner_; mojo::Receiver<network::mojom::NetworkContextClient> network_context_client_receiver_{this}; // Always valid/non-null after `Initialize()`. std::unique_ptr<ReconnectableURLLoaderFactoryForIOThreadWrapper> shared_url_loader_factory_for_browser_process_; mojo::Remote<cert_verifier::mojom::CertVerifierServiceUpdater> cert_verifier_service_updater_; // URLLoaderFactory/CookieManager for use in the browser process only. // See the method comment for // StoragePartition::GetURLLoaderFactoryForBrowserProcess() for // more details mojo::Remote<network::mojom::CookieManager> cookie_manager_for_browser_process_; // The list of cors exempt headers that are set on `network_context_`. // Initialized in InitNetworkContext() and never updated after then. std::vector<std::string> cors_exempt_header_list_; // See comments for is_guest(). bool is_guest_ = false; // Track number of running deletion. For test use only. int deletion_helpers_running_; base::ObserverList<DataRemovalObserver> data_removal_observers_; // Called when all deletions are done. For test use only. base::OnceClosure on_deletion_helpers_done_callback_; // A set of connections to the network service used to notify browser process // about cookie reads and writes made by a service worker in this process. mojo::UniqueReceiverSet<network::mojom::CookieAccessObserver> service_worker_cookie_observers_; // A set of connections to the network service used to notify browser process // about Trust Token accesses made by a service worker in this process. mojo::UniqueReceiverSet<network::mojom::TrustTokenAccessObserver> service_worker_trust_token_observers_; // A set of connections to the network service used to notify browser process // about shared dictionary accesses made by a service worker in this process. mojo::UniqueReceiverSet<network::mojom::SharedDictionaryAccessObserver> service_worker_shared_dictionary_observers_; mojo::ReceiverSet<network::mojom::URLLoaderNetworkServiceObserver, URLLoaderNetworkContext> url_loader_network_observers_; int next_pending_trust_token_issuance_callback_key_ = 0; // Maps frame tokens to NavigationStateKeepAlives. There is one // NavigationStateKeepAlive per LocalFrameToken. It's possible to have // multiple keep alives per LocalFrameToken (e.g., multiple in-flight // navigations per RenderFrameHost), but this map will store the most recent // NavigationStateKeepAlive. // In the case of multiple navigations for a RenderFrameHost, // it is assumed that they are handled in order, with the latest navigation's // keep alive storing the state for that RenderFrameHost. // Note: This member must be above `keep_alive_handles_receiver_set_`. During // destruction, when NavigationStateKeepAlives get removed from the receiver // set, they will them remove themselves from // `navigation_state_keep_alive_map_`, so this map must still be alive when // that happens. using TokenNavigationStateKeepAliveMap = std::unordered_map<blink::LocalFrameToken, NavigationStateKeepAlive*, blink::LocalFrameToken::Hasher>; TokenNavigationStateKeepAliveMap navigation_state_keep_alive_map_; // Active keepalive handles for in-flight navigations. They are retained // on `StoragePartition` because, by design, they may need to outlive the // `RenderFrameHostImpl` that initiated the navigation, but shouldn't be used // in a different StoragePartition. // Note that this set may contain in-flight navigations for different // RenderFrameHosts, and furthermore, there may even be multiple in-flight // navigations for a single RenderFrameHost. // Lookups should not be done from this set. Accessing PolicyContainerHosts // kept alive by NavigationStateKeepAlive should be done through // PolicyContainerHost::FromFrameToken. mojo::UniqueReceiverSet<blink::mojom::NavigationStateKeepAliveHandle> keep_alive_handles_receiver_set_; #if DCHECK_IS_ON() bool on_browser_context_will_be_destroyed_called_ = false; #endif // A copy of the network revocation nonces in `NetworkContext`. It is used for // restoring the network revocation states of fenced frames when there is a // `NetworkService` crash. std::set<base::UnguessableToken> network_revocation_nonces_; // We need to delay deleting stale session cookies until after the cookie db // has initialized, otherwise we will bypass lazy loading and block. // See crbug.com/40285083 for more info. base::TimeDelta delete_stale_session_only_cookies_delay_{base::Minutes(1)}; // We need a delay when removing fenced frame nonces from here and from the // network service, to avoid races where a fenced frame could regain network // access during destruction. See the comment on // `ClearNoncesInNetworkContextAfterDelay` for more info. base::TimeDelta clear_nonces_in_network_context_delay_{base::Minutes(1)}; // Because removing the nonces after a delay is async, we need a callback to // execute when the task completes in order to test it. base::RepeatingClosure clear_nonces_in_network_context_callback_for_testing_ = base::DoNothing(); base::WeakPtrFactory<StoragePartitionImpl> weak_factory_{this}; }; } // namespace content #endif // CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_