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

#include "chrome/browser/media/cdm_document_service_impl.h"

#include <utility>

#include "base/functional/bind.h"
#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "media/media_buildflags.h"

#if BUILDFLAG(ENABLE_CDM_STORAGE_ID)
#include "chrome/browser/media/cdm_storage_id.h"
#include "chrome/browser/media/media_storage_id_salt.h"
#include "content/public/browser/render_process_host.h"
#endif

#if BUILDFLAG(ENABLE_CDM_STORAGE_ID) || BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/render_frame_host.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/media/platform_verification_chromeos.h"
#include "chromeos/ash/components/settings/cros_settings.h"
#include "chromeos/ash/components/settings/cros_settings_names.h"
#endif

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/system/sys_info.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/win/security_util.h"
#include "base/win/sid.h"
#include "chrome/browser/media/cdm_pref_service_helper.h"
#include "chrome/browser/media/media_foundation_service_monitor.h"
#include "media/cdm/media_foundation_cdm_data.h"
#include "media/cdm/win/media_foundation_cdm.h"
#include "sandbox/policy/win/lpac_capability.h"
#endif  // BUILDFLAG(IS_WIN)

namespace {

#if BUILDFLAG(ENABLE_CDM_STORAGE_ID)
// Only support version 1 of Storage Id. However, the "latest" version can also
// be requested.
const uint32_t kRequestLatestStorageIdVersion = 0;
const uint32_t kCurrentStorageIdVersion = 1;

std::vector<uint8_t> GetStorageIdSaltFromProfile(
    content::RenderFrameHost* rfh) {
  DCHECK(rfh);
  Profile* profile =
      Profile::FromBrowserContext(rfh->GetProcess()->GetBrowserContext());
  return MediaStorageIdSalt::GetSalt(profile->GetPrefs());
}

#endif  // BUILDFLAG(ENABLE_CDM_STORAGE_ID)

#if BUILDFLAG(IS_WIN)
const char kCdmStore[] = "MediaFoundationCdmStore";

base::FilePath GetCdmStorePathRootForProfile(
    const base::FilePath& profile_path) {
  return profile_path.AppendASCII(kCdmStore).AppendASCII(
      base::SysInfo::ProcessCPUArchitecture());
}
#endif  // BUILDFLAG(IS_WIN)

}  // namespace

#if BUILDFLAG(IS_WIN)
bool CreateCdmStorePathRootAndGrantAccessIfNeeded(
    const base::FilePath& cdm_store_path_root) {
  if (!media::MediaFoundationCdm::IsAvailable()) {
    DLOG(ERROR) << "Granting access to LPAC process is not supported prior to "
                   "Windows 10.";
    return false;
  }
  // If the path exist, we can assume the right permission are already
  // set on it.
  if (base::PathExists(cdm_store_path_root))
    return true;

  base::File::Error file_error;
  if (!base::CreateDirectoryAndGetError(cdm_store_path_root, &file_error)) {
    DLOG(ERROR) << "Create CDM store path failed with " << file_error;
    return false;
  }

  auto sids = base::win::Sid::FromNamedCapabilityVector(
      {sandbox::policy::kMediaFoundationCdmData});
  return base::win::GrantAccessToPath(
      cdm_store_path_root, sids,
      FILE_GENERIC_READ | FILE_GENERIC_WRITE | GENERIC_EXECUTE | DELETE,
      CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
}

std::unique_ptr<media::MediaFoundationCdmData>
GetMediaFoundationCdmDataInternal(const base::FilePath profile_path,
                                  std::unique_ptr<CdmPrefData> pref_data) {
  DCHECK(pref_data);

  auto cdm_store_path_root = GetCdmStorePathRootForProfile(profile_path);
  if (!CreateCdmStorePathRootAndGrantAccessIfNeeded(cdm_store_path_root)) {
    return nullptr;
  }

  std::unique_ptr<media::MediaFoundationCdmData> cdm_data;
  return std::make_unique<media::MediaFoundationCdmData>(
      pref_data->origin_id(), pref_data->client_token(), cdm_store_path_root);
}
#endif  // BUILDFLAG(IS_WIN)

// static
void CdmDocumentServiceImpl::Create(
    content::RenderFrameHost* render_frame_host,
    mojo::PendingReceiver<media::mojom::CdmDocumentService> receiver) {
  DVLOG(2) << __func__;
  CHECK(render_frame_host);

  // PlatformVerificationFlow and the pref service requires to be run/accessed
  // on the UI thread.
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // The object is bound to the lifetime of |render_frame_host| and the mojo
  // connection. See DocumentService for details.
  new CdmDocumentServiceImpl(*render_frame_host, std::move(receiver));
}

CdmDocumentServiceImpl::CdmDocumentServiceImpl(
    content::RenderFrameHost& render_frame_host,
    mojo::PendingReceiver<media::mojom::CdmDocumentService> receiver)
    : DocumentService(render_frame_host, std::move(receiver)) {}

CdmDocumentServiceImpl::~CdmDocumentServiceImpl() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

void CdmDocumentServiceImpl::ChallengePlatform(
    const std::string& service_id,
    const std::string& challenge,
    ChallengePlatformCallback callback) {
  DVLOG(2) << __func__;
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // TODO(crbug.com/40499115). This should be commented out at the mojom
  // level so that it's only available for ChromeOS.

#if BUILDFLAG(IS_CHROMEOS)
  bool success = platform_verification::PerformBrowserChecks(
      render_frame_host().GetMainFrame());
  if (!success) {
    std::move(callback).Run(false, std::string(), std::string(), std::string());
    return;
  }

  if (!platform_verification_flow_)
    platform_verification_flow_ =
        base::MakeRefCounted<ash::attestation::PlatformVerificationFlow>();

  platform_verification_flow_->ChallengePlatformKey(
      content::WebContents::FromRenderFrameHost(&render_frame_host()),
      service_id, challenge,
      base::BindOnce(&CdmDocumentServiceImpl::OnPlatformChallenged,
                     weak_factory_.GetWeakPtr(), std::move(callback)));
#else
  // Not supported, so return failure.
  std::move(callback).Run(false, std::string(), std::string(), std::string());
#endif  // BUILDFLAG(IS_CHROMEOS)
}

#if BUILDFLAG(IS_CHROMEOS)
void CdmDocumentServiceImpl::OnPlatformChallenged(
    ChallengePlatformCallback callback,
    PlatformVerificationResult result,
    const std::string& signed_data,
    const std::string& signature,
    const std::string& platform_key_certificate) {
  DVLOG(2) << __func__ << ": " << result;
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (result != ash::attestation::PlatformVerificationFlow::SUCCESS) {
    DCHECK(signed_data.empty());
    DCHECK(signature.empty());
    DCHECK(platform_key_certificate.empty());
    LOG(ERROR) << "Platform verification failed.";
    std::move(callback).Run(false, "", "", "");
    return;
  }

  DCHECK(!signed_data.empty());
  DCHECK(!signature.empty());
  DCHECK(!platform_key_certificate.empty());
  std::move(callback).Run(true, signed_data, signature,
                          platform_key_certificate);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

void CdmDocumentServiceImpl::GetStorageId(uint32_t version,
                                          GetStorageIdCallback callback) {
  DVLOG(2) << __func__ << " version: " << version;
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // TODO(crbug.com/40499115). This should be commented out at the mojom
  // level so that it's only available if Storage Id is available.

#if BUILDFLAG(ENABLE_CDM_STORAGE_ID)
  // Check that the request is for a supported version.
  if (version == kCurrentStorageIdVersion ||
      version == kRequestLatestStorageIdVersion) {
    ComputeStorageId(
        GetStorageIdSaltFromProfile(&render_frame_host()), origin(),
        base::BindOnce(&CdmDocumentServiceImpl::OnStorageIdResponse,
                       weak_factory_.GetWeakPtr(), std::move(callback)));
    return;
  }
#endif  // BUILDFLAG(ENABLE_CDM_STORAGE_ID)

  // Version not supported, so no Storage Id to return.
  DVLOG(2) << __func__ << " not supported";
  std::move(callback).Run(version, std::vector<uint8_t>());
}

#if BUILDFLAG(ENABLE_CDM_STORAGE_ID)
void CdmDocumentServiceImpl::OnStorageIdResponse(
    GetStorageIdCallback callback,
    const std::vector<uint8_t>& storage_id) {
  DVLOG(2) << __func__ << " version: " << kCurrentStorageIdVersion
           << ", size: " << storage_id.size();

  std::move(callback).Run(kCurrentStorageIdVersion, storage_id);
}
#endif  // BUILDFLAG(ENABLE_CDM_STORAGE_ID)

#if BUILDFLAG(IS_CHROMEOS)
void CdmDocumentServiceImpl::IsVerifiedAccessEnabled(
    IsVerifiedAccessEnabledCallback callback) {
  // If we are in guest/incognito mode, then verified access is effectively
  // disabled.
  Profile* profile =
      Profile::FromBrowserContext(render_frame_host().GetBrowserContext());
  if (profile->IsOffTheRecord() || profile->IsGuestSession()) {
    std::move(callback).Run(false);
    return;
  }

  bool enabled_for_device = false;
  ash::CrosSettings::Get()->GetBoolean(
      ash::kAttestationForContentProtectionEnabled, &enabled_for_device);
  std::move(callback).Run(enabled_for_device);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_WIN)
void CdmDocumentServiceImpl::GetMediaFoundationCdmData(
    GetMediaFoundationCdmDataCallback callback) {
  const url::Origin cdm_origin = origin();
  if (cdm_origin.opaque()) {
    mojo::ReportBadMessage("EME use is not allowed on opaque origin");
    return;
  }

  Profile* profile =
      Profile::FromBrowserContext(render_frame_host().GetBrowserContext());

  PrefService* user_prefs = profile->GetPrefs();
  std::unique_ptr<CdmPrefData> pref_data =
      CdmPrefServiceHelper::GetCdmPrefData(user_prefs, cdm_origin);

  if (!pref_data) {
    std::move(callback).Run(nullptr);
    return;
  }

  // PostTask because the task is doing IO operation that can block.
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
      base::BindOnce(&GetMediaFoundationCdmDataInternal, profile->GetPath(),
                     std::move(pref_data)),
      std::move(callback));
}

void CdmDocumentServiceImpl::SetCdmClientToken(
    const std::vector<uint8_t>& client_token) {
  const url::Origin cdm_origin = origin();
  if (cdm_origin.opaque()) {
    mojo::ReportBadMessage("EME use is not allowed on opaque origin");
    return;
  }

  PrefService* user_prefs =
      Profile::FromBrowserContext(render_frame_host().GetBrowserContext())
          ->GetPrefs();
  CdmPrefServiceHelper::SetCdmClientToken(user_prefs, cdm_origin, client_token);
}

void CdmDocumentServiceImpl::OnCdmEvent(media::CdmEvent event,
                                        uint32_t hresult) {
  DVLOG(1) << __func__ << ": event=" << static_cast<int>(event);

  auto* monitor = MediaFoundationServiceMonitor::GetInstance();

  // Hardware context reset after power or display change is expected.
  if (event == media::CdmEvent::kHardwareContextReset) {
    bool has_change = monitor->HasRecentPowerOrDisplayChange();
    base::UmaHistogramBoolean(
        "Media.EME.MediaFoundationService.HardwareContextReset", has_change);
    if (has_change) {
      DVLOG(2) << __func__
               << ": HardwareContextReset ignored after power/display change";
      return;
    }
  }

  // CdmDocumentServiceImpl is shared by all CDMs in the same RenderFrame.
  //
  // We choose to only handle each event type at most once because:
  // 1. A site could create many CDM instances, e.g. to prefetch licenses. This
  //    could cause multiple errors to be reported.
  // 2. The media::Renderer could be destroyed and then recreated as part of the
  //    suspend/resume process (e.g. paused for long time). This could cause
  //    multiple significant playback or hardware context reset without playback
  //    to be reported.
  // In all cases, our data could be skewed if we don't throttle them.
  //
  // A different event will still be reported. For example, if an error happens
  // after a significant playback both will be reported. This is fine since
  // MediaFoundationServiceMonitor calculates a score.
  if (auto [ignored, inserted] = reported_cdm_event_.insert(event); !inserted) {
    DVLOG(2) << __func__ << ": Repeated CdmEvent ignored";
    return;
  }

  auto site = render_frame_host().GetSiteInstance()->GetSiteURL();
  switch (event) {
    case media::CdmEvent::kSignificantPlayback:
      monitor->OnSignificantPlayback(site);
      break;
    case media::CdmEvent::kPlaybackError:
    case media::CdmEvent::kCdmError:
      monitor->OnPlaybackOrCdmError(site, static_cast<HRESULT>(hresult));
      break;
    case media::CdmEvent::kHardwareContextReset:
      monitor->OnUnexpectedHardwareContextReset(site);
      break;
  }
}

// This function goes over each folder located under the MediaFoundationCdm
// store root path and delete them as needed. A folder needs to be deleted for
// the following reason:
// - The origin id the folder is associated with is no longer present in the
// PrefService
// - The folder refers to an origin matched by `filter` AND the folder was last
// modified between `start` and `end`
void DeleteMediaFoundationCdmData(
    const base::FilePath& profile_path,
    const std::map<std::string, url::Origin> origin_id_mapping,
    base::Time start,
    base::Time end,
    const base::RepeatingCallback<bool(const GURL&)>& filter) {
  auto cdm_store_path_root = GetCdmStorePathRootForProfile(profile_path);

  // Enumerate all folder under `cdm_store_path_root` which should give a list
  // of folder whose names are origin ids. Each folder contains CDM data
  // associated with that origin id.
  //
  base::FileEnumerator directory_enumerator(cdm_store_path_root,
                                            /*recursive=*/false,
                                            base::FileEnumerator::DIRECTORIES);

  for (auto file_path = directory_enumerator.Next(); !file_path.value().empty();
       file_path = directory_enumerator.Next()) {
    // The folder name is a string representation of a base::UnguessableToken,
    // using MaybeAsASCII() is fine.
    std::string origin_id_string = file_path.BaseName().MaybeAsASCII();
    if (origin_id_string.empty())
      continue;

    DVLOG(2) << __func__ << ": Processing: " << file_path;
    std::optional<url::Origin> origin = std::nullopt;
    if (origin_id_mapping.count(origin_id_string) != 0)
      origin = origin_id_mapping.at(origin_id_string);

    // If we couldn't find the origin, this mean the origin was not present in
    // the PrefService and we should also delete the folder.
    if (!origin) {
      base::DeletePathRecursively(file_path);
      continue;
    }

    // Null filter indicates that we should delete everything.
    if (filter && !filter.Run(GURL(origin->Serialize())))
      continue;

    // Now go over every files under the current folder and delete them if
    // needed.
    base::FileEnumerator file_enumerator(file_path, /*recursive=*/true,
                                         base::FileEnumerator::FILES);

    // If at least one files was modified between `start` and `end`, we should
    // delete the whole folder.
    bool should_delete = false;
    for (auto cdm_data_file_path = file_enumerator.Next();
         !cdm_data_file_path.value().empty();
         cdm_data_file_path = file_enumerator.Next()) {
      DVLOG(2) << __func__ << ": - Processing: " << cdm_data_file_path;
      base::File::Info file_info;
      if (!base::GetFileInfo(cdm_data_file_path, &file_info)) {
        DVLOG(ERROR) << "Failed to get FileInfo";
        should_delete = true;
        break;
      }

      if (file_info.last_modified >= start &&
          (end.is_null() || file_info.last_modified <= end)) {
        DVLOG(2) << "Deleting file. Last modified: " << file_info.last_modified;
        should_delete = true;
        break;
      }
    }

    if (should_delete)
      base::DeletePathRecursively(file_path);
  }
}

void CdmDocumentServiceImpl::ClearCdmData(
    Profile* profile,
    base::Time start,
    base::Time end,
    const base::RepeatingCallback<bool(const GURL&)>& filter,
    base::OnceClosure complete_cb) {
  PrefService* user_prefs = profile->GetPrefs();
  CdmPrefServiceHelper::ClearCdmPreferenceData(user_prefs, start, end, filter);

  // Get the origin_id mapping here because the PrefService needs to be accessed
  // from the UI thread.
  auto origin_id_mapping = CdmPrefServiceHelper::GetOriginIdMapping(user_prefs);

  // PostTask because is doing IO operation that can block.
  base::ThreadPool::PostTaskAndReply(
      FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
      base::BindOnce(&DeleteMediaFoundationCdmData, profile->GetPath(),
                     std::move(origin_id_mapping), start, end, filter),
      std::move(complete_cb));
}
#endif  // BUILDFLAG(IS_WIN)
