blob: f790358e21045cab4663dcb4161694c7f95dca36 [file] [log] [blame]
// Copyright 2016 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_MEDIA_MEDIA_INTERFACE_PROXY_H_
#define CONTENT_BROWSER_MEDIA_MEDIA_INTERFACE_PROXY_H_
#include <map>
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "content/browser/media/media_interface_factory_holder.h"
#include "content/public/browser/document_user_data.h"
#include "content/public/common/cdm_info.h"
#include "media/cdm/cdm_type.h"
#include "media/media_buildflags.h"
#include "media/mojo/buildflags.h"
#include "media/mojo/mojom/content_decryption_module.mojom.h"
#include "media/mojo/mojom/decryptor.mojom.h"
#include "media/mojo/mojom/interface_factory.mojom.h"
#include "media/mojo/services/media_service.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 "services/service_manager/public/mojom/interface_provider.mojom.h"
#if BUILDFLAG(IS_WIN)
#include "base/task/sequenced_task_runner.h"
#include "media/mojo/mojom/media_foundation_service.mojom.h"
#endif
namespace content {
class RenderFrameHost;
// This implements the media::mojom::InterfaceFactory interface for a
// RenderFrameHostImpl to help create remote media components in different
// processes.
class MediaInterfaceProxy final : public DocumentUserData<MediaInterfaceProxy>,
public media::mojom::InterfaceFactory {
public:
~MediaInterfaceProxy() final;
void Bind(mojo::PendingReceiver<media::mojom::InterfaceFactory> receiver);
// media::mojom::InterfaceFactory implementation.
void CreateAudioDecoder(
mojo::PendingReceiver<media::mojom::AudioDecoder> receiver) final;
void CreateVideoDecoder(
mojo::PendingReceiver<media::mojom::VideoDecoder> receiver,
mojo::PendingRemote<media::mojom::VideoDecoder> dst_video_decoder) final;
#if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
void CreateVideoDecoderWithTracker(
mojo::PendingReceiver<media::mojom::VideoDecoder> receiver,
mojo::PendingRemote<media::mojom::VideoDecoderTracker> tracker) final;
#endif // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
void CreateAudioEncoder(
mojo::PendingReceiver<media::mojom::AudioEncoder> receiver) final;
void CreateDefaultRenderer(
const std::string& audio_device_id,
mojo::PendingReceiver<media::mojom::Renderer> receiver) final;
#if BUILDFLAG(ENABLE_CAST_RENDERER)
void CreateCastRenderer(
const base::UnguessableToken& overlay_plane_id,
mojo::PendingReceiver<media::mojom::Renderer> receiver) final;
#endif
#if BUILDFLAG(IS_ANDROID)
void CreateFlingingRenderer(
const std::string& presentation_id,
mojo::PendingRemote<media::mojom::FlingingRendererClientExtension>
client_extension,
mojo::PendingReceiver<media::mojom::Renderer> receiver) final;
#endif // BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_WIN)
void CreateMediaFoundationRenderer(
mojo::PendingRemote<media::mojom::MediaLog> media_log_remote,
mojo::PendingReceiver<media::mojom::Renderer> receiver,
mojo::PendingReceiver<media::mojom::MediaFoundationRendererExtension>
renderer_extension_receiver,
mojo::PendingRemote<media::mojom::MediaFoundationRendererClientExtension>
client_extension_remote) final;
#endif // BUILDFLAG(IS_WIN)
void CreateCdm(const media::CdmConfig& cdm_config,
CreateCdmCallback create_cdm_cb) final;
private:
friend class DocumentUserData<MediaInterfaceProxy>;
explicit MediaInterfaceProxy(RenderFrameHost* rfh);
DOCUMENT_USER_DATA_KEY_DECL();
// Gets services provided by the browser (at RenderFrameHost level) to the
// mojo media (or CDM) service running remotely. |cdm_type| is used to
// register the appropriate CdmStorage interface needed by the CDM. If
// |cdm_type| is empty, CdmStorage interface won't be available.
mojo::PendingRemote<media::mojom::FrameInterfaceFactory> GetFrameServices(
const media::CdmType& cdm_type);
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// Gets a CdmFactory pointer for |key_system|. Returns null if unexpected
// error happened.
media::mojom::CdmFactory* GetCdmFactory(const std::string& key_system);
// Connects to the CDM service associated with |cdm_info|, adds the new
// CdmFactoryPtr to the |cdm_factory_map_|, and returns the newly created
// CdmFactory pointer. Returns nullptr if unexpected error happened.
media::mojom::CdmFactory* ConnectToCdmService(const CdmInfo& cdm_info);
// Callback for connection error from the CdmFactoryPtr in the
// |cdm_factory_map_| associated with |cdm_type|.
void OnCdmServiceConnectionError(const media::CdmType& cdm_type);
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if BUILDFLAG(IS_CHROMEOS)
// Callback for for Chrome OS CDM creation to facilitate falling back to the
// library CDM if the daemon is unavailable or other settings prevent usage of
// it.
void OnChromeOsCdmCreated(
const media::CdmConfig& cdm_config,
CreateCdmCallback callback,
mojo::PendingRemote<media::mojom::ContentDecryptionModule> receiver,
media::mojom::CdmContextPtr cdm_context,
media::CreateCdmStatus status);
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_WIN)
// Gets the InterfaceFactory from MediaFoundationService. May return null if
// MediaFoundationService cannot be used or connection failed.
InterfaceFactory* GetMediaFoundationServiceInterfaceFactory(
const base::FilePath& cdm_path);
void ConnectToMediaFoundationService(const base::FilePath& cdm_path);
bool ShouldUseMediaFoundationServiceForCdm(
const media::CdmConfig& cdm_config);
mojo::Remote<media::mojom::InterfaceFactory> mf_interface_factory_remote_;
#endif // BUILDFLAG(IS_WIN)
mojo::UniqueReceiverSet<media::mojom::FrameInterfaceFactory> frame_factories_;
// InterfacePtr to the remote InterfaceFactory implementation in the Media
// Service hosted in the process specified by the "mojo_media_host" gn
// argument. Available options are browser or GPU processes.
std::unique_ptr<MediaInterfaceFactoryHolder> media_interface_factory_ptr_;
// An interface factory bound to a secondary instance of the Media Service,
// initialized only if the embedder provides an implementation of
// |ContentBrowserClient::RunSecondaryMediaService()|. This is used to bind to
// CDM interfaces as well as Cast-specific Renderer interfaces when available.
std::unique_ptr<MediaInterfaceFactoryHolder> secondary_interface_factory_;
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// CDM type to CDM InterfaceFactory Remotes mapping, where the
// InterfaceFactory instances live in the standalone CdmService instances.
// These map entries effectively own the corresponding CDM processes.
// Only using the CDM type to identify the CdmFactory is sufficient because
// the BrowserContext and Site URL should never change.
std::map<media::CdmType, mojo::Remote<media::mojom::CdmFactory>>
cdm_factory_map_;
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
base::ThreadChecker thread_checker_;
// Receivers for incoming interface requests from the the RenderFrameImpl.
mojo::ReceiverSet<media::mojom::InterfaceFactory> receivers_;
base::WeakPtrFactory<MediaInterfaceProxy> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_MEDIA_INTERFACE_PROXY_H_