// 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_PUBLIC_BROWSER_BROWSER_CONTEXT_H_
#define CONTENT_PUBLIC_BROWSER_BROWSER_CONTEXT_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <optional>
#include <string>
#include <unordered_set>
#include <vector>

#include "base/functional/function_ref.h"
#include "base/memory/sanitized_object.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "base/unguessable_token.h"
#include "content/common/content_export.h"
#include "content/public/browser/pre_prefetch_handle.h"
#include "content/public/browser/prefetch_handle.h"
#include "content/public/browser/prefetch_priority.h"
#include "content/public/browser/prefetch_request_status_listener.h"
#include "content/public/browser/preload_pipeline_info.h"
#include "content/public/browser/zoom_level_delegate.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/http/http_request_headers.h"
#include "third_party/blink/public/mojom/blob/blob.mojom-forward.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-forward.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-forward.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"

class GURL;

namespace base {
class FilePath;
}  // namespace base

namespace download {
class InProgressDownloadManager;
}

namespace storage {
class ExternalMountPoints;
}

namespace leveldb_proto {
class ProtoDatabaseProvider;
}

namespace media {
class VideoDecodePerfHistory;
class WebrtcVideoPerfHistory;
}  // namespace media

namespace net {
class HttpNoVarySearchData;
}  // namespace net

namespace network {
class SharedURLLoaderFactory;
}  // namespace network

namespace storage {
class BlobStorageContext;
class SpecialStoragePolicy;
}  // namespace storage

namespace variations {
class VariationsClient;
}  // namespace variations

namespace perfetto {
template <typename>
class TracedProto;

namespace protos::pbzero {
class ChromeBrowserContext;
}  // namespace protos::pbzero

}  // namespace perfetto

namespace content {

class BackgroundFetchDelegate;
class BackgroundSyncController;
class BlobHandle;
class BrowserContextImpl;
class BrowserPluginGuestManager;
class BrowsingDataRemover;
class BrowsingDataRemoverDelegate;
class ClientHintsControllerDelegate;
class ContentIndexProvider;
class DownloadManager;
class DownloadManagerDelegate;
class FederatedIdentityPermissionContextDelegate;
class FederatedIdentityApiPermissionContextDelegate;
class FederatedIdentityAutoReauthnPermissionContextDelegate;
class FileSystemAccessPermissionContext;
class OriginTrialsControllerDelegate;
class PermissionController;
class PermissionControllerDelegate;
class PlatformNotificationService;
class PushMessagingService;
class ReduceAcceptLanguageControllerDelegate;
class ResourceContext;
class SSLHostStateDelegate;
class SharedCorsOriginAccessList;
class SiteInstance;
class StorageNotificationService;
class StoragePartition;
class StoragePartitionConfig;

// This class holds the context needed for a browsing session.
// It lives on the UI thread. All these methods must only be called on the UI
// thread.
class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
  // Do not remove this macro!
  // The macro is maintained by the memory safety team.
  SANITIZED_OBJECT();

 public:
  //////////////////////////////////////////////////////////////////////////////
  // The BrowserContext methods below are provided/implemented by the //content
  // layer (e.g. there is no need to override these methods in layers above
  // //content).
  //
  // The currently recommended practice is to make the methods in this section
  // non-virtual instance methods.
  //
  // TODO(crbug.com/40169693): Consider moving these methods to
  // BrowserContextImpl.

  BrowserContext();
  ~BrowserContext() override;

  DownloadManager* GetDownloadManager();

  // Returns BrowserContext specific external mount points. It may return
  // nullptr if the context doesn't have any BrowserContext specific external
  // mount points. Currently, non-nullptr value is returned only on ChromeOS.
  storage::ExternalMountPoints* GetMountPoints();

  // Returns a BrowsingDataRemover that can schedule data deletion tasks
  // for this |context|.
  BrowsingDataRemover* GetBrowsingDataRemover();

  // Returns the PermissionController associated with this context. There's
  // always a PermissionController instance for each BrowserContext.
  PermissionController* GetPermissionController();

  // Returns a StoragePartition for the given SiteInstance. By default this will
  // create a new StoragePartition if it doesn't exist, unless |can_create| is
  // false.
  StoragePartition* GetStoragePartition(SiteInstance* site_instance,
                                        bool can_create = true);

