1 // Copyright (c) 2012 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.
9 #include "base/callback_helpers.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/base/decoder_buffer.h"
12 #include "media/base/decrypt_config.h"
13 #include "media/base/gmock_callback_support.h"
14 #include "media/base/mock_filters.h"
15 #include "media/base/test_helpers.h"
16 #include "media/filters/decrypting_demuxer_stream.h"
17 #include "testing/gmock/include/gmock/gmock.h"
20 using ::testing::IsNull;
21 using ::testing::Return;
22 using ::testing::SaveArg;
23 using ::testing::StrictMock;
27 static const int kFakeBufferSize = 16;
28 static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
29 static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
31 // Create a fake non-empty buffer in an encrypted stream. When |is_clear| is
32 // ture, the buffer is not encrypted (signaled by an empty IV).
33 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedStreamBuffer(
35 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(kFakeBufferSize));
36 std::string iv = is_clear ? std::string() :
37 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv));
38 buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(new DecryptConfig(
39 std::string(reinterpret_cast<const char*>(kFakeKeyId),
40 arraysize(kFakeKeyId)),
41 iv, std::vector<SubsampleEntry>())));
45 // Use anonymous namespace here to prevent the actions to be defined multiple
46 // times across multiple test files. Sadly we can't use static for them.
49 ACTION_P(ReturnBuffer, buffer) {
50 arg0.Run(buffer.get() ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer);
53 // Sets the |decryptor| if the DecryptorReadyCB (arg0) is not null. Sets
54 // |is_decryptor_set| to true if a non-NULL |decryptor| has been set through the
56 ACTION_P3(SetDecryptorIfNotNull, decryptor, done_cb, is_decryptor_set) {
58 arg0.Run(decryptor, done_cb);
60 *is_decryptor_set = !arg0.is_null() && decryptor;
63 ACTION_P2(ResetAndRunCallback, callback, param) {
64 base::ResetAndReturn(callback).Run(param);
67 MATCHER(IsEndOfStream, "end of stream") {
68 return arg->end_of_stream();
73 class DecryptingDemuxerStreamTest : public testing::Test {
75 DecryptingDemuxerStreamTest()
76 : demuxer_stream_(new DecryptingDemuxerStream(
77 message_loop_.message_loop_proxy(),
79 &DecryptingDemuxerStreamTest::RequestDecryptorNotification,
80 base::Unretained(this)))),
81 decryptor_(new StrictMock<MockDecryptor>()),
82 is_decryptor_set_(false),
84 new StrictMock<MockDemuxerStream>(DemuxerStream::AUDIO)),
86 new StrictMock<MockDemuxerStream>(DemuxerStream::VIDEO)),
87 clear_buffer_(CreateFakeEncryptedStreamBuffer(true)),
88 encrypted_buffer_(CreateFakeEncryptedStreamBuffer(false)),
89 decrypted_buffer_(new DecoderBuffer(kFakeBufferSize)) {
92 virtual ~DecryptingDemuxerStreamTest() {
93 if (is_decryptor_set_)
94 EXPECT_CALL(*decryptor_, CancelDecrypt(_));
95 demuxer_stream_.reset();
96 message_loop_.RunUntilIdle();
99 void InitializeAudioAndExpectStatus(const AudioDecoderConfig& config,
100 PipelineStatus status) {
101 input_audio_stream_->set_audio_decoder_config(config);
102 demuxer_stream_->Initialize(input_audio_stream_.get(),
103 NewExpectedStatusCB(status));
104 message_loop_.RunUntilIdle();
107 void InitializeVideoAndExpectStatus(const VideoDecoderConfig& config,
108 PipelineStatus status) {
109 input_video_stream_->set_video_decoder_config(config);
110 demuxer_stream_->Initialize(input_video_stream_.get(),
111 NewExpectedStatusCB(status));
112 message_loop_.RunUntilIdle();
115 void ExpectDecryptorNotification(Decryptor* decryptor, bool expected_result) {
116 EXPECT_CALL(*this, RequestDecryptorNotification(_))
117 .WillOnce(SetDecryptorIfNotNull(
119 base::Bind(&DecryptingDemuxerStreamTest::DecryptorSet,
120 base::Unretained(this)),
121 &is_decryptor_set_));
122 EXPECT_CALL(*this, DecryptorSet(expected_result));
125 // The following functions are used to test stream-type-neutral logic in
126 // DecryptingDemuxerStream. Therefore, we don't specify audio or video in the
127 // function names. But for testing purpose, they all use an audio input
131 ExpectDecryptorNotification(decryptor_.get(), true);
132 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
133 .WillOnce(SaveArg<1>(&key_added_cb_));
135 AudioDecoderConfig input_config(
136 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
138 InitializeAudioAndExpectStatus(input_config, PIPELINE_OK);
140 const AudioDecoderConfig& output_config =
141 demuxer_stream_->audio_decoder_config();
142 EXPECT_EQ(DemuxerStream::AUDIO, demuxer_stream_->type());
143 EXPECT_FALSE(output_config.is_encrypted());
144 EXPECT_EQ(input_config.bits_per_channel(),
145 output_config.bits_per_channel());
146 EXPECT_EQ(input_config.channel_layout(), output_config.channel_layout());
147 EXPECT_EQ(input_config.sample_format(), output_config.sample_format());
148 EXPECT_EQ(input_config.samples_per_second(),
149 output_config.samples_per_second());
152 void ReadAndExpectBufferReadyWith(
153 DemuxerStream::Status status,
154 const scoped_refptr<DecoderBuffer>& decrypted_buffer) {
155 if (status != DemuxerStream::kOk)
156 EXPECT_CALL(*this, BufferReady(status, IsNull()));
157 else if (decrypted_buffer->end_of_stream())
158 EXPECT_CALL(*this, BufferReady(status, IsEndOfStream()));
160 EXPECT_CALL(*this, BufferReady(status, decrypted_buffer));
162 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
163 base::Unretained(this)));
164 message_loop_.RunUntilIdle();
167 void EnterClearReadingState() {
168 EXPECT_TRUE(clear_buffer_->decrypt_config());
169 EXPECT_CALL(*input_audio_stream_, Read(_))
170 .WillOnce(ReturnBuffer(clear_buffer_));
172 // For clearbuffer, decryptor->Decrypt() will not be called.
174 scoped_refptr<DecoderBuffer> decrypted_buffer;
175 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, _))
176 .WillOnce(SaveArg<1>(&decrypted_buffer));
177 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
178 base::Unretained(this)));
179 message_loop_.RunUntilIdle();
181 EXPECT_FALSE(decrypted_buffer->decrypt_config());
184 // Sets up expectations and actions to put DecryptingDemuxerStream in an
185 // active normal reading state.
186 void EnterNormalReadingState() {
187 EXPECT_CALL(*input_audio_stream_, Read(_))
188 .WillOnce(ReturnBuffer(encrypted_buffer_));
189 EXPECT_CALL(*decryptor_, Decrypt(_, _, _))
190 .WillOnce(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_));
192 ReadAndExpectBufferReadyWith(DemuxerStream::kOk, decrypted_buffer_);
195 // Make the read callback pending by saving and not firing it.
196 void EnterPendingReadState() {
197 EXPECT_TRUE(pending_demuxer_read_cb_.is_null());
198 EXPECT_CALL(*input_audio_stream_, Read(_))
199 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_));
200 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
201 base::Unretained(this)));
202 message_loop_.RunUntilIdle();
203 // Make sure the Read() triggers a Read() on the input demuxer stream.
204 EXPECT_FALSE(pending_demuxer_read_cb_.is_null());
207 // Make the decrypt callback pending by saving and not firing it.
208 void EnterPendingDecryptState() {
209 EXPECT_TRUE(pending_decrypt_cb_.is_null());
210 EXPECT_CALL(*input_audio_stream_, Read(_))
211 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
212 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
213 .WillOnce(SaveArg<2>(&pending_decrypt_cb_));
215 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
216 base::Unretained(this)));
217 message_loop_.RunUntilIdle();
218 // Make sure Read() triggers a Decrypt() on the decryptor.
219 EXPECT_FALSE(pending_decrypt_cb_.is_null());
222 void EnterWaitingForKeyState() {
223 EXPECT_CALL(*input_audio_stream_, Read(_))
224 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
225 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
226 .WillRepeatedly(RunCallback<2>(Decryptor::kNoKey,
227 scoped_refptr<DecoderBuffer>()));
228 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
229 base::Unretained(this)));
230 message_loop_.RunUntilIdle();
233 void AbortPendingDecryptCB() {
234 if (!pending_decrypt_cb_.is_null()) {
235 base::ResetAndReturn(&pending_decrypt_cb_).Run(Decryptor::kSuccess, NULL);
239 void SatisfyPendingDemuxerReadCB(DemuxerStream::Status status) {
240 scoped_refptr<DecoderBuffer> buffer =
241 (status == DemuxerStream::kOk) ? encrypted_buffer_ : NULL;
242 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(status, buffer);
246 if (is_decryptor_set_) {
247 EXPECT_CALL(*decryptor_, CancelDecrypt(Decryptor::kAudio))
248 .WillRepeatedly(InvokeWithoutArgs(
249 this, &DecryptingDemuxerStreamTest::AbortPendingDecryptCB));
252 demuxer_stream_->Reset(NewExpectedClosure());
253 message_loop_.RunUntilIdle();
256 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
258 MOCK_METHOD2(BufferReady, void(DemuxerStream::Status,
259 const scoped_refptr<DecoderBuffer>&));
261 MOCK_METHOD1(DecryptorSet, void(bool));
263 base::MessageLoop message_loop_;
264 scoped_ptr<DecryptingDemuxerStream> demuxer_stream_;
265 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
266 // Whether a valid Decryptor has been set in the |demuxer_stream_|.
267 bool is_decryptor_set_;
268 scoped_ptr<StrictMock<MockDemuxerStream> > input_audio_stream_;
269 scoped_ptr<StrictMock<MockDemuxerStream> > input_video_stream_;
271 DemuxerStream::ReadCB pending_demuxer_read_cb_;
272 Decryptor::NewKeyCB key_added_cb_;
273 Decryptor::DecryptCB pending_decrypt_cb_;
275 // Constant buffers to be returned by the input demuxer streams and the
277 scoped_refptr<DecoderBuffer> clear_buffer_;
278 scoped_refptr<DecoderBuffer> encrypted_buffer_;
279 scoped_refptr<DecoderBuffer> decrypted_buffer_;
282 DISALLOW_COPY_AND_ASSIGN(DecryptingDemuxerStreamTest);
285 TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalAudio) {
289 TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalVideo) {
290 ExpectDecryptorNotification(decryptor_.get(), true);
291 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _))
292 .WillOnce(SaveArg<1>(&key_added_cb_));
294 VideoDecoderConfig input_config = TestVideoConfig::NormalEncrypted();
295 InitializeVideoAndExpectStatus(input_config, PIPELINE_OK);
297 const VideoDecoderConfig& output_config =
298 demuxer_stream_->video_decoder_config();
299 EXPECT_EQ(DemuxerStream::VIDEO, demuxer_stream_->type());
300 EXPECT_FALSE(output_config.is_encrypted());
301 EXPECT_EQ(input_config.codec(), output_config.codec());
302 EXPECT_EQ(input_config.format(), output_config.format());
303 EXPECT_EQ(input_config.profile(), output_config.profile());
304 EXPECT_EQ(input_config.coded_size(), output_config.coded_size());
305 EXPECT_EQ(input_config.visible_rect(), output_config.visible_rect());
306 EXPECT_EQ(input_config.natural_size(), output_config.natural_size());
307 ASSERT_EQ(input_config.extra_data_size(), output_config.extra_data_size());
308 if (input_config.extra_data_size() > 0) {
309 EXPECT_FALSE(output_config.extra_data());
310 EXPECT_EQ(0, memcmp(output_config.extra_data(), input_config.extra_data(),
311 input_config.extra_data_size()));
315 TEST_F(DecryptingDemuxerStreamTest, Initialize_NullDecryptor) {
316 ExpectDecryptorNotification(NULL, false);
317 AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32,
318 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, true);
319 InitializeAudioAndExpectStatus(input_config, DECODER_ERROR_NOT_SUPPORTED);
322 // Test normal read case where the buffer is encrypted.
323 TEST_F(DecryptingDemuxerStreamTest, Read_Normal) {
325 EnterNormalReadingState();
328 // Test normal read case where the buffer is clear.
329 TEST_F(DecryptingDemuxerStreamTest, Read_Clear) {
331 EnterClearReadingState();
334 // Test the case where the decryptor returns error during read.
335 TEST_F(DecryptingDemuxerStreamTest, Read_DecryptError) {
338 EXPECT_CALL(*input_audio_stream_, Read(_))
339 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
340 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
341 .WillRepeatedly(RunCallback<2>(Decryptor::kError,
342 scoped_refptr<DecoderBuffer>()));
343 ReadAndExpectBufferReadyWith(DemuxerStream::kAborted, NULL);
346 // Test the case where the input is an end-of-stream buffer.
347 TEST_F(DecryptingDemuxerStreamTest, Read_EndOfStream) {
349 EnterNormalReadingState();
351 // No Decryptor::Decrypt() call is expected for EOS buffer.
352 EXPECT_CALL(*input_audio_stream_, Read(_))
353 .WillOnce(ReturnBuffer(DecoderBuffer::CreateEOSBuffer()));
355 ReadAndExpectBufferReadyWith(DemuxerStream::kOk,
356 DecoderBuffer::CreateEOSBuffer());
359 // Test the case where the a key is added when the decryptor is in
360 // kWaitingForKey state.
361 TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DuringWaitingForKey) {
363 EnterWaitingForKeyState();
365 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
366 .WillRepeatedly(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_));
367 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, decrypted_buffer_));
369 message_loop_.RunUntilIdle();
372 // Test the case where the a key is added when the decryptor is in
373 // kPendingDecrypt state.
374 TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DruingPendingDecrypt) {
376 EnterPendingDecryptState();
378 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
379 .WillRepeatedly(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_));
380 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, decrypted_buffer_));
381 // The decrypt callback is returned after the correct decryption key is added.
383 base::ResetAndReturn(&pending_decrypt_cb_).Run(Decryptor::kNoKey, NULL);
384 message_loop_.RunUntilIdle();
387 // Test resetting in kDecryptorRequested state.
388 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringDecryptorRequested) {
389 // One for decryptor request, one for canceling request during Reset().
390 EXPECT_CALL(*this, RequestDecryptorNotification(_))
392 AudioDecoderConfig input_config(
393 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
395 InitializeAudioAndExpectStatus(input_config, PIPELINE_ERROR_ABORT);
399 // Test resetting in kIdle state but has not returned any buffer.
400 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringIdleAfterInitialization) {
405 // Test resetting in kIdle state after having returned one buffer.
406 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringIdleAfterReadOneBuffer) {
408 EnterNormalReadingState();
412 // Test resetting in kPendingDemuxerRead state.
413 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringPendingDemuxerRead) {
415 EnterPendingReadState();
417 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
420 SatisfyPendingDemuxerReadCB(DemuxerStream::kOk);
421 message_loop_.RunUntilIdle();
424 // Test resetting in kPendingDecrypt state.
425 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringPendingDecrypt) {
427 EnterPendingDecryptState();
429 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
434 // Test resetting in kWaitingForKey state.
435 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringWaitingForKey) {
437 EnterWaitingForKeyState();
439 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
444 // Test resetting after reset.
445 TEST_F(DecryptingDemuxerStreamTest, Reset_AfterReset) {
447 EnterNormalReadingState();
452 // Test aborted read on the demuxer stream.
453 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_Aborted) {
456 // ReturnBuffer() with NULL triggers aborted demuxer read.
457 EXPECT_CALL(*input_audio_stream_, Read(_))
458 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>()));
460 ReadAndExpectBufferReadyWith(DemuxerStream::kAborted, NULL);
463 // Test resetting when waiting for an aborted read.
464 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringAbortedDemuxerRead) {
466 EnterPendingReadState();
468 // Make sure we get a NULL audio frame returned.
469 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
472 SatisfyPendingDemuxerReadCB(DemuxerStream::kAborted);
473 message_loop_.RunUntilIdle();
476 // Test config change on the input demuxer stream.
477 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_ConfigChanged) {
480 AudioDecoderConfig new_config(
481 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 88200, NULL,
483 input_audio_stream_->set_audio_decoder_config(new_config);
485 EXPECT_CALL(*input_audio_stream_, Read(_))
486 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged,
487 scoped_refptr<DecoderBuffer>()));
489 ReadAndExpectBufferReadyWith(DemuxerStream::kConfigChanged, NULL);
492 // Test resetting when waiting for a config changed read.
493 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringConfigChangedDemuxerRead) {
495 EnterPendingReadState();
497 // Make sure we get a |kConfigChanged| instead of a |kAborted|.
498 EXPECT_CALL(*this, BufferReady(DemuxerStream::kConfigChanged, IsNull()));
501 SatisfyPendingDemuxerReadCB(DemuxerStream::kConfigChanged);
502 message_loop_.RunUntilIdle();
505 // The following tests test destruction in various scenarios. The destruction
506 // happens in DecryptingDemuxerStreamTest's dtor.
508 // Test destruction in kDecryptorRequested state.
509 TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringDecryptorRequested) {
510 // One for decryptor request, one for canceling request during Reset().
511 EXPECT_CALL(*this, RequestDecryptorNotification(_))
513 AudioDecoderConfig input_config(
514 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
516 InitializeAudioAndExpectStatus(input_config, PIPELINE_ERROR_ABORT);
519 // Test destruction in kIdle state but has not returned any buffer.
520 TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringIdleAfterInitialization) {
524 // Test destruction in kIdle state after having returned one buffer.
525 TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringIdleAfterReadOneBuffer) {
527 EnterNormalReadingState();
530 // Test destruction in kPendingDemuxerRead state.
531 TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringPendingDemuxerRead) {
533 EnterPendingReadState();
535 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
538 // Test destruction in kPendingDecrypt state.
539 TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringPendingDecrypt) {
541 EnterPendingDecryptState();
543 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
546 // Test destruction in kWaitingForKey state.
547 TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringWaitingForKey) {
549 EnterWaitingForKeyState();
551 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
554 // Test destruction after reset.
555 TEST_F(DecryptingDemuxerStreamTest, Destroy_AfterReset) {
557 EnterNormalReadingState();