| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/blink/webmediaplayer_impl.h" | 5 #include "media/blink/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "media/blink/webmediaplayer_delegate.h" | 26 #include "media/blink/webmediaplayer_delegate.h" |
| 27 #include "media/blink/webmediaplayer_params.h" | 27 #include "media/blink/webmediaplayer_params.h" |
| 28 #include "media/renderers/default_renderer_factory.h" | 28 #include "media/renderers/default_renderer_factory.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 31 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" | 31 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" |
| 32 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | 32 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
| 33 #include "third_party/WebKit/public/platform/WebSize.h" | 33 #include "third_party/WebKit/public/platform/WebSize.h" |
| 34 #include "third_party/WebKit/public/web/WebFrameClient.h" | 34 #include "third_party/WebKit/public/web/WebFrameClient.h" |
| 35 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 35 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 36 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" |
| 36 #include "third_party/WebKit/public/web/WebView.h" | 37 #include "third_party/WebKit/public/web/WebView.h" |
| 37 #include "url/gurl.h" | 38 #include "url/gurl.h" |
| 38 | 39 |
| 39 using ::testing::AnyNumber; | 40 using ::testing::AnyNumber; |
| 40 using ::testing::InSequence; | 41 using ::testing::InSequence; |
| 41 using ::testing::Return; | 42 using ::testing::Return; |
| 42 using ::testing::_; | 43 using ::testing::_; |
| 43 | 44 |
| 44 namespace media { | 45 namespace media { |
| 45 | 46 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 } | 117 } |
| 117 | 118 |
| 118 void RemoveObserver(int player_id) override { | 119 void RemoveObserver(int player_id) override { |
| 119 DCHECK_EQ(player_id_, player_id); | 120 DCHECK_EQ(player_id_, player_id); |
| 120 observer_ = nullptr; | 121 observer_ = nullptr; |
| 121 } | 122 } |
| 122 | 123 |
| 123 MOCK_METHOD4(DidPlay, void(int, bool, bool, MediaContentType)); | 124 MOCK_METHOD4(DidPlay, void(int, bool, bool, MediaContentType)); |
| 124 MOCK_METHOD1(DidPause, void(int)); | 125 MOCK_METHOD1(DidPause, void(int)); |
| 125 MOCK_METHOD1(PlayerGone, void(int)); | 126 MOCK_METHOD1(PlayerGone, void(int)); |
| 126 MOCK_METHOD0(IsBackgroundVideoPlaybackUnlocked, bool()); | |
| 127 | 127 |
| 128 void SetIdle(int player_id, bool is_idle) override { | 128 void SetIdle(int player_id, bool is_idle) override { |
| 129 DCHECK_EQ(player_id_, player_id); | 129 DCHECK_EQ(player_id_, player_id); |
| 130 is_idle_ = is_idle; | 130 is_idle_ = is_idle; |
| 131 is_stale_ &= is_idle; | 131 is_stale_ &= is_idle; |
| 132 } | 132 } |
| 133 | 133 |
| 134 bool IsIdle(int player_id) override { | 134 bool IsIdle(int player_id) override { |
| 135 DCHECK_EQ(player_id_, player_id); | 135 DCHECK_EQ(player_id_, player_id); |
| 136 return is_idle_; | 136 return is_idle_; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 bool IsSuspended() { return wmpi_->pipeline_controller_.IsSuspended(); } | 274 bool IsSuspended() { return wmpi_->pipeline_controller_.IsSuspended(); } |
| 275 | 275 |
| 276 void AddBufferedRanges() { | 276 void AddBufferedRanges() { |
| 277 wmpi_->buffered_data_source_host_.AddBufferedByteRange(0, 1); | 277 wmpi_->buffered_data_source_host_.AddBufferedByteRange(0, 1); |
| 278 } | 278 } |
| 279 | 279 |
| 280 void SetDelegateState(WebMediaPlayerImpl::DelegateState state) { | 280 void SetDelegateState(WebMediaPlayerImpl::DelegateState state) { |
| 281 wmpi_->SetDelegateState(state, false); | 281 wmpi_->SetDelegateState(state, false); |
| 282 } | 282 } |
| 283 | 283 |
| 284 bool ShouldDisableVideoWhenHidden() const { | 284 void SetUpMediaSuspend(bool enable) { |
| 285 return wmpi_->ShouldDisableVideoWhenHidden(); | 285 #if defined(OS_ANDROID) |
| 286 if (!enable) { |
| 287 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 288 switches::kDisableMediaSuspend); |
| 289 } |
| 290 #else |
| 291 if (enable) { |
| 292 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 293 switches::kEnableMediaSuspend); |
| 294 } |
| 295 #endif |
| 286 } | 296 } |
| 287 | 297 |
| 288 bool ShouldPauseVideoWhenHidden() const { | 298 bool IsVideoLockedWhenPausedWhenHidden() const { |
| 289 return wmpi_->ShouldPauseVideoWhenHidden(); | 299 return wmpi_->video_locked_when_paused_when_hidden_; |
| 290 } | 300 } |
| 291 | 301 |
| 292 bool IsBackgroundOptimizationCandidate() const { | 302 void BackgroundPlayer() { |
| 293 return wmpi_->IsBackgroundOptimizationCandidate(); | 303 delegate_.SetFrameHiddenForTesting(true); |
| 304 delegate_.SetFrameClosedForTesting(false); |
| 305 wmpi_->OnFrameHidden(); |
| 294 } | 306 } |
| 295 | 307 |
| 296 void SetVideoKeyframeDistanceAverage(base::TimeDelta value) { | 308 void ForegroundPlayer() { |
| 297 PipelineStatistics statistics; | 309 delegate_.SetFrameHiddenForTesting(false); |
| 298 statistics.video_keyframe_distance_average = value; | 310 delegate_.SetFrameClosedForTesting(false); |
| 299 wmpi_->SetPipelineStatisticsForTest(statistics); | 311 wmpi_->OnFrameShown(); |
| 300 } | 312 } |
| 301 | 313 |
| 302 void SetDuration(base::TimeDelta value) { | 314 void Play() { wmpi_->play(); } |
| 303 wmpi_->SetPipelineMediaDurationForTest(value); | 315 |
| 304 } | 316 void Pause() { wmpi_->pause(); } |
| 305 | 317 |
| 306 // "Renderer" thread. | 318 // "Renderer" thread. |
| 307 base::MessageLoop message_loop_; | 319 base::MessageLoop message_loop_; |
| 308 | 320 |
| 309 // "Media" thread. This is necessary because WMPI destruction waits on a | 321 // "Media" thread. This is necessary because WMPI destruction waits on a |
| 310 // WaitableEvent. | 322 // WaitableEvent. |
| 311 base::Thread media_thread_; | 323 base::Thread media_thread_; |
| 312 | 324 |
| 313 // Blink state. | 325 // Blink state. |
| 314 blink::WebFrameClient web_frame_client_; | 326 blink::WebFrameClient web_frame_client_; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 EXPECT_FALSE(state.is_suspended); | 464 EXPECT_FALSE(state.is_suspended); |
| 453 EXPECT_TRUE(state.is_memory_reporting_enabled); | 465 EXPECT_TRUE(state.is_memory_reporting_enabled); |
| 454 } | 466 } |
| 455 | 467 |
| 456 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHidden) { | 468 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHidden) { |
| 457 InitializeWebMediaPlayerImpl(true); | 469 InitializeWebMediaPlayerImpl(true); |
| 458 SetMetadata(true, true); | 470 SetMetadata(true, true); |
| 459 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); | 471 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); |
| 460 SetPaused(false); | 472 SetPaused(false); |
| 461 | 473 |
| 462 { | 474 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); |
| 463 base::test::ScopedFeatureList scoped_feature_list; | 475 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); |
| 464 scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo); | 476 EXPECT_FALSE(state.is_idle); |
| 477 EXPECT_FALSE(state.is_suspended); |
| 478 EXPECT_TRUE(state.is_memory_reporting_enabled); |
| 479 } |
| 465 | 480 |
| 466 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); | 481 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenAudioOnly) { |
| 467 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); | 482 InitializeWebMediaPlayerImpl(true); |
| 468 EXPECT_TRUE(state.is_idle); | 483 SetMetadata(true, true); |
| 469 EXPECT_TRUE(state.is_suspended); | 484 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); |
| 470 EXPECT_FALSE(state.is_memory_reporting_enabled); | 485 SetPaused(false); |
| 471 } | |
| 472 | 486 |
| 473 { | 487 SetMetadata(true, false); |
| 474 base::test::ScopedFeatureList scoped_feature_list; | 488 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); |
| 475 scoped_feature_list.InitAndDisableFeature(kResumeBackgroundVideo); | 489 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); |
| 490 EXPECT_FALSE(state.is_idle); |
| 491 EXPECT_FALSE(state.is_suspended); |
| 492 EXPECT_TRUE(state.is_memory_reporting_enabled); |
| 493 } |
| 476 | 494 |
| 477 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); | 495 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendNoResume) { |
| 478 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); | 496 SetUpMediaSuspend(true); |
| 479 EXPECT_TRUE(state.is_idle); | 497 base::test::ScopedFeatureList scoped_feature_list; |
| 480 EXPECT_TRUE(state.is_suspended); | 498 scoped_feature_list.InitAndDisableFeature(kResumeBackgroundVideo); |
| 481 EXPECT_FALSE(state.is_memory_reporting_enabled); | 499 |
| 482 } | 500 InitializeWebMediaPlayerImpl(true); |
| 501 SetMetadata(true, true); |
| 502 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); |
| 503 SetPaused(false); |
| 504 |
| 505 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); |
| 506 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); |
| 507 EXPECT_TRUE(state.is_idle); |
| 508 EXPECT_FALSE(state.is_suspended); |
| 509 EXPECT_TRUE(state.is_memory_reporting_enabled); |
| 510 } |
| 511 |
| 512 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendWithResume) { |
| 513 SetUpMediaSuspend(true); |
| 514 base::test::ScopedFeatureList scoped_feature_list; |
| 515 scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo); |
| 516 |
| 517 InitializeWebMediaPlayerImpl(true); |
| 518 SetMetadata(true, true); |
| 519 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); |
| 520 SetPaused(false); |
| 521 |
| 522 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); |
| 523 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); |
| 524 EXPECT_FALSE(state.is_idle); |
| 525 EXPECT_FALSE(state.is_suspended); |
| 526 EXPECT_TRUE(state.is_memory_reporting_enabled); |
| 483 } | 527 } |
| 484 | 528 |
| 485 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameClosed) { | 529 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameClosed) { |
| 486 InitializeWebMediaPlayerImpl(true); | 530 InitializeWebMediaPlayerImpl(true); |
| 487 SetMetadata(true, true); | 531 SetMetadata(true, true); |
| 488 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); | 532 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); |
| 489 SetPaused(false); | 533 SetPaused(false); |
| 490 delegate_.SetFrameClosedForTesting(true); | 534 delegate_.SetFrameClosedForTesting(true); |
| 491 WebMediaPlayerImpl::PlayState state = ComputePlayState(); | 535 WebMediaPlayerImpl::PlayState state = ComputePlayState(); |
| 492 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); | 536 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 | 635 |
| 592 // Streaming media should suspend when the tab is closed, regardless. | 636 // Streaming media should suspend when the tab is closed, regardless. |
| 593 delegate_.SetFrameClosedForTesting(true); | 637 delegate_.SetFrameClosedForTesting(true); |
| 594 state = ComputePlayState_BackgroundedStreaming(); | 638 state = ComputePlayState_BackgroundedStreaming(); |
| 595 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); | 639 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::GONE, state.delegate_state); |
| 596 EXPECT_TRUE(state.is_idle); | 640 EXPECT_TRUE(state.is_idle); |
| 597 EXPECT_TRUE(state.is_suspended); | 641 EXPECT_TRUE(state.is_suspended); |
| 598 EXPECT_FALSE(state.is_memory_reporting_enabled); | 642 EXPECT_FALSE(state.is_memory_reporting_enabled); |
| 599 } | 643 } |
| 600 | 644 |
| 601 TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingBackgroundedVideo) { | |
| 602 base::test::ScopedFeatureList scoped_feature_list; | |
| 603 scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo); | |
| 604 | |
| 605 InitializeWebMediaPlayerImpl(true); | |
| 606 SetMetadata(true, true); | |
| 607 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); | |
| 608 SetPaused(false); | |
| 609 EXPECT_CALL(delegate_, IsBackgroundVideoPlaybackUnlocked()) | |
| 610 .WillRepeatedly(Return(true)); | |
| 611 | |
| 612 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); | |
| 613 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); | |
| 614 EXPECT_FALSE(state.is_idle); | |
| 615 EXPECT_FALSE(state.is_suspended); | |
| 616 EXPECT_TRUE(state.is_memory_reporting_enabled); | |
| 617 } | |
| 618 | |
| 619 TEST_F(WebMediaPlayerImplTest, ComputePlayState_AudioOnly) { | |
| 620 InitializeWebMediaPlayerImpl(true); | |
| 621 SetMetadata(true, false); | |
| 622 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); | |
| 623 SetPaused(false); | |
| 624 | |
| 625 // Backgrounded audio-only playback stays playing. | |
| 626 WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); | |
| 627 EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); | |
| 628 EXPECT_FALSE(state.is_idle); | |
| 629 EXPECT_FALSE(state.is_suspended); | |
| 630 EXPECT_TRUE(state.is_memory_reporting_enabled); | |
| 631 } | |
| 632 | |
| 633 TEST_F(WebMediaPlayerImplTest, AutoplayMuted_StartsAndStops) { | 645 TEST_F(WebMediaPlayerImplTest, AutoplayMuted_StartsAndStops) { |
| 634 InitializeWebMediaPlayerImpl(true); | 646 InitializeWebMediaPlayerImpl(true); |
| 635 SetMetadata(true, true); | 647 SetMetadata(true, true); |
| 636 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); | 648 SetReadyState(blink::WebMediaPlayer::ReadyStateHaveFutureData); |
| 637 SetPaused(false); | 649 SetPaused(false); |
| 638 client_.set_is_autoplaying_muted(true); | 650 client_.set_is_autoplaying_muted(true); |
| 639 | 651 |
| 640 EXPECT_CALL(delegate_, DidPlay(_, true, false, _)); | 652 EXPECT_CALL(delegate_, DidPlay(_, true, false, _)); |
| 641 SetDelegateState(WebMediaPlayerImpl::DelegateState::PLAYING); | 653 SetDelegateState(WebMediaPlayerImpl::DelegateState::PLAYING); |
| 642 | 654 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 metadata.video_rotation = VIDEO_ROTATION_90; | 694 metadata.video_rotation = VIDEO_ROTATION_90; |
| 683 | 695 |
| 684 OnMetadata(metadata); | 696 OnMetadata(metadata); |
| 685 ASSERT_EQ(blink::WebSize(320, 240), wmpi_->naturalSize()); | 697 ASSERT_EQ(blink::WebSize(320, 240), wmpi_->naturalSize()); |
| 686 | 698 |
| 687 // For 90/270deg rotations, the natural size should be transposed. | 699 // For 90/270deg rotations, the natural size should be transposed. |
| 688 OnVideoNaturalSizeChange(gfx::Size(1920, 1080)); | 700 OnVideoNaturalSizeChange(gfx::Size(1920, 1080)); |
| 689 ASSERT_EQ(blink::WebSize(1080, 1920), wmpi_->naturalSize()); | 701 ASSERT_EQ(blink::WebSize(1080, 1920), wmpi_->naturalSize()); |
| 690 } | 702 } |
| 691 | 703 |
| 692 TEST_F(WebMediaPlayerImplTest, BackgroundOptimizationsFeatureEnabled) { | 704 TEST_F(WebMediaPlayerImplTest, VideoLockedWhenPausedWhenHidden) { |
| 693 base::test::ScopedFeatureList scoped_feature_list; | |
| 694 scoped_feature_list.InitAndEnableFeature(kBackgroundVideoTrackOptimization); | |
| 695 InitializeWebMediaPlayerImpl(true); | 705 InitializeWebMediaPlayerImpl(true); |
| 696 SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5)); | |
| 697 SetDuration(base::TimeDelta::FromSeconds(300)); | |
| 698 | 706 |
| 699 // Audible video. | 707 // Setting metadata initializes |watch_time_reporter_| used in play(). |
| 700 SetMetadata(true, true); | 708 PipelineMetadata metadata; |
| 701 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | 709 metadata.has_video = true; |
| 702 EXPECT_TRUE(ShouldDisableVideoWhenHidden()); | 710 OnMetadata(metadata); |
| 703 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | |
| 704 | 711 |
| 705 // Video only. | 712 EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden()); |
| 706 SetMetadata(false, true); | |
| 707 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | |
| 708 EXPECT_TRUE(ShouldPauseVideoWhenHidden()); | |
| 709 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | |
| 710 | 713 |
| 711 // Audio only. | 714 // Backgrounding the player sets the lock. |
| 715 BackgroundPlayer(); |
| 716 EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden()); |
| 717 |
| 718 // Play without a user gesture doesn't unlock the player. |
| 719 Play(); |
| 720 EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden()); |
| 721 |
| 722 // With a user gesture it does unlock the player. |
| 723 { |
| 724 blink::WebScopedUserGesture user_gesture(nullptr); |
| 725 Play(); |
| 726 EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden()); |
| 727 } |
| 728 |
| 729 // Pause without a user gesture doesn't lock the player. |
| 730 Pause(); |
| 731 EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden()); |
| 732 |
| 733 // With a user gesture, pause does lock the player. |
| 734 { |
| 735 blink::WebScopedUserGesture user_gesture(nullptr); |
| 736 Pause(); |
| 737 EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden()); |
| 738 } |
| 739 |
| 740 // Foregrounding the player unsets the lock. |
| 741 ForegroundPlayer(); |
| 742 EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden()); |
| 743 } |
| 744 |
| 745 class WebMediaPlayerImplBackgroundBehaviorTest |
| 746 : public WebMediaPlayerImplTest, |
| 747 public ::testing::WithParamInterface< |
| 748 std::tuple<bool, bool, int, int, bool>> { |
| 749 public: |
| 750 // Indices of the tuple parameters. |
| 751 static const int kIsMediaSuspendEnabled = 0; |
| 752 static const int kIsBackgroundOptimizationEnabled = 1; |
| 753 static const int kDurationSec = 2; |
| 754 static const int kAverageKeyframeDistanceSec = 3; |
| 755 static const int kIsResumeBackgroundVideoEnabled = 4; |
| 756 |
| 757 void SetUp() override { |
| 758 WebMediaPlayerImplTest::SetUp(); |
| 759 |
| 760 SetUpMediaSuspend(IsMediaSuspendOn()); |
| 761 |
| 762 std::string enabled_features; |
| 763 std::string disabled_features; |
| 764 if (IsBackgroundOptimizationOn()) { |
| 765 enabled_features += kBackgroundVideoTrackOptimization.name; |
| 766 } else { |
| 767 disabled_features += kBackgroundVideoTrackOptimization.name; |
| 768 } |
| 769 |
| 770 if (IsResumeBackgroundVideoEnabled()) { |
| 771 if (!enabled_features.empty()) |
| 772 enabled_features += ","; |
| 773 enabled_features += kResumeBackgroundVideo.name; |
| 774 } else { |
| 775 if (!disabled_features.empty()) |
| 776 disabled_features += ","; |
| 777 disabled_features += kResumeBackgroundVideo.name; |
| 778 } |
| 779 |
| 780 feature_list_.InitFromCommandLine(enabled_features, disabled_features); |
| 781 |
| 782 InitializeWebMediaPlayerImpl(true); |
| 783 SetVideoKeyframeDistanceAverage( |
| 784 base::TimeDelta::FromSeconds(GetAverageKeyframeDistanceSec())); |
| 785 SetDuration(base::TimeDelta::FromSeconds(GetDurationSec())); |
| 786 BackgroundPlayer(); |
| 787 } |
| 788 |
| 789 void SetDuration(base::TimeDelta value) { |
| 790 wmpi_->SetPipelineMediaDurationForTest(value); |
| 791 } |
| 792 |
| 793 void SetVideoKeyframeDistanceAverage(base::TimeDelta value) { |
| 794 PipelineStatistics statistics; |
| 795 statistics.video_keyframe_distance_average = value; |
| 796 wmpi_->SetPipelineStatisticsForTest(statistics); |
| 797 } |
| 798 |
| 799 bool IsMediaSuspendOn() { |
| 800 return std::get<kIsMediaSuspendEnabled>(GetParam()); |
| 801 } |
| 802 |
| 803 bool IsBackgroundOptimizationOn() { |
| 804 return std::get<kIsBackgroundOptimizationEnabled>(GetParam()); |
| 805 } |
| 806 |
| 807 bool IsResumeBackgroundVideoEnabled() { |
| 808 return std::get<kIsResumeBackgroundVideoEnabled>(GetParam()); |
| 809 } |
| 810 |
| 811 int GetDurationSec() const { return std::get<kDurationSec>(GetParam()); } |
| 812 |
| 813 int GetAverageKeyframeDistanceSec() const { |
| 814 return std::get<kAverageKeyframeDistanceSec>(GetParam()); |
| 815 } |
| 816 |
| 817 bool IsAndroid() { |
| 818 #if defined(OS_ANDROID) |
| 819 return true; |
| 820 #else |
| 821 return false; |
| 822 #endif |
| 823 } |
| 824 |
| 825 bool ShouldDisableVideoWhenHidden() const { |
| 826 return wmpi_->ShouldDisableVideoWhenHidden(); |
| 827 } |
| 828 |
| 829 bool ShouldPauseVideoWhenHidden() const { |
| 830 return wmpi_->ShouldPauseVideoWhenHidden(); |
| 831 } |
| 832 |
| 833 bool IsBackgroundOptimizationCandidate() const { |
| 834 return wmpi_->IsBackgroundOptimizationCandidate(); |
| 835 } |
| 836 |
| 837 private: |
| 838 base::test::ScopedFeatureList feature_list_; |
| 839 }; |
| 840 |
| 841 TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, AudioOnly) { |
| 842 // Never optimize or pause an audio-only player. |
| 712 SetMetadata(true, false); | 843 SetMetadata(true, false); |
| 713 EXPECT_FALSE(IsBackgroundOptimizationCandidate()); | 844 EXPECT_FALSE(IsBackgroundOptimizationCandidate()); |
| 714 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | 845 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); |
| 715 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | 846 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); |
| 716 | |
| 717 // Duration is shorter than max video keyframe distance. | |
| 718 SetDuration(base::TimeDelta::FromSeconds(5)); | |
| 719 SetMetadata(true, true); | |
| 720 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | |
| 721 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | |
| 722 EXPECT_TRUE(ShouldDisableVideoWhenHidden()); | |
| 723 | |
| 724 // Average keyframe distance is too big. | |
| 725 SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100)); | |
| 726 SetDuration(base::TimeDelta::FromSeconds(300)); | |
| 727 EXPECT_FALSE(IsBackgroundOptimizationCandidate()); | |
| 728 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | |
| 729 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | |
| 730 } | 847 } |
| 731 | 848 |
| 732 TEST_F(WebMediaPlayerImplTest, BackgroundOptimizationsFeatureDisabled) { | 849 TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, VideoOnly) { |
| 733 base::test::ScopedFeatureList scoped_feature_list; | 850 // Video only. |
| 734 scoped_feature_list.InitAndDisableFeature(kBackgroundVideoTrackOptimization); | 851 SetMetadata(false, true); |
| 735 | 852 |
| 736 InitializeWebMediaPlayerImpl(true); | 853 // Never disable video track for a video only stream. |
| 737 SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5)); | |
| 738 SetDuration(base::TimeDelta::FromSeconds(300)); | |
| 739 | |
| 740 // Audible video. | |
| 741 SetMetadata(true, true); | |
| 742 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | |
| 743 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | |
| 744 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | |
| 745 | |
| 746 // Video only (pausing is enabled on Android). | |
| 747 SetMetadata(false, true); | |
| 748 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | |
| 749 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | |
| 750 #if defined(OS_ANDROID) | |
| 751 EXPECT_TRUE(ShouldPauseVideoWhenHidden()); | |
| 752 | |
| 753 // On Android, the duration and keyframe distance don't matter for video-only. | |
| 754 SetDuration(base::TimeDelta::FromSeconds(5)); | |
| 755 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | |
| 756 EXPECT_TRUE(ShouldPauseVideoWhenHidden()); | |
| 757 | |
| 758 SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100)); | |
| 759 SetDuration(base::TimeDelta::FromSeconds(300)); | |
| 760 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | |
| 761 EXPECT_TRUE(ShouldPauseVideoWhenHidden()); | |
| 762 | |
| 763 // Restore average keyframe distance. | |
| 764 SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5)); | |
| 765 #else | |
| 766 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | |
| 767 #endif | |
| 768 | |
| 769 // Audio only. | |
| 770 SetMetadata(true, false); | |
| 771 EXPECT_FALSE(IsBackgroundOptimizationCandidate()); | |
| 772 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | |
| 773 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | 854 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); |
| 774 | 855 |
| 775 // Duration is shorter than max video keyframe distance. | 856 // There's no optimization criteria for video only on Android. |
| 776 SetDuration(base::TimeDelta::FromSeconds(5)); | 857 bool matches_requirements = |
| 777 SetMetadata(true, true); | 858 IsAndroid() || |
| 778 EXPECT_TRUE(IsBackgroundOptimizationCandidate()); | 859 ((GetDurationSec() < GetAverageKeyframeDistanceSec()) || |
| 779 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | 860 (GetAverageKeyframeDistanceSec() < 10)); |
| 780 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | 861 EXPECT_EQ(matches_requirements, IsBackgroundOptimizationCandidate()); |
| 781 | 862 |
| 782 // Average keyframe distance is too big. | 863 // Video is always paused when suspension is on and only if matches the |
| 783 SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100)); | 864 // optimization criteria if the optimization is on. |
| 784 SetDuration(base::TimeDelta::FromSeconds(300)); | 865 bool should_pause = IsMediaSuspendOn() || |
| 785 EXPECT_FALSE(IsBackgroundOptimizationCandidate()); | 866 (IsBackgroundOptimizationOn() && matches_requirements); |
| 786 EXPECT_FALSE(ShouldPauseVideoWhenHidden()); | 867 EXPECT_EQ(should_pause, ShouldPauseVideoWhenHidden()); |
| 787 EXPECT_FALSE(ShouldDisableVideoWhenHidden()); | |
| 788 } | 868 } |
| 789 | 869 |
| 870 TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, AudioVideo) { |
| 871 SetMetadata(true, true); |
| 872 |
| 873 // Optimization requirements are the same for all platforms. |
| 874 bool matches_requirements = |
| 875 (GetDurationSec() < GetAverageKeyframeDistanceSec()) || |
| 876 (GetAverageKeyframeDistanceSec() < 10); |
| 877 |
| 878 EXPECT_EQ(matches_requirements, IsBackgroundOptimizationCandidate()); |
| 879 EXPECT_EQ(IsBackgroundOptimizationOn() && matches_requirements, |
| 880 ShouldDisableVideoWhenHidden()); |
| 881 |
| 882 // Only pause audible videos on Android if both media suspend and resume |
| 883 // background videos is on. On Desktop |
| 884 EXPECT_EQ(IsMediaSuspendOn() && IsResumeBackgroundVideoEnabled(), |
| 885 ShouldPauseVideoWhenHidden()); |
| 886 } |
| 887 |
| 888 INSTANTIATE_TEST_CASE_P(BackgroundBehaviorTestInstances, |
| 889 WebMediaPlayerImplBackgroundBehaviorTest, |
| 890 ::testing::Combine(::testing::Bool(), |
| 891 ::testing::Bool(), |
| 892 ::testing::Values(5, 300), |
| 893 ::testing::Values(5, 100), |
| 894 ::testing::Bool())); |
| 895 |
| 790 } // namespace media | 896 } // namespace media |
| OLD | NEW |