| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/media/session/media_session_impl.h" |
| |
| #include <stddef.h> |
| |
| #include <list> |
| #include <memory> |
| #include <vector> |
| |
| #include "base/atomic_sequence_num.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/metrics/histogram_samples.h" |
| #include "base/strings/strcat.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/bind.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/simple_test_tick_clock.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| #include "content/browser/media/session/audio_focus_delegate.h" |
| #include "content/browser/media/session/mock_media_session_player_observer.h" |
| #include "content/browser/media/session/mock_media_session_service_impl.h" |
| #include "content/browser/renderer_host/back_forward_cache_impl.h" |
| #include "content/browser/renderer_host/render_frame_host_impl.h" |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/public/browser/media_session.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/content_browser_test.h" |
| #include "content/public/test/content_browser_test_utils.h" |
| #include "content/public/test/prerender_test_util.h" |
| #include "content/shell/browser/shell.h" |
| #include "content/test/content_browser_test_utils_internal.h" |
| #include "media/base/media_content_type.h" |
| #include "net/base/filename_util.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/http_request.h" |
| #include "net/test/embedded_test_server/http_response.h" |
| #include "services/media_session/public/cpp/test/mock_media_session.h" |
| #include "services/media_session/public/mojom/audio_focus.mojom.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" |
| |
| using media_session::mojom::AudioFocusType; |
| using media_session::mojom::MediaPlaybackState; |
| using media_session::mojom::MediaSessionInfo; |
| |
| using ::testing::_; |
| using ::testing::Eq; |
| using ::testing::Expectation; |
| using ::testing::NiceMock; |
| |
| namespace { |
| |
| const double kDefaultVolumeMultiplier = 1.0; |
| const double kDuckingVolumeMultiplier = 0.2; |
| const double kDifferentDuckingVolumeMultiplier = 0.018; |
| |
| const std::u16string kExpectedSourceTitlePrefix = u"http://example.com:"; |
| |
| constexpr gfx::Size kDefaultFaviconSize = gfx::Size(16, 16); |
| |
| const std::string kExampleSinkId = "example_device_id"; |
| |
| class MockAudioFocusDelegate : public content::AudioFocusDelegate { |
| public: |
| MockAudioFocusDelegate(content::MediaSessionImpl* media_session, |
| bool async_mode) |
| : media_session_(media_session), async_mode_(async_mode) {} |
| |
| MOCK_METHOD0(AbandonAudioFocus, void()); |
| |
| AudioFocusDelegate::AudioFocusResult RequestAudioFocus( |
| AudioFocusType audio_focus_type) { |
| if (async_mode_) { |
| requests_.push_back(audio_focus_type); |
| return AudioFocusDelegate::AudioFocusResult::kDelayed; |
| } else { |
| audio_focus_type_ = audio_focus_type; |
| return sync_result_; |
| } |
| } |
| |
| absl::optional<AudioFocusType> GetCurrentFocusType() const { |
| return audio_focus_type_; |
| } |
| |
| void MediaSessionInfoChanged( |
| const media_session::mojom::MediaSessionInfoPtr& session_info) override {} |
| |
| MOCK_CONST_METHOD0(request_id, const base::UnguessableToken&()); |
| |
| MOCK_METHOD(void, ReleaseRequestId, (), (override)); |
| |
| void ResolveRequest(bool result) { |
| if (!async_mode_) |
| return; |
| |
| audio_focus_type_ = requests_.front(); |
| requests_.pop_front(); |
| |
| media_session_->FinishSystemAudioFocusRequest(audio_focus_type_.value(), |
| result); |
| } |
| |
| bool HasRequests() const { return !requests_.empty(); } |
| |
| void SetSyncResult(AudioFocusDelegate::AudioFocusResult result) { |
| sync_result_ = result; |
| } |
| |
| private: |
| AudioFocusDelegate::AudioFocusResult sync_result_ = |
| AudioFocusDelegate::AudioFocusResult::kSuccess; |
| |
| raw_ptr<content::MediaSessionImpl> media_session_; |
| const bool async_mode_ = false; |
| |
| std::list<AudioFocusType> requests_; |
| absl::optional<AudioFocusType> audio_focus_type_; |
| }; |
| |
| } // namespace |
| |
| namespace content { |
| |
| class MediaSessionImplBrowserTest : public ContentBrowserTest { |
| public: |
| MediaSessionImplBrowserTest(const MediaSessionImplBrowserTest&) = delete; |
| MediaSessionImplBrowserTest& operator=(const MediaSessionImplBrowserTest&) = |
| delete; |
| |
| protected: |
| MediaSessionImplBrowserTest() = default; |
| |
| void SetUpOnMainThread() override { |
| ContentBrowserTest::SetUpOnMainThread(); |
| |
| // Navigate to a test page with a a real origin. |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| host_resolver()->AddRule("*", "127.0.0.1"); |
| EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL( |
| "example.com", "/title1.html"))); |
| |
| // Setup the favicon server. |
| favicon_server().RegisterRequestHandler(base::BindRepeating( |
| &MediaSessionImplBrowserTest::HandleRequest, base::Unretained(this))); |
| ASSERT_TRUE(favicon_server().Start()); |
| |
| media_session_ = MediaSessionImpl::Get(shell()->web_contents()); |
| mock_audio_focus_delegate_ = new NiceMock<MockAudioFocusDelegate>( |
| media_session_, true /* async_mode */); |
| media_session_->SetDelegateForTests( |
| base::WrapUnique(mock_audio_focus_delegate_.get())); |
| ASSERT_TRUE(media_session_); |
| } |
| |
| void TearDownOnMainThread() override { |
| media_session_->RemoveAllPlayersForTest(); |
| mock_media_session_service_.reset(); |
| |
| media_session_ = nullptr; |
| |
| ContentBrowserTest::TearDownOnMainThread(); |
| } |
| |
| void StartNewPlayer(MockMediaSessionPlayerObserver* player_observer) { |
| int player_id = player_observer->StartNewPlayer(); |
| |
| bool result = AddPlayer(player_observer, player_id); |
| |
| EXPECT_TRUE(result); |
| } |
| |
| bool AddPlayer(MockMediaSessionPlayerObserver* player_observer, |
| int player_id) { |
| return media_session_->AddPlayer(player_observer, player_id); |
| } |
| |
| void RemovePlayer(MockMediaSessionPlayerObserver* player_observer, |
| int player_id) { |
| media_session_->RemovePlayer(player_observer, player_id); |
| } |
| |
| void RemovePlayers(MockMediaSessionPlayerObserver* player_observer) { |
| media_session_->RemovePlayers(player_observer); |
| } |
| |
| void OnPlayerPaused(MockMediaSessionPlayerObserver* player_observer, |
| int player_id) { |
| media_session_->OnPlayerPaused(player_observer, player_id); |
| } |
| |
| void SetPosition(MockMediaSessionPlayerObserver* player_observer, |
| int player_id, |
| media_session::MediaPosition& position) { |
| player_observer->SetPosition(player_id, position); |
| media_session_->RebuildAndNotifyMediaPositionChanged(); |
| } |
| |
| bool IsActive() { return media_session_->IsActive(); } |
| |
| absl::optional<AudioFocusType> GetSessionAudioFocusType() { |
| return mock_audio_focus_delegate_->GetCurrentFocusType(); |
| } |
| |
| bool IsControllable() { return media_session_->IsControllable(); } |
| |
| void UIResume() { media_session_->Resume(MediaSession::SuspendType::kUI); } |
| |
| void SystemResume() { |
| media_session_->OnResumeInternal(MediaSession::SuspendType::kSystem); |
| } |
| |
| void UISuspend() { media_session_->Suspend(MediaSession::SuspendType::kUI); } |
| |
| void SystemSuspend(bool temporary) { |
| media_session_->OnSuspendInternal(MediaSession::SuspendType::kSystem, |
| temporary |
| ? MediaSessionImpl::State::SUSPENDED |
| : MediaSessionImpl::State::INACTIVE); |
| } |
| |
| void UISeekForward() { media_session_->Seek(base::Seconds(1)); } |
| |
| void UISeekBackward() { media_session_->Seek(base::Seconds(-1)); } |
| |
| void UISeekTo() { media_session_->SeekTo(base::Seconds(10)); } |
| |
| void UIScrubTo() { media_session_->ScrubTo(base::Seconds(10)); } |
| |
| void UISetAudioSink(const std::string& sink_id) { |
| media_session_->SetAudioSinkId(sink_id); |
| } |
| |
| void SystemStartDucking() { media_session_->StartDucking(); } |
| |
| void SystemStopDucking() { media_session_->StopDucking(); } |
| |
| void EnsureMediaSessionService() { |
| mock_media_session_service_ = |
| std::make_unique<NiceMock<MockMediaSessionServiceImpl>>( |
| shell()->web_contents()->GetMainFrame()); |
| } |
| |
| void SetPlaybackState(blink::mojom::MediaSessionPlaybackState state) { |
| mock_media_session_service_->SetPlaybackState(state); |
| } |
| |
| void ResolveAudioFocusSuccess() { |
| mock_audio_focus_delegate()->ResolveRequest(true /* result */); |
| } |
| |
| void ResolveAudioFocusFailure() { |
| mock_audio_focus_delegate()->ResolveRequest(false /* result */); |
| } |
| |
| void SetSyncAudioFocusResult(AudioFocusDelegate::AudioFocusResult result) { |
| mock_audio_focus_delegate()->SetSyncResult(result); |
| } |
| |
| bool HasUnresolvedAudioFocusRequest() { |
| return mock_audio_focus_delegate()->HasRequests(); |
| } |
| |
| MockAudioFocusDelegate* mock_audio_focus_delegate() { |
| return mock_audio_focus_delegate_; |
| } |
| |
| std::unique_ptr<MediaSessionImpl> CreateDummyMediaSession() { |
| return base::WrapUnique<MediaSessionImpl>( |
| new MediaSessionImpl(CreateBrowser()->web_contents())); |
| } |
| |
| MediaSessionUmaHelper* GetMediaSessionUMAHelper() { |
| return media_session_->uma_helper_for_test(); |
| } |
| |
| void SetAudioFocusDelegateForTests(MockAudioFocusDelegate* delegate) { |
| mock_audio_focus_delegate_ = delegate; |
| media_session_->SetDelegateForTests( |
| base::WrapUnique(mock_audio_focus_delegate_.get())); |
| } |
| |
| bool IsDucking() const { return media_session_->is_ducking_; } |
| |
| std::u16string GetExpectedSourceTitle() { |
| std::u16string expected_title = |
| base::StrCat({kExpectedSourceTitlePrefix, |
| base::NumberToString16(embedded_test_server()->port())}); |
| |
| return expected_title.substr(strlen("http://")); |
| } |
| |
| net::EmbeddedTestServer& favicon_server() { return favicon_server_; } |
| |
| int get_favicon_calls() { return favicon_calls_.GetNext(); } |
| |
| protected: |
| std::unique_ptr<net::test_server::HttpResponse> HandleRequest( |
| const net::test_server::HttpRequest& request) { |
| get_favicon_calls(); |
| return std::make_unique<net::test_server::BasicHttpResponse>(); |
| } |
| |
| raw_ptr<MediaSessionImpl> media_session_; |
| raw_ptr<MockAudioFocusDelegate> mock_audio_focus_delegate_; |
| std::unique_ptr<MockMediaSessionServiceImpl> mock_media_session_service_; |
| net::EmbeddedTestServer favicon_server_; |
| base::AtomicSequenceNumber favicon_calls_; |
| }; |
| |
| class MediaSessionImplParamBrowserTest |
| : public MediaSessionImplBrowserTest, |
| public testing::WithParamInterface<bool> { |
| protected: |
| MediaSessionImplParamBrowserTest() = default; |
| |
| void SetUpOnMainThread() override { |
| MediaSessionImplBrowserTest::SetUpOnMainThread(); |
| |
| SetAudioFocusDelegateForTests( |
| new NiceMock<MockAudioFocusDelegate>(media_session_, GetParam())); |
| } |
| }; |
| |
| class MediaSessionImplSyncBrowserTest : public MediaSessionImplBrowserTest { |
| protected: |
| MediaSessionImplSyncBrowserTest() = default; |
| |
| void SetUpOnMainThread() override { |
| MediaSessionImplBrowserTest::SetUpOnMainThread(); |
| |
| SetAudioFocusDelegateForTests(new NiceMock<MockAudioFocusDelegate>( |
| media_session_, false /* async_mode */)); |
| } |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(All, |
| MediaSessionImplParamBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| PlayersFromSameObserverDoNotStopEachOtherInSameSession) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(player_observer->IsPlaying(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| PlayersFromManyObserverDoNotStopEachOtherInSameSession) { |
| auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| auto player_observer_3 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer_1.get()); |
| StartNewPlayer(player_observer_2.get()); |
| StartNewPlayer(player_observer_3.get()); |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_TRUE(player_observer_1->IsPlaying(0)); |
| EXPECT_TRUE(player_observer_2->IsPlaying(0)); |
| EXPECT_TRUE(player_observer_3->IsPlaying(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| SuspendedMediaSessionStopsPlayers) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(player_observer->IsPlaying(1)); |
| EXPECT_FALSE(player_observer->IsPlaying(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ResumedMediaSessionRestartsPlayers) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| SystemResume(); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(player_observer->IsPlaying(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| StartedPlayerOnSuspendedSessionPlaysAlone) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| SystemSuspend(true); |
| |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(player_observer->IsPlaying(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| InitialVolumeMultiplier) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1)); |
| |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| StartDuckingReducesVolumeMultiplier) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| SystemStartDucking(); |
| |
| EXPECT_EQ(kDuckingVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| EXPECT_EQ(kDuckingVolumeMultiplier, player_observer->GetVolumeMultiplier(1)); |
| |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_EQ(kDuckingVolumeMultiplier, player_observer->GetVolumeMultiplier(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| StopDuckingRecoversVolumeMultiplier) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| SystemStartDucking(); |
| SystemStopDucking(); |
| |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1)); |
| |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| DuckingUsesConfiguredMultiplier) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| media_session_->SetDuckingVolumeMultiplier(kDifferentDuckingVolumeMultiplier); |
| SystemStartDucking(); |
| EXPECT_EQ(kDifferentDuckingVolumeMultiplier, |
| player_observer->GetVolumeMultiplier(0)); |
| EXPECT_EQ(kDifferentDuckingVolumeMultiplier, |
| player_observer->GetVolumeMultiplier(1)); |
| SystemStopDucking(); |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| AudioFocusInitialState) { |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| AddPlayerOnSuspendedFocusUnducks) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| UISuspend(); |
| EXPECT_FALSE(IsActive()); |
| |
| SystemStartDucking(); |
| EXPECT_EQ(kDuckingVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| |
| EXPECT_TRUE(AddPlayer(player_observer.get(), 0)); |
| ResolveAudioFocusSuccess(); |
| EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| CanRequestFocusBeforePlayerCreation) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| media_session_->RequestSystemAudioFocus(AudioFocusType::kGain); |
| EXPECT_TRUE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsActive()); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| StartPlayerGivesFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| SuspendGivesAwayAudioFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| StopGivesAwayAudioFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| SystemResumeGivesBackAudioFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| SystemResume(); |
| |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UIResumeGivesBackAudioFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| UISuspend(); |
| |
| UIResume(); |
| EXPECT_TRUE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| RemovingLastPlayerDropsAudioFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| RemovePlayer(player_observer.get(), 0); |
| EXPECT_TRUE(IsActive()); |
| RemovePlayer(player_observer.get(), 1); |
| EXPECT_TRUE(IsActive()); |
| RemovePlayer(player_observer.get(), 2); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| RemovingLastPlayerFromManyObserversDropsAudioFocus) { |
| auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| auto player_observer_3 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer_1.get()); |
| StartNewPlayer(player_observer_2.get()); |
| StartNewPlayer(player_observer_3.get()); |
| ResolveAudioFocusSuccess(); |
| |
| RemovePlayer(player_observer_1.get(), 0); |
| EXPECT_TRUE(IsActive()); |
| RemovePlayer(player_observer_2.get(), 0); |
| EXPECT_TRUE(IsActive()); |
| RemovePlayer(player_observer_3.get(), 0); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| RemovingAllPlayersFromObserversDropsAudioFocus) { |
| auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer_1.get()); |
| StartNewPlayer(player_observer_1.get()); |
| StartNewPlayer(player_observer_2.get()); |
| StartNewPlayer(player_observer_2.get()); |
| ResolveAudioFocusSuccess(); |
| |
| RemovePlayers(player_observer_1.get()); |
| EXPECT_TRUE(IsActive()); |
| RemovePlayers(player_observer_2.get()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ResumePlayGivesAudioFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| RemovePlayer(player_observer.get(), 0); |
| EXPECT_FALSE(IsActive()); |
| |
| EXPECT_TRUE(AddPlayer(player_observer.get(), 0)); |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ResumeSuspendSeekAreSentOnlyOncePerPlayers) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| EXPECT_EQ(0, player_observer->received_resume_calls()); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| EXPECT_EQ(0, player_observer->received_resume_calls()); |
| |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| EXPECT_EQ(0, player_observer->received_resume_calls()); |
| EXPECT_EQ(0, player_observer->received_seek_forward_calls()); |
| EXPECT_EQ(0, player_observer->received_seek_backward_calls()); |
| EXPECT_EQ(0, player_observer->received_seek_to_calls()); |
| |
| SystemSuspend(true); |
| EXPECT_EQ(3, player_observer->received_suspend_calls()); |
| |
| SystemResume(); |
| EXPECT_EQ(3, player_observer->received_resume_calls()); |
| |
| UISeekForward(); |
| EXPECT_EQ(3, player_observer->received_seek_forward_calls()); |
| |
| UISeekBackward(); |
| EXPECT_EQ(3, player_observer->received_seek_backward_calls()); |
| |
| UISeekTo(); |
| EXPECT_EQ(3, player_observer->received_seek_to_calls()); |
| |
| UIScrubTo(); |
| EXPECT_EQ(6, player_observer->received_seek_to_calls()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ResumeSuspendSeekAreSentOnlyOncePerPlayersAddedTwice) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| EXPECT_EQ(0, player_observer->received_resume_calls()); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| EXPECT_EQ(0, player_observer->received_resume_calls()); |
| |
| ResolveAudioFocusSuccess(); |
| |
| // Adding the three players above again. |
| EXPECT_TRUE(AddPlayer(player_observer.get(), 0)); |
| EXPECT_TRUE(AddPlayer(player_observer.get(), 1)); |
| EXPECT_TRUE(AddPlayer(player_observer.get(), 2)); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| EXPECT_EQ(0, player_observer->received_resume_calls()); |
| EXPECT_EQ(0, player_observer->received_seek_forward_calls()); |
| EXPECT_EQ(0, player_observer->received_seek_backward_calls()); |
| EXPECT_EQ(0, player_observer->received_seek_to_calls()); |
| |
| SystemSuspend(true); |
| EXPECT_EQ(3, player_observer->received_suspend_calls()); |
| |
| SystemResume(); |
| EXPECT_EQ(3, player_observer->received_resume_calls()); |
| |
| UISeekForward(); |
| EXPECT_EQ(3, player_observer->received_seek_forward_calls()); |
| |
| UISeekBackward(); |
| EXPECT_EQ(3, player_observer->received_seek_backward_calls()); |
| |
| UISeekTo(); |
| EXPECT_EQ(3, player_observer->received_seek_to_calls()); |
| |
| UIScrubTo(); |
| EXPECT_EQ(6, player_observer->received_seek_to_calls()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| RemovingTheSamePlayerTwiceIsANoop) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| RemovePlayer(player_observer.get(), 0); |
| RemovePlayer(player_observer.get(), 0); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, AudioFocusType) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Transient); |
| |
| // Starting a player with a given type should set the session to that type. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| EXPECT_EQ(AudioFocusType::kGainTransientMayDuck, GetSessionAudioFocusType()); |
| |
| // Adding a player of the same type should have no effect on the type. |
| StartNewPlayer(player_observer.get()); |
| EXPECT_FALSE(HasUnresolvedAudioFocusRequest()); |
| EXPECT_EQ(AudioFocusType::kGainTransientMayDuck, GetSessionAudioFocusType()); |
| |
| // Adding a player of Content type should override the current type. |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType()); |
| |
| // Adding a player of the Transient type should have no effect on the type. |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| EXPECT_FALSE(HasUnresolvedAudioFocusRequest()); |
| EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType()); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(player_observer->IsPlaying(2)); |
| EXPECT_TRUE(player_observer->IsPlaying(3)); |
| |
| SystemSuspend(true); |
| |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(player_observer->IsPlaying(1)); |
| EXPECT_FALSE(player_observer->IsPlaying(2)); |
| EXPECT_FALSE(player_observer->IsPlaying(3)); |
| |
| EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType()); |
| |
| SystemResume(); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(player_observer->IsPlaying(2)); |
| EXPECT_TRUE(player_observer->IsPlaying(3)); |
| |
| EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsShowForContent) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // Starting a player with a persistent type should show the media controls. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsNoShowForTransient) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Transient); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // Starting a player with a transient type should not show the media |
| // controls. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| // This behaviour is specific to desktop. |
| #if !BUILDFLAG(IS_ANDROID) |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsNoShowForTransientAndRoutedService) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Transient); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // Starting a player with a transient type should show the media controls. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsNoShowForTransientAndPlaybackStateNone) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Transient); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // Starting a player with a transient type should not show the media |
| // controls. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsShowForTransientAndPlaybackStatePaused) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Transient); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // Starting a player with a transient type should show the media controls if |
| // we have a playback state from the service. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PAUSED); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsShowForTransientAndPlaybackStatePlaying) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Transient); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // Starting a player with a transient type should show the media controls if |
| // we have a playback state from the service. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| #endif // !BUILDFLAG(IS_ANDROID) |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHideWhenStopped) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| RemovePlayers(player_observer.get()); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| observer.WaitForControllable(false); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsShownAcceptTransient) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| // Transient player join the session without affecting the controls. |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsShownAfterContentAdded) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Transient); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| // The controls are shown when the content player is added. |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsStayIfOnlyOnePlayerHasBeenPaused) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| // Removing only content player doesn't hide the controls since the session |
| // is still active. |
| RemovePlayer(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHideWhenTheLastPlayerIsRemoved) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| RemovePlayer(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| |
| RemovePlayer(player_observer.get(), 1); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| observer.WaitForControllable(false); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHideWhenAllThePlayersAreRemoved) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| RemovePlayers(player_observer.get()); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| observer.WaitForControllable(false); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsNotHideWhenTheLastPlayerIsPaused) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| OnPlayerPaused(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| |
| OnPlayerPaused(player_observer.get(), 1); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| SuspendTemporaryUpdatesControls) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SystemSuspend(true); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsUpdatedWhenResumed) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SystemSuspend(true); |
| SystemResume(); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHideWhenSessionSuspendedPermanently) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SystemSuspend(false); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| observer.WaitForControllable(false); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHideWhenSessionStops) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| observer.WaitForControllable(false); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHideWhenSessionChangesFromContentToTransient) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SystemSuspend(true); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // This should reset the session and change it to a transient, so |
| // hide the controls. |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsUpdatedWhenNewPlayerResetsSession) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SystemSuspend(true); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // This should reset the session and update the controls. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsResumedWhenPlayerIsResumed) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SystemSuspend(true); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| // This should resume the session and update the controls. |
| AddPlayer(player_observer.get(), 0); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsUpdatedDueToResumeSessionAction) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| UISuspend(); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsUpdatedDueToSuspendSessionAction) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| UISuspend(); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| UIResume(); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsDontShowWhenOnlyOneShotIsPresent) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsHiddenAfterRemoveOneShotWithoutOtherPlayers) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| } |
| |
| RemovePlayer(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| observer.WaitForControllable(false); |
| } |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ControlsShowAfterRemoveOneShotWithPersistentPresent) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(false); |
| } |
| |
| RemovePlayer(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| observer.WaitForControllable(true); |
| } |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| DontSuspendWhenOnlyOneShotIsPresent) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(false); |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| |
| EXPECT_EQ(0, player_observer->received_suspend_calls()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| SuspendWhenOneShotAndNormalArePresent) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(false); |
| |
| EXPECT_FALSE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| |
| EXPECT_EQ(2, player_observer->received_suspend_calls()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| DontResumeBySystemUISuspendedSessions) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| UISuspend(); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| |
| SystemResume(); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| AllowUIResumeForSystemSuspend) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| |
| UIResume(); |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, ResumeSuspendFromUI) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| UISuspend(); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| |
| UIResume(); |
| EXPECT_TRUE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ResumeSuspendFromSystem) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_FALSE(IsActive()); |
| |
| SystemResume(); |
| EXPECT_FALSE(HasUnresolvedAudioFocusRequest()); |
| EXPECT_TRUE(IsControllable()); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| OneShotTakesGainFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| EXPECT_FALSE(HasUnresolvedAudioFocusRequest()); |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| EXPECT_FALSE(HasUnresolvedAudioFocusRequest()); |
| |
| EXPECT_EQ(AudioFocusType::kGain, |
| mock_audio_focus_delegate()->GetCurrentFocusType()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| RemovingOneShotDropsFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus()); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| RemovePlayer(player_observer.get(), 0); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| RemovingOneShotWhileStillHavingOtherPlayersKeepsFocus) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| |
| EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus()) |
| .Times(1); // Called in TearDown |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| EXPECT_FALSE(HasUnresolvedAudioFocusRequest()); |
| |
| RemovePlayer(player_observer.get(), 0); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ActualPlaybackStateWhilePlayerPaused) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| OnPlayerPaused(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PAUSED); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ActualPlaybackStateWhilePlayerPlaying) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PAUSED); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| ActualPlaybackStateWhilePlayerRemoved) { |
| EnsureMediaSessionService(); |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForState(MediaSessionInfo::SessionState::kActive); |
| EXPECT_EQ(MediaPlaybackState::kPlaying, |
| observer.session_info()->playback_state); |
| } |
| |
| RemovePlayer(player_observer.get(), 0); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PAUSED); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| |
| SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForState(MediaSessionInfo::SessionState::kInactive); |
| EXPECT_EQ(MediaPlaybackState::kPaused, |
| observer.session_info()->playback_state); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_Suspended_SystemTransient) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| SystemSuspend(true); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(0)); // System Transient |
| EXPECT_EQ(0, samples->GetCount(1)); // System Permanent |
| EXPECT_EQ(0, samples->GetCount(2)); // UI |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_Suspended_SystemPermantent) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| SystemSuspend(false); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(0, samples->GetCount(0)); // System Transient |
| EXPECT_EQ(1, samples->GetCount(1)); // System Permanent |
| EXPECT_EQ(0, samples->GetCount(2)); // UI |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, UMA_Suspended_UI) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| base::HistogramTester tester; |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| UISuspend(); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(0, samples->GetCount(0)); // System Transient |
| EXPECT_EQ(0, samples->GetCount(1)); // System Permanent |
| EXPECT_EQ(1, samples->GetCount(2)); // UI |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_Suspended_Multiple) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| UISuspend(); |
| UIResume(); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| SystemResume(); |
| |
| UISuspend(); |
| UIResume(); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(false); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended")); |
| EXPECT_EQ(4, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(0)); // System Transient |
| EXPECT_EQ(1, samples->GetCount(1)); // System Permanent |
| EXPECT_EQ(2, samples->GetCount(2)); // UI |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_Suspended_Crossing) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| UISuspend(); |
| SystemSuspend(true); |
| SystemSuspend(false); |
| UIResume(); |
| ResolveAudioFocusSuccess(); |
| |
| SystemSuspend(true); |
| SystemSuspend(true); |
| SystemSuspend(false); |
| SystemResume(); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended")); |
| EXPECT_EQ(2, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(0)); // System Transient |
| EXPECT_EQ(0, samples->GetCount(1)); // System Permanent |
| EXPECT_EQ(1, samples->GetCount(2)); // UI |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, UMA_Suspended_Stop) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(0, samples->GetCount(0)); // System Transient |
| EXPECT_EQ(0, samples->GetCount(1)); // System Permanent |
| EXPECT_EQ(1, samples->GetCount(2)); // UI |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_NoActivation) { |
| base::HistogramTester tester; |
| |
| std::unique_ptr<MediaSessionImpl> media_session = CreateDummyMediaSession(); |
| media_session.reset(); |
| |
| // A MediaSession that wasn't active doesn't register an active time. |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(0, samples->TotalCount()); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_SimpleActivation) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper(); |
| base::SimpleTestTickClock clock; |
| clock.SetNowTicks(base::TimeTicks::Now()); |
| media_session_uma_helper->SetClockForTest(&clock); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| clock.Advance(base::Milliseconds(1000)); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(1000)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_ActivationWithUISuspension) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper(); |
| base::SimpleTestTickClock clock; |
| clock.SetNowTicks(base::TimeTicks::Now()); |
| media_session_uma_helper->SetClockForTest(&clock); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| clock.Advance(base::Milliseconds(1000)); |
| UISuspend(); |
| |
| clock.Advance(base::Milliseconds(2000)); |
| UIResume(); |
| ResolveAudioFocusSuccess(); |
| |
| clock.Advance(base::Milliseconds(1000)); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(2000)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_ActivationWithSystemSuspension) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper(); |
| base::SimpleTestTickClock clock; |
| clock.SetNowTicks(base::TimeTicks::Now()); |
| media_session_uma_helper->SetClockForTest(&clock); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| clock.Advance(base::Milliseconds(1000)); |
| SystemSuspend(true); |
| |
| clock.Advance(base::Milliseconds(2000)); |
| SystemResume(); |
| |
| clock.Advance(base::Milliseconds(1000)); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(1, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(2000)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_ActivateSuspendedButNotStopped) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper(); |
| base::SimpleTestTickClock clock; |
| clock.SetNowTicks(base::TimeTicks::Now()); |
| media_session_uma_helper->SetClockForTest(&clock); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| clock.Advance(base::Milliseconds(500)); |
| SystemSuspend(true); |
| |
| { |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(0, samples->TotalCount()); |
| } |
| |
| SystemResume(); |
| clock.Advance(base::Milliseconds(5000)); |
| UISuspend(); |
| |
| { |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(0, samples->TotalCount()); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_ActivateSuspendStopTwice) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper(); |
| base::SimpleTestTickClock clock; |
| clock.SetNowTicks(base::TimeTicks::Now()); |
| media_session_uma_helper->SetClockForTest(&clock); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| clock.Advance(base::Milliseconds(500)); |
| SystemSuspend(true); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| clock.Advance(base::Milliseconds(5000)); |
| SystemResume(); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(2, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(500)); |
| EXPECT_EQ(1, samples->GetCount(5000)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| UMA_ActiveTime_MultipleActivations) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| base::HistogramTester tester; |
| |
| MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper(); |
| base::SimpleTestTickClock clock; |
| clock.SetNowTicks(base::TimeTicks::Now()); |
| media_session_uma_helper->SetClockForTest(&clock); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| clock.Advance(base::Milliseconds(10000)); |
| RemovePlayer(player_observer.get(), 0); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| clock.Advance(base::Milliseconds(1000)); |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| |
| std::unique_ptr<base::HistogramSamples> samples( |
| tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime")); |
| EXPECT_EQ(2, samples->TotalCount()); |
| EXPECT_EQ(1, samples->GetCount(1000)); |
| EXPECT_EQ(1, samples->GetCount(10000)); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| AddingObserverNotifiesCurrentInformation_EmptyInfo) { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| media_session::MediaMetadata expected_metadata; |
| expected_metadata.title = shell()->web_contents()->GetTitle(); |
| expected_metadata.source_title = GetExpectedSourceTitle(); |
| observer.WaitForExpectedMetadata(expected_metadata); |
| } |
| |
| IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, |
| AddingMojoObserverNotifiesCurrentInformation_WithInfo) { |
| // Set up the service and information. |
| EnsureMediaSessionService(); |
| |
| media_session::MediaMetadata expected_metadata; |
| expected_metadata.title = u"title"; |
| expected_metadata.artist = u"artist"; |
| expected_metadata.album = u"album"; |
| expected_metadata.source_title = GetExpectedSourceTitle(); |
| |
| blink::mojom::SpecMediaMetadataPtr spec_metadata( |
| blink::mojom::SpecMediaMetadata::New()); |
| spec_metadata->title = u"title"; |
| spec_metadata->artist = u"artist"; |
| spec_metadata->album = u"album"; |
| mock_media_session_service_->SetMetadata(std::move(spec_metadata)); |
| |
| // Make sure the service is routed, |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| shell()->web_contents()->GetMainFrame(), |
| media::MediaContentType::Persistent); |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| |
| observer.WaitForExpectedMetadata(expected_metadata); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplSyncBrowserTest, |
| PepperPlayerNotAddedIfFocusFailed) { |
| SetSyncAudioFocusResult(AudioFocusDelegate::AudioFocusResult::kFailed); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Pepper); |
| int player_id = player_observer->StartNewPlayer(); |
| |
| EXPECT_FALSE(AddPlayer(player_observer.get(), player_id)); |
| |
| EXPECT_FALSE(media_session_->HasPepper()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_RequestFailure_Gain) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(IsActive()); |
| |
| // The gain request failed so we should suspend the whole session. |
| ResolveAudioFocusFailure(); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(player_observer->IsPlaying(1)); |
| EXPECT_FALSE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(player_observer->IsPlaying(1)); |
| EXPECT_FALSE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| Async_RequestFailure_GainTransient) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(IsActive()); |
| |
| // A transient audio focus failure should only affect transient players. |
| ResolveAudioFocusFailure(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(player_observer->IsPlaying(1)); |
| EXPECT_TRUE(IsActive()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_GainThenTransient) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Transient); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_TransientThenGain) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Transient); |
| |
| StartNewPlayer(player_observer.get()); |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| Async_SuspendBeforeResolve) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| SystemSuspend(true); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(IsActive()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(IsActive()); |
| |
| SystemResume(); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_ResumeBeforeResolve) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| UISuspend(); |
| EXPECT_FALSE(IsActive()); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| |
| UIResume(); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| ResolveAudioFocusFailure(); |
| EXPECT_FALSE(IsActive()); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_RemoveBeforeResolve) { |
| { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus()); |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| RemovePlayer(player_observer.get(), 0); |
| } |
| |
| ResolveAudioFocusSuccess(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_StopBeforeResolve) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Transient); |
| |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| player_observer->SetMediaContentType(media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| ResolveAudioFocusSuccess(); |
| |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| EXPECT_FALSE(player_observer->IsPlaying(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Failure) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| SystemStartDucking(); |
| EXPECT_TRUE(IsDucking()); |
| |
| ResolveAudioFocusFailure(); |
| EXPECT_TRUE(IsDucking()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Inactive) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| media_session_->Stop(MediaSession::SuspendType::kUI); |
| SystemStartDucking(); |
| EXPECT_TRUE(IsDucking()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsDucking()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Success) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| SystemStartDucking(); |
| EXPECT_TRUE(IsDucking()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_FALSE(IsDucking()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Suspended) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| EXPECT_TRUE(IsActive()); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| |
| UISuspend(); |
| SystemStartDucking(); |
| EXPECT_TRUE(IsDucking()); |
| |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(IsDucking()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, MetadataWhenFileUrlScheme) { |
| base::FilePath path = GetTestFilePath(nullptr, "title1.html"); |
| GURL file_url = net::FilePathToFileURL(path); |
| EXPECT_TRUE(NavigateToURL(shell(), file_url)); |
| |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| media_session::MediaMetadata expected_metadata; |
| expected_metadata.title = shell()->web_contents()->GetTitle(); |
| expected_metadata.source_title = u"Local File"; |
| observer.WaitForExpectedMetadata(expected_metadata); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UpdateFaviconURL) { |
| std::vector<gfx::Size> valid_sizes; |
| valid_sizes.push_back(gfx::Size(100, 100)); |
| valid_sizes.push_back(gfx::Size(200, 200)); |
| |
| std::vector<blink::mojom::FaviconURLPtr> favicons; |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon1.png"), |
| blink::mojom::FaviconIconType::kInvalid, valid_sizes)); |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL(), blink::mojom::FaviconIconType::kFavicon, valid_sizes)); |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon2.png"), |
| blink::mojom::FaviconIconType::kFavicon, std::vector<gfx::Size>())); |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon3.png"), |
| blink::mojom::FaviconIconType::kFavicon, valid_sizes)); |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon4.png"), |
| blink::mojom::FaviconIconType::kTouchIcon, valid_sizes)); |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon5.png"), |
| blink::mojom::FaviconIconType::kTouchPrecomposedIcon, valid_sizes)); |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon6.png"), |
| blink::mojom::FaviconIconType::kTouchIcon, std::vector<gfx::Size>())); |
| |
| media_session_->DidUpdateFaviconURL(shell()->web_contents()->GetMainFrame(), |
| favicons); |
| |
| { |
| std::vector<media_session::MediaImage> expected_images; |
| media_session::MediaImage test_image_1; |
| test_image_1.src = GURL("https://www.example.org/favicon2.png"); |
| test_image_1.sizes.push_back(kDefaultFaviconSize); |
| expected_images.push_back(test_image_1); |
| |
| media_session::MediaImage test_image_2; |
| test_image_2.src = GURL("https://www.example.org/favicon3.png"); |
| test_image_2.sizes = valid_sizes; |
| expected_images.push_back(test_image_2); |
| |
| media_session::MediaImage test_image_3; |
| test_image_3.src = GURL("https://www.example.org/favicon4.png"); |
| test_image_3.sizes = valid_sizes; |
| expected_images.push_back(test_image_3); |
| |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForExpectedImagesOfType( |
| media_session::mojom::MediaSessionImageType::kSourceIcon, |
| expected_images); |
| } |
| |
| { |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| media_session_->DidUpdateFaviconURL( |
| shell()->web_contents()->GetMainFrame(), |
| std::vector<blink::mojom::FaviconURLPtr>()); |
| observer.WaitForExpectedImagesOfType( |
| media_session::mojom::MediaSessionImageType::kSourceIcon, |
| std::vector<media_session::MediaImage>()); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| UpdateFaviconURL_ClearOnNavigate) { |
| std::vector<blink::mojom::FaviconURLPtr> favicons; |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| GURL("https://www.example.org/favicon1.png"), |
| blink::mojom::FaviconIconType::kFavicon, std::vector<gfx::Size>())); |
| |
| media_session_->DidUpdateFaviconURL(shell()->web_contents()->GetMainFrame(), |
| favicons); |
| |
| { |
| std::vector<media_session::MediaImage> expected_images; |
| media_session::MediaImage test_image_1; |
| test_image_1.src = GURL("https://www.example.org/favicon1.png"); |
| test_image_1.sizes.push_back(kDefaultFaviconSize); |
| expected_images.push_back(test_image_1); |
| |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForExpectedImagesOfType( |
| media_session::mojom::MediaSessionImageType::kSourceIcon, |
| expected_images); |
| } |
| |
| { |
| std::vector<media_session::MediaImage> expected_images; |
| media_session::MediaImage test_image_1; |
| test_image_1.src = |
| embedded_test_server()->GetURL("example.com", "/favicon.ico"); |
| test_image_1.sizes.push_back(kDefaultFaviconSize); |
| expected_images.push_back(test_image_1); |
| |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL( |
| "example.com", "/title1.html"))); |
| |
| observer.WaitForExpectedImagesOfType( |
| media_session::mojom::MediaSessionImageType::kSourceIcon, |
| expected_images); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| SinkIdChangeNotifiesObservers) { |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| StartNewPlayer(player_observer.get()); |
| |
| UISetAudioSink(kExampleSinkId); |
| EXPECT_EQ(player_observer->received_set_audio_sink_id_calls(), 1); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(0), kExampleSinkId); |
| } |
| |
| class MediaSessionFaviconBrowserTest : public ContentBrowserTest { |
| protected: |
| MediaSessionFaviconBrowserTest() = default; |
| |
| void SetUpOnMainThread() override { |
| ContentBrowserTest::SetUpOnMainThread(); |
| |
| host_resolver()->AddRule("*", "127.0.0.1"); |
| } |
| }; |
| |
| // Helper class that waits to receive a favicon from the renderer process. |
| class FaviconWaiter : public WebContentsObserver { |
| public: |
| explicit FaviconWaiter(WebContents* web_contents) |
| : WebContentsObserver(web_contents) {} |
| |
| void DidUpdateFaviconURL( |
| RenderFrameHost* render_frame_host, |
| const std::vector<blink::mojom::FaviconURLPtr>& candidates) override { |
| received_favicon_ = true; |
| run_loop_.Quit(); |
| } |
| |
| void Wait() { |
| if (received_favicon_) |
| return; |
| run_loop_.Run(); |
| } |
| |
| private: |
| bool received_favicon_ = false; |
| base::RunLoop run_loop_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionFaviconBrowserTest, StartupInitalization) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("example.com", "/title1.html"))); |
| |
| std::unique_ptr<FaviconWaiter> favicon_waiter( |
| new FaviconWaiter(shell()->web_contents())); |
| |
| // Insert the favicon dynamically. |
| ASSERT_TRUE( |
| ExecJs(shell()->web_contents(), |
| "let l = document.createElement('link'); " |
| "l.rel='icon'; l.type='image/png'; l.href='single_face.jpg'; " |
| "document.head.appendChild(l)")); |
| |
| // Wait until it's received by the browser process. |
| favicon_waiter->Wait(); |
| |
| // The MediaSession should be created with the favicon already available. |
| MediaSession* media_session = MediaSessionImpl::Get(shell()->web_contents()); |
| |
| media_session::MediaImage icon; |
| icon.src = embedded_test_server()->GetURL("example.com", "/single_face.jpg"); |
| icon.sizes.push_back({16, 16}); |
| |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session); |
| observer.WaitForExpectedImagesOfType( |
| media_session::mojom::MediaSessionImageType::kSourceIcon, {icon}); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| PositionStateRouteWithTwoPlayers) { |
| media_session::MediaPosition expected_position( |
| /*playback_rate=*/0.0, /*duration=*/base::Seconds(10), |
| /*position=*/base::TimeDelta(), /*end_of_media=*/false); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| int player_id = player_observer->StartNewPlayer(); |
| SetPosition(player_observer.get(), player_id, expected_position); |
| |
| { |
| // With one normal player we should use the position that one provides. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| AddPlayer(player_observer.get(), player_id); |
| observer.WaitForExpectedPosition(expected_position); |
| } |
| |
| int player_id_2 = player_observer->StartNewPlayer(); |
| |
| { |
| // If we add another player then we should become empty again. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| AddPlayer(player_observer.get(), player_id_2); |
| observer.WaitForEmptyPosition(); |
| } |
| |
| { |
| // If we remove the player then we should use the first player position. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| RemovePlayer(player_observer.get(), player_id_2); |
| observer.WaitForExpectedPosition(expected_position); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| PositionStateWithOneShotPlayer) { |
| media_session::MediaPosition expected_position( |
| /*playback_rate=*/0.0, /*duration=*/base::Seconds(10), |
| /*position=*/base::TimeDelta(), /*end_of_media=*/false); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::OneShot); |
| int player_id = player_observer->StartNewPlayer(); |
| SetPosition(player_observer.get(), player_id, expected_position); |
| AddPlayer(player_observer.get(), player_id); |
| |
| // OneShot players should be ignored for position data. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForEmptyPosition(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| PositionStateWithPepperPlayer) { |
| media_session::MediaPosition expected_position( |
| /*playback_rate=*/0.0, /*duration=*/base::Seconds(10), |
| /*position=*/base::TimeDelta(), /*end_of_media=*/false); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Pepper); |
| int player_id = player_observer->StartNewPlayer(); |
| SetPosition(player_observer.get(), player_id, expected_position); |
| AddPlayer(player_observer.get(), player_id); |
| |
| // Pepper players should be ignored for position data. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForEmptyPosition(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| PositionStateRouteWithTwoPlayers_OneShot) { |
| media_session::MediaPosition expected_position( |
| /*playback_rate=*/0.0, /*duration=*/base::Seconds(10), |
| /*position=*/base::TimeDelta(), /*end_of_media=*/false); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| int player_id = player_observer->StartNewPlayer(); |
| SetPosition(player_observer.get(), player_id, expected_position); |
| |
| { |
| // With one normal player we should use the position that one provides. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| AddPlayer(player_observer.get(), player_id); |
| observer.WaitForExpectedPosition(expected_position); |
| } |
| |
| { |
| // If we add an OneShot player then we should become empty again. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| player_observer->SetMediaContentType(media::MediaContentType::OneShot); |
| StartNewPlayer(player_observer.get()); |
| observer.WaitForEmptyPosition(); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| PositionStateRouteWithTwoPlayers_Pepper) { |
| media_session::MediaPosition expected_position( |
| /*playback_rate=*/0.0, /*duration=*/base::Seconds(10), |
| /*position=*/base::TimeDelta(), /*end_of_media=*/false); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| int player_id = player_observer->StartNewPlayer(); |
| SetPosition(player_observer.get(), player_id, expected_position); |
| |
| { |
| // With one normal player we should use the position that one provides. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| AddPlayer(player_observer.get(), player_id); |
| observer.WaitForExpectedPosition(expected_position); |
| } |
| |
| { |
| // If we add a Papper player then we should become empty again. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| player_observer->SetMediaContentType(media::MediaContentType::Pepper); |
| StartNewPlayer(player_observer.get()); |
| observer.WaitForEmptyPosition(); |
| } |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) |
| // TODO(https://crbug.com/1000400): Re-enable this test. |
| #define MAYBE_PositionStateRouteWithOnePlayer \ |
| DISABLED_PositionStateRouteWithOnePlayer |
| #else |
| #define MAYBE_PositionStateRouteWithOnePlayer PositionStateRouteWithOnePlayer |
| #endif |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| MAYBE_PositionStateRouteWithOnePlayer) { |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("example.com", |
| "/media/session/position.html"))); |
| |
| auto* main_frame = shell()->web_contents()->GetMainFrame(); |
| const base::TimeDelta duration = base::Milliseconds(6060); |
| |
| { |
| // By default we should have an empty position. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| observer.WaitForEmptyPosition(); |
| } |
| |
| { |
| // With one normal player we should use the position that one provides. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| ASSERT_TRUE(ExecJs(main_frame, "document.getElementById('video').play()")); |
| |
| observer.WaitForExpectedPosition(media_session::MediaPosition( |
| /*playback_rate=*/1.0, duration, |
| /*position=*/base::TimeDelta(), /*end_of_media=*/false)); |
| } |
| |
| { |
| // If we seek the player then the position should be updated. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| ASSERT_TRUE( |
| ExecJs(main_frame, "document.getElementById('video').currentTime = 1")); |
| |
| // We might only learn about the rate going back to 1.0 when the media time |
| // has already progressed a bit. |
| observer.WaitForExpectedPositionAtLeast(media_session::MediaPosition( |
| /*playback_rate=*/1.0, duration, |
| /*position=*/base::Seconds(1), /*end_of_media=*/false)); |
| } |
| |
| base::TimeDelta paused_position; |
| { |
| // If we pause the player then the rate should be updated. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| ASSERT_TRUE(ExecJs(main_frame, "document.getElementById('video').pause()")); |
| |
| // Media time may have progressed since the time we seeked to 1s. |
| paused_position = |
| observer.WaitForExpectedPositionAtLeast(media_session::MediaPosition( |
| /*playback_rate=*/0.0, duration, |
| /*position=*/base::Seconds(1), |
| /*end_of_media=*/false)); |
| } |
| |
| base::TimeDelta resumed_position; |
| { |
| // If we resume the player then the rate should be updated. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| ASSERT_TRUE(ExecJs(main_frame, "document.getElementById('video').play()")); |
| |
| // We might only learn about the rate going back to 1.0 when the media time |
| // has already progressed a bit. |
| resumed_position = |
| observer.WaitForExpectedPositionAtLeast(media_session::MediaPosition( |
| /*playback_rate=*/1.0, duration, paused_position, |
| /*end_of_media=*/false)); |
| } |
| |
| { |
| // If we change the playback rate then the MediaPosition should be updated. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| ASSERT_TRUE(ExecJs(main_frame, |
| "document.getElementById('video').playbackRate = 2")); |
| |
| // Media time may have progressed since the time we resumed playback. |
| observer.WaitForExpectedPositionAtLeast(media_session::MediaPosition( |
| /*playback_rate=*/2.0, duration, resumed_position, |
| /*end_of_media=*/false)); |
| } |
| |
| { |
| // If we remove the player then we should become empty again. |
| media_session::test::MockMediaSessionMojoObserver observer(*media_session_); |
| |
| ASSERT_TRUE( |
| ExecJs(main_frame, "document.getElementById('video').src = ''")); |
| |
| observer.WaitForEmptyPosition(); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, |
| AudioDeviceSettingPersists) { |
| // When an audio output device has been set: in addition to players switching |
| // to that audio device, players created later on the same origin in the same |
| // session should also use that device. |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| int player_1 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_1); |
| UISetAudioSink("speaker1"); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(player_1), "speaker1"); |
| |
| // When a second player has been added on the same page, it should use the |
| // audio device previously set. |
| int player_2 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_2); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(player_2), "speaker1"); |
| |
| // Clear the players and navigate to a new page on the same origin. |
| RemovePlayers(player_observer.get()); |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("a.com", "/title2.html"))); |
| player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| // After navigating to another page on the same origin, newly created players |
| // should use the previously set device. |
| player_1 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_1); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(player_1), "speaker1"); |
| |
| // Clear the players and navigate to a new page on a different origin |
| RemovePlayers(player_observer.get()); |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("b.com", "/title1.html"))); |
| player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| // After navigating to another page on a different origin, newly created |
| // players should not use the previously set device. |
| player_1 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_1); |
| EXPECT_NE(player_observer->GetAudioOutputSinkId(player_1), "speaker1"); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, CacheFaviconImages) { |
| std::vector<gfx::Size> valid_sizes; |
| valid_sizes.push_back(gfx::Size(100, 100)); |
| valid_sizes.push_back(gfx::Size(200, 200)); |
| |
| std::vector<blink::mojom::FaviconURLPtr> favicons; |
| favicons.push_back(blink::mojom::FaviconURL::New( |
| favicon_server().GetURL("/favicon.ico"), |
| blink::mojom::FaviconIconType::kFavicon, valid_sizes)); |
| |
| media_session_->DidUpdateFaviconURL(shell()->web_contents()->GetMainFrame(), |
| favicons); |
| |
| media_session::MediaImage test_image; |
| test_image.src = favicon_server().GetURL("/favicon.ico"); |
| test_image.sizes = valid_sizes; |
| |
| { |
| EXPECT_EQ(0, get_favicon_calls()); |
| |
| base::RunLoop run_loop; |
| media_session_->GetMediaImageBitmap( |
| test_image, 100, 100, |
| base::BindLambdaForTesting([&](const SkBitmap&) { run_loop.Quit(); })); |
| run_loop.Run(); |
| |
| EXPECT_EQ(2, get_favicon_calls()); |
| } |
| |
| { |
| base::RunLoop run_loop; |
| media_session_->GetMediaImageBitmap( |
| test_image, 100, 100, |
| base::BindLambdaForTesting([&](const SkBitmap&) { run_loop.Quit(); })); |
| run_loop.Run(); |
| |
| EXPECT_EQ(3, get_favicon_calls()); |
| } |
| } |
| |
| class MediaSessionImplPrerenderingBrowserTest |
| : public MediaSessionImplBrowserTest { |
| public: |
| MediaSessionImplPrerenderingBrowserTest( |
| const MediaSessionImplPrerenderingBrowserTest&) = delete; |
| MediaSessionImplPrerenderingBrowserTest( |
| MediaSessionImplPrerenderingBrowserTest&&) = delete; |
| |
| protected: |
| MediaSessionImplPrerenderingBrowserTest() |
| : prerender_helper_(base::BindRepeating( |
| &MediaSessionImplPrerenderingBrowserTest::web_contents, |
| base::Unretained(this))) {} |
| |
| WebContents* web_contents() { return shell()->web_contents(); } |
| |
| protected: |
| test::PrerenderTestHelper prerender_helper_; |
| }; |
| |
| // Tests the audio device persists a prerender activation on same origin and |
| // that it is reset after a navigation cross-origin. |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplPrerenderingBrowserTest, |
| AudioDeviceSettingPersists) { |
| // When an audio output device has been set: in addition to players switching |
| // to that audio device, players created later on the same origin in the same |
| // session should also use that device. |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| int player_1 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_1); |
| UISetAudioSink("speaker1"); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(player_1), "speaker1"); |
| |
| // When a second player has been added on the same page, it should use the |
| // audio device previously set. |
| int player_2 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_2); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(player_2), "speaker1"); |
| |
| // Clear the players. |
| RemovePlayers(player_observer.get()); |
| |
| // Prerender the next page. |
| auto prerender_url_a = |
| embedded_test_server()->GetURL("a.com", "/title2.html"); |
| auto prerender_host_a = prerender_helper_.AddPrerender(prerender_url_a); |
| content::test::PrerenderHostObserver host_observer_a(*web_contents(), |
| prerender_host_a); |
| // Navigate to a new page on the same origin. |
| test::PrerenderTestHelper::NavigatePrimaryPage(*web_contents(), |
| prerender_url_a); |
| EXPECT_TRUE(host_observer_a.was_activated()); |
| player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| // After navigating to another page on the same origin, newly created players |
| // should use the previously set device. |
| player_1 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_1); |
| EXPECT_EQ(player_observer->GetAudioOutputSinkId(player_1), "speaker1"); |
| |
| // Clear the players and navigate to a new page on a different origin |
| RemovePlayers(player_observer.get()); |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("b.com", "/title1.html"))); |
| player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| media::MediaContentType::Persistent); |
| |
| // After navigating to another page on a different origin, newly created |
| // players should not use the previously set device. |
| player_1 = player_observer->StartNewPlayer(); |
| AddPlayer(player_observer.get(), player_1); |
| EXPECT_NE(player_observer->GetAudioOutputSinkId(player_1), "speaker1"); |
| } |
| |
| class MediaSessionImplWithBackForwardCacheBrowserTest |
| : public MediaSessionImplBrowserTest { |
| protected: |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| MediaSessionImplBrowserTest::SetUpCommandLine(command_line); |
| |
| std::vector<base::test::ScopedFeatureList::FeatureAndParams> |
| enabled_features; |
| std::map<std::string, std::string> params; |
| #if BUILDFLAG(IS_ANDROID) |
| params["process_binding_strength"] = "NORMAL"; |
| #endif |
| enabled_features.emplace_back(features::kBackForwardCache, params); |
| |
| std::vector<base::Feature> disabled_features = { |
| features::kBackForwardCacheMemoryControls, |
| }; |
| |
| feature_list_.InitWithFeaturesAndParameters(enabled_features, |
| disabled_features); |
| } |
| |
| RenderFrameHost* GetMainFrame() { |
| return shell()->web_contents()->GetMainFrame(); |
| } |
| |
| private: |
| base::test::ScopedFeatureList feature_list_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplWithBackForwardCacheBrowserTest, |
| PlayAndCache) { |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("a.test", "/title1.html"))); |
| |
| // Add a player. |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| GetMainFrame(), media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| RenderFrameHostImplWrapper frame_host(GetMainFrame()); |
| |
| // Navigate to another page. The page is cached in back-forward cache. |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("b.test", "/title1.html"))); |
| EXPECT_TRUE(frame_host->IsInBackForwardCache()); |
| |
| // Restore the page from the back-forward cache. |
| shell()->web_contents()->GetController().GoBack(); |
| EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
| EXPECT_FALSE(frame_host->IsInBackForwardCache()); |
| |
| // After the page is restored from back-forward cache, the player observer |
| // must be paused. |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplWithBackForwardCacheBrowserTest, |
| PauseAndCache) { |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("a.test", "/title1.html"))); |
| |
| // Add a player and pause this. |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| GetMainFrame(), media::MediaContentType::Persistent); |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| UISuspend(); |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| RenderFrameHostImplWrapper frame_host(GetMainFrame()); |
| |
| // Navigate to another page. The page is cached in back-forward cache. |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("b.test", "/title1.html"))); |
| EXPECT_TRUE(frame_host->IsInBackForwardCache()); |
| |
| // Restore the page from the back-forward cache. |
| shell()->web_contents()->GetController().GoBack(); |
| EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
| EXPECT_FALSE(frame_host->IsInBackForwardCache()); |
| |
| // After the page is restored from back-forward cache, the player observer |
| // must be still paused. |
| EXPECT_FALSE(player_observer->IsPlaying(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(MediaSessionImplWithBackForwardCacheBrowserTest, |
| CacheClearDoesntAffectCurrentPage) { |
| // The bug this test is protecting against (https://crbug.com/1288620) only |
| // reproduces on pages with an iframe, so load one. |
| EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL( |
| "a.test", "/iframe_clipped.html"))); |
| |
| auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( |
| GetMainFrame(), media::MediaContentType::Persistent); |
| |
| // Add a player. |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(0)); |
| RenderFrameHostImplWrapper frame_host(GetMainFrame()); |
| |
| // Navigate to another page. The original page is cached in back-forward |
| // cache. |
| EXPECT_TRUE(NavigateToURL( |
| shell(), embedded_test_server()->GetURL("b.test", "/title1.html"))); |
| EXPECT_TRUE(frame_host->IsInBackForwardCache()); |
| |
| // Add a player on the new page |
| StartNewPlayer(player_observer.get()); |
| ResolveAudioFocusSuccess(); |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| |
| // Evict the page from the back-forward cache. |
| shell()->web_contents()->GetController().GetBackForwardCache().Flush(); |
| EXPECT_TRUE(frame_host.WaitUntilRenderFrameDeleted()); |
| |
| // The page being removed from the back-forward cache should not affect the |
| // play state of the current page. |
| EXPECT_TRUE(player_observer->IsPlaying(1)); |
| } |
| |
| } // namespace content |