1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_
6 #define MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/synchronization/lock.h"
16 #include "media/cdm/aes_decryptor.h"
17 #include "media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h"
19 // Enable this to use the fake decoder for testing.
20 // TODO(tomfinegan): Move fake audio decoder into a separate class.
22 #define CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
28 class FileIOTestRunner
;
29 class CdmVideoDecoder
;
31 class FFmpegCdmAudioDecoder
;
33 // Clear key implementation of the cdm::ContentDecryptionModule interface.
34 class ClearKeyCdm
: public ClearKeyCdmInterface
{
36 ClearKeyCdm(Host
* host
, const std::string
& key_system
, const GURL
& origin
);
37 ~ClearKeyCdm() override
;
39 // ContentDecryptionModule implementation.
40 void Initialize(bool allow_distinctive_identifier
,
41 bool allow_persistent_state
) override
;
42 void CreateSessionAndGenerateRequest(uint32 promise_id
,
43 cdm::SessionType session_type
,
44 cdm::InitDataType init_data_type
,
45 const uint8
* init_data
,
46 uint32 init_data_size
) override
;
47 void LoadSession(uint32 promise_id
,
48 cdm::SessionType session_type
,
49 const char* session_id
,
50 uint32_t session_id_length
) override
;
51 void UpdateSession(uint32 promise_id
,
52 const char* session_id
,
53 uint32_t session_id_length
,
54 const uint8
* response
,
55 uint32 response_size
) override
;
56 void CloseSession(uint32 promise_id
,
57 const char* session_id
,
58 uint32_t session_id_length
) override
;
59 void RemoveSession(uint32 promise_id
,
60 const char* session_id
,
61 uint32_t session_id_length
) override
;
62 void SetServerCertificate(uint32 promise_id
,
63 const uint8_t* server_certificate_data
,
64 uint32_t server_certificate_data_size
) override
;
65 void TimerExpired(void* context
) override
;
66 cdm::Status
Decrypt(const cdm::InputBuffer
& encrypted_buffer
,
67 cdm::DecryptedBlock
* decrypted_block
) override
;
68 cdm::Status
InitializeAudioDecoder(
69 const cdm::AudioDecoderConfig
& audio_decoder_config
) override
;
70 cdm::Status
InitializeVideoDecoder(
71 const cdm::VideoDecoderConfig
& video_decoder_config
) override
;
72 void DeinitializeDecoder(cdm::StreamType decoder_type
) override
;
73 void ResetDecoder(cdm::StreamType decoder_type
) override
;
74 cdm::Status
DecryptAndDecodeFrame(const cdm::InputBuffer
& encrypted_buffer
,
75 cdm::VideoFrame
* video_frame
) override
;
76 cdm::Status
DecryptAndDecodeSamples(const cdm::InputBuffer
& encrypted_buffer
,
77 cdm::AudioFrames
* audio_frames
) override
;
78 void Destroy() override
;
79 void OnPlatformChallengeResponse(
80 const cdm::PlatformChallengeResponse
& response
) override
;
81 void OnQueryOutputProtectionStatus(cdm::QueryResult result
,
83 uint32_t output_protection_mask
) override
;
86 // Emulates a session stored for |session_id_for_emulated_loadsession_|. This
87 // is necessary since aes_decryptor.cc does not support storing sessions.
88 void LoadLoadableSession();
89 void OnLoadSessionUpdated();
91 // ContentDecryptionModule callbacks.
92 void OnSessionMessage(const std::string
& session_id
,
93 MediaKeys::MessageType message_type
,
94 const std::vector
<uint8
>& message
,
95 const GURL
& legacy_destination_url
);
96 void OnSessionKeysChange(const std::string
& session_id
,
97 bool has_additional_usable_key
,
98 CdmKeysInfo keys_info
);
99 void OnSessionClosed(const std::string
& session_id
);
101 // Handle the success/failure of a promise. These methods are responsible for
102 // calling |host_| to resolve or reject the promise.
103 void OnSessionCreated(uint32 promise_id
, const std::string
& session_id
);
104 void OnSessionLoaded(uint32 promise_id
, const std::string
& session_id
);
105 void OnPromiseResolved(uint32 promise_id
);
106 void OnPromiseFailed(uint32 promise_id
,
107 MediaKeys::Exception exception_code
,
109 const std::string
& error_message
);
111 // Prepares next renewal message and sets a timer for it.
112 void ScheduleNextRenewal();
114 // Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|.
115 // Returns cdm::kSuccess if decryption succeeded. The decrypted result is
116 // put in |decrypted_buffer|. If |encrypted_buffer| is empty, the
117 // |decrypted_buffer| is set to an empty (EOS) buffer.
118 // Returns cdm::kNoKey if no decryption key was available. In this case
119 // |decrypted_buffer| should be ignored by the caller.
120 // Returns cdm::kDecryptError if any decryption error occurred. In this case
121 // |decrypted_buffer| should be ignored by the caller.
122 cdm::Status
DecryptToMediaDecoderBuffer(
123 const cdm::InputBuffer
& encrypted_buffer
,
124 scoped_refptr
<DecoderBuffer
>* decrypted_buffer
);
126 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
127 int64
CurrentTimeStampInMicroseconds() const;
129 // Generates fake video frames with |duration_in_microseconds|.
130 // Returns the number of samples generated in the |audio_frames|.
131 int GenerateFakeAudioFramesFromDuration(int64 duration_in_microseconds
,
132 cdm::AudioFrames
* audio_frames
) const;
134 // Generates fake video frames given |input_timestamp|.
135 // Returns cdm::kSuccess if any audio frame is successfully generated.
136 cdm::Status
GenerateFakeAudioFrames(int64 timestamp_in_microseconds
,
137 cdm::AudioFrames
* audio_frames
);
138 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
140 void StartFileIOTest();
142 // Callback for CDM File IO test.
143 void OnFileIOTestComplete(bool success
);
145 // Keep track of the last session created.
146 void SetSessionId(const std::string
& session_id
);
148 AesDecryptor decryptor_
;
150 ClearKeyCdmHost
* host_
;
152 const std::string key_system_
;
154 std::string last_session_id_
;
155 std::string next_renewal_message_
;
157 // In order to simulate LoadSession(), CreateSession() and then
158 // UpdateSession() will be called to create a session with known keys.
159 // |session_id_for_emulated_loadsession_| is used to keep track of the
160 // session_id allocated by aes_decryptor, as the session_id will be returned
161 // as |kLoadableSessionId|. Future requests for this simulated session
162 // need to use |session_id_for_emulated_loadsession_| for all calls
164 // |promise_id_for_emulated_loadsession_| is used to keep track of the
165 // original LoadSession() promise, as it is not resolved until the
166 // UpdateSession() call succeeds.
167 // |has_received_keys_change_event_for_emulated_loadsession_| is used to keep
168 // track of whether a keyschange event has been received for the loadable
169 // session in case it happens before the emulated session is fully created.
170 // |keys_info_for_emulated_loadsession_| is used to keep track of the list
171 // of keys provided as a result of calling UpdateSession() if it happens,
172 // since they can't be forwarded on until the LoadSession() promise is
174 // TODO(xhwang): Extract testing code from main implementation.
175 // See http://crbug.com/341751
176 // TODO(jrummell): Once the order of events is fixed,
177 // |has_received_keys_change_event_for_emulated_loadsession_| should be
178 // removed (the event should have either happened or never happened).
179 // |keys_info_for_emulated_loadsession_| may also go away if the event is
180 // not expected. See http://crbug.com/448225
181 std::string session_id_for_emulated_loadsession_
;
182 uint32_t promise_id_for_emulated_loadsession_
;
183 bool has_received_keys_change_event_for_emulated_loadsession_
;
184 CdmKeysInfo keys_info_for_emulated_loadsession_
;
186 // Timer delay in milliseconds for the next host_->SetTimer() call.
187 int64 timer_delay_ms_
;
189 // Indicates whether a renewal timer has been set to prevent multiple timers
191 bool renewal_timer_set_
;
193 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
195 int bits_per_channel_
;
196 int samples_per_second_
;
197 int64 output_timestamp_base_in_microseconds_
;
198 int total_samples_generated_
;
199 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
201 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
202 scoped_ptr
<FFmpegCdmAudioDecoder
> audio_decoder_
;
203 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
205 scoped_ptr
<CdmVideoDecoder
> video_decoder_
;
207 scoped_ptr
<FileIOTestRunner
> file_io_test_runner_
;
209 DISALLOW_COPY_AND_ASSIGN(ClearKeyCdm
);
214 #endif // MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_