  // Returns a StoragePartition for the given StoragePartitionConfig. By
  // default this will create a new StoragePartition if it doesn't exist,
  // unless |can_create| is false.
  StoragePartition* GetStoragePartition(
      const StoragePartitionConfig& storage_partition_config,
      bool can_create = true);

  // Deprecated. Do not add new callers. Use the SiteInstance or
  // StoragePartitionConfig methods above instead.
  // Returns a StoragePartition for the given URL. By default this will
  // create a new StoragePartition if it doesn't exist, unless |can_create| is
  // false.
  StoragePartition* GetStoragePartitionForUrl(const GURL& url,
                                              bool can_create = true);

  // Synchronously invokes `fn` for each loaded StoragePartition.
  // Persisted StoragePartitions (not in-memory) are loaded lazily on first
  // use, at which point a StoragePartition object will be created that's
  // backed by the on-disk storage. StoragePartitions will not be unloaded for
  // the remainder of the BrowserContext's lifetime.
  void ForEachLoadedStoragePartition(
      base::FunctionRef<void(StoragePartition*)> fn);

  // Returns the number of loaded StoragePartitions that exist for `this`
  // BrowserContext.
  // See |ForEachLoadedStoragePartition| for details about loaded
  // StoragePartitions.
  size_t GetLoadedStoragePartitionCount();

  // Starts an asynchronous best-effort attempt to delete all on-disk storage
  // related to |partition_domain| and synchronously invokes |done_callback|
  // once all deletable on-disk storage is deleted. |on_gc_required| will be
  // invoked if |partition_domain| corresponds to any StoragePartitions that
  // are loaded and can't safely be deleted. In this case the caller should
  // attempt to delete the StoragePartition again at next browser launch.
  void AsyncObliterateStoragePartition(const std::string& partition_domain,
                                       base::OnceClosure on_gc_required,
                                       base::OnceClosure done_callback);

  // Examines all on-disk StoragePartitions and removes any entries that are
  // not loaded or listed in `active_paths`.
  //
  // The `done` closure is executed on the calling thread when garbage
  // collection is complete.
  void GarbageCollectStoragePartitions(
      std::unordered_set<base::FilePath> active_paths,
      base::OnceClosure done);

  StoragePartition* GetDefaultStoragePartition();

  // Returns the main URLLoaderFactory.
  virtual scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();

  // Starts a prefetch network request for the given `url`.
  // `embedder_histogram_suffix` is used for generating internal histogram names
  // recorded per trigger. `priority` is an optimization hint of how quickly
  // this prefetch should be available. `ttl` (Time-To-Live) specifies how long
  // prefetched data remains valid in the cache. After this period, the data is
  // reset. `should_disable_block_until_head_timeout` specifies whether we
  // should have a timeout when this prefetch blocks the navigation until its
  // head is determined. Returns `PrefetchHandle` to control prefetch resources.
  // This can be null when it can't add `PrefetchContainer` to
  // `PrefetchService`.
  [[nodiscard]] std::unique_ptr<content::PrefetchHandle>
  StartBrowserPrefetchRequest(
      const GURL& url,
      const std::string& embedder_histogram_suffix,
      bool javascript_enabled,
      std::optional<net::HttpNoVarySearchData> no_vary_search_hint,
      std::optional<PrefetchPriority> priority,
      scoped_refptr<PreloadPipelineInfo> preload_pipeline_info,
      const net::HttpRequestHeaders& additional_headers,
      std::unique_ptr<PrefetchRequestStatusListener> request_status_listener,
      base::TimeDelta ttl,
      bool should_append_variations_header,
      bool should_disable_block_until_head_timeout,
      bool should_bypass_http_cache);

  // Adds a `PrefetchContainer` from a `PrePrefetchHandle` and starts prefetch.
  [[nodiscard]] std::unique_ptr<content::PrefetchHandle>
  StartPrefetchFromPrePrefetch(
      std::unique_ptr<content::PrePrefetchHandle> pre_prefetch_handle);

  // Updates the "Accept Language" header that the prefetch service delegate
  // will use.
  void UpdatePrefetchServiceDelegateAcceptLanguageHeader(
      std::string accept_language_header);

  // Returns `true` if a new prefetch request with `url` and
  // `no_vary_search_hint` has a duplicate in the prefetch cache and thus the
  // caller can choose not to start the prefetch request.
  //
  // Note: This is currently used for WebView initiated prefetches
  // so consideration should be taken if updating the
  // underlying implementation (or its dependencies).
  bool IsPrefetchDuplicate(
      const GURL& url,
      const std::optional<net::HttpNoVarySearchData>& no_vary_search_hint);

