| Index: media/base/android/media_source_player_unittest.cc
|
| diff --git a/media/base/android/media_source_player_unittest.cc b/media/base/android/media_source_player_unittest.cc
|
| index e329ac6eee6dc529fc3f4f6f46c40146036f6f21..8b33f13899d2e6466a3e7c8f256d272bef3570b2 100644
|
| --- a/media/base/android/media_source_player_unittest.cc
|
| +++ b/media/base/android/media_source_player_unittest.cc
|
| @@ -11,6 +11,7 @@
|
| #include "media/base/android/media_drm_bridge.h"
|
| #include "media/base/android/media_player_manager.h"
|
| #include "media/base/android/media_source_player.h"
|
| +#include "media/base/bind_to_loop.h"
|
| #include "media/base/decoder_buffer.h"
|
| #include "media/base/test_data_util.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| @@ -142,6 +143,7 @@ class MediaSourcePlayerTest : public testing::Test {
|
| : manager_(&message_loop_),
|
| demuxer_(new MockDemuxerAndroid(&message_loop_)),
|
| player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)),
|
| + decoder_callback_hook_executed_(false),
|
| surface_texture_a_is_next_(true) {}
|
| virtual ~MediaSourcePlayerTest() {}
|
|
|
| @@ -167,6 +169,45 @@ class MediaSourcePlayerTest : public testing::Test {
|
| return player_.preroll_timestamp_;
|
| }
|
|
|
| + // Simulate player has reached starvation timeout.
|
| + void TriggerPlayerStarvation() {
|
| + player_.decoder_starvation_callback_.Cancel();
|
| + player_.OnDecoderStarved();
|
| + }
|
| +
|
| + // Release() the player.
|
| + void ReleasePlayer() {
|
| + EXPECT_TRUE(player_.IsPlaying());
|
| + player_.Release();
|
| + EXPECT_FALSE(player_.IsPlaying());
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_FALSE(GetMediaDecoderJob(false));
|
| + }
|
| +
|
| + // Upon the next successful decode callback, post a task to call Release()
|
| + // on the |player_|. TEST_F's do not have access to the private player
|
| + // members, hence this helper method.
|
| + // Prevent usage creep of MSP::set_decode_callback_for_testing() by
|
| + // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
|
| + void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
|
| + player_.set_decode_callback_for_testing(media::BindToLoop(
|
| + message_loop_.message_loop_proxy(),
|
| + base::Bind(
|
| + &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification,
|
| + base::Unretained(this))));
|
| + }
|
| +
|
| + // Asynch test callback posted upon decode completion to verify that a pending
|
| + // prefetch done event is cleared across |player_|'s Release(). This helps
|
| + // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
|
| + void ReleaseWithPendingPrefetchDoneVerification() {
|
| + EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
|
| + ReleasePlayer();
|
| + EXPECT_FALSE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
|
| + EXPECT_FALSE(decoder_callback_hook_executed_);
|
| + decoder_callback_hook_executed_ = true;
|
| + }
|
| +
|
| DemuxerConfigs CreateAudioDemuxerConfigs() {
|
| DemuxerConfigs configs;
|
| configs.audio_codec = kCodecVorbis;
|
| @@ -267,6 +308,30 @@ class MediaSourcePlayerTest : public testing::Test {
|
| return data;
|
| }
|
|
|
| + // Helper method for use at test start. It starts an audio decoder job and
|
| + // immediately feeds it some data to decode. Then, without letting the decoder
|
| + // job complete a decode cycle, it also starts player SeekTo(). Upon return,
|
| + // the player should not yet have sent the DemuxerSeek IPC request, though
|
| + // seek event should be pending. The audio decoder job will also still be
|
| + // decoding.
|
| + void StartAudioDecoderJobAndSeekToWhileDecoding(
|
| + const base::TimeDelta& seek_time) {
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_FALSE(player_.IsPlaying());
|
| + EXPECT_EQ(0, demuxer_->num_data_requests());
|
| + EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_EQ(player_.GetCurrentTime(), GetPrerollTimestamp());
|
| + StartAudioDecoderJob();
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
|
| + player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
|
| + EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
|
| + player_.SeekTo(seek_time);
|
| + EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| + EXPECT_EQ(0, demuxer_->num_seek_requests());
|
| + }
|
| +
|
| // Seek, including simulated receipt of |kAborted| read between SeekTo()
|
| // and OnDemuxerSeekDone(). Use this helper method only when the player
|
| // already has created the decoder job.
|
| @@ -336,7 +401,7 @@ class MediaSourcePlayerTest : public testing::Test {
|
| EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
|
|
|
| if (trigger_with_release_start) {
|
| - player_.Release();
|
| + ReleasePlayer();
|
|
|
| // Simulate demuxer's response to the video data request.
|
| player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
|
| @@ -468,12 +533,14 @@ class MediaSourcePlayerTest : public testing::Test {
|
| scheme_uuid, security_level, container, codecs);
|
| }
|
|
|
| - protected:
|
| base::MessageLoop message_loop_;
|
| MockMediaPlayerManager manager_;
|
| MockDemuxerAndroid* demuxer_; // Owned by |player_|.
|
| MediaSourcePlayer player_;
|
|
|
| + // Track whether a possibly asynch decoder callback test hook has run.
|
| + bool decoder_callback_hook_executed_;
|
| +
|
| // We need to keep the surface texture while the decoder is actively decoding.
|
| // Otherwise, it may trigger unexpected crashes on some devices. To switch
|
| // surfaces, tests need to create a new surface texture without releasing
|
| @@ -912,7 +979,7 @@ TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) {
|
| EXPECT_EQ(1, demuxer_->num_data_requests());
|
| EXPECT_TRUE(GetMediaDecoderJob(true));
|
|
|
| - player_.Release();
|
| + ReleasePlayer();
|
| player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
|
|
|
| // The decoder job should have been released.
|
| @@ -964,8 +1031,7 @@ TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) {
|
| EXPECT_EQ(1, demuxer_->num_data_requests());
|
| EXPECT_TRUE(GetMediaDecoderJob(false));
|
|
|
| - player_.Release();
|
| - EXPECT_FALSE(player_.IsPlaying());
|
| + ReleasePlayer();
|
|
|
| // Pass a new non-empty surface.
|
| CreateNextTextureAndSetVideoSurface();
|
| @@ -986,7 +1052,6 @@ TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) {
|
| // Test that one browser seek is requested if player Release() + Start(), with
|
| // video data received between Release() and Start().
|
| BrowserSeekPlayer(true);
|
| - EXPECT_FALSE(GetMediaDecoderJob(false));
|
| EXPECT_EQ(1, demuxer_->num_data_requests());
|
|
|
| // Simulate browser seek is done and confirm player requests more data.
|
| @@ -1140,7 +1205,7 @@ TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossReleaseAndStart) {
|
| // first request's data arrives before Start(). Though that data is not
|
| // seen by decoder, this assumption allows preroll continuation
|
| // verification and prevents multiple in-flight data requests.
|
| - player_.Release();
|
| + ReleasePlayer();
|
| player_.OnDemuxerDataAvailable(data);
|
| message_loop_.RunUntilIdle();
|
| EXPECT_FALSE(GetMediaDecoderJob(true));
|
| @@ -1379,6 +1444,270 @@ TEST_F(MediaSourcePlayerTest, NewSurfaceWhileChangingConfigs) {
|
| EXPECT_EQ(0, demuxer_->num_seek_requests());
|
| }
|
|
|
| +TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if OnPrefetchDone() had already been posted before and is executed
|
| + // after Release(), then player does not DCHECK. This test is fragile to
|
| + // change to MediaDecoderJob::Prefetch() implementation; it assumes task
|
| + // is posted to run |prefetch_cb| if the job already HasData().
|
| + // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
|
| + // becomes obsolete. See http://crbug.com/304234.
|
| + StartAudioDecoderJob();
|
| +
|
| + // Escape the original prefetch by decoding a single access unit.
|
| + player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
|
| + message_loop_.Run();
|
| +
|
| + // Prime the job with a few more access units, so that a later prefetch,
|
| + // triggered by starvation to simulate decoder underrun, can trivially
|
| + // post task to run OnPrefetchDone().
|
| + player_.OnDemuxerDataAvailable(
|
| + CreateReadFromDemuxerAckWithConfigChanged(true, 4));
|
| + EXPECT_TRUE(GetMediaDecoderJob(true) &&
|
| + GetMediaDecoderJob(true)->is_decoding());
|
| +
|
| + // Simulate decoder underrun, so trivial prefetch starts while still decoding.
|
| + // The prefetch and posting of OnPrefetchDone() will not occur until next
|
| + // MediaDecoderCallBack() occurs.
|
| + TriggerPlayerStarvation();
|
| +
|
| + // Upon the next successful decode callback, post a task to call Release() on
|
| + // the |player_|, such that the trivial OnPrefetchDone() task posting also
|
| + // occurs and should execute after the Release().
|
| + OnNextTestDecodeCallbackPostTaskToReleasePlayer();
|
| +
|
| + while (GetMediaDecoderJob(true))
|
| + message_loop_.RunUntilIdle();
|
| + EXPECT_TRUE(decoder_callback_hook_executed_);
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // Player should have no decoder job until after Start().
|
| + StartAudioDecoderJob();
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
|
| + // has not yet been sent, then the seek request is sent after Release(). Also,
|
| + // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
|
| + // will resume correct post-seek preroll upon Start().
|
| + StartAudioDecoderJobAndSeekToWhileDecoding(
|
| + base::TimeDelta::FromMilliseconds(100));
|
| + ReleasePlayer();
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +
|
| + player_.OnDemuxerSeekDone(kNoTimestamp());
|
| + EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_FALSE(player_.IsPlaying());
|
| +
|
| + // Player should begin prefetch and resume preroll upon Start().
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| + StartAudioDecoderJob();
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_TRUE(IsPrerolling(true));
|
| + EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further seek should have been requested since Release(), above.
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
|
| + // has not yet been sent, then the seek request is sent after Release(). Also,
|
| + // test if OnDemuxerSeekDone() does not occur until after the next Start(),
|
| + // then the player remains pending seek done until (and resumes correct
|
| + // post-seek preroll after) OnDemuxerSeekDone().
|
| + StartAudioDecoderJobAndSeekToWhileDecoding(
|
| + base::TimeDelta::FromMilliseconds(100));
|
| + ReleasePlayer();
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +
|
| + // Player should not prefetch upon Start() nor create the decoder job, due to
|
| + // awaiting DemuxerSeekDone.
|
| + StartAudioDecoderJob();
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| +
|
| + player_.OnDemuxerSeekDone(kNoTimestamp());
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_TRUE(IsPrerolling(true));
|
| + EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further seek should have been requested since Release(), above.
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
|
| + // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
|
| + // player will resume correct post-seek preroll upon Start().
|
| + StartAudioDecoderJobAndSeekToWhileDecoding(
|
| + base::TimeDelta::FromMilliseconds(100));
|
| + while (GetMediaDecoderJob(true)->is_decoding())
|
| + message_loop_.RunUntilIdle();
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +
|
| + ReleasePlayer();
|
| + player_.OnDemuxerSeekDone(kNoTimestamp());
|
| + EXPECT_FALSE(player_.IsPlaying());
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
|
| +
|
| + // Player should begin prefetch and resume preroll upon Start().
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| + StartAudioDecoderJob();
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_TRUE(IsPrerolling(true));
|
| + EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further seek should have been requested since before Release(), above.
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
|
| + // request OnDemuxerSeekDone() does not occur until after the next Start(),
|
| + // then the player remains pending seek done until (and resumes correct
|
| + // post-seek preroll after) OnDemuxerSeekDone().
|
| + StartAudioDecoderJobAndSeekToWhileDecoding(
|
| + base::TimeDelta::FromMilliseconds(100));
|
| + while (GetMediaDecoderJob(true)->is_decoding())
|
| + message_loop_.RunUntilIdle();
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +
|
| + ReleasePlayer();
|
| + StartAudioDecoderJob();
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| +
|
| + player_.OnDemuxerSeekDone(kNoTimestamp());
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_TRUE(IsPrerolling(true));
|
| + EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further seek should have been requested since before Release(), above.
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenConfigsAvailable) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if Release() occurs after |kConfigChanged| detected, new configs
|
| + // requested of demuxer, and the requested configs arrive before the next
|
| + // Start(), then the player completes the pending config change processing on
|
| + // their receipt.
|
| + StartConfigChange(true, true, 0);
|
| + ReleasePlayer();
|
| +
|
| + player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_FALSE(player_.IsPlaying());
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| +
|
| + // Player should resume upon Start(), even without further configs supplied.
|
| + player_.Start();
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_TRUE(player_.IsPlaying());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further config request should have occurred since StartConfigChange().
|
| + EXPECT_EQ(1, demuxer_->num_config_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test if Release() occurs after |kConfigChanged| detected, new configs
|
| + // requested of demuxer, and the requested configs arrive after the next
|
| + // Start(), then the player pends job creation until the new configs arrive.
|
| + StartConfigChange(true, true, 0);
|
| + ReleasePlayer();
|
| +
|
| + player_.Start();
|
| + EXPECT_TRUE(player_.IsPlaying());
|
| + EXPECT_FALSE(GetMediaDecoderJob(true));
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| +
|
| + player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
|
| + EXPECT_TRUE(GetMediaDecoderJob(true));
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further config request should have occurred since StartConfigChange().
|
| + EXPECT_EQ(1, demuxer_->num_config_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test that Release() after a browser seek's DemuxerSeek IPC request has been
|
| + // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
|
| + // before the next Start()+SetVideoSurface(), then the player will resume
|
| + // correct post-seek preroll upon Start()+SetVideoSurface().
|
| + BrowserSeekPlayer(false);
|
| + base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
|
| + ReleasePlayer();
|
| +
|
| + player_.OnDemuxerSeekDone(expected_preroll_timestamp);
|
| + EXPECT_FALSE(player_.IsPlaying());
|
| + EXPECT_FALSE(GetMediaDecoderJob(false));
|
| + EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
|
| +
|
| + // Player should begin prefetch and resume preroll upon Start().
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| + StartVideoDecoderJob();
|
| + CreateNextTextureAndSetVideoSurface();
|
| + EXPECT_TRUE(GetMediaDecoderJob(false));
|
| + EXPECT_TRUE(IsPrerolling(false));
|
| + EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
|
| + EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further seek should have been requested since BrowserSeekPlayer().
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +}
|
| +
|
| +TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // Test that Release() after a browser seek's DemuxerSeek IPC request has been
|
| + // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
|
| + // occur until after the next Start()+SetVideoSurface(), then the player
|
| + // remains pending seek done until (and resumes correct post-seek preroll
|
| + // after) OnDemuxerSeekDone().
|
| + BrowserSeekPlayer(false);
|
| + base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
|
| + ReleasePlayer();
|
| +
|
| + StartVideoDecoderJob();
|
| + CreateNextTextureAndSetVideoSurface();
|
| + EXPECT_FALSE(GetMediaDecoderJob(false));
|
| + EXPECT_EQ(1, demuxer_->num_data_requests());
|
| +
|
| + player_.OnDemuxerSeekDone(expected_preroll_timestamp);
|
| + EXPECT_TRUE(GetMediaDecoderJob(false));
|
| + EXPECT_TRUE(IsPrerolling(false));
|
| + EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
|
| + EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
|
| + EXPECT_EQ(2, demuxer_->num_data_requests());
|
| +
|
| + // No further seek should have been requested since BrowserSeekPlayer().
|
| + EXPECT_EQ(1, demuxer_->num_seek_requests());
|
| +}
|
| +
|
| // TODO(xhwang): Enable this test when the test devices are updated.
|
| TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) {
|
| if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
|
|
|