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. 4 5 #include <string> 6 #include <vector> 7 8 #include "base/bind.h" 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" 18 19 using ::testing::_; 20 using ::testing::IsNull; 21 using ::testing::Return; 22 using ::testing::SaveArg; 23 using ::testing::StrictMock; 24 25 namespace media { 26 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 }; 30 31 // Create a fake non-empty encrypted buffer. 32 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() { 33 scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(kFakeBufferSize)); 34 buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(new DecryptConfig( 35 std::string(reinterpret_cast<const char*>(kFakeKeyId), 36 arraysize(kFakeKeyId)), 37 std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)), 38 0, 39 std::vector<SubsampleEntry>()))); 40 return buffer; 41 } 42 43 // Use anonymous namespace here to prevent the actions to be defined multiple 44 // times across multiple test files. Sadly we can't use static for them. 45 namespace { 46 47 ACTION_P(ReturnBuffer, buffer) { 48 arg0.Run(buffer.get() ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer); 49 } 50 51 ACTION_P(RunCallbackIfNotNull, param) { 52 if (!arg0.is_null()) 53 arg0.Run(param); 54 } 55 56 ACTION_P2(ResetAndRunCallback, callback, param) { 57 base::ResetAndReturn(callback).Run(param); 58 } 59 60 MATCHER(IsEndOfStream, "end of stream") { 61 return arg->end_of_stream(); 62 } 63 64 } // namespace 65 66 class DecryptingDemuxerStreamTest : public testing::Test { 67 public: 68 DecryptingDemuxerStreamTest() 69 : demuxer_stream_(new DecryptingDemuxerStream( 70 message_loop_.message_loop_proxy(), 71 base::Bind( 72 &DecryptingDemuxerStreamTest::RequestDecryptorNotification, 73 base::Unretained(this)))), 74 decryptor_(new StrictMock<MockDecryptor>()), 75 input_audio_stream_( 76 new StrictMock<MockDemuxerStream>(DemuxerStream::AUDIO)), 77 input_video_stream_( 78 new StrictMock<MockDemuxerStream>(DemuxerStream::VIDEO)), 79 encrypted_buffer_(CreateFakeEncryptedBuffer()), 80 decrypted_buffer_(new DecoderBuffer(kFakeBufferSize)) { 81 } 82 83 void InitializeAudioAndExpectStatus(const AudioDecoderConfig& config, 84 PipelineStatus status) { 85 input_audio_stream_->set_audio_decoder_config(config); 86 demuxer_stream_->Initialize(input_audio_stream_.get(), 87 NewExpectedStatusCB(status)); 88 message_loop_.RunUntilIdle(); 89 } 90 91 void InitializeVideoAndExpectStatus(const VideoDecoderConfig& config, 92 PipelineStatus status) { 93 input_video_stream_->set_video_decoder_config(config); 94 demuxer_stream_->Initialize(input_video_stream_.get(), 95 NewExpectedStatusCB(status)); 96 message_loop_.RunUntilIdle(); 97 } 98 99 // The following functions are used to test stream-type-neutral logic in 100 // DecryptingDemuxerStream. Therefore, we don't specify audio or video in the 101 // function names. But for testing purpose, they all use an audio input 102 // demuxer stream. 103 104 void Initialize() { 105 EXPECT_CALL(*this, RequestDecryptorNotification(_)) 106 .WillOnce(RunCallbackIfNotNull(decryptor_.get())); 107 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) 108 .WillOnce(SaveArg<1>(&key_added_cb_)); 109 110 AudioDecoderConfig input_config( 111 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, 112 NULL, 0, true); 113 InitializeAudioAndExpectStatus(input_config, PIPELINE_OK); 114 115 const AudioDecoderConfig& output_config = 116 demuxer_stream_->audio_decoder_config(); 117 EXPECT_EQ(DemuxerStream::AUDIO, demuxer_stream_->type()); 118 EXPECT_FALSE(output_config.is_encrypted()); 119 EXPECT_EQ(input_config.bits_per_channel(), 120 output_config.bits_per_channel()); 121 EXPECT_EQ(input_config.channel_layout(), output_config.channel_layout()); 122 EXPECT_EQ(input_config.sample_format(), output_config.sample_format()); 123 EXPECT_EQ(input_config.samples_per_second(), 124 output_config.samples_per_second()); 125 } 126 127 void ReadAndExpectBufferReadyWith( 128 DemuxerStream::Status status, 129 const scoped_refptr<DecoderBuffer>& decrypted_buffer) { 130 if (status != DemuxerStream::kOk) 131 EXPECT_CALL(*this, BufferReady(status, IsNull())); 132 else if (decrypted_buffer->end_of_stream()) 133 EXPECT_CALL(*this, BufferReady(status, IsEndOfStream())); 134 else 135 EXPECT_CALL(*this, BufferReady(status, decrypted_buffer)); 136 137 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady, 138 base::Unretained(this))); 139 message_loop_.RunUntilIdle(); 140 } 141 142 // Sets up expectations and actions to put DecryptingDemuxerStream in an 143 // active normal reading state. 144 void EnterNormalReadingState() { 145 EXPECT_CALL(*input_audio_stream_, Read(_)) 146 .WillOnce(ReturnBuffer(encrypted_buffer_)); 147 EXPECT_CALL(*decryptor_, Decrypt(_, _, _)) 148 .WillOnce(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_)); 149 150 ReadAndExpectBufferReadyWith(DemuxerStream::kOk, decrypted_buffer_); 151 } 152 153 // Make the read callback pending by saving and not firing it. 154 void EnterPendingReadState() { 155 EXPECT_TRUE(pending_demuxer_read_cb_.is_null()); 156 EXPECT_CALL(*input_audio_stream_, Read(_)) 157 .WillOnce(SaveArg<0>(&pending_demuxer_read_cb_)); 158 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady, 159 base::Unretained(this))); 160 message_loop_.RunUntilIdle(); 161 // Make sure the Read() triggers a Read() on the input demuxer stream. 162 EXPECT_FALSE(pending_demuxer_read_cb_.is_null()); 163 } 164 165 // Make the decrypt callback pending by saving and not firing it. 166 void EnterPendingDecryptState() { 167 EXPECT_TRUE(pending_decrypt_cb_.is_null()); 168 EXPECT_CALL(*input_audio_stream_, Read(_)) 169 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); 170 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _)) 171 .WillOnce(SaveArg<2>(&pending_decrypt_cb_)); 172 173 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady, 174 base::Unretained(this))); 175 message_loop_.RunUntilIdle(); 176 // Make sure Read() triggers a Decrypt() on the decryptor. 177 EXPECT_FALSE(pending_decrypt_cb_.is_null()); 178 } 179 180 void EnterWaitingForKeyState() { 181 EXPECT_CALL(*input_audio_stream_, Read(_)) 182 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); 183 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _)) 184 .WillRepeatedly(RunCallback<2>(Decryptor::kNoKey, 185 scoped_refptr<DecoderBuffer>())); 186 demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady, 187 base::Unretained(this))); 188 message_loop_.RunUntilIdle(); 189 } 190 191 void AbortPendingDecryptCB() { 192 if (!pending_decrypt_cb_.is_null()) { 193 base::ResetAndReturn(&pending_decrypt_cb_).Run(Decryptor::kSuccess, NULL); 194 } 195 } 196 197 void Reset() { 198 EXPECT_CALL(*decryptor_, CancelDecrypt(Decryptor::kAudio)) 199 .WillRepeatedly(InvokeWithoutArgs( 200 this, &DecryptingDemuxerStreamTest::AbortPendingDecryptCB)); 201 202 demuxer_stream_->Reset(NewExpectedClosure()); 203 message_loop_.RunUntilIdle(); 204 } 205 206 MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&)); 207 208 MOCK_METHOD2(BufferReady, void(DemuxerStream::Status, 209 const scoped_refptr<DecoderBuffer>&)); 210 211 base::MessageLoop message_loop_; 212 scoped_ptr<DecryptingDemuxerStream> demuxer_stream_; 213 scoped_ptr<StrictMock<MockDecryptor> > decryptor_; 214 scoped_ptr<StrictMock<MockDemuxerStream> > input_audio_stream_; 215 scoped_ptr<StrictMock<MockDemuxerStream> > input_video_stream_; 216 217 DemuxerStream::ReadCB pending_demuxer_read_cb_; 218 Decryptor::NewKeyCB key_added_cb_; 219 Decryptor::DecryptCB pending_decrypt_cb_; 220 221 // Constant buffers to be returned by the input demuxer streams and the 222 // |decryptor_|. 223 scoped_refptr<DecoderBuffer> encrypted_buffer_; 224 scoped_refptr<DecoderBuffer> decrypted_buffer_; 225 226 private: 227 DISALLOW_COPY_AND_ASSIGN(DecryptingDemuxerStreamTest); 228 }; 229 230 TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalAudio) { 231 Initialize(); 232 } 233 234 TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalVideo) { 235 EXPECT_CALL(*this, RequestDecryptorNotification(_)) 236 .WillOnce(RunCallbackIfNotNull(decryptor_.get())); 237 EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) 238 .WillOnce(SaveArg<1>(&key_added_cb_)); 239 240 VideoDecoderConfig input_config = TestVideoConfig::NormalEncrypted(); 241 InitializeVideoAndExpectStatus(input_config, PIPELINE_OK); 242 243 const VideoDecoderConfig& output_config = 244 demuxer_stream_->video_decoder_config(); 245 EXPECT_EQ(DemuxerStream::VIDEO, demuxer_stream_->type()); 246 EXPECT_FALSE(output_config.is_encrypted()); 247 EXPECT_EQ(input_config.codec(), output_config.codec()); 248 EXPECT_EQ(input_config.format(), output_config.format()); 249 EXPECT_EQ(input_config.profile(), output_config.profile()); 250 EXPECT_EQ(input_config.coded_size(), output_config.coded_size()); 251 EXPECT_EQ(input_config.visible_rect(), output_config.visible_rect()); 252 EXPECT_EQ(input_config.natural_size(), output_config.natural_size()); 253 ASSERT_EQ(input_config.extra_data_size(), output_config.extra_data_size()); 254 if (input_config.extra_data_size() > 0) { 255 EXPECT_FALSE(output_config.extra_data()); 256 EXPECT_EQ(0, memcmp(output_config.extra_data(), input_config.extra_data(), 257 input_config.extra_data_size())); 258 } 259 } 260 261 TEST_F(DecryptingDemuxerStreamTest, Initialize_NullDecryptor) { 262 EXPECT_CALL(*this, RequestDecryptorNotification(_)) 263 .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL))); 264 265 AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, 266 CHANNEL_LAYOUT_STEREO, 44100, NULL, 0, true); 267 InitializeAudioAndExpectStatus(input_config, DECODER_ERROR_NOT_SUPPORTED); 268 } 269 270 // Test normal read case. 271 TEST_F(DecryptingDemuxerStreamTest, Read_Normal) { 272 Initialize(); 273 EnterNormalReadingState(); 274 } 275 276 // Test the case where the decryptor returns error during read. 277 TEST_F(DecryptingDemuxerStreamTest, Read_DecryptError) { 278 Initialize(); 279 280 EXPECT_CALL(*input_audio_stream_, Read(_)) 281 .WillRepeatedly(ReturnBuffer(encrypted_buffer_)); 282 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _)) 283 .WillRepeatedly(RunCallback<2>(Decryptor::kError, 284 scoped_refptr<DecoderBuffer>())); 285 ReadAndExpectBufferReadyWith(DemuxerStream::kAborted, NULL); 286 } 287 288 // Test the case where the input is an end-of-stream buffer. 289 TEST_F(DecryptingDemuxerStreamTest, Read_EndOfStream) { 290 Initialize(); 291 EnterNormalReadingState(); 292 293 // No Decryptor::Decrypt() call is expected for EOS buffer. 294 EXPECT_CALL(*input_audio_stream_, Read(_)) 295 .WillOnce(ReturnBuffer(DecoderBuffer::CreateEOSBuffer())); 296 297 ReadAndExpectBufferReadyWith(DemuxerStream::kOk, 298 DecoderBuffer::CreateEOSBuffer()); 299 } 300 301 // Test the case where the a key is added when the decryptor is in 302 // kWaitingForKey state. 303 TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DuringWaitingForKey) { 304 Initialize(); 305 EnterWaitingForKeyState(); 306 307 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _)) 308 .WillRepeatedly(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_)); 309 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, decrypted_buffer_)); 310 key_added_cb_.Run(); 311 message_loop_.RunUntilIdle(); 312 } 313 314 // Test the case where the a key is added when the decryptor is in 315 // kPendingDecrypt state. 316 TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DruingPendingDecrypt) { 317 Initialize(); 318 EnterPendingDecryptState(); 319 320 EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _)) 321 .WillRepeatedly(RunCallback<2>(Decryptor::kSuccess, decrypted_buffer_)); 322 EXPECT_CALL(*this, BufferReady(DemuxerStream::kOk, decrypted_buffer_)); 323 // The decrypt callback is returned after the correct decryption key is added. 324 key_added_cb_.Run(); 325 base::ResetAndReturn(&pending_decrypt_cb_).Run(Decryptor::kNoKey, NULL); 326 message_loop_.RunUntilIdle(); 327 } 328 329 // Test resetting when the DecryptingDemuxerStream is in kIdle state but has 330 // not returned any buffer. 331 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringIdleAfterInitialization) { 332 Initialize(); 333 Reset(); 334 } 335 336 // Test resetting when the DecryptingDemuxerStream is in kIdle state after it 337 // has returned one buffer. 338 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringIdleAfterReadOneBuffer) { 339 Initialize(); 340 EnterNormalReadingState(); 341 Reset(); 342 } 343 344 // Test resetting when DecryptingDemuxerStream is in kPendingDemuxerRead state. 345 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringPendingDemuxerRead) { 346 Initialize(); 347 EnterPendingReadState(); 348 349 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull())); 350 351 Reset(); 352 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kOk, 353 encrypted_buffer_); 354 message_loop_.RunUntilIdle(); 355 } 356 357 // Test resetting when the DecryptingDemuxerStream is in kPendingDecrypt state. 358 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringPendingDecrypt) { 359 Initialize(); 360 EnterPendingDecryptState(); 361 362 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull())); 363 364 Reset(); 365 } 366 367 // Test resetting when the DecryptingDemuxerStream is in kWaitingForKey state. 368 TEST_F(DecryptingDemuxerStreamTest, Reset_DuringWaitingForKey) { 369 Initialize(); 370 EnterWaitingForKeyState(); 371 372 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull())); 373 374 Reset(); 375 } 376 377 // Test resetting after the DecryptingDemuxerStream has been reset. 378 TEST_F(DecryptingDemuxerStreamTest, Reset_AfterReset) { 379 Initialize(); 380 EnterNormalReadingState(); 381 Reset(); 382 Reset(); 383 } 384 385 // Test aborted read on the demuxer stream. 386 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_Aborted) { 387 Initialize(); 388 389 // ReturnBuffer() with NULL triggers aborted demuxer read. 390 EXPECT_CALL(*input_audio_stream_, Read(_)) 391 .WillOnce(ReturnBuffer(scoped_refptr<DecoderBuffer>())); 392 393 ReadAndExpectBufferReadyWith(DemuxerStream::kAborted, NULL); 394 } 395 396 // Test aborted read on the input demuxer stream when the 397 // DecryptingDemuxerStream is being reset. 398 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_AbortedDuringReset) { 399 Initialize(); 400 EnterPendingReadState(); 401 402 // Make sure we get a NULL audio frame returned. 403 EXPECT_CALL(*this, BufferReady(DemuxerStream::kAborted, IsNull())); 404 405 Reset(); 406 base::ResetAndReturn(&pending_demuxer_read_cb_).Run(DemuxerStream::kAborted, 407 NULL); 408 message_loop_.RunUntilIdle(); 409 } 410 411 // Test config change on the input demuxer stream. 412 TEST_F(DecryptingDemuxerStreamTest, DemuxerRead_ConfigChanged) { 413 Initialize(); 414 415 AudioDecoderConfig new_config( 416 kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 88200, NULL, 417 0, true); 418 input_audio_stream_->set_audio_decoder_config(new_config); 419 420 EXPECT_CALL(*input_audio_stream_, Read(_)) 421 .WillOnce(RunCallback<0>(DemuxerStream::kConfigChanged, 422 scoped_refptr<DecoderBuffer>())); 423 424 ReadAndExpectBufferReadyWith(DemuxerStream::kConfigChanged, NULL); 425 } 426 427 } // namespace media 428