  using BlobCallback = base::OnceCallback<void(std::unique_ptr<BlobHandle>)>;
  using BlobContextGetter =
      base::RepeatingCallback<base::WeakPtr<storage::BlobStorageContext>()>;

  // This method should be called on UI thread and calls back on UI thread
  // as well. Note that retrieving a blob ptr out of BlobHandle can only be
  // done on IO. |callback| returns a nullptr on failure.
  void CreateMemoryBackedBlob(base::span<const uint8_t> data,
                              const std::string& content_type,
                              BlobCallback callback);

  // Get a BlobStorageContext getter that needs to run on IO thread.
  BlobContextGetter GetBlobStorageContext();

  // Returns a mojom::mojo::PendingRemote<blink::mojom::Blob> for a specific
  // blob. If no blob exists with the given UUID, the
  // mojo::PendingRemote<blink::mojom::Blob> pipe will close. This method should
  // be called on the UI thread.
  // TODO(mek): Blob UUIDs should be entirely internal to the blob system, so
  // eliminate this method in favor of just passing around the
  // mojo::PendingRemote<blink::mojom::Blob> directly.
  mojo::PendingRemote<blink::mojom::Blob> GetBlobRemote(
      const std::string& uuid);

  // Delivers a push message with |data| to the Service Worker identified by
  // |origin| and |service_worker_registration_id|. |record_network_requests|
  // indicates whether network request urls should be recorded during the push
  // event.
  void DeliverPushMessage(
      const GURL& origin,
      int64_t service_worker_registration_id,
      const std::string& message_id,
      std::optional<std::string> payload,
      bool record_network_requests,
      base::OnceCallback<void(blink::mojom::PushEventStatus)> callback);

  // Fires a push subscription change event to the Service Worker identified by
  // |origin| and |service_worker_registration_id| with |new_subscription| and
  // |old_subscription| as event information.
  void FirePushSubscriptionChangeEvent(
      const GURL& origin,
      int64_t service_worker_registration_id,
      blink::mojom::PushSubscriptionPtr new_subscription,
      blink::mojom::PushSubscriptionPtr old_subscription,
      base::OnceCallback<void(blink::mojom::PushEventStatus)> callback);

  void NotifyWillBeDestroyed();

  // Ensures that the corresponding ResourceContext is initialized. Normally the
  // BrowserContext initializs the corresponding getters when its objects are
  // created, but if the embedder wants to pass the ResourceContext to another
  // thread before they use BrowserContext, they should call this to make sure
  // that the ResourceContext is ready.
  void EnsureResourceContextInitialized();

  // Tells the HTML5 objects on this context to persist their session state
  // across the next restart.
  void SaveSessionState();

  void SetDownloadManagerForTesting(
      std::unique_ptr<DownloadManager> download_manager);

  void SetPermissionControllerForTesting(
      std::unique_ptr<PermissionController> permission_controller);

  // The list of CORS exemptions.  This list needs to be 1) replicated when
  // creating or re-creating new network::mojom::NetworkContexts (see
  // network::mojom::NetworkContextParams::cors_origin_access_list) and 2)
  // consulted by CORS-aware factories (e.g. passed when constructing
  // FileURLLoaderFactory).
  SharedCorsOriginAccessList* GetSharedCorsOriginAccessList();

  // Shuts down the storage partitions associated to this browser context.
  // This must be called before the browser context is actually destroyed
  // and before a clean-up task for its corresponding IO thread residents (e.g.
  // ResourceContext) is posted, so that the classes that hung on
  // StoragePartition can have time to do necessary cleanups on IO thread.
  void ShutdownStoragePartitions();

  // Returns true if shutdown has been initiated via a
  // NotifyWillBeDestroyed() call. This is a signal that the object will be
  // destroyed soon and no new references to this object should be created.
  bool ShutdownStarted();

  // Returns a unique string associated with this browser context.
  // DEPRECATED: Use UniqueToken() instead. See crbug.com/466132514.
  virtual const std::string& UniqueId() const;

  // Returns a unique unguessable token associated with this browser context.
  const base::UnguessableToken& UniqueToken() const;

  // Gets media service for storing/retrieving video decoding performance stats.
  // Exposed here rather than StoragePartition because all SiteInstances should
  // have similar decode performance and stats are not exposed to the web
  // directly, so privacy is not compromised.
  media::VideoDecodePerfHistory* GetVideoDecodePerfHistory();

