1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
media / cdm / library_cdm / clear_key_cdm / clear_key_cdm.h [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_CDM_LIBRARY_CDM_CLEAR_KEY_CDM_CLEAR_KEY_CDM_H_
#define MEDIA_CDM_LIBRARY_CDM_CLEAR_KEY_CDM_CLEAR_KEY_CDM_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "media/base/cdm_key_information.h"
#include "media/base/cdm_promise.h"
#include "media/cdm/api/content_decryption_module.h"
#include "media/cdm/library_cdm/clear_key_cdm/clear_key_persistent_session_cdm.h"
namespace media {
class CdmHostProxy;
class CdmVideoDecoder;
class DecoderBuffer;
class FFmpegCdmAudioDecoder;
class FileIOTestRunner;
const int64_t kInitialTimerDelayMs = 200;
// Clear key implementation of the cdm::ContentDecryptionModule interfaces.
class ClearKeyCdm : public cdm::ContentDecryptionModule_10,
public cdm::ContentDecryptionModule_11,
public cdm::ContentDecryptionModule_12 {
public:
template <typename HostInterface>
ClearKeyCdm(HostInterface* host, const std::string& key_system);
ClearKeyCdm(const ClearKeyCdm&) = delete;
ClearKeyCdm& operator=(const ClearKeyCdm&) = delete;
~ClearKeyCdm() override;
// cdm::ContentDecryptionModule_10 and cdm::ContentDecryptionModule_11
// implementation.
cdm::Status InitializeVideoDecoder(
const cdm::VideoDecoderConfig_2& video_decoder_config) override;
cdm::Status DecryptAndDecodeFrame(const cdm::InputBuffer_2& encrypted_buffer,
cdm::VideoFrame* video_frame) override;
// cdm::ContentDecryptionModule_12 implementation.
cdm::Status InitializeVideoDecoder(
const cdm::VideoDecoderConfig_3& video_decoder_config) override;
cdm::Status DecryptAndDecodeFrame(const cdm::InputBuffer_2& encrypted_buffer,
cdm::VideoFrame_2* video_frame) override;
// Common cdm::ContentDecryptionModule_10/11 implementation.
void Initialize(bool allow_distinctive_identifier,
bool allow_persistent_state,
bool use_hw_secure_codecs) override;
cdm::Status InitializeAudioDecoder(
const cdm::AudioDecoderConfig_2& audio_decoder_config) override;
cdm::Status Decrypt(const cdm::InputBuffer_2& encrypted_buffer,
cdm::DecryptedBlock* decrypted_block) override;
cdm::Status DecryptAndDecodeSamples(
const cdm::InputBuffer_2& encrypted_buffer,
cdm::AudioFrames* audio_frames) override;
// Common cdm::ContentDecryptionModule_* implementation.
void GetStatusForPolicy(uint32_t promise_id,
const cdm::Policy& policy) override;
void CreateSessionAndGenerateRequest(uint32_t promise_id,
cdm::SessionType session_type,
cdm::InitDataType init_data_type,
const uint8_t* init_data,
uint32_t init_data_size) override;
void LoadSession(uint32_t promise_id,
cdm::SessionType session_type,
const char* session_id,
uint32_t session_id_length) override;
void UpdateSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_length,
const uint8_t* response,
uint32_t response_size) override;
void CloseSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_length) override;
void RemoveSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_length) override;
void SetServerCertificate(uint32_t promise_id,
const uint8_t* server_certificate_data,
uint32_t server_certificate_data_size) override;
void TimerExpired(void* context) override;
void DeinitializeDecoder(cdm::StreamType decoder_type) override;
void ResetDecoder(cdm::StreamType decoder_type) override;
void Destroy() override;
void OnPlatformChallengeResponse(
const cdm::PlatformChallengeResponse& response) override;
void OnQueryOutputProtectionStatus(cdm::QueryResult result,
uint32_t link_mask,
uint32_t output_protection_mask) override;
void OnStorageId(uint32_t version,
const uint8_t* storage_id,
uint32_t storage_id_size) override;
private:
// ContentDecryptionModule callbacks.
void OnSessionMessage(const std::string& session_id,
CdmMessageType message_type,
const std::vector<uint8_t>& message);
void OnSessionKeysChange(const std::string& session_id,
bool has_additional_usable_key,
CdmKeysInfo keys_info);
void OnSessionClosed(const std::string& session_id,
CdmSessionClosedReason reason);
void OnSessionExpirationUpdate(const std::string& session_id,
base::Time new_expiry_time);
// Handle the success/failure of a promise. These methods are responsible for
// calling |cdm_host_proxy_| to resolve or reject the promise.
void OnSessionCreated(uint32_t promise_id, const std::string& session_id);
void OnPromiseResolved(uint32_t promise_id);
void OnPromiseFailed(uint32_t promise_id,
CdmPromise::Exception exception_code,
uint32_t system_code,
const std::string& error_message);
// After updating a session send a 'expirationChange' event.
void OnUpdateSuccess(uint32_t promise_id, const std::string& session_id);
// Prepares next renewal message and sets a timer for it.
void ScheduleNextTimer();
// Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|.
// Returns cdm::kSuccess if decryption succeeded. The decrypted result is
// put in |decrypted_buffer|. If |encrypted_buffer| is empty, the
// |decrypted_buffer| is set to an empty (EOS) buffer.
// Returns cdm::kNoKey if no decryption key was available. In this case
// |decrypted_buffer| should be ignored by the caller.
// Returns cdm::kDecryptError if any decryption error occurred. In this case
// |decrypted_buffer| should be ignored by the caller.
cdm::Status DecryptToMediaDecoderBuffer(
const cdm::InputBuffer_2& encrypted_buffer,
scoped_refptr<DecoderBuffer>* decrypted_buffer);
void OnUnitTestComplete(bool success);
void StartFileIOTest();
void OnFileIOTestComplete(bool success);
void StartOutputProtectionTest();
void StartPlatformVerificationTest();
void ReportVerifyCdmHostTestResult();
void StartStorageIdTest();
int host_interface_version_ = 0;
std::unique_ptr<CdmHostProxy> cdm_host_proxy_;
scoped_refptr<ContentDecryptionModule> cdm_;
const std::string key_system_;
bool allow_persistent_state_ = false;
std::string last_session_id_;
std::string next_renewal_message_;
// Timer delay in milliseconds for the next cdm_host_proxy_->SetTimer() call.
int64_t timer_delay_ms_ = kInitialTimerDelayMs;
// Indicates whether a timer has been set to prevent multiple timers from
// running.
bool has_set_timer_ = false;
bool has_sent_individualization_request_ = false;
#if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
std::unique_ptr<FFmpegCdmAudioDecoder> audio_decoder_;
#endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
std::unique_ptr<CdmVideoDecoder> video_decoder_;
std::unique_ptr<FileIOTestRunner> file_io_test_runner_;
bool is_running_output_protection_test_ = false;
bool is_running_platform_verification_test_ = false;
bool is_running_storage_id_test_ = false;
};
} // namespace media
#endif // MEDIA_CDM_LIBRARY_CDM_CLEAR_KEY_CDM_CLEAR_KEY_CDM_H_