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

#include "content/browser/browser_context_impl.h"

#include <utility>

#include "base/memory/ref_counted.h"
#include "base/task/sequenced_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/background_sync/background_sync_scheduler.h"
#include "content/browser/browsing_data/browsing_data_remover_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/preloading/prefetch/prefetch_service.h"
#include "content/browser/renderer_host/navigation_transitions/navigation_entry_screenshot_cache.h"
#include "content/browser/renderer_host/navigation_transitions/navigation_entry_screenshot_manager.h"
#include "content/browser/speech/tts_controller_impl.h"
#include "content/browser/storage_partition_impl_map.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/shared_worker_service.h"
#include "media/capabilities/webrtc_video_stats_db_impl.h"
#include "media/learning/common/media_learning_tasks.h"
#include "media/learning/impl/learning_session_impl.h"
#include "media/mojo/services/video_decode_perf_history.h"
#include "media/mojo/services/webrtc_video_perf_history.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "storage/browser/file_system/external_mount_points.h"
#endif

namespace content {

namespace {

void ShutdownServiceWorkerContext(StoragePartition* partition) {
  ServiceWorkerContextWrapper* wrapper =
      static_cast<ServiceWorkerContextWrapper*>(
          partition->GetServiceWorkerContext());
  wrapper->process_manager()->Shutdown();
}

void ShutdownSharedWorkerContext(StoragePartition* partition) {
  partition->GetSharedWorkerService()->Shutdown();
}

void RegisterMediaLearningTask(
    media::learning::LearningSessionImpl* learning_session,
    const media::learning::LearningTask& task) {
  // The RegisterTask method cannot be directly used in base::Bind, because it
  // provides a default argument value for the 2nd parameter
  // (`feature_provider`).
  learning_session->RegisterTask(task);
}

}  // namespace

// static
BrowserContextImpl* BrowserContextImpl::From(BrowserContext* self) {
  return self->impl();
}

BrowserContextImpl::BrowserContextImpl(BrowserContext* self) : self_(self) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  background_sync_scheduler_ = base::MakeRefCounted<BackgroundSyncScheduler>();
}

BrowserContextImpl::~BrowserContextImpl() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!storage_partition_map_)
      << "StoragePartitionMap is not shut down properly";

  if (!will_be_destroyed_soon_) {
    NOTREACHED();
  }

  // Verify that there are no outstanding RenderProcessHosts that reference
  // this context. Trigger a crash report if there are still references so
  // we can detect/diagnose potential UAFs.
  std::string rph_crash_key_value;
  ChildProcessSecurityPolicyImpl* policy =
      ChildProcessSecurityPolicyImpl::GetInstance();
  for (RenderProcessHost::iterator host_iterator =
           RenderProcessHost::AllHostsIterator();
       !host_iterator.IsAtEnd(); host_iterator.Advance()) {
    RenderProcessHost* host = host_iterator.GetCurrentValue();
    if (host->GetBrowserContext() == self_) {
      rph_crash_key_value +=
          "{ " + host->GetInfoForBrowserContextDestructionCrashReporting() +
          " }";
    }
  }
  if (!rph_crash_key_value.empty()) {
    SCOPED_CRASH_KEY_STRING256("BrowserContext", "dangling_rph",
                               rph_crash_key_value);
    NOTREACHED() << "rph_with_bc_reference : " << rph_crash_key_value;
  }

  // Clean up any isolated origins and other security state associated with this
  // BrowserContext.
  policy->RemoveStateForBrowserContext(*self_);

  if (download_manager_)
    download_manager_->Shutdown();

  TtsControllerImpl::GetInstance()->OnBrowserContextDestroyed(self_);

  TRACE_EVENT_NESTABLE_ASYNC_END1(
      "shutdown", "BrowserContextImpl::NotifyWillBeDestroyed() called.", this,
      "browser_context_impl", static_cast<void*>(this));
}

bool BrowserContextImpl::ShutdownStarted() {
  return will_be_destroyed_soon_;
}

void BrowserContextImpl::NotifyWillBeDestroyed() {
  TRACE_EVENT1("shutdown", "BrowserContextImpl::NotifyWillBeDestroyed",
               "browser_context_impl", static_cast<void*>(this));
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
      "shutdown", "BrowserContextImpl::NotifyWillBeDestroyed() called.", this,
      "browser_context_impl", static_cast<void*>(this));
  // Make sure NotifyWillBeDestroyed is idempotent.  This helps facilitate the
  // pattern where NotifyWillBeDestroyed is called from *both*
  // ShellBrowserContext and its derived classes (e.g. WebTestBrowserContext).
  if (will_be_destroyed_soon_)
    return;
  will_be_destroyed_soon_ = true;

  // Shut down service worker and shared worker machinery because these can keep
  // RenderProcessHosts and SiteInstances alive, and the codebase assumes these
  // are destroyed before the BrowserContext is destroyed.
  self_->ForEachLoadedStoragePartition(
      base::BindRepeating(ShutdownServiceWorkerContext));
  self_->ForEachLoadedStoragePartition(
      base::BindRepeating(ShutdownSharedWorkerContext));

  // Also forcibly release keep alive refcounts on RenderProcessHosts, to ensure
  // they destruct before the BrowserContext does.
  for (RenderProcessHost::iterator host_iterator =
           RenderProcessHost::AllHostsIterator();
       !host_iterator.IsAtEnd(); host_iterator.Advance()) {
    RenderProcessHost* host = host_iterator.GetCurrentValue();
    if (host->GetBrowserContext() == self_) {
      // This will also clean up spare RPH references.
      host->DisableRefCounts();
    }
  }
}

