Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(765)

Unified Diff: content/browser/media/android/media_session_browsertest.cc

Issue 1110833004: Move audio focus control from media/ to content/ and make it per WebContents. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/media/android/media_session_browsertest.cc
diff --git a/content/browser/media/android/media_session_browsertest.cc b/content/browser/media/android/media_session_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1fc812189feb70e3189b7700a763a87e55d1a808
--- /dev/null
+++ b/content/browser/media/android/media_session_browsertest.cc
@@ -0,0 +1,544 @@
+// 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/android/media_session.h"
+
+#include <list>
+#include <vector>
+
+#include "content/browser/media/android/media_session_observer.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/shell/browser/shell.h"
+
+namespace content {
+
+class MockMediaSessionObserver : public MediaSessionObserver {
+ public:
+ MockMediaSessionObserver()
+ : received_resume_calls_(0),
+ received_suspend_calls_(0) {
+ }
+
+ ~MockMediaSessionObserver() override = default;
+
+ // Implements MediaSessionObserver.
+ void OnSuspend(int player_id) override {
+ DCHECK(player_id >= 0);
+ DCHECK(players_.size() > static_cast<size_t>(player_id));
+
+ ++received_suspend_calls_;
+ players_[player_id] = false;
+ }
+ void OnResume(int player_id) override {
+ DCHECK(player_id >= 0);
+ DCHECK(players_.size() > static_cast<size_t>(player_id));
+
+ ++received_resume_calls_;
+ players_[player_id] = true;
+ }
+
+ int StartNewPlayer() {
+ players_.push_back(true);
+ return players_.size() - 1;
+ }
+
+ bool IsPlaying(size_t player_id) {
+ DCHECK(players_.size() > player_id);
+ return players_[player_id];
+ }
+
+ void SetPlaying(size_t player_id, bool playing) {
+ DCHECK(players_.size() > player_id);
+ players_[player_id] = playing;
+ }
+
+ int received_suspend_calls() const {
+ return received_suspend_calls_;
+ }
+
+ int received_resume_calls() const {
+ return received_resume_calls_;
+ }
+
+ private:
+ // Basic representation of the players. The position in the vector is the
+ // player_id. The value of the vector is the playing status.
+ std::vector<bool> players_;
+
+ int received_resume_calls_;
+ int received_suspend_calls_;
+};
+
+class MediaSessionBrowserTest : public ContentBrowserTest {
+ protected:
+ MediaSessionBrowserTest() = default;
+
+ void DisableNativeBackend(MediaSession* media_session) {
+ media_session->ResetJavaRefForTest();
+ }
+
+ void StartNewPlayer(MediaSession* media_session,
+ MockMediaSessionObserver* media_session_observer,
+ MediaSession::Type type) {
+ bool result = media_session->AddPlayer(
+ media_session_observer,
+ media_session_observer->StartNewPlayer(),
+ type);
+ EXPECT_TRUE(result);
+ }
+
+ void SuspendSession(MediaSession* media_session) {
+ media_session->OnSuspend(true);
+ }
+
+ void ResumeSession(MediaSession* media_session) {
+ media_session->OnResume();
+ }
+
+ bool HasAudioFocus(MediaSession* media_session) {
+ return media_session->IsActiveForTest();
+ }
+
+ MediaSession::Type GetSessionType(MediaSession* media_session) {
+ return media_session->audio_focus_type_for_test();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MediaSessionBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ PlayersFromSameObserverDoNotStopEachOtherInSameSession) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_TRUE(media_session_observer->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer->IsPlaying(1));
+ EXPECT_TRUE(media_session_observer->IsPlaying(2));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ PlayersFromManyObserverDoNotStopEachOtherInSameSession) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_1(
+ new MockMediaSessionObserver);
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_2(
+ new MockMediaSessionObserver);
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_3(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer_1.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_2.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_3.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_TRUE(media_session_observer_1->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer_2->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer_3->IsPlaying(0));
+
+ media_session->RemovePlayers(media_session_observer_1.get());
+ media_session->RemovePlayers(media_session_observer_2.get());
+ media_session->RemovePlayers(media_session_observer_3.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ SuspendedMediaSessionStopsPlayers) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ SuspendSession(media_session);
+
+ EXPECT_FALSE(media_session_observer->IsPlaying(0));
+ EXPECT_FALSE(media_session_observer->IsPlaying(1));
+ EXPECT_FALSE(media_session_observer->IsPlaying(2));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ ResumedMediaSessionRestartsPlayers) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ SuspendSession(media_session);
+ ResumeSession(media_session);
+
+ EXPECT_TRUE(media_session_observer->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer->IsPlaying(1));
+ EXPECT_TRUE(media_session_observer->IsPlaying(2));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ StartedPlayerOnSuspendedSessionPlaysAlone) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_TRUE(media_session_observer->IsPlaying(0));
+
+ SuspendSession(media_session);
+
+ EXPECT_FALSE(media_session_observer->IsPlaying(0));
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_FALSE(media_session_observer->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer->IsPlaying(1));
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_FALSE(media_session_observer->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer->IsPlaying(1));
+ EXPECT_TRUE(media_session_observer->IsPlaying(2));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, AudioFocusInitialState) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ EXPECT_FALSE(HasAudioFocus(media_session));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, StartPlayerGivesFocus) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_TRUE(HasAudioFocus(media_session));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, SuspendGivesAwayAudioFocus) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ SuspendSession(media_session);
+
+ EXPECT_FALSE(HasAudioFocus(media_session));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumeGivesBackAudioFocus) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ SuspendSession(media_session);
+ ResumeSession(media_session);
+
+ EXPECT_TRUE(HasAudioFocus(media_session));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ RemovingLastPlayerDropsAudioFocus_1) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ media_session->RemovePlayer(media_session_observer.get(), 0);
+ EXPECT_TRUE(HasAudioFocus(media_session));
+ media_session->RemovePlayer(media_session_observer.get(), 1);
+ EXPECT_TRUE(HasAudioFocus(media_session));
+ media_session->RemovePlayer(media_session_observer.get(), 2);
+ EXPECT_FALSE(HasAudioFocus(media_session));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ RemovingLastPlayerDropsAudioFocus_2) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_1(
+ new MockMediaSessionObserver);
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_2(
+ new MockMediaSessionObserver);
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_3(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer_1.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_2.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_3.get(),
+ MediaSession::Type::Content);
+
+ media_session->RemovePlayer(media_session_observer_1.get(), 0);
+ EXPECT_TRUE(HasAudioFocus(media_session));
+ media_session->RemovePlayer(media_session_observer_2.get(), 0);
+ EXPECT_TRUE(HasAudioFocus(media_session));
+ media_session->RemovePlayer(media_session_observer_3.get(), 0);
+ EXPECT_FALSE(HasAudioFocus(media_session));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ RemovingLastPlayerDropsAudioFocus_3) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_1(
+ new MockMediaSessionObserver);
+ scoped_ptr<MockMediaSessionObserver> media_session_observer_2(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer_1.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_1.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_2.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer_2.get(),
+ MediaSession::Type::Content);
+
+ media_session->RemovePlayers(media_session_observer_1.get());
+ EXPECT_TRUE(HasAudioFocus(media_session));
+ media_session->RemovePlayers(media_session_observer_2.get());
+ EXPECT_FALSE(HasAudioFocus(media_session));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumePlayGivesAudioFocus) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ media_session->RemovePlayer(media_session_observer.get(), 0);
+ EXPECT_FALSE(HasAudioFocus(media_session));
+
+ EXPECT_TRUE(media_session->AddPlayer(media_session_observer.get(), 0,
+ MediaSession::Type::Content));
+ EXPECT_TRUE(HasAudioFocus(media_session));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ ResumeSuspendAreSentOnlyOncePerPlayers_1) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ EXPECT_EQ(0, media_session_observer->received_suspend_calls());
+ EXPECT_EQ(0, media_session_observer->received_resume_calls());
+
+ SuspendSession(media_session);
+ EXPECT_EQ(3, media_session_observer->received_suspend_calls());
+
+ ResumeSession(media_session);
+ EXPECT_EQ(3, media_session_observer->received_resume_calls());
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ ResumeSuspendAreSentOnlyOncePerPlayers_2) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ // Adding the three players above again.
+ EXPECT_TRUE(media_session->AddPlayer(media_session_observer.get(), 0,
+ MediaSession::Type::Content));
+ EXPECT_TRUE(media_session->AddPlayer(media_session_observer.get(), 1,
+ MediaSession::Type::Content));
+ EXPECT_TRUE(media_session->AddPlayer(media_session_observer.get(), 2,
+ MediaSession::Type::Content));
+
+ EXPECT_EQ(0, media_session_observer->received_suspend_calls());
+ EXPECT_EQ(0, media_session_observer->received_resume_calls());
+
+ SuspendSession(media_session);
+ EXPECT_EQ(3, media_session_observer->received_suspend_calls());
+
+ ResumeSession(media_session);
+ EXPECT_EQ(3, media_session_observer->received_resume_calls());
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ RemovingTheSamePlayerTwiceIsANoop) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+
+ media_session->RemovePlayer(media_session_observer.get(), 0);
+ media_session->RemovePlayer(media_session_observer.get(), 0);
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, MediaSessionType) {
+ MediaSession* media_session = MediaSession::Get(shell()->web_contents());
+ ASSERT_TRUE(media_session);
+ DisableNativeBackend(media_session);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ // Starting a player with a given type should set the session to that type.
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Transient);
+ EXPECT_EQ(MediaSession::Type::Transient, GetSessionType(media_session));
+
+ // Adding a player of the same type should have no effect on the type.
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Transient);
+ EXPECT_EQ(MediaSession::Type::Transient, GetSessionType(media_session));
+
+ // Adding a player of Content type should override the current type.
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Content);
+ EXPECT_EQ(MediaSession::Type::Content, GetSessionType(media_session));
+
+ // Adding a player of the Transient type should have no effect on the type.
+ StartNewPlayer(media_session, media_session_observer.get(),
+ MediaSession::Type::Transient);
+ EXPECT_EQ(MediaSession::Type::Content, GetSessionType(media_session));
+
+ EXPECT_TRUE(media_session_observer->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer->IsPlaying(1));
+ EXPECT_TRUE(media_session_observer->IsPlaying(2));
+ EXPECT_TRUE(media_session_observer->IsPlaying(3));
+
+ SuspendSession(media_session);
+
+ EXPECT_FALSE(media_session_observer->IsPlaying(0));
+ EXPECT_FALSE(media_session_observer->IsPlaying(1));
+ EXPECT_FALSE(media_session_observer->IsPlaying(2));
+ EXPECT_FALSE(media_session_observer->IsPlaying(3));
+
+ EXPECT_EQ(MediaSession::Type::Content, GetSessionType(media_session));
+
+ ResumeSession(media_session);
+
+ EXPECT_TRUE(media_session_observer->IsPlaying(0));
+ EXPECT_TRUE(media_session_observer->IsPlaying(1));
+ EXPECT_TRUE(media_session_observer->IsPlaying(2));
+ EXPECT_TRUE(media_session_observer->IsPlaying(3));
+
+ EXPECT_EQ(MediaSession::Type::Content, GetSessionType(media_session));
+
+ media_session->RemovePlayers(media_session_observer.get());
+}
+
+} // namespace content
« no previous file with comments | « content/browser/media/android/media_session.cc ('k') | content/browser/media/android/media_session_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698