| Index: media/blink/webmediaplayer_impl_unittest.cc
|
| diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc
|
| index e66351be6ca3629b9923dc00bd4da347dd150d4d..5bd42ca109356a29dd826e90e8fb3d4a4d0b4244 100644
|
| --- a/media/blink/webmediaplayer_impl_unittest.cc
|
| +++ b/media/blink/webmediaplayer_impl_unittest.cc
|
| @@ -33,6 +33,7 @@
|
| #include "third_party/WebKit/public/platform/WebSize.h"
|
| #include "third_party/WebKit/public/web/WebFrameClient.h"
|
| #include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| +#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
|
| #include "third_party/WebKit/public/web/WebView.h"
|
| #include "url/gurl.h"
|
|
|
| @@ -123,7 +124,6 @@ class MockWebMediaPlayerDelegate : public WebMediaPlayerDelegate {
|
| MOCK_METHOD4(DidPlay, void(int, bool, bool, MediaContentType));
|
| MOCK_METHOD1(DidPause, void(int));
|
| MOCK_METHOD1(PlayerGone, void(int));
|
| - MOCK_METHOD0(IsBackgroundVideoPlaybackUnlocked, bool());
|
|
|
| void SetIdle(int player_id, bool is_idle) override {
|
| DCHECK_EQ(player_id_, player_id);
|
| @@ -281,27 +281,39 @@ class WebMediaPlayerImplTest : public testing::Test {
|
| wmpi_->SetDelegateState(state, false);
|
| }
|
|
|
| - bool ShouldDisableVideoWhenHidden() const {
|
| - return wmpi_->ShouldDisableVideoWhenHidden();
|
| + void SetUpMediaSuspend(bool enable) {
|
| +#if defined(OS_ANDROID)
|
| + if (!enable) {
|
| + base::CommandLine::ForCurrentProcess()->AppendSwitch(
|
| + switches::kDisableMediaSuspend);
|
| + }
|
| +#else
|
| + if (enable) {
|
| + base::CommandLine::ForCurrentProcess()->AppendSwitch(
|
| + switches::kEnableMediaSuspend);
|
| + }
|
| +#endif
|
| }
|
|
|
| - bool ShouldPauseVideoWhenHidden() const {
|
| - return wmpi_->ShouldPauseVideoWhenHidden();
|
| + bool IsVideoLockedWhenPausedWhenHidden() const {
|
| + return wmpi_->video_locked_when_paused_when_hidden_;
|
| }
|
|
|
| - bool IsBackgroundOptimizationCandidate() const {
|
| - return wmpi_->IsBackgroundOptimizationCandidate();
|
| + void BackgroundPlayer() {
|
| + delegate_.SetFrameHiddenForTesting(true);
|
| + delegate_.SetFrameClosedForTesting(false);
|
| + wmpi_->OnFrameHidden();
|
| }
|
|
|
| - void SetVideoKeyframeDistanceAverage(base::TimeDelta value) {
|
| - PipelineStatistics statistics;
|
| - statistics.video_keyframe_distance_average = value;
|
| - wmpi_->SetPipelineStatisticsForTest(statistics);
|
| + void ForegroundPlayer() {
|
| + delegate_.SetFrameHiddenForTesting(false);
|
| + delegate_.SetFrameClosedForTesting(false);
|
| + wmpi_->OnFrameShown();
|
| }
|
|
|
| - void SetDuration(base::TimeDelta value) {
|
| - wmpi_->SetPipelineMediaDurationForTest(value);
|
| - }
|
| + void Play() { wmpi_->play(); }
|
| +
|
| + void Pause() { wmpi_->pause(); }
|
|
|
| // "Renderer" thread.
|
| base::MessageLoop message_loop_;
|
| @@ -459,27 +471,59 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHidden) {
|
| SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData);
|
| SetPaused(false);
|
|
|
| - {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo);
|
| + WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state);
|
| + EXPECT_FALSE(state.is_idle);
|
| + EXPECT_FALSE(state.is_suspended);
|
| + EXPECT_TRUE(state.is_memory_reporting_enabled);
|
| +}
|
|
|
| - WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state);
|
| - EXPECT_TRUE(state.is_idle);
|
| - EXPECT_TRUE(state.is_suspended);
|
| - EXPECT_FALSE(state.is_memory_reporting_enabled);
|
| - }
|
| +TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenAudioOnly) {
|
| + InitializeWebMediaPlayerImpl(true);
|
| + SetMetadata(true, true);
|
| + SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData);
|
| + SetPaused(false);
|
|
|
| - {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndDisableFeature(kResumeBackgroundVideo);
|
| + SetMetadata(true, false);
|
| + WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state);
|
| + EXPECT_FALSE(state.is_idle);
|
| + EXPECT_FALSE(state.is_suspended);
|
| + EXPECT_TRUE(state.is_memory_reporting_enabled);
|
| +}
|
|
|
| - WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state);
|
| - EXPECT_TRUE(state.is_idle);
|
| - EXPECT_TRUE(state.is_suspended);
|
| - EXPECT_FALSE(state.is_memory_reporting_enabled);
|
| - }
|
| +TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendNoResume) {
|
| + SetUpMediaSuspend(true);
|
| + base::test::ScopedFeatureList scoped_feature_list;
|
| + scoped_feature_list.InitAndDisableFeature(kResumeBackgroundVideo);
|
| +
|
| + InitializeWebMediaPlayerImpl(true);
|
| + SetMetadata(true, true);
|
| + SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData);
|
| + SetPaused(false);
|
| +
|
| + WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state);
|
| + EXPECT_TRUE(state.is_idle);
|
| + EXPECT_FALSE(state.is_suspended);
|
| + EXPECT_TRUE(state.is_memory_reporting_enabled);
|
| +}
|
| +
|
| +TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendWithResume) {
|
| + SetUpMediaSuspend(true);
|
| + base::test::ScopedFeatureList scoped_feature_list;
|
| + scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo);
|
| +
|
| + InitializeWebMediaPlayerImpl(true);
|
| + SetMetadata(true, true);
|
| + SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData);
|
| + SetPaused(false);
|
| +
|
| + WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state);
|
| + EXPECT_FALSE(state.is_idle);
|
| + EXPECT_FALSE(state.is_suspended);
|
| + EXPECT_TRUE(state.is_memory_reporting_enabled);
|
| }
|
|
|
| TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameClosed) {
|
| @@ -598,38 +642,6 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Streaming) {
|
| EXPECT_FALSE(state.is_memory_reporting_enabled);
|
| }
|
|
|
| -TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingBackgroundedVideo) {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo);
|
| -
|
| - InitializeWebMediaPlayerImpl(true);
|
| - SetMetadata(true, true);
|
| - SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData);
|
| - SetPaused(false);
|
| - EXPECT_CALL(delegate_, IsBackgroundVideoPlaybackUnlocked())
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state);
|
| - EXPECT_FALSE(state.is_idle);
|
| - EXPECT_FALSE(state.is_suspended);
|
| - EXPECT_TRUE(state.is_memory_reporting_enabled);
|
| -}
|
| -
|
| -TEST_F(WebMediaPlayerImplTest, ComputePlayState_AudioOnly) {
|
| - InitializeWebMediaPlayerImpl(true);
|
| - SetMetadata(true, false);
|
| - SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData);
|
| - SetPaused(false);
|
| -
|
| - // Backgrounded audio-only playback stays playing.
|
| - WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden();
|
| - EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state);
|
| - EXPECT_FALSE(state.is_idle);
|
| - EXPECT_FALSE(state.is_suspended);
|
| - EXPECT_TRUE(state.is_memory_reporting_enabled);
|
| -}
|
| -
|
| TEST_F(WebMediaPlayerImplTest, AutoplayMuted_StartsAndStops) {
|
| InitializeWebMediaPlayerImpl(true);
|
| SetMetadata(true, true);
|
| @@ -689,102 +701,196 @@ TEST_F(WebMediaPlayerImplTest, NaturalSizeChange_Rotated) {
|
| ASSERT_EQ(blink::WebSize(1080, 1920), wmpi_->naturalSize());
|
| }
|
|
|
| -TEST_F(WebMediaPlayerImplTest, BackgroundOptimizationsFeatureEnabled) {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndEnableFeature(kBackgroundVideoTrackOptimization);
|
| +TEST_F(WebMediaPlayerImplTest, VideoLockedWhenPausedWhenHidden) {
|
| InitializeWebMediaPlayerImpl(true);
|
| - SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5));
|
| - SetDuration(base::TimeDelta::FromSeconds(300));
|
|
|
| - // Audible video.
|
| - SetMetadata(true, true);
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_TRUE(ShouldDisableVideoWhenHidden());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| + // Setting metadata initializes |watch_time_reporter_| used in play().
|
| + PipelineMetadata metadata;
|
| + metadata.has_video = true;
|
| + OnMetadata(metadata);
|
|
|
| - // Video only.
|
| - SetMetadata(false, true);
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_TRUE(ShouldPauseVideoWhenHidden());
|
| - EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| + EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden());
|
|
|
| - // Audio only.
|
| - SetMetadata(true, false);
|
| - EXPECT_FALSE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| - EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| + // Backgrounding the player sets the lock.
|
| + BackgroundPlayer();
|
| + EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden());
|
|
|
| - // Duration is shorter than max video keyframe distance.
|
| - SetDuration(base::TimeDelta::FromSeconds(5));
|
| - SetMetadata(true, true);
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| - EXPECT_TRUE(ShouldDisableVideoWhenHidden());
|
| + // Play without a user gesture doesn't unlock the player.
|
| + Play();
|
| + EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden());
|
|
|
| - // Average keyframe distance is too big.
|
| - SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100));
|
| - SetDuration(base::TimeDelta::FromSeconds(300));
|
| - EXPECT_FALSE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| - EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| + // With a user gesture it does unlock the player.
|
| + {
|
| + blink::WebScopedUserGesture user_gesture(nullptr);
|
| + Play();
|
| + EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden());
|
| + }
|
| +
|
| + // Pause without a user gesture doesn't lock the player.
|
| + Pause();
|
| + EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden());
|
| +
|
| + // With a user gesture, pause does lock the player.
|
| + {
|
| + blink::WebScopedUserGesture user_gesture(nullptr);
|
| + Pause();
|
| + EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden());
|
| + }
|
| +
|
| + // Foregrounding the player unsets the lock.
|
| + ForegroundPlayer();
|
| + EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden());
|
| }
|
|
|
| -TEST_F(WebMediaPlayerImplTest, BackgroundOptimizationsFeatureDisabled) {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndDisableFeature(kBackgroundVideoTrackOptimization);
|
| +class WebMediaPlayerImplBackgroundBehaviorTest
|
| + : public WebMediaPlayerImplTest,
|
| + public ::testing::WithParamInterface<
|
| + std::tuple<bool, bool, int, int, bool>> {
|
| + public:
|
| + // Indices of the tuple parameters.
|
| + static const int kIsMediaSuspendEnabled = 0;
|
| + static const int kIsBackgroundOptimizationEnabled = 1;
|
| + static const int kDurationSec = 2;
|
| + static const int kAverageKeyframeDistanceSec = 3;
|
| + static const int kIsResumeBackgroundVideoEnabled = 4;
|
| +
|
| + void SetUp() override {
|
| + WebMediaPlayerImplTest::SetUp();
|
| +
|
| + SetUpMediaSuspend(IsMediaSuspendOn());
|
| +
|
| + std::string enabled_features;
|
| + std::string disabled_features;
|
| + if (IsBackgroundOptimizationOn()) {
|
| + enabled_features += kBackgroundVideoTrackOptimization.name;
|
| + } else {
|
| + disabled_features += kBackgroundVideoTrackOptimization.name;
|
| + }
|
|
|
| - InitializeWebMediaPlayerImpl(true);
|
| - SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5));
|
| - SetDuration(base::TimeDelta::FromSeconds(300));
|
| + if (IsResumeBackgroundVideoEnabled()) {
|
| + if (!enabled_features.empty())
|
| + enabled_features += ",";
|
| + enabled_features += kResumeBackgroundVideo.name;
|
| + } else {
|
| + if (!disabled_features.empty())
|
| + disabled_features += ",";
|
| + disabled_features += kResumeBackgroundVideo.name;
|
| + }
|
|
|
| - // Audible video.
|
| - SetMetadata(true, true);
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| + feature_list_.InitFromCommandLine(enabled_features, disabled_features);
|
|
|
| - // Video only (pausing is enabled on Android).
|
| - SetMetadata(false, true);
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| -#if defined(OS_ANDROID)
|
| - EXPECT_TRUE(ShouldPauseVideoWhenHidden());
|
| + InitializeWebMediaPlayerImpl(true);
|
| + SetVideoKeyframeDistanceAverage(
|
| + base::TimeDelta::FromSeconds(GetAverageKeyframeDistanceSec()));
|
| + SetDuration(base::TimeDelta::FromSeconds(GetDurationSec()));
|
| + BackgroundPlayer();
|
| + }
|
|
|
| - // On Android, the duration and keyframe distance don't matter for video-only.
|
| - SetDuration(base::TimeDelta::FromSeconds(5));
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_TRUE(ShouldPauseVideoWhenHidden());
|
| + void SetDuration(base::TimeDelta value) {
|
| + wmpi_->SetPipelineMediaDurationForTest(value);
|
| + }
|
|
|
| - SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100));
|
| - SetDuration(base::TimeDelta::FromSeconds(300));
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_TRUE(ShouldPauseVideoWhenHidden());
|
| + void SetVideoKeyframeDistanceAverage(base::TimeDelta value) {
|
| + PipelineStatistics statistics;
|
| + statistics.video_keyframe_distance_average = value;
|
| + wmpi_->SetPipelineStatisticsForTest(statistics);
|
| + }
|
| +
|
| + bool IsMediaSuspendOn() {
|
| + return std::get<kIsMediaSuspendEnabled>(GetParam());
|
| + }
|
| +
|
| + bool IsBackgroundOptimizationOn() {
|
| + return std::get<kIsBackgroundOptimizationEnabled>(GetParam());
|
| + }
|
|
|
| - // Restore average keyframe distance.
|
| - SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5));
|
| + bool IsResumeBackgroundVideoEnabled() {
|
| + return std::get<kIsResumeBackgroundVideoEnabled>(GetParam());
|
| + }
|
| +
|
| + int GetDurationSec() const { return std::get<kDurationSec>(GetParam()); }
|
| +
|
| + int GetAverageKeyframeDistanceSec() const {
|
| + return std::get<kAverageKeyframeDistanceSec>(GetParam());
|
| + }
|
| +
|
| + bool IsAndroid() {
|
| +#if defined(OS_ANDROID)
|
| + return true;
|
| #else
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| + return false;
|
| #endif
|
| + }
|
| +
|
| + bool ShouldDisableVideoWhenHidden() const {
|
| + return wmpi_->ShouldDisableVideoWhenHidden();
|
| + }
|
|
|
| - // Audio only.
|
| + bool ShouldPauseVideoWhenHidden() const {
|
| + return wmpi_->ShouldPauseVideoWhenHidden();
|
| + }
|
| +
|
| + bool IsBackgroundOptimizationCandidate() const {
|
| + return wmpi_->IsBackgroundOptimizationCandidate();
|
| + }
|
| +
|
| + private:
|
| + base::test::ScopedFeatureList feature_list_;
|
| +};
|
| +
|
| +TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, AudioOnly) {
|
| + // Never optimize or pause an audio-only player.
|
| SetMetadata(true, false);
|
| EXPECT_FALSE(IsBackgroundOptimizationCandidate());
|
| EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| +}
|
|
|
| - // Duration is shorter than max video keyframe distance.
|
| - SetDuration(base::TimeDelta::FromSeconds(5));
|
| - SetMetadata(true, true);
|
| - EXPECT_TRUE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| - EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| +TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, VideoOnly) {
|
| + // Video only.
|
| + SetMetadata(false, true);
|
|
|
| - // Average keyframe distance is too big.
|
| - SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100));
|
| - SetDuration(base::TimeDelta::FromSeconds(300));
|
| - EXPECT_FALSE(IsBackgroundOptimizationCandidate());
|
| - EXPECT_FALSE(ShouldPauseVideoWhenHidden());
|
| + // Never disable video track for a video only stream.
|
| EXPECT_FALSE(ShouldDisableVideoWhenHidden());
|
| +
|
| + // There's no optimization criteria for video only on Android.
|
| + bool matches_requirements =
|
| + IsAndroid() ||
|
| + ((GetDurationSec() < GetAverageKeyframeDistanceSec()) ||
|
| + (GetAverageKeyframeDistanceSec() < 10));
|
| + EXPECT_EQ(matches_requirements, IsBackgroundOptimizationCandidate());
|
| +
|
| + // Video is always paused when suspension is on and only if matches the
|
| + // optimization criteria if the optimization is on.
|
| + bool should_pause = IsMediaSuspendOn() ||
|
| + (IsBackgroundOptimizationOn() && matches_requirements);
|
| + EXPECT_EQ(should_pause, ShouldPauseVideoWhenHidden());
|
| }
|
|
|
| +TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, AudioVideo) {
|
| + SetMetadata(true, true);
|
| +
|
| + // Optimization requirements are the same for all platforms.
|
| + bool matches_requirements =
|
| + (GetDurationSec() < GetAverageKeyframeDistanceSec()) ||
|
| + (GetAverageKeyframeDistanceSec() < 10);
|
| +
|
| + EXPECT_EQ(matches_requirements, IsBackgroundOptimizationCandidate());
|
| + EXPECT_EQ(IsBackgroundOptimizationOn() && matches_requirements,
|
| + ShouldDisableVideoWhenHidden());
|
| +
|
| + // Only pause audible videos on Android if both media suspend and resume
|
| + // background videos is on. On Desktop
|
| + EXPECT_EQ(IsMediaSuspendOn() && IsResumeBackgroundVideoEnabled(),
|
| + ShouldPauseVideoWhenHidden());
|
| +}
|
| +
|
| +INSTANTIATE_TEST_CASE_P(BackgroundBehaviorTestInstances,
|
| + WebMediaPlayerImplBackgroundBehaviorTest,
|
| + ::testing::Combine(::testing::Bool(),
|
| + ::testing::Bool(),
|
| + ::testing::Values(5, 300),
|
| + ::testing::Values(5, 100),
|
| + ::testing::Bool()));
|
| +
|
| } // namespace media
|
|
|