#ifndef MEDIA_CDM_CDM_ADAPTER_H_
#define MEDIA_CDM_CDM_ADAPTER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_native_library.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/types/pass_key.h"
#include "components/crash/core/common/crash_key.h"
#include "media/base/audio_buffer.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_config.h"
#include "media/base/cdm_context.h"
#include "media/base/cdm_factory.h"
#include "media/base/cdm_promise_adapter.h"
#include "media/base/content_decryption_module.h"
#include "media/base/decryptor.h"
#include "media/base/media_export.h"
#include "media/base/video_aspect_ratio.h"
#include "media/cdm/api/content_decryption_module.h"
#include "media/cdm/cdm_auxiliary_helper.h"
#include "ui/gfx/geometry/size.h"
namespace media {
class AudioFramesImpl;
class CdmWrapper;
class MEDIA_EXPORT CdmAdapter final : public ContentDecryptionModule,
public CdmContext,
public Decryptor,
public cdm::Host_10,
public cdm::Host_11,
public cdm::Host_12 {
public:
using CreateCdmFunc = void* (*)(int cdm_interface_version,
const char* key_system,
uint32_t key_system_size,
GetCdmHostFunc get_cdm_host_func,
void* user_data);
static void Create(
const CdmConfig& cdm_config,
CreateCdmFunc create_cdm_func,
std::unique_ptr<CdmAuxiliaryHelper> helper,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb,
CdmCreatedCB cdm_created_cb,
bool is_debugger_attached);
CdmAdapter(base::PassKey<CdmAdapter>,
const CdmConfig& cdm_config,
CreateCdmFunc create_cdm_func,
std::unique_ptr<CdmAuxiliaryHelper> helper,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb,
bool is_debugger_attached);
CdmAdapter(const CdmAdapter&) = delete;
CdmAdapter& operator=(const CdmAdapter&) = delete;
int GetInterfaceVersion();
void SetServerCertificate(const std::vector<uint8_t>& certificate,
std::unique_ptr<SimpleCdmPromise> promise) final;
void GetStatusForPolicy(HdcpVersion min_hdcp_version,
std::unique_ptr<KeyStatusCdmPromise> promise) final;
void CreateSessionAndGenerateRequest(
CdmSessionType session_type,
EmeInitDataType init_data_type,
const std::vector<uint8_t>& init_data,
std::unique_ptr<NewSessionCdmPromise> promise) final;
void LoadSession(CdmSessionType session_type,
const std::string& session_id,
std::unique_ptr<NewSessionCdmPromise> promise) final;
void UpdateSession(const std::string& session_id,
const std::vector<uint8_t>& response,
std::unique_ptr<SimpleCdmPromise> promise) final;
void CloseSession(const std::string& session_id,
std::unique_ptr<SimpleCdmPromise> promise) final;
void RemoveSession(const std::string& session_id,
std::unique_ptr<SimpleCdmPromise> promise) final;
CdmContext* GetCdmContext() final;
std::unique_ptr<CallbackRegistration> RegisterEventCB(EventCB event_cb) final;
Decryptor* GetDecryptor() final;
std::optional<base::UnguessableToken> GetCdmId() const final;
void Decrypt(StreamType stream_type,
scoped_refptr<DecoderBuffer> encrypted,
DecryptCB decrypt_cb) final;
void CancelDecrypt(StreamType stream_type) final;
void InitializeAudioDecoder(const AudioDecoderConfig& config,
DecoderInitCB init_cb) final;
void InitializeVideoDecoder(const VideoDecoderConfig& config,
DecoderInitCB init_cb) final;
void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
AudioDecodeCB audio_decode_cb) final;
void DecryptAndDecodeVideo(scoped_refptr<DecoderBuffer> encrypted,
VideoDecodeCB video_decode_cb) final;
void ResetDecoder(StreamType stream_type) final;
void DeinitializeDecoder(StreamType stream_type) final;
void OnResolveKeyStatusPromise(uint32_t promise_id,
cdm::KeyStatus_2 key_status) override;
void OnSessionKeysChange(const char* session_id,
uint32_t session_id_size,
bool has_additional_usable_key,
const cdm::KeyInformation_2* keys_info,
uint32_t keys_info_count) override;
void OnResolveKeyStatusPromise(uint32_t promise_id,
cdm::KeyStatus key_status) override;
void OnSessionKeysChange(const char* session_id,
uint32_t session_id_size,
bool has_additional_usable_key,
const cdm::KeyInformation* keys_info,
uint32_t keys_info_count) override;
cdm::Buffer* Allocate(uint32_t capacity) override;
void SetTimer(int64_t delay_ms, void* context) override;
cdm::Time GetCurrentWallTime() override;
void OnInitialized(bool success) override;
void OnResolveNewSessionPromise(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) override;
void OnResolvePromise(uint32_t promise_id) override;
void OnRejectPromise(uint32_t promise_id,
cdm::Exception exception,
uint32_t system_code,
const char* error_message,
uint32_t error_message_size) override;
void OnSessionMessage(const char* session_id,
uint32_t session_id_size,
cdm::MessageType message_type,
const char* message,
uint32_t message_size) override;
void OnExpirationChange(const char* session_id,
uint32_t session_id_size,
cdm::Time new_expiry_time) override;
void OnSessionClosed(const char* session_id,
uint32_t session_id_size) override;
void SendPlatformChallenge(const char* service_id,
uint32_t service_id_size,
const char* challenge,
uint32_t challenge_size) override;
void EnableOutputProtection(uint32_t desired_protection_mask) override;
void QueryOutputProtectionStatus() override;
void OnDeferredInitializationDone(cdm::StreamType stream_type,
cdm::Status decoder_status) override;
cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) override;
void RequestStorageId(uint32_t version) override;
void ReportMetrics(cdm::MetricName metric_name, uint64_t value) override;
private:
FRIEND_TEST_ALL_PREFIXES(CdmAdapterTestWithMockCdm, RecordUMA);
~CdmAdapter() final;
void Initialize(std::unique_ptr<media::SimpleCdmPromise> promise);
CdmWrapper* CreateCdmInstance(const std::string& key_system);
void TimerExpired(void* context);
bool AudioFramesDataToAudioFrames(
std::unique_ptr<AudioFramesImpl> audio_frames,
Decryptor::AudioFrames* result_frames);
void OnChallengePlatformDone(bool success,
const std::string& signed_data,
const std::string& signed_data_signature,
const std::string& platform_key_certificate);
void OnStorageIdObtained(uint32_t version,
const std::vector<uint8_t>& storage_id);
void OnEnableOutputProtectionDone(bool success);
void OnQueryOutputProtectionStatusDone(bool success,
uint32_t link_mask,
uint32_t protection_mask);
void ReportOutputProtectionQuery();
void ReportOutputProtectionQueryResult(uint32_t link_mask,
uint32_t protection_mask);
void OnFileRead(int file_size_bytes);
void SetFrameCountForTesting(uint64_t count) { frames_processed_ = count; }
const CdmConfig cdm_config_;
CreateCdmFunc create_cdm_func_;
std::unique_ptr<CdmAuxiliaryHelper> helper_;
SessionMessageCB session_message_cb_;
SessionClosedCB session_closed_cb_;
SessionKeysChangeCB session_keys_change_cb_;
SessionExpirationUpdateCB session_expiration_update_cb_;
const url::Origin cdm_origin_;
crash_reporter::ScopedCrashKeyString scoped_crash_key_;
crash_reporter::ScopedCrashKeyString debugger_attached_crash_key_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<AudioBufferMemoryPool> pool_;
uint32_t init_promise_id_ = CdmPromiseAdapter::kInvalidPromiseId;
DecoderInitCB audio_init_cb_;
DecoderInitCB video_init_cb_;
CallbackRegistry<EventCB::RunType> event_callbacks_;
int audio_samples_per_second_ = 0;
ChannelLayout audio_channel_layout_ = CHANNEL_LAYOUT_NONE;
VideoAspectRatio aspect_ratio_;
bool is_video_encrypted_ = false;
bool uma_for_output_protection_query_reported_ = false;
bool uma_for_output_protection_positive_result_reported_ = false;
uint64_t frames_processed_ = 0;
int last_read_file_size_kb_ = 0;
bool file_size_uma_reported_ = false;
CdmMetricsData cdm_metrics_data_;
CdmPromiseAdapter cdm_promise_adapter_;
std::unique_ptr<CdmWrapper> cdm_;
base::WeakPtrFactory<CdmAdapter> weak_factory_{this};
};
}
#endif