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_P2(SetDecryptorIfNotNull, decryptor, is_decryptor_set) {
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 void InitializeAudioAndExpectStatus(const AudioDecoderConfig& config,
93 PipelineStatus status) {
94 input_audio_stream_->set_audio_decoder_config(config);
95 demuxer_stream_->Initialize(input_audio_stream_.get(),
96 NewExpectedStatusCB(status));
97 message_loop_.RunUntilIdle();
100 void InitializeVideoAndExpectStatus(const VideoDecoderConfig& config,
101 PipelineStatus status) {
102 input_video_stream_->set_video_decoder_config(config);
103 demuxer_stream_->Initialize(input_video_stream_.get(),
104 NewExpectedStatusCB(status));
105 message_loop_.RunUntilIdle();
108 // The following functions are used to test stream-type-neutral logic in
109 // DecryptingDemuxerStream. Therefore, we don't specify audio or video in the
110 // function names. But for testing purpose, they all use an audio input
114 EXPECT_CALL(*this, RequestDecryptorNotification(_))
115 .WillOnce(SetDecryptorIfNotNull(decryptor_.get(), &is_decryptor_set_));
116 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
117 .WillOnce(SaveArg<1>(&key_added_cb_));
119 AudioDecoderConfig input_config(
120 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
122 InitializeAudioAndExpectStatus(input_config, PIPELINE_OK);
124 const AudioDecoderConfig& output_config =
125 demuxer_stream_->audio_decoder_config();
126 EXPECT_EQ(DemuxerStream::AUDIO, demuxer_stream_->type());
127 EXPECT_FALSE(output_config.is_encrypted());
128 EXPECT_EQ(input_config.bits_per_channel(),
129 output_config.bits_per_channel());
130 EXPECT_EQ(input_config.channel_layout(), output_config.channel_layout());
131 EXPECT_EQ(input_config.sample_format(), output_config.sample_format());
132 EXPECT_EQ(input_config.samples_per_second(),
133 output_config.samples_per_second());
136 void ReadAndExpectBufferReadyWith(
137 DemuxerStream::Status status,
138 const scoped_refptr<DecoderBuffer>& decrypted_buffer) {
139 if (status != DemuxerStream::kOk)
140 EXPECT_CALL(*this, BufferReady(status, IsNull()));
141 else if (decrypted_buffer->end_of_stream())
142 EXPECT_CALL(*this, BufferReady(status, IsEndOfStream()));
144 EXPECT_CALL(*this, BufferReady(status, decrypted_buffer));
146 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
147 base::Unretained(this)));
148 message_loop_.RunUntilIdle();
151 void EnterClearReadingState() {
152 EXPECT_TRUE(clear_buffer_->decrypt_config());
153 EXPECT_CALL(*input_audio_stream_, Read(_))
154 .WillOnce(ReturnBuffer(clear_buffer_));
156 // For clearbuffer, decryptor->Decrypt() will not be called.
158 scoped_refptr<DecoderBuffer> decrypted_buffer;
159 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, _))
160 .WillOnce(SaveArg<1>(&decrypted_buffer));
161 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
162 base::Unretained(this)));
163 message_loop_.RunUntilIdle();
165 EXPECT_FALSE(decrypted_buffer->decrypt_config());
168 // Sets up expectations and actions to put DecryptingDemuxerStream in an
169 // active normal reading state.
170 void EnterNormalReadingState() {
171 EXPECT_CALL(*input_audio_stream_, Read(_))
172 .WillOnce(ReturnBuffer(encrypted_buffer_));
173 EXPECT_CALL(*decryptor_, Decrypt(_, _, _))
174 .WillOnce(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_));
176 ReadAndExpectBufferReadyWith(DemuxerStream::kOk, decrypted_buffer_);
179 // Make the read callback pending by saving and not firing it.
180 void EnterPendingReadState() {
181 EXPECT_TRUE(pending_demuxer_read_cb_.is_null());
182 EXPECT_CALL(*input_audio_stream_, Read(_))
183 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_));
184 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
185 base::Unretained(this)));
186 message_loop_.RunUntilIdle();
187 // Make sure the Read() triggers a Read() on the input demuxer stream.
188 EXPECT_FALSE(pending_demuxer_read_cb_.is_null());
191 // Make the decrypt callback pending by saving and not firing it.
192 void EnterPendingDecryptState() {
193 EXPECT_TRUE(pending_decrypt_cb_.is_null());
194 EXPECT_CALL(*input_audio_stream_, Read(_))
195 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
196 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
197 .WillOnce(SaveArg<2>(&pending_decrypt_cb_));
199 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
200 base::Unretained(this)));
201 message_loop_.RunUntilIdle();
202 // Make sure Read() triggers a Decrypt() on the decryptor.
203 EXPECT_FALSE(pending_decrypt_cb_.is_null());
206 void EnterWaitingForKeyState() {
207 EXPECT_CALL(*input_audio_stream_, Read(_))
208 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
209 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
210 .WillRepeatedly(RunCallback<2>(Decryptor::kNoKey,
211 scoped_refptr<DecoderBuffer>()));
212 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
213 base::Unretained(this)));
214 message_loop_.RunUntilIdle();
217 void AbortPendingDecryptCB() {
218 if (!pending_decrypt_cb_.is_null()) {
219 base::ResetAndReturn(&pending_decrypt_cb_).Run(Decryptor::kSuccess, NULL);
223 void SatisfyPendingDemuxerReadCB(DemuxerStream::Status status) {
224 scoped_refptr<DecoderBuffer> buffer =
225 (status == DemuxerStream::kOk) ? encrypted_buffer_ : NULL;
226 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(status, buffer);
230 if (is_decryptor_set_) {
231 EXPECT_CALL(*decryptor_, CancelDecrypt(Decryptor::kAudio))
232 .WillRepeatedly(InvokeWithoutArgs(
233 this, &DecryptingDemuxerStreamTest::AbortPendingDecryptCB));
236 demuxer_stream_->Reset(NewExpectedClosure());
237 message_loop_.RunUntilIdle();
240 // Stops the |demuxer_stream_| without satisfying/aborting any pending
243 if (is_decryptor_set_)
244 EXPECT_CALL(*decryptor_, CancelDecrypt(Decryptor::kAudio));
245 demuxer_stream_->Stop(NewExpectedClosure());
246 message_loop_.RunUntilIdle();
249 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
251 MOCK_METHOD2(BufferReady, void(DemuxerStream::Status,
252 const scoped_refptr<DecoderBuffer>&));
254 base::MessageLoop message_loop_;
255 scoped_ptr<DecryptingDemuxerStream> demuxer_stream_;
256 scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
257 // Whether a valid Decryptor has been set in the |demuxer_stream_|.
258 bool is_decryptor_set_;
259 scoped_ptr<StrictMock<MockDemuxerStream> > input_audio_stream_;
260 scoped_ptr<StrictMock<MockDemuxerStream> > input_video_stream_;
262 DemuxerStream::ReadCB pending_demuxer_read_cb_;
263 Decryptor::NewKeyCB key_added_cb_;
264 Decryptor::DecryptCB pending_decrypt_cb_;
266 // Constant buffers to be returned by the input demuxer streams and the
268 scoped_refptr<DecoderBuffer> clear_buffer_;
269 scoped_refptr<DecoderBuffer> encrypted_buffer_;
270 scoped_refptr<DecoderBuffer> decrypted_buffer_;
273 DISALLOW_COPY_AND_ASSIGN(DecryptingDemuxerStreamTest);
276 TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalAudio) {
280 TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalVideo) {
281 EXPECT_CALL(*this, RequestDecryptorNotification(_))
282 .WillOnce(SetDecryptorIfNotNull(decryptor_.get(), &is_decryptor_set_));
283 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _))
284 .WillOnce(SaveArg<1>(&key_added_cb_));
286 VideoDecoderConfig input_config = TestVideoConfig::NormalEncrypted();
287 InitializeVideoAndExpectStatus(input_config, PIPELINE_OK);
289 const VideoDecoderConfig& output_config =
290 demuxer_stream_->video_decoder_config();
291 EXPECT_EQ(DemuxerStream::VIDEO, demuxer_stream_->type());
292 EXPECT_FALSE(output_config.is_encrypted());
293 EXPECT_EQ(input_config.codec(), output_config.codec());
294 EXPECT_EQ(input_config.format(), output_config.format());
295 EXPECT_EQ(input_config.profile(), output_config.profile());
296 EXPECT_EQ(input_config.coded_size(), output_config.coded_size());
297 EXPECT_EQ(input_config.visible_rect(), output_config.visible_rect());
298 EXPECT_EQ(input_config.natural_size(), output_config.natural_size());
299 ASSERT_EQ(input_config.extra_data_size(), output_config.extra_data_size());
300 if (input_config.extra_data_size() > 0) {
301 EXPECT_FALSE(output_config.extra_data());
302 EXPECT_EQ(0, memcmp(output_config.extra_data(), input_config.extra_data(),
303 input_config.extra_data_size()));
307 TEST_F(DecryptingDemuxerStreamTest, Initialize_NullDecryptor) {
308 EXPECT_CALL(*this, RequestDecryptorNotification(_))
309 .WillRepeatedly(SetDecryptorIfNotNull(static_cast<Decryptor*>(NULL),
310 &is_decryptor_set_));
312 AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32,
313 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, true);
314 InitializeAudioAndExpectStatus(input_config, DECODER_ERROR_NOT_SUPPORTED);
317 // Test normal read case where the buffer is encrypted.
318 TEST_F(DecryptingDemuxerStreamTest, Read_Normal) {
320 EnterNormalReadingState();
323 // Test normal read case where the buffer is clear.
324 TEST_F(DecryptingDemuxerStreamTest, Read_Clear) {
326 EnterClearReadingState();
329 // Test the case where the decryptor returns error during read.
330 TEST_F(DecryptingDemuxerStreamTest, Read_DecryptError) {
333 EXPECT_CALL(*input_audio_stream_, Read(_))
334 .WillRepeatedly(ReturnBuffer(encrypted_buffer_));
335 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
336 .WillRepeatedly(RunCallback<2>(Decryptor::kError,
337 scoped_refptr<DecoderBuffer>()));
338 ReadAndExpectBufferReadyWith(DemuxerStream::kAborted, NULL);
341 // Test the case where the input is an end-of-stream buffer.
342 TEST_F(DecryptingDemuxerStreamTest, Read_EndOfStream) {
344 EnterNormalReadingState();
346 // No Decryptor::Decrypt() call is expected for EOS buffer.
347 EXPECT_CALL(*input_audio_stream_, Read(_))
348 .WillOnce(ReturnBuffer(DecoderBuffer::CreateEOSBuffer()));
350 ReadAndExpectBufferReadyWith(DemuxerStream::kOk,
351 DecoderBuffer::CreateEOSBuffer());
354 // Test the case where the a key is added when the decryptor is in
355 // kWaitingForKey state.
356 TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DuringWaitingForKey) {
358 EnterWaitingForKeyState();
360 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
361 .WillRepeatedly(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_));
362 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, decrypted_buffer_));
364 message_loop_.RunUntilIdle();
367 // Test the case where the a key is added when the decryptor is in
368 // kPendingDecrypt state.
369 TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DruingPendingDecrypt) {
371 EnterPendingDecryptState();
373 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
374 .WillRepeatedly(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_));
375 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, decrypted_buffer_));
376 // The decrypt callback is returned after the correct decryption key is added.
378 base::ResetAndReturn(&pending_decrypt_cb_).Run(Decryptor::kNoKey, NULL);
379 message_loop_.RunUntilIdle();
382 // Test resetting when the DecryptingDemuxerStream is in kDecryptorRequested
384 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringDecryptorRequested) {
385 // One for decryptor request, one for canceling request during Reset().
386 EXPECT_CALL(*this, RequestDecryptorNotification(_))
388 AudioDecoderConfig input_config(
389 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
391 InitializeAudioAndExpectStatus(input_config, PIPELINE_ERROR_ABORT);
395 // Test resetting when the DecryptingDemuxerStream is in kIdle state but has
396 // not returned any buffer.
397 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringIdleAfterInitialization) {
402 // Test resetting when the DecryptingDemuxerStream is in kIdle state after it
403 // has returned one buffer.
404 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringIdleAfterReadOneBuffer) {
406 EnterNormalReadingState();
410 // Test resetting when DecryptingDemuxerStream is in kPendingDemuxerRead state.
411 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringPendingDemuxerRead) {
413 EnterPendingReadState();
415 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
418 SatisfyPendingDemuxerReadCB(DemuxerStream::kOk);
419 message_loop_.RunUntilIdle();
422 // Test resetting when the DecryptingDemuxerStream is in kPendingDecrypt state.
423 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringPendingDecrypt) {
425 EnterPendingDecryptState();
427 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
432 // Test resetting when the DecryptingDemuxerStream is in kWaitingForKey state.
433 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringWaitingForKey) {
435 EnterWaitingForKeyState();
437 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
442 // Test resetting after the DecryptingDemuxerStream has been reset.
443 TEST_F(DecryptingDemuxerStreamTest, Reset_AfterReset) {
445 EnterNormalReadingState();
450 // Test aborted read on the demuxer stream.
451 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_Aborted) {
454 // ReturnBuffer() with NULL triggers aborted demuxer read.
455 EXPECT_CALL(*input_audio_stream_, Read(_))
456 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>()));
458 ReadAndExpectBufferReadyWith(DemuxerStream::kAborted, NULL);
461 // Test resetting when DecryptingDemuxerStream is waiting for an aborted read.
462 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringAbortedDemuxerRead) {
464 EnterPendingReadState();
466 // Make sure we get a NULL audio frame returned.
467 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
470 SatisfyPendingDemuxerReadCB(DemuxerStream::kAborted);
471 message_loop_.RunUntilIdle();
474 // Test config change on the input demuxer stream.
475 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_ConfigChanged) {
478 AudioDecoderConfig new_config(
479 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 88200, NULL,
481 input_audio_stream_->set_audio_decoder_config(new_config);
483 EXPECT_CALL(*input_audio_stream_, Read(_))
484 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged,
485 scoped_refptr<DecoderBuffer>()));
487 ReadAndExpectBufferReadyWith(DemuxerStream::kConfigChanged, NULL);
490 // Test resetting when DecryptingDemuxerStream is waiting for a config changed
492 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringConfigChangedDemuxerRead) {
494 EnterPendingReadState();
496 // Make sure we get a |kConfigChanged| instead of a |kAborted|.
497 EXPECT_CALL(*this, BufferReady(DemuxerStream::kConfigChanged, IsNull()));
500 SatisfyPendingDemuxerReadCB(DemuxerStream::kConfigChanged);
501 message_loop_.RunUntilIdle();
504 // Test stopping when the DecryptingDemuxerStream is in kDecryptorRequested
506 TEST_F(DecryptingDemuxerStreamTest, Stop_DuringDecryptorRequested) {
507 // One for decryptor request, one for canceling request during Reset().
508 EXPECT_CALL(*this, RequestDecryptorNotification(_))
510 AudioDecoderConfig input_config(
511 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
513 InitializeAudioAndExpectStatus(input_config, PIPELINE_ERROR_ABORT);
517 // Test stopping when the DecryptingDemuxerStream is in kIdle state but has
518 // not returned any buffer.
519 TEST_F(DecryptingDemuxerStreamTest, Stop_DuringIdleAfterInitialization) {
524 // Test stopping when the DecryptingDemuxerStream is in kIdle state after it
525 // has returned one buffer.
526 TEST_F(DecryptingDemuxerStreamTest, Stop_DuringIdleAfterReadOneBuffer) {
528 EnterNormalReadingState();
532 // Test stopping when DecryptingDemuxerStream is in kPendingDemuxerRead state.
533 TEST_F(DecryptingDemuxerStreamTest, Stop_DuringPendingDemuxerRead) {
535 EnterPendingReadState();
537 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
541 // Test stopping when the DecryptingDemuxerStream is in kPendingDecrypt state.
542 TEST_F(DecryptingDemuxerStreamTest, Stop_DuringPendingDecrypt) {
544 EnterPendingDecryptState();
546 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
550 // Test stopping when the DecryptingDemuxerStream is in kWaitingForKey state.
551 TEST_F(DecryptingDemuxerStreamTest, Stop_DuringWaitingForKey) {
553 EnterWaitingForKeyState();
555 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull()));
559 // Test stopping after the DecryptingDemuxerStream has been reset.
560 TEST_F(DecryptingDemuxerStreamTest, Stop_AfterReset) {
562 EnterNormalReadingState();