| Index: media/renderers/renderer_impl_unittest.cc
|
| diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc
|
| index bbc0e980c9feb634872b0efff485515ed38d2ac8..24bea4d6b9d28406608f734f3d19c29398186334 100644
|
| --- a/media/renderers/renderer_impl_unittest.cc
|
| +++ b/media/renderers/renderer_impl_unittest.cc
|
| @@ -53,6 +53,7 @@ class RendererImplTest : public ::testing::Test {
|
| MOCK_METHOD1(OnUpdateStatistics, void(const PipelineStatistics&));
|
| MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
|
| MOCK_METHOD0(OnWaitingForDecryptionKey, void());
|
| + MOCK_METHOD1(OnCdmAttached, void(bool));
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
|
| @@ -65,7 +66,9 @@ class RendererImplTest : public ::testing::Test {
|
| renderer_impl_(
|
| new RendererImpl(message_loop_.task_runner(),
|
| scoped_ptr<AudioRenderer>(audio_renderer_),
|
| - scoped_ptr<VideoRenderer>(video_renderer_))) {
|
| + scoped_ptr<VideoRenderer>(video_renderer_))),
|
| + cdm_context_(new StrictMock<MockCdmContext>()),
|
| + initialization_status_(PIPELINE_ERROR_OPERATION_PENDING) {
|
| // SetDemuxerExpectations() adds overriding expectations for expected
|
| // non-NULL streams.
|
| DemuxerStream* null_pointer = NULL;
|
| @@ -73,14 +76,16 @@ class RendererImplTest : public ::testing::Test {
|
| .WillRepeatedly(Return(null_pointer));
|
| }
|
|
|
| - virtual ~RendererImplTest() {
|
| - renderer_impl_.reset();
|
| - base::RunLoop().RunUntilIdle();
|
| - }
|
| + virtual ~RendererImplTest() { Destroy(); }
|
|
|
| protected:
|
| typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
|
|
|
| + void Destroy() {
|
| + renderer_impl_.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream(
|
| DemuxerStream::Type type) {
|
| scoped_ptr<StrictMock<MockDemuxerStream> > stream(
|
| @@ -106,7 +111,8 @@ class RendererImplTest : public ::testing::Test {
|
| }
|
|
|
| void InitializeAndExpect(PipelineStatus start_status) {
|
| - EXPECT_CALL(callbacks_, OnInitialize(start_status));
|
| + EXPECT_CALL(callbacks_, OnInitialize(start_status))
|
| + .WillOnce(SaveArg<0>(&initialization_status_));
|
| EXPECT_CALL(callbacks_, OnWaitingForDecryptionKey()).Times(0);
|
|
|
| if (start_status == PIPELINE_OK && audio_stream_) {
|
| @@ -138,14 +144,18 @@ class RendererImplTest : public ::testing::Test {
|
| .WillRepeatedly(Return(audio_stream_.get()));
|
| }
|
|
|
| - void CreateVideoStream() {
|
| + void CreateVideoStream(bool is_encrypted = false) {
|
| video_stream_ = CreateStream(DemuxerStream::VIDEO);
|
| - video_stream_->set_video_decoder_config(video_decoder_config_);
|
| + video_stream_->set_video_decoder_config(
|
| + is_encrypted ? TestVideoConfig::NormalEncrypted()
|
| + : TestVideoConfig::Normal());
|
| streams_.push_back(video_stream_.get());
|
| EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO))
|
| .WillRepeatedly(Return(video_stream_.get()));
|
| }
|
|
|
| + void CreateEncryptedVideoStream() { CreateVideoStream(true); }
|
| +
|
| void CreateAudioAndVideoStream() {
|
| CreateAudioStream();
|
| CreateVideoStream();
|
| @@ -248,6 +258,14 @@ class RendererImplTest : public ::testing::Test {
|
| return IsMediaTimeAdvancing(1.0);
|
| }
|
|
|
| + void SetCdmAndExpect(bool expected_result) {
|
| + EXPECT_CALL(callbacks_, OnCdmAttached(expected_result));
|
| + renderer_impl_->SetCdm(cdm_context_.get(),
|
| + base::Bind(&CallbackHelper::OnCdmAttached,
|
| + base::Unretained(&callbacks_)));
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| // Fixture members.
|
| base::MessageLoop message_loop_;
|
| StrictMock<CallbackHelper> callbacks_;
|
| @@ -257,6 +275,7 @@ class RendererImplTest : public ::testing::Test {
|
| StrictMock<MockVideoRenderer>* video_renderer_;
|
| StrictMock<MockAudioRenderer>* audio_renderer_;
|
| scoped_ptr<RendererImpl> renderer_impl_;
|
| + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_;
|
|
|
| StrictMock<MockTimeSource> time_source_;
|
| scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
|
| @@ -268,13 +287,65 @@ class RendererImplTest : public ::testing::Test {
|
| base::Closure video_ended_cb_;
|
| PipelineStatusCB audio_error_cb_;
|
| VideoDecoderConfig video_decoder_config_;
|
| + PipelineStatus initialization_status_;
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(RendererImplTest);
|
| };
|
|
|
| -TEST_F(RendererImplTest, DestroyBeforeInitialize) {
|
| - // |renderer_impl_| will be destroyed in the dtor.
|
| +TEST_F(RendererImplTest, Destroy_BeforeInitialize) {
|
| + Destroy();
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, Destroy_PendingInitialize) {
|
| + CreateAudioAndVideoStream();
|
| +
|
| + SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| + // Not returning the video initialization callback.
|
| + EXPECT_CALL(*video_renderer_,
|
| + Initialize(video_stream_.get(), _, _, _, _, _, _, _, _));
|
| +
|
| + InitializeAndExpect(PIPELINE_ERROR_ABORT);
|
| + EXPECT_EQ(PIPELINE_ERROR_OPERATION_PENDING, initialization_status_);
|
| +
|
| + Destroy();
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, Destroy_PendingInitializeWithoutCdm) {
|
| + CreateAudioStream();
|
| + CreateEncryptedVideoStream();
|
| +
|
| + // Audio is clear and video is encrypted. Initialization will not start
|
| + // because no CDM is set. So neither AudioRenderer::Initialize() nor
|
| + // VideoRenderer::Initialize() should not be called. The InitCB will be
|
| + // aborted when |renderer_impl_| is destructed.
|
| + InitializeAndExpect(PIPELINE_ERROR_ABORT);
|
| + EXPECT_EQ(PIPELINE_ERROR_OPERATION_PENDING, initialization_status_);
|
| +
|
| + Destroy();
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, Destroy_PendingInitializeAfterSetCdm) {
|
| + CreateAudioStream();
|
| + CreateEncryptedVideoStream();
|
| +
|
| + // Audio is clear and video is encrypted. Initialization will not start
|
| + // because no CDM is set.
|
| + InitializeAndExpect(PIPELINE_ERROR_ABORT);
|
| + EXPECT_EQ(PIPELINE_ERROR_OPERATION_PENDING, initialization_status_);
|
| +
|
| + SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| + // Not returning the video initialization callback. So initialization will
|
| + // be pending.
|
| + EXPECT_CALL(*video_renderer_,
|
| + Initialize(video_stream_.get(), _, _, _, _, _, _, _, _));
|
| +
|
| + // SetCdm() will trigger the initialization to start. But it will not complete
|
| + // because the |video_renderer_| is not returning the initialization callback.
|
| + SetCdmAndExpect(false);
|
| + EXPECT_EQ(PIPELINE_ERROR_OPERATION_PENDING, initialization_status_);
|
| +
|
| + Destroy();
|
| }
|
|
|
| TEST_F(RendererImplTest, InitializeWithAudio) {
|
| @@ -315,6 +386,54 @@ TEST_F(RendererImplTest, InitializeWithAudioVideo_VideoRendererFailed) {
|
| InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| }
|
|
|
| +TEST_F(RendererImplTest, SetCdmBeforeInitialize) {
|
| + // CDM will be successfully attached immediately if set before RendererImpl
|
| + // initialization, regardless of the later initialization result.
|
| + SetCdmAndExpect(true);
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, SetCdmAfterInitialize_ClearStream) {
|
| + InitializeWithAudioAndVideo();
|
| + EXPECT_EQ(PIPELINE_OK, initialization_status_);
|
| +
|
| + // CDM will be successfully attached immediately since initialization is
|
| + // completed.
|
| + SetCdmAndExpect(true);
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, SetCdmAfterInitialize_EncryptedStream_Success) {
|
| + CreateAudioStream();
|
| + CreateEncryptedVideoStream();
|
| +
|
| + SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| + SetVideoRendererInitializeExpectations(PIPELINE_OK);
|
| + InitializeAndExpect(PIPELINE_OK);
|
| + // Initialization is pending until CDM is set.
|
| + EXPECT_EQ(PIPELINE_ERROR_OPERATION_PENDING, initialization_status_);
|
| +
|
| + SetCdmAndExpect(true);
|
| + EXPECT_EQ(PIPELINE_OK, initialization_status_);
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, SetCdmAfterInitialize_EncryptedStream_Failure) {
|
| + CreateAudioStream();
|
| + CreateEncryptedVideoStream();
|
| +
|
| + SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| + SetVideoRendererInitializeExpectations(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| + InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| + // Initialization is pending until CDM is set.
|
| + EXPECT_EQ(PIPELINE_ERROR_OPERATION_PENDING, initialization_status_);
|
| +
|
| + SetCdmAndExpect(false);
|
| + EXPECT_EQ(PIPELINE_ERROR_INITIALIZATION_FAILED, initialization_status_);
|
| +}
|
| +
|
| +TEST_F(RendererImplTest, SetCdmMultipleTimes) {
|
| + SetCdmAndExpect(true);
|
| + SetCdmAndExpect(false); // Do not support switching CDM.
|
| +}
|
| +
|
| TEST_F(RendererImplTest, StartPlayingFrom) {
|
| InitializeWithAudioAndVideo();
|
| Play();
|
|
|