| // 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/device_bound_sessions.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; |
| class DeviceBoundSessionAccessObserver; |
| } // 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; |
| #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 SharedStorageRuntimeManager; |
| 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 OverrideSharedStorageRuntimeManagerForTesting( |
| std::unique_ptr<SharedStorageRuntimeManager> |
| shared_storage_runtime_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); |
| void OverrideDeviceBoundSessionManagerForTesting( |
| std::unique_ptr<network::mojom::DeviceBoundSessionManager> |
| device_bound_session_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; |
| 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 SharedStorageRuntimeManager |
| // an interface accessible in //content/public/. |
| SharedStorageRuntimeManager* GetSharedStorageRuntimeManager(); // 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) |
| network::mojom::DeviceBoundSessionManager* GetDeviceBoundSessionManager() |
| override; |
| |
| void DeleteStaleSessionData() 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(); |
| |
| 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_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 OnUrlLoaderConnectedToPrivateNetwork( |
| const GURL& request_url, |
| network::mojom::IPAddressSpace response_address_space, |
| network::mojom::IPAddressSpace client_address_space, |
| network::mojom::IPAddressSpace target_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 OnLocalNetworkAccessPermissionRequired( |
| OnLocalNetworkAccessPermissionRequiredCallback 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::SharedStorageModifierMethodWithOptionsPtr> |
| methods_with_options, |
| const std::optional<std::string>& with_lock, |
| OnSharedStorageHeaderReceivedCallback callback) override; |
| void OnAdAuctionEventRecordHeaderReceived( |
| network::AdAuctionEventRecord event_record, |
| const std::optional<url::Origin>& top_frame_origin) 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, |
| net::CookieSettingOverrides devtools_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); |
| |
| mojo::PendingRemote<network::mojom::DeviceBoundSessionAccessObserver> |
| CreateDeviceBoundSessionObserverForServiceWorker(); |
| |
| 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; |
| class ServiceWorkerDeviceBoundSessionAccessObserver; |
| 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 DeleteStaleSessionOnlyCookiesAfterDelay(); |
| |
| 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<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_; |
| #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) |
| mojo::Remote<network::mojom::DeviceBoundSessionManager> |
| device_bound_session_manager_; |
| |
| // 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_runtime_manager_`) ultimately stores a raw pointer on |
| // it. |
| std::unique_ptr<SharedStorageRuntimeManager> shared_storage_runtime_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_; |
| |
| // A set of connections to the network service used to notify the |
| // browser process about device bound session accesses made by a |
| // service worker in this process. |
| mojo::UniqueReceiverSet<network::mojom::DeviceBoundSessionAccessObserver> |
| service_worker_device_bound_session_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_ |