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

#include "content/browser/media/media_interface_proxy.h"

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/system_connector.h"
#include "content/public/common/content_client.h"
#include "media/mojo/buildflags.h"
#include "media/mojo/interfaces/cdm_proxy.mojom.h"
#include "media/mojo/interfaces/constants.mojom.h"
#include "media/mojo/interfaces/media_service.mojom.h"
#include "media/mojo/services/media_interface_provider.h"
#include "services/service_manager/public/cpp/connector.h"

#if BUILDFLAG(ENABLE_MOJO_CDM)
#include "content/public/browser/browser_context.h"
#include "content/public/browser/provision_fetcher_impl.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#endif

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "content/browser/media/cdm_storage_impl.h"
#include "content/browser/media/key_system_support_impl.h"
#include "content/public/common/cdm_info.h"
#include "media/base/key_system_names.h"
#include "media/mojo/interfaces/cdm_service.mojom.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#if defined(OS_MACOSX)
#include "sandbox/mac/seatbelt_extension.h"
#endif  // defined(OS_MACOSX)
#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)

#if defined(OS_ANDROID)
#include "content/browser/media/android/media_player_renderer.h"
#include "content/browser/media/flinging_renderer.h"
#include "media/mojo/services/mojo_renderer_service.h"  // nogncheck
#endif

namespace content {

#if BUILDFLAG(ENABLE_LIBRARY_CDMS) && defined(OS_MACOSX)

namespace {

#if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
// TODO(xhwang): Move this to a common place.
const base::FilePath::CharType kSignatureFileExtension[] =
    FILE_PATH_LITERAL(".sig");

// Returns the signature file path given the |file_path|. This function should
// only be used when the signature file and the file are located in the same
// directory, which is the case for the CDM and CDM adapter.
base::FilePath GetSigFilePath(const base::FilePath& file_path) {
  return file_path.AddExtension(kSignatureFileExtension);
}
#endif  // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)

class SeatbeltExtensionTokenProviderImpl
    : public media::mojom::SeatbeltExtensionTokenProvider {
 public:
  explicit SeatbeltExtensionTokenProviderImpl(const base::FilePath& cdm_path)
      : cdm_path_(cdm_path) {}
  void GetTokens(GetTokensCallback callback) final {
    std::vector<sandbox::SeatbeltExtensionToken> tokens;

    // Allow the CDM to be loaded in the CDM service process.
    auto cdm_token = sandbox::SeatbeltExtension::Issue(
        sandbox::SeatbeltExtension::FILE_READ, cdm_path_.value());
    if (cdm_token) {
      tokens.push_back(std::move(*cdm_token));
    } else {
      std::move(callback).Run({});
      return;
    }

#if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
    // If CDM host verification is enabled, also allow to open the CDM signature
    // file.
    auto cdm_sig_token =
        sandbox::SeatbeltExtension::Issue(sandbox::SeatbeltExtension::FILE_READ,
                                          GetSigFilePath(cdm_path_).value());
    if (cdm_sig_token) {
      tokens.push_back(std::move(*cdm_sig_token));
    } else {
      std::move(callback).Run({});
      return;
    }
#endif  // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)

    std::move(callback).Run(std::move(tokens));
  }

 private:
  base::FilePath cdm_path_;

  DISALLOW_COPY_AND_ASSIGN(SeatbeltExtensionTokenProviderImpl);
};

}  // namespace

#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS) && defined(OS_MACOSX)

MediaInterfaceProxy::MediaInterfaceProxy(
    RenderFrameHost* render_frame_host,
    media::mojom::InterfaceFactoryRequest request,
    const base::Closure& error_handler)
    : render_frame_host_(render_frame_host),
      binding_(this, std::move(request)) {
  DVLOG(1) << __func__;
  DCHECK(render_frame_host_);
  DCHECK(!error_handler.is_null());

  binding_.set_connection_error_handler(error_handler);

  // |interface_factory_ptr_| and |cdm_factory_map_| will be lazily
  // connected in GetMediaInterfaceFactory() and GetCdmFactory().
}

MediaInterfaceProxy::~MediaInterfaceProxy() {
  DVLOG(1) << __func__;
  DCHECK(thread_checker_.CalledOnValidThread());
}

void MediaInterfaceProxy::CreateAudioDecoder(
    media::mojom::AudioDecoderRequest request) {
  DCHECK(thread_checker_.CalledOnValidThread());
  InterfaceFactory* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateAudioDecoder(std::move(request));
}

void MediaInterfaceProxy::CreateVideoDecoder(
    media::mojom::VideoDecoderRequest request) {
  DCHECK(thread_checker_.CalledOnValidThread());
  InterfaceFactory* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateVideoDecoder(std::move(request));
}

void MediaInterfaceProxy::CreateDefaultRenderer(
    const std::string& audio_device_id,
    media::mojom::RendererRequest request) {
  DCHECK(thread_checker_.CalledOnValidThread());

  InterfaceFactory* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateDefaultRenderer(audio_device_id, std::move(request));
}

#if BUILDFLAG(ENABLE_CAST_RENDERER)
void MediaInterfaceProxy::CreateCastRenderer(
    const base::UnguessableToken& overlay_plane_id,
    media::mojom::RendererRequest request) {
  DCHECK(thread_checker_.CalledOnValidThread());

  InterfaceFactory* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateCastRenderer(overlay_plane_id, std::move(request));
}
#endif

#if defined(OS_ANDROID)
void MediaInterfaceProxy::CreateFlingingRenderer(
    const std::string& presentation_id,
    media::mojom::FlingingRendererClientExtensionPtr client_extension,
    media::mojom::RendererRequest request) {
  DCHECK(thread_checker_.CalledOnValidThread());

  media::MojoRendererService::Create(
      nullptr,
      FlingingRenderer::Create(render_frame_host_, presentation_id,
                               std::move(client_extension)),
      std::move(request));
}

void MediaInterfaceProxy::CreateMediaPlayerRenderer(
    media::mojom::MediaPlayerRendererClientExtensionPtr client_extension_ptr,
    media::mojom::RendererRequest request,
    media::mojom::MediaPlayerRendererExtensionRequest
        renderer_extension_request) {
  DCHECK(thread_checker_.CalledOnValidThread());

  media::MojoRendererService::Create(
      nullptr,
      std::make_unique<MediaPlayerRenderer>(
          render_frame_host_->GetProcess()->GetID(),
          render_frame_host_->GetRoutingID(),
          static_cast<RenderFrameHostImpl*>(render_frame_host_)
              ->delegate()
              ->GetAsWebContents(),
          std::move(renderer_extension_request),
          std::move(client_extension_ptr)),
      std::move(request));
}
#endif

void MediaInterfaceProxy::CreateCdm(
    const std::string& key_system,
    media::mojom::ContentDecryptionModuleRequest request) {
  DCHECK(thread_checker_.CalledOnValidThread());
#if !BUILDFLAG(ENABLE_LIBRARY_CDMS)
  auto* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateCdm(key_system, std::move(request));
#else
  auto* factory = GetCdmFactory(key_system);
  if (factory)
    factory->CreateCdm(key_system, std::move(request));
#endif
}

void MediaInterfaceProxy::CreateDecryptor(
    int cdm_id,
    media::mojom::DecryptorRequest request) {
  InterfaceFactory* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateDecryptor(cdm_id, std::move(request));
}

void MediaInterfaceProxy::CreateCdmProxy(
    const base::Token& cdm_guid,
    media::mojom::CdmProxyRequest request) {
  NOTREACHED() << "The CdmProxy should only be created by a CDM.";
}

service_manager::mojom::InterfaceProviderPtr
MediaInterfaceProxy::GetFrameServices(const base::Token& cdm_guid,
                                      const std::string& cdm_file_system_id) {
  // Register frame services.
  service_manager::mojom::InterfaceProviderPtr interfaces;

  // TODO(xhwang): Replace this InterfaceProvider with a dedicated media host
  // interface. See http://crbug.com/660573
  auto provider = std::make_unique<media::MediaInterfaceProvider>(
      mojo::MakeRequest(&interfaces));

#if BUILDFLAG(ENABLE_MOJO_CDM)
  // TODO(slan): Wrap these into a RenderFrame specific ProvisionFetcher impl.
  provider->registry()->AddInterface(base::BindRepeating(
      &ProvisionFetcherImpl::Create,
      base::RetainedRef(
          BrowserContext::GetDefaultStoragePartition(
              render_frame_host_->GetProcess()->GetBrowserContext())
              ->GetURLLoaderFactoryForBrowserProcess())));

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
  // Only provide CdmStorageImpl when we have a valid |cdm_file_system_id|,
  // which is currently only set for the CdmService (not the MediaService).
  if (!cdm_file_system_id.empty()) {
    provider->registry()->AddInterface(base::BindRepeating(
        &CdmStorageImpl::Create, render_frame_host_, cdm_file_system_id));
  }

  provider->registry()->AddInterface(
      base::BindRepeating(&MediaInterfaceProxy::CreateCdmProxyInternal,
                          base::Unretained(this), cdm_guid));
#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
#endif  // BUILDFLAG(ENABLE_MOJO_CDM)

  GetContentClient()->browser()->ExposeInterfacesToMediaService(
      provider->registry(), render_frame_host_);

  media_registries_.push_back(std::move(provider));

  return interfaces;
}

media::mojom::InterfaceFactory*
MediaInterfaceProxy::GetMediaInterfaceFactory() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (!interface_factory_ptr_)
    ConnectToMediaService();

  return interface_factory_ptr_.get();
}