  // Gets media service for storing/retrieving WebRTC video performance stats.
  // Exposed here rather than StoragePartition because all SiteInstances should
  // have similar encode/decode performance and stats are not exposed to the web
  // directly, so privacy is not compromised.
  media::WebrtcVideoPerfHistory* GetWebrtcVideoPerfHistory();

  // Retrieves the InProgressDownloadManager associated with this object if
  // available
  virtual std::unique_ptr<download::InProgressDownloadManager>
  RetrieveInProgressDownloadManager();

  using TraceProto = perfetto::protos::pbzero::ChromeBrowserContext;
  // Write a representation of this object into tracing proto.
  // rvalue ensure that the this method can be called without having access
  // to the declaration of ChromeBrowserContext proto.
  void WriteIntoTrace(perfetto::TracedProto<TraceProto> context) const;

  base::WeakPtr<BrowserContext> GetWeakPtr();

  //////////////////////////////////////////////////////////////////////////////
  // The //content embedder can override the methods below to change or extend
  // how the //content layer interacts with a BrowserContext.
  //
  // All the methods below should be virtual.  Most of the methods should be
  // pure (i.e. `= 0`) although it may make sense to provide a default
  // implementation for some of the methods.
  //
  // TODO(crbug.com/40169693): Migrate method declarations from this
  // section into a separate BrowserContextDelegate class.

  // Creates a delegate to initialize a HostZoomMap and persist its information.
  // This is called during creation of each StoragePartition.
  virtual std::unique_ptr<ZoomLevelDelegate> CreateZoomLevelDelegate(
      const base::FilePath& partition_path) = 0;

  // Returns the path of the directory where this context's data is stored.
  virtual base::FilePath GetPath() const = 0;

  // Return whether this context is off the record. Default is false.
  // Note that for Chrome this does not imply Incognito as Guest sessions are
  // also off the record.
  virtual bool IsOffTheRecord() = 0;

  // Returns the DownloadManagerDelegate for this context. This will be called
  // once per context. The embedder owns the delegate and is responsible for
  // ensuring that it outlives DownloadManager. Note in particular that it is
  // unsafe to destroy the delegate in the destructor of a subclass of
  // BrowserContext, since it needs to be alive in ~BrowserContext.
  // It's valid to return nullptr.
  virtual DownloadManagerDelegate* GetDownloadManagerDelegate() = 0;

  // Returns the guest manager for this context.
  virtual BrowserPluginGuestManager* GetGuestManager() = 0;

  // Returns a special storage policy implementation, or nullptr.
  virtual storage::SpecialStoragePolicy* GetSpecialStoragePolicy() = 0;

  // Returns the platform notification service, capable of displaying Web
  // Notifications to the user. The embedder can return a nullptr if they don't
  // support this functionality. Must be called on the UI thread.
  virtual PlatformNotificationService* GetPlatformNotificationService() = 0;

  // Returns a push messaging service. The embedder owns the service, and is
  // responsible for ensuring that it outlives RenderProcessHost. It's valid to
  // return nullptr.
  virtual PushMessagingService* GetPushMessagingService() = 0;

  // Returns a storage notification service associated with that context,
  // nullptr otherwise. In the case that nullptr is returned, QuotaManager
  // and the rest of the storage layer will have no connection to the Chrome
  // layer for UI purposes.
  virtual StorageNotificationService* GetStorageNotificationService() = 0;

  // Returns the SSL host state decisions for this context. The context may
  // return nullptr, implementing the default exception storage strategy.
  virtual SSLHostStateDelegate* GetSSLHostStateDelegate() = 0;

  // Returns the PermissionControllerDelegate associated with this context if
  // any, nullptr otherwise.
  //
  // Note: if you want to check a permission status, you probably need
  // BrowserContext::GetPermissionController() instead.
  virtual PermissionControllerDelegate* GetPermissionControllerDelegate() = 0;

  // Returns the ReduceAcceptLanguageControllerDelegate associated with that
  // context if any, nullptr otherwise.
  virtual ReduceAcceptLanguageControllerDelegate*
  GetReduceAcceptLanguageControllerDelegate() = 0;

  // Returns the ClientHintsControllerDelegate associated with that context if
  // any, nullptr otherwise.
  virtual ClientHintsControllerDelegate* GetClientHintsControllerDelegate() = 0;