StoragePartitionImplMap* BrowserContextImpl::GetOrCreateStoragePartitionMap() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!storage_partition_map_)
    storage_partition_map_ = std::make_unique<StoragePartitionImplMap>(self_);

  return storage_partition_map_.get();
}

BrowsingDataRemoverImpl* BrowserContextImpl::GetBrowsingDataRemover() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!browsing_data_remover_) {
    browsing_data_remover_ = std::make_unique<BrowsingDataRemoverImpl>(self_);
    browsing_data_remover_->SetEmbedderDelegate(
        self_->GetBrowsingDataRemoverDelegate());
  }

  return browsing_data_remover_.get();
}

media::learning::LearningSession* BrowserContextImpl::GetLearningSession() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!learning_session_) {
    learning_session_ = std::make_unique<media::learning::LearningSessionImpl>(
        base::SequencedTaskRunner::GetCurrentDefault());

    // Using base::Unretained is safe below, because the callback here will not
    // be called or retained after the Register method below returns.
    media::learning::MediaLearningTasks::Register(base::BindRepeating(
        &RegisterMediaLearningTask, base::Unretained(learning_session_.get())));
  }

  return learning_session_.get();
}

media::VideoDecodePerfHistory* BrowserContextImpl::GetVideoDecodePerfHistory() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!video_decode_perf_history_)
    video_decode_perf_history_ = self_->CreateVideoDecodePerfHistory();

  return video_decode_perf_history_.get();
}

std::unique_ptr<media::WebrtcVideoPerfHistory>
BrowserContextImpl::CreateWebrtcVideoPerfHistory() {
  // TODO(https://crbug.com/1187565): Implement in memory path in
  // off_the_record_profile_impl.cc and web_engine_browser_context.cc

  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  auto* db_provider =
      self_->GetDefaultStoragePartition()->GetProtoDatabaseProvider();

  std::unique_ptr<media::WebrtcVideoStatsDB> stats_db =
      media::WebrtcVideoStatsDBImpl::Create(
          self_->GetPath().Append(FILE_PATH_LITERAL("WebrtcVideoStats")),
          db_provider);

  return std::make_unique<media::WebrtcVideoPerfHistory>(std::move(stats_db));
}

media::WebrtcVideoPerfHistory* BrowserContextImpl::GetWebrtcVideoPerfHistory() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!webrtc_video_perf_history_)
    webrtc_video_perf_history_ = CreateWebrtcVideoPerfHistory();

  return webrtc_video_perf_history_.get();
}

void BrowserContextImpl::ShutdownStoragePartitions() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // The BackgroundSyncScheduler keeps raw pointers to partitions; clear it
  // first.
  DCHECK(background_sync_scheduler_->HasOneRef());
  background_sync_scheduler_.reset();

  storage_partition_map_.reset();
}

DownloadManager* BrowserContextImpl::GetDownloadManager() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // Lazily populate `download_manager_`.  This is important to
  // 1) Avoid constructing DownloadManagerImpl when a test might have provided
  //    an alternative object via SetDownloadManagerForTesting.
  // 2) Avoiding calling into DownloadManagerImpl's constructor with a partially
  //    constructed BrowserContext.
  if (!download_manager_) {
    download_manager_ = std::make_unique<DownloadManagerImpl>(self_);

    // Note that GetDownloadManagerDelegate might call into GetDownloadManager,
    // leading to re-entrancy concerns.  We avoid re-entrancy by making sure
    // `download_manager_` is set earlier, above.
    download_manager_->SetDelegate(self_->GetDownloadManagerDelegate());
  }

  return download_manager_.get();
}

void BrowserContextImpl::SetDownloadManagerForTesting(
    std::unique_ptr<DownloadManager> download_manager) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (download_manager_)
    download_manager_->Shutdown();
  download_manager_ = std::move(download_manager);
}

PermissionController* BrowserContextImpl::GetPermissionController() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!permission_controller_)
    permission_controller_ = std::make_unique<PermissionControllerImpl>(self_);

  return permission_controller_.get();
}

void BrowserContextImpl::SetPermissionControllerForTesting(
    std::unique_ptr<PermissionController> permission_controller) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  permission_controller_ = std::move(permission_controller);
}

storage::ExternalMountPoints* BrowserContextImpl::GetMountPoints() {
  // Ensure that these methods are called on the UI thread, except for
  // unittests where a UI thread might not have been created.
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
         !BrowserThread::IsThreadInitialized(BrowserThread::UI));

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (!external_mount_points_)
    external_mount_points_ = storage::ExternalMountPoints::CreateRefCounted();
  return external_mount_points_.get();
#else
  return nullptr;
#endif
}

PrefetchService* BrowserContextImpl::GetPrefetchService() {
  if (!prefetch_service_)
    prefetch_service_ = PrefetchService::CreateIfPossible(self_);

  return prefetch_service_.get();
}

void BrowserContextImpl::SetPrefetchServiceForTesting(
    std::unique_ptr<PrefetchService> prefetch_service) {
  prefetch_service_ = std::move(prefetch_service);
}

NavigationEntryScreenshotManager*
BrowserContextImpl::GetNavigationEntryScreenshotManager() {
  if (!nav_entry_screenshot_manager_ && AreBackForwardTransitionsEnabled()) {
    nav_entry_screenshot_manager_ =
        std::make_unique<NavigationEntryScreenshotManager>();
  }
  return nav_entry_screenshot_manager_.get();
}

void BrowserContextImpl::WriteIntoTrace(
    perfetto::TracedProto<TraceProto> proto) const {
  proto->set_id(UniqueId());
}

}  // namespace content