void MediaInterfaceProxy::ConnectToMediaService() {
  DVLOG(1) << __func__;
  DCHECK(!interface_factory_ptr_);

  media::mojom::MediaServicePtr media_service;

  // TODO(slan): Use the BrowserContext Connector instead. See crbug.com/638950.
  GetSystemConnector()->BindInterface(media::mojom::kMediaServiceName,
                                      &media_service);

  media_service->CreateInterfaceFactory(
      MakeRequest(&interface_factory_ptr_),
      GetFrameServices(base::Token{}, std::string()));

  interface_factory_ptr_.set_connection_error_handler(
      base::BindOnce(&MediaInterfaceProxy::OnMediaServiceConnectionError,
                     base::Unretained(this)));
}

void MediaInterfaceProxy::OnMediaServiceConnectionError() {
  DVLOG(1) << __func__;
  DCHECK(thread_checker_.CalledOnValidThread());

  interface_factory_ptr_.reset();
}

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)

media::mojom::CdmFactory* MediaInterfaceProxy::GetCdmFactory(
    const std::string& key_system) {
  DCHECK(thread_checker_.CalledOnValidThread());

  base::Token cdm_guid;
  base::FilePath cdm_path;
  std::string cdm_file_system_id;

  std::unique_ptr<CdmInfo> cdm_info =
      KeySystemSupportImpl::GetCdmInfoForKeySystem(key_system);
  if (!cdm_info) {
    NOTREACHED() << "No valid CdmInfo for " << key_system;
    return nullptr;
  }
  if (cdm_info->path.empty()) {
    NOTREACHED() << "CDM path for " << key_system << " is empty.";
    return nullptr;
  }
  if (!CdmStorageImpl::IsValidCdmFileSystemId(cdm_info->file_system_id)) {
    NOTREACHED() << "Invalid file system ID " << cdm_info->file_system_id;
    return nullptr;
  }
  cdm_guid = cdm_info->guid;
  cdm_path = cdm_info->path;
  cdm_file_system_id = cdm_info->file_system_id;

  auto found = cdm_factory_map_.find(cdm_guid);
  if (found != cdm_factory_map_.end())
    return found->second.get();

  return ConnectToCdmService(cdm_guid, cdm_path, cdm_file_system_id);
}

media::mojom::CdmFactory* MediaInterfaceProxy::ConnectToCdmService(
    const base::Token& cdm_guid,
    const base::FilePath& cdm_path,
    const std::string& cdm_file_system_id) {
  DVLOG(1) << __func__ << ": cdm_guid = " << cdm_guid.ToString();

  DCHECK(!cdm_factory_map_.count(cdm_guid));

  // TODO(slan): Use the BrowserContext Connector instead. See crbug.com/638950.
  media::mojom::CdmServicePtr cdm_service;
  GetSystemConnector()->BindInterface(
      service_manager::ServiceFilter::ByNameWithId(
          media::mojom::kCdmServiceName, cdm_guid),
      &cdm_service);

#if defined(OS_MACOSX)
  // LoadCdm() should always be called before CreateInterfaceFactory().
  media::mojom::SeatbeltExtensionTokenProviderPtr token_provider_ptr;
  mojo::MakeStrongBinding(
      std::make_unique<SeatbeltExtensionTokenProviderImpl>(cdm_path),
      mojo::MakeRequest(&token_provider_ptr));

  cdm_service->LoadCdm(cdm_path, std::move(token_provider_ptr));
#else
  cdm_service->LoadCdm(cdm_path);
#endif  // defined(OS_MACOSX)

  media::mojom::CdmFactoryPtr cdm_factory_ptr;
  cdm_service->CreateCdmFactory(MakeRequest(&cdm_factory_ptr),
                                GetFrameServices(cdm_guid, cdm_file_system_id));
  cdm_factory_ptr.set_connection_error_handler(
      base::BindOnce(&MediaInterfaceProxy::OnCdmServiceConnectionError,
                     base::Unretained(this), cdm_guid));

  auto* cdm_factory = cdm_factory_ptr.get();
  cdm_factory_map_.emplace(cdm_guid, std::move(cdm_factory_ptr));
  return cdm_factory;
}

void MediaInterfaceProxy::OnCdmServiceConnectionError(
    const base::Token& cdm_guid) {
  DVLOG(1) << __func__;
  DCHECK(thread_checker_.CalledOnValidThread());

  DCHECK(cdm_factory_map_.count(cdm_guid));
  cdm_factory_map_.erase(cdm_guid);
}

void MediaInterfaceProxy::CreateCdmProxyInternal(
    const base::Token& cdm_guid,
    media::mojom::CdmProxyRequest request) {
  DVLOG(1) << __func__;
  DCHECK(thread_checker_.CalledOnValidThread());

  InterfaceFactory* factory = GetMediaInterfaceFactory();
  if (factory)
    factory->CreateCdmProxy(cdm_guid, std::move(request));
}
#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
}  // namespace content