  // Returns the BackgroundFetchDelegate associated with that context if any,
  // nullptr otherwise.
  virtual BackgroundFetchDelegate* GetBackgroundFetchDelegate() = 0;

  // Returns the BackgroundSyncController associated with that context if any,
  // nullptr otherwise.
  virtual BackgroundSyncController* GetBackgroundSyncController() = 0;

  // Returns the BrowsingDataRemoverDelegate for this context. This will be
  // called once per context. It's valid to return nullptr.
  virtual BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate() = 0;

  // Returns the FileSystemAccessPermissionContext associated with this context
  // if any, nullptr otherwise.
  virtual FileSystemAccessPermissionContext*
  GetFileSystemAccessPermissionContext();

  // Returns the ContentIndexProvider associated with that context if any,
  // nullptr otherwise.
  virtual ContentIndexProvider* GetContentIndexProvider();

  // Returns true iff the sandboxed file system implementation should be disk
  // backed, even if this browser context is off the record. By default this
  // returns false, an embedded could override this to return true if for
  // example the off-the-record browser context is stored in a in-memory file
  // system anyway, in which case using the disk backed sandboxed file system
  // API implementation can give some benefits over the in-memory
  // implementation.
  virtual bool CanUseDiskWhenOffTheRecord();

  // Returns true if the session storage database should be cleared on startup
  // instead of preserving data from the previous session.
  // The default implementation returns false.
  virtual bool ShouldClearSessionStorageOnStartup();

  // Returns the VariationsClient associated with the context if any, or
  // nullptr if there isn't one.
  virtual variations::VariationsClient* GetVariationsClient();

  // Creates the media service for storing/retrieving video decoding performance
  // stats.  Exposed here rather than StoragePartition because all SiteInstances
  // should have similar decode performance and stats are not exposed to the web
  // directly, so privacy is not compromised.
  virtual std::unique_ptr<media::VideoDecodePerfHistory>
  CreateVideoDecodePerfHistory();

  // Gets the permission context for determining whether the FedCM API is
  // enabled in site settings.
  virtual FederatedIdentityApiPermissionContextDelegate*
  GetFederatedIdentityApiPermissionContext();
  // Gets the permission context for determining whether the FedCM API's auto
  // re-authentication feature is enabled in site settings.
  virtual FederatedIdentityAutoReauthnPermissionContextDelegate*
  GetFederatedIdentityAutoReauthnPermissionContext();
  // Gets the permission context for allowing session management capabilities
  // between an identity provider and a relying party if one exists, or
  // nullptr otherwise.
  virtual FederatedIdentityPermissionContextDelegate*
  GetFederatedIdentityPermissionContext();

  // Returns the OriginTrialsControllerDelegate associated with the context if
  // any, nullptr otherwise.
  virtual OriginTrialsControllerDelegate* GetOriginTrialsControllerDelegate();

  // Takes the ProtoDatabaseProvider, if any, for the default storage partition.
  // Embedders may choose to create a ProtoDatabaseProvider early, so this
  // provides a way to reuse it.
  virtual std::unique_ptr<leveldb_proto::ProtoDatabaseProvider>
  TakeDefaultProtoDatabaseProvider();

#if BUILDFLAG(IS_ANDROID)
  // Returns extra request headers to be set when navigation happens for `url`.
  // This function is designed for the headers provided by WebView.loadUrl().
  virtual std::string GetExtraHeadersForUrl(const GURL& url);
#endif  // BUILDFLAG(IS_ANDROID)

 private:
  // Please don't add more fields to BrowserContext.
  //
  // Ideally, BrowserContext would be a pure interface (only pure-virtual
  // methods and no fields), but currently BrowserContext and BrowserContextImpl
  // and BrowserContextDelegate are kind of mixed together in a single class.
  //
  // TODO(crbug.com/40169693): Make BrowserContextImpl to implement
  // BrowserContext instead (Removing afterwards the BrowserContextImpl,
  // fwd-declaration, `impl_` field, `friend` declaration and `impl` accessor
  // below).
  friend class BrowserContextImpl;
  std::unique_ptr<BrowserContextImpl> impl_;
  BrowserContextImpl* impl() { return impl_.get(); }
  const BrowserContextImpl* impl() const { return impl_.get(); }
  base::WeakPtrFactory<BrowserContext> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_BROWSER_CONTEXT_H_
