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