123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746 |
- // Copyright 2018 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 "services/media_session/audio_focus_manager.h"
- #include <memory>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/containers/adapters.h"
- #include "base/run_loop.h"
- #include "base/test/power_monitor_test.h"
- #include "base/test/task_environment.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "services/media_session/audio_focus_request.h"
- #include "services/media_session/media_session_service_impl.h"
- #include "services/media_session/public/cpp/test/audio_focus_test_util.h"
- #include "services/media_session/public/cpp/test/mock_media_session.h"
- #include "services/media_session/public/mojom/audio_focus.mojom.h"
- #include "services/media_session/public/mojom/media_session.mojom.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace media_session {
- namespace {
- const char kExampleSourceName[] = "test";
- const char kExampleSourceName2[] = "test2";
- } // anonymous namespace
- // This tests the Audio Focus Manager API. The parameter determines whether
- // audio focus is enabled or not. If it is not enabled it should track the media
- // sessions but not enforce single session focus.
- class AudioFocusManagerTest
- : public testing::TestWithParam<mojom::EnforcementMode> {
- public:
- AudioFocusManagerTest() = default;
- AudioFocusManagerTest(const AudioFocusManagerTest&) = delete;
- AudioFocusManagerTest& operator=(const AudioFocusManagerTest&) = delete;
- void SetUp() override {
- // Create an instance of the MediaSessionService.
- service_ = std::make_unique<MediaSessionServiceImpl>();
- service_->BindAudioFocusManager(
- audio_focus_remote_.BindNewPipeAndPassReceiver());
- service_->BindAudioFocusManagerDebug(
- audio_focus_debug_remote_.BindNewPipeAndPassReceiver());
- service_->BindMediaControllerManager(
- controller_manager_remote_.BindNewPipeAndPassReceiver());
- audio_focus_remote_->SetEnforcementMode(GetParam());
- audio_focus_remote_.FlushForTesting();
- }
- void TearDown() override {
- // Run pending tasks.
- base::RunLoop().RunUntilIdle();
- service_.reset();
- }
- AudioFocusManager::RequestId GetAudioFocusedSession() {
- const auto audio_focus_requests = GetRequests();
- for (const auto& request : base::Reversed(audio_focus_requests)) {
- if (request->audio_focus_type == mojom::AudioFocusType::kGain)
- return request->request_id.value();
- }
- return base::UnguessableToken::Null();
- }
- int GetTransientCount() {
- return GetCountForType(mojom::AudioFocusType::kGainTransient);
- }
- int GetTransientMaybeDuckCount() {
- return GetCountForType(mojom::AudioFocusType::kGainTransientMayDuck);
- }
- int GetAmbientCount() {
- return GetCountForType(mojom::AudioFocusType::kAmbient);
- }
- void AbandonAudioFocusNoReset(test::MockMediaSession* session) {
- session->audio_focus_request()->AbandonAudioFocus();
- session->FlushForTesting();
- audio_focus_remote_.FlushForTesting();
- }
- AudioFocusManager::RequestId RequestAudioFocus(
- test::MockMediaSession* session,
- mojom::AudioFocusType audio_focus_type) {
- return session->RequestAudioFocusFromService(audio_focus_remote_,
- audio_focus_type);
- }
- bool RequestGroupedAudioFocus(const base::UnguessableToken& request_id,
- test::MockMediaSession* session,
- mojom::AudioFocusType audio_focus_type,
- const base::UnguessableToken& group_id) {
- return session->RequestGroupedAudioFocusFromService(
- request_id, audio_focus_remote_, audio_focus_type, group_id);
- }
- mojom::MediaSessionDebugInfoPtr GetDebugInfo(
- AudioFocusManager::RequestId request_id) {
- mojom::MediaSessionDebugInfoPtr result;
- base::OnceCallback<void(mojom::MediaSessionDebugInfoPtr)> callback =
- base::BindOnce(
- [](mojom::MediaSessionDebugInfoPtr* out_result,
- mojom::MediaSessionDebugInfoPtr result) {
- *out_result = std::move(result);
- },
- &result);
- GetDebugService()->GetDebugInfoForRequest(request_id, std::move(callback));
- audio_focus_remote_.FlushForTesting();
- audio_focus_debug_remote_.FlushForTesting();
- return result;
- }
- mojom::MediaSessionInfo::SessionState GetState(
- test::MockMediaSession* session) {
- mojom::MediaSessionInfo::SessionState state = session->GetState();
- if (!IsEnforcementEnabled()) {
- // If audio focus enforcement is disabled then we should never see ducking
- // in the tests.
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking, state);
- }
- return state;
- }
- std::unique_ptr<test::TestAudioFocusObserver> CreateObserver() {
- std::unique_ptr<test::TestAudioFocusObserver> observer =
- std::make_unique<test::TestAudioFocusObserver>();
- GetService()->AddObserver(observer->BindNewPipeAndPassRemote());
- audio_focus_remote_.FlushForTesting();
- return observer;
- }
- std::unique_ptr<test::TestAudioFocusObserver> CreateSourceObserver(
- const base::UnguessableToken& source_id) {
- std::unique_ptr<test::TestAudioFocusObserver> observer =
- std::make_unique<test::TestAudioFocusObserver>();
- GetService()->AddSourceObserver(source_id,
- observer->BindNewPipeAndPassRemote());
- audio_focus_remote_.FlushForTesting();
- return observer;
- }
- mojom::MediaSessionInfo::SessionState GetStateFromParam(
- mojom::MediaSessionInfo::SessionState state) {
- // If enforcement is enabled then returns the provided state, otherwise
- // returns kActive because without enforcement we did not change state.
- if (IsEnforcementEnabled())
- return state;
- return mojom::MediaSessionInfo::SessionState::kActive;
- }
- void SetSource(const base::UnguessableToken& identity,
- const std::string& name) {
- GetService()->SetSource(identity, name);
- audio_focus_remote_.FlushForTesting();
- }
- mojo::Remote<mojom::AudioFocusManager> CreateAudioFocusManagerRemote() {
- mojo::Remote<mojom::AudioFocusManager> remote;
- service_->BindAudioFocusManager(remote.BindNewPipeAndPassReceiver());
- return remote;
- }
- const std::string GetSourceNameForLastRequest() {
- std::vector<mojom::AudioFocusRequestStatePtr> requests = GetRequests();
- EXPECT_TRUE(requests.back());
- return requests.back()->source_name.value();
- }
- bool IsEnforcementEnabled() const {
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- // Enforcement is enabled by default on Chrome OS.
- if (GetParam() == mojom::EnforcementMode::kDefault)
- return true;
- #endif
- return GetParam() == mojom::EnforcementMode::kSingleSession ||
- GetParam() == mojom::EnforcementMode::kSingleGroup;
- }
- bool IsGroupingEnabled() const {
- return GetParam() != mojom::EnforcementMode::kSingleSession;
- }
- void GenerateSuspendEvent() { power_source_.GenerateSuspendEvent(); }
- mojo::Remote<mojom::MediaControllerManager>& controller_manager() {
- return controller_manager_remote_;
- }
- std::vector<mojom::AudioFocusRequestStatePtr> GetSourceFocusRequests(
- const base::UnguessableToken& source_id) {
- std::vector<mojom::AudioFocusRequestStatePtr> result;
- GetService()->GetSourceFocusRequests(
- source_id,
- base::BindOnce(
- [](std::vector<mojom::AudioFocusRequestStatePtr>* out,
- std::vector<mojom::AudioFocusRequestStatePtr> requests) {
- *out = std::move(requests);
- },
- &result));
- audio_focus_remote_.FlushForTesting();
- return result;
- }
- const base::UnguessableToken& GetIdentityForLastRequest() const {
- return service_->audio_focus_manager_for_testing()
- .audio_focus_stack_.back()
- ->identity();
- }
- void FlushForTesting() { audio_focus_remote_.FlushForTesting(); }
- private:
- int GetCountForType(mojom::AudioFocusType type) {
- const auto audio_focus_requests = GetRequests();
- return std::count_if(audio_focus_requests.begin(),
- audio_focus_requests.end(),
- [type](const auto& session) {
- return session->audio_focus_type == type;
- });
- }
- std::vector<mojom::AudioFocusRequestStatePtr> GetRequests() {
- std::vector<mojom::AudioFocusRequestStatePtr> result;
- GetService()->GetFocusRequests(base::BindOnce(
- [](std::vector<mojom::AudioFocusRequestStatePtr>* out,
- std::vector<mojom::AudioFocusRequestStatePtr> requests) {
- for (auto& request : requests)
- out->push_back(request.Clone());
- },
- &result));
- audio_focus_remote_.FlushForTesting();
- return result;
- }
- mojom::AudioFocusManager* GetService() const {
- return audio_focus_remote_.get();
- }
- mojom::AudioFocusManagerDebug* GetDebugService() const {
- return audio_focus_debug_remote_.get();
- }
- void FlushForTestingIfEnabled() {
- if (!IsEnforcementEnabled())
- return;
- audio_focus_remote_.FlushForTesting();
- }
- base::test::TaskEnvironment task_environment_;
- std::unique_ptr<MediaSessionServiceImpl> service_;
- mojo::Remote<mojom::AudioFocusManager> audio_focus_remote_;
- mojo::Remote<mojom::AudioFocusManagerDebug> audio_focus_debug_remote_;
- mojo::Remote<mojom::MediaControllerManager> controller_manager_remote_;
- base::test::ScopedPowerMonitorTestSource power_source_;
- };
- INSTANTIATE_TEST_SUITE_P(
- All,
- AudioFocusManagerTest,
- testing::Values(mojom::EnforcementMode::kDefault,
- mojom::EnforcementMode::kNone,
- mojom::EnforcementMode::kSingleGroup,
- mojom::EnforcementMode::kSingleSession));
- TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_ReplaceFocusedEntry) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kInactive,
- GetState(&media_session_1));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kInactive,
- GetState(&media_session_2));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kInactive,
- GetState(&media_session_3));
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- AudioFocusManager::RequestId request_id_2 =
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_2, GetAudioFocusedSession());
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- AudioFocusManager::RequestId request_id_3 =
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_3, GetAudioFocusedSession());
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_Duplicate) {
- test::MockMediaSession media_session;
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_FromTransient) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- EXPECT_EQ(1, GetTransientCount());
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- EXPECT_EQ(0, GetTransientCount());
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_FromTransientMayDuck) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id = RequestAudioFocus(
- &media_session, mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocusTransient_FromGain) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- EXPECT_EQ(0, GetTransientCount());
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- EXPECT_EQ(1, GetTransientCount());
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session));
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocusTransientMayDuck_FromGain) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- RequestAudioFocus(&media_session,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session));
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocusTransient_FromGainWhileDucking) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(0, GetTransientCount());
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(1, GetTransientCount());
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest,
- RequestAudioFocusTransientMayDuck_FromGainWhileDucking) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_1,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(2, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_RemovesFocusedEntry) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- media_session.AbandonAudioFocusFromClient();
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_MultipleCalls) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- AbandonAudioFocusNoReset(&media_session);
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session.AbandonAudioFocusFromClient();
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- EXPECT_TRUE(observer->focus_lost_session().is_null());
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_RemovesTransientMayDuckEntry) {
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
- test::GetMediaSessionInfoSync(&media_session)));
- }
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_RemovesTransientEntry) {
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(1, GetTransientCount());
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientCount());
- EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
- test::GetMediaSessionInfoSync(&media_session)));
- }
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_WhileDuckingThenResume) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- media_session_1.AbandonAudioFocusFromClient();
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_StopsDucking) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AbandonAudioFocus_ResumesPlayback) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(1, GetTransientCount());
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, DuckWhilePlaying) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, GainSuspendsTransient) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- }
- TEST_P(AudioFocusManagerTest, GainSuspendsTransientMayDuck) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- }
- TEST_P(AudioFocusManagerTest, DuckWithMultipleTransientMayDucks) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- test::MockMediaSession media_session_4;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_2));
- RequestAudioFocus(&media_session_3,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_2));
- RequestAudioFocus(&media_session_4,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_2));
- media_session_3.AbandonAudioFocusFromClient();
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_2));
- media_session_4.AbandonAudioFocusFromClient();
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_1));
- EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
- GetState(&media_session_2));
- }
- TEST_P(AudioFocusManagerTest, MediaSessionDestroyed_ReleasesFocus) {
- {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- }
- // If the media session is destroyed without abandoning audio focus we do not
- // know until we next interact with the manager.
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- }
- TEST_P(AudioFocusManagerTest, MediaSessionDestroyed_ReleasesTransient) {
- {
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(1, GetTransientCount());
- }
- // If the media session is destroyed without abandoning audio focus we do not
- // know until we next interact with the manager.
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientCount());
- }
- TEST_P(AudioFocusManagerTest, MediaSessionDestroyed_ReleasesTransientMayDucks) {
- {
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- }
- // If the media session is destroyed without abandoning audio focus we do not
- // know until we next interact with the manager.
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- }
- TEST_P(AudioFocusManagerTest, GainDucksForceDuck) {
- test::MockMediaSession media_session_1(true /* force_duck */);
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- AudioFocusManager::RequestId request_id_2 =
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_2, GetAudioFocusedSession());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, ForceDuckSessionShouldAlwaysBeDuckedFromGain) {
- test::MockMediaSession media_session_1(true /* force_duck */);
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- AudioFocusManager::RequestId request_id_2 =
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- AudioFocusManager::RequestId request_id_3 =
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_3, GetAudioFocusedSession());
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- media_session_3.AbandonAudioFocusFromClient();
- EXPECT_EQ(request_id_2, GetAudioFocusedSession());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest,
- ForceDuckSessionShouldAlwaysBeDuckedFromTransient) {
- test::MockMediaSession media_session_1(true /* force_duck */);
- test::MockMediaSession media_session_2;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AudioFocusObserver_RequestNoop) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id;
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- EXPECT_EQ(mojom::AudioFocusType::kGain,
- observer->focus_gained_session()->audio_focus_type);
- }
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- EXPECT_TRUE(observer->focus_gained_session().is_null());
- }
- }
- TEST_P(AudioFocusManagerTest, AudioFocusObserver_TransientMayDuck) {
- test::MockMediaSession media_session;
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- RequestAudioFocus(&media_session,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::AudioFocusType::kGainTransientMayDuck,
- observer->focus_gained_session()->audio_focus_type);
- }
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
- test::GetMediaSessionInfoSync(&media_session)));
- }
- }
- TEST_P(AudioFocusManagerTest, GetDebugInfo) {
- test::MockMediaSession media_session;
- AudioFocusManager::RequestId request_id =
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- mojom::MediaSessionDebugInfoPtr debug_info = GetDebugInfo(request_id);
- EXPECT_FALSE(debug_info->name.empty());
- EXPECT_FALSE(debug_info->owner.empty());
- EXPECT_FALSE(debug_info->state.empty());
- }
- TEST_P(AudioFocusManagerTest, GetDebugInfo_BadRequestId) {
- mojom::MediaSessionDebugInfoPtr debug_info =
- GetDebugInfo(base::UnguessableToken::Create());
- EXPECT_TRUE(debug_info->name.empty());
- }
- TEST_P(AudioFocusManagerTest,
- RequestAudioFocusTransient_FromGainWhileSuspended) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(1, GetTransientCount());
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(2, GetTransientCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest,
- RequestAudioFocusTransientMayDuck_FromGainWhileSuspended) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientCount());
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(1, GetTransientCount());
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_1,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientCount());
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, Source_AssociatedWithBinding) {
- base::UnguessableToken identity = base::UnguessableToken::Create();
- SetSource(identity, kExampleSourceName);
- base::UnguessableToken new_identity = base::UnguessableToken::Create();
- mojo::Remote<mojom::AudioFocusManager> new_ptr =
- CreateAudioFocusManagerRemote();
- new_ptr->SetSource(new_identity, kExampleSourceName2);
- new_ptr.FlushForTesting();
- test::MockMediaSession media_session_1;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(kExampleSourceName, GetSourceNameForLastRequest());
- EXPECT_EQ(identity, GetIdentityForLastRequest());
- test::MockMediaSession media_session_2;
- media_session_2.RequestAudioFocusFromService(new_ptr,
- mojom::AudioFocusType::kGain);
- EXPECT_EQ(kExampleSourceName2, GetSourceNameForLastRequest());
- EXPECT_EQ(new_identity, GetIdentityForLastRequest());
- }
- TEST_P(AudioFocusManagerTest, Source_Empty) {
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_TRUE(GetSourceNameForLastRequest().empty());
- EXPECT_EQ(base::UnguessableToken::Null(), GetIdentityForLastRequest());
- }
- TEST_P(AudioFocusManagerTest, Source_Updated) {
- base::UnguessableToken identity = base::UnguessableToken::Create();
- SetSource(identity, kExampleSourceName);
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
- EXPECT_EQ(kExampleSourceName, GetSourceNameForLastRequest());
- EXPECT_EQ(identity, GetIdentityForLastRequest());
- base::UnguessableToken new_identity = base::UnguessableToken::Create();
- SetSource(new_identity, kExampleSourceName2);
- EXPECT_EQ(kExampleSourceName, GetSourceNameForLastRequest());
- EXPECT_EQ(identity, GetIdentityForLastRequest());
- }
- TEST_P(AudioFocusManagerTest,
- AbandonAudioFocus_ObserverFocusGain_NoTopSession) {
- test::MockMediaSession media_session;
- RequestAudioFocus(&media_session,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session));
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
- test::GetMediaSessionInfoSync(&media_session)));
- EXPECT_TRUE(observer->focus_gained_session().is_null());
- auto notifications = observer->notifications();
- EXPECT_EQ(1u, notifications.size());
- EXPECT_EQ(test::TestAudioFocusObserver::NotificationType::kFocusLost,
- notifications[0]);
- }
- }
- TEST_P(AudioFocusManagerTest,
- AbandonAudioFocus_ObserverFocusGain_NewTopSession) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- mojom::MediaSessionInfoPtr media_session_1_info =
- test::GetMediaSessionInfoSync(&media_session_1);
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
- test::GetMediaSessionInfoSync(&media_session_2)));
- EXPECT_TRUE(observer->focus_gained_session()->session_info.Equals(
- media_session_1_info));
- // FocusLost should always come before FocusGained so observers always know
- // the current session that has focus.
- auto notifications = observer->notifications();
- EXPECT_EQ(2u, notifications.size());
- EXPECT_EQ(test::TestAudioFocusObserver::NotificationType::kFocusLost,
- notifications[0]);
- EXPECT_EQ(test::TestAudioFocusObserver::NotificationType::kFocusGained,
- notifications[1]);
- }
- }
- TEST_P(AudioFocusManagerTest, AudioFocusGrouping_LayeredFocus) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- base::UnguessableToken group_id = base::UnguessableToken::Create();
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_1,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- // When we request audio focus for media_session_3 the group will take audio
- // focus and we suspend the ducking session.
- ASSERT_TRUE(RequestGroupedAudioFocus(
- base::UnguessableToken::Create(), &media_session_3,
- mojom::AudioFocusType::kGainTransient, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_3));
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- EXPECT_EQ(GetStateFromParam(
- IsGroupingEnabled()
- ? mojom::MediaSessionInfo::SessionState::kActive
- : mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AudioFocusGrouping_TransientResume) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- test::MockMediaSession media_session_4;
- base::UnguessableToken group_id = base::UnguessableToken::Create();
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_1,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_3,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_3));
- RequestAudioFocus(&media_session_4, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_3));
- media_session_4.AbandonAudioFocusFromClient();
- // TODO(https://crbug.com/916177): This should wait on a more precise
- // condition than RunLoop idling, but it's not clear exactly what that
- // should be.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(IsGroupingEnabled()
- ? mojom::MediaSessionInfo::SessionState::kActive
- : mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_2));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_3));
- }
- TEST_P(AudioFocusManagerTest, AudioFocusGrouping_DoNotSuspendSameGroup) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- base::UnguessableToken group_id = base::UnguessableToken::Create();
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_1,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_2,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(IsGroupingEnabled()
- ? mojom::MediaSessionInfo::SessionState::kActive
- : mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- }
- TEST_P(AudioFocusManagerTest, AudioFocusGrouping_DuckSameGroup) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- base::UnguessableToken group_id = base::UnguessableToken::Create();
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_1,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- ASSERT_TRUE(RequestGroupedAudioFocus(
- base::UnguessableToken::Create(), &media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck, group_id));
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AudioFocusGrouping_TransientSameGroup) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- base::UnguessableToken group_id = base::UnguessableToken::Create();
- ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
- &media_session_1,
- mojom::AudioFocusType::kGain, group_id));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- ASSERT_TRUE(RequestGroupedAudioFocus(
- base::UnguessableToken::Create(), &media_session_2,
- mojom::AudioFocusType::kGainTransient, group_id));
- EXPECT_EQ(IsGroupingEnabled()
- ? mojom::MediaSessionInfo::SessionState::kActive
- : mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- }
- TEST_P(AudioFocusManagerTest, RequestAudioFocus_PreferStop_LossToGain) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- media_session_1.SetPreferStop(true);
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- AudioFocusManager::RequestId request_id_2 =
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_2, GetAudioFocusedSession());
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kInactive),
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest,
- RequestAudioFocus_PreferStop_LossToGainTransient) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- media_session_1.SetPreferStop(true);
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, GainFocusTypeHasEffectEvenIfSuspended) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- // When the second session becomes suspended and that event originated from
- // the session itself then we should keep the other session suspended.
- media_session_2.Suspend(mojom::MediaSession::SuspendType::kUI);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- // When the second session is resumed then we should still keep the other
- // session suspended.
- media_session_2.Resume(mojom::MediaSession::SuspendType::kUI);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- // If a new session takes focus then this should suspend all sessions.
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGainTransient);
- {
- test::MockMediaSessionMojoObserver observer(media_session_2);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- // If the second session regains focus then it should suspend all sessions.
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_3);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- }
- TEST_P(AudioFocusManagerTest, TransientFocusTypeHasNoEffectIfSuspended) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- // When the transient session becomes suspended and that event originates from
- // the session itself then we should stop pausing the other session.
- media_session_2.Suspend(mojom::MediaSession::SuspendType::kUI);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
- }
- // When the transient session is resumed then we should pause the other
- // session again.
- media_session_2.Resume(mojom::MediaSession::SuspendType::kUI);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- // If we have a new session take focus then this should suspend all the other
- // sessions and the transient session should have no effect.
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGainTransient);
- {
- test::MockMediaSessionMojoObserver observer(media_session_2);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- // If the second session regains focus then it should start pausing again.
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_3);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- }
- TEST_P(AudioFocusManagerTest, TransientDuckFocusTypeHasNoEffectIfSuspended) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- test::MockMediaSession media_session_3;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- // When the ducking session becomes suspended and that event originates from
- // the session itself then we should stop ducking.
- media_session_2.Suspend(mojom::MediaSession::SuspendType::kUI);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
- }
- // When the ducking session is resumed then we should resume ducking.
- media_session_2.Resume(mojom::MediaSession::SuspendType::kUI);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking));
- }
- // If we have a new session take focus then this should suspend all the other
- // sessions and we should not have any ducking from the ducking session (since
- // it is suspended).
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGainTransient);
- {
- test::MockMediaSessionMojoObserver observer(media_session_2);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
- }
- // If the ducking session regains focus then it should start ducking again.
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking));
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_3);
- observer.WaitForState(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking));
- }
- }
- TEST_P(AudioFocusManagerTest, AmbientFocusHasNoEffect) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- EXPECT_EQ(0, GetAmbientCount());
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kAmbient);
- EXPECT_EQ(1, GetAmbientCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(0, GetAmbientCount());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, AudioFocusObserver_NotTopMost) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- AudioFocusManager::RequestId request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(request_id_1, GetAudioFocusedSession());
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2,
- mojom::AudioFocusType::kGainTransientMayDuck);
- EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
- GetState(&media_session_1));
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_2));
- {
- std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
- media_session_1.AbandonAudioFocusFromClient();
- EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
- test::GetMediaSessionInfoSync(&media_session_1)));
- }
- }
- TEST_P(AudioFocusManagerTest, SuspendAllSessionOnPowerSuspend) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- {
- test::MockMediaSessionMojoObserver observer(media_session_1);
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
- }
- {
- test::MockMediaSessionMojoObserver observer(media_session_2);
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
- }
- test::MockMediaSessionMojoObserver observer_1(media_session_1);
- test::MockMediaSessionMojoObserver observer_2(media_session_2);
- GenerateSuspendEvent();
- observer_1.WaitForState(mojom::MediaSessionInfo::SessionState::kSuspended);
- observer_2.WaitForState(mojom::MediaSessionInfo::SessionState::kSuspended);
- }
- TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayControllerPause) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- mojo::Remote<mojom::MediaController> controller;
- controller_manager()->CreateMediaControllerForSession(
- controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
- controller_manager().FlushForTesting();
- controller->Suspend();
- controller.FlushForTesting();
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- // When we abandon the transient session then we will apply the last
- // controller action.
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayControllerStop) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- mojo::Remote<mojom::MediaController> controller;
- controller_manager()->CreateMediaControllerForSession(
- controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
- controller_manager().FlushForTesting();
- controller->Stop();
- controller.FlushForTesting();
- // If enforcement is enabled then the session was previously suspended by the
- // transient session and therefore we should be suspended. Otherwise, we
- // should be inactive because the stop command would not have been delayed.
- EXPECT_EQ(IsEnforcementEnabled()
- ? mojom::MediaSessionInfo::SessionState::kSuspended
- : mojom::MediaSessionInfo::SessionState::kInactive,
- GetState(&media_session_1));
- {
- // When we abandon the transient session then we will apply the last
- // controller action.
- test::MockMediaSessionMojoObserver observer(media_session_1);
- media_session_2.AbandonAudioFocusFromClient();
- observer.WaitForState(mojom::MediaSessionInfo::SessionState::kInactive);
- }
- }
- TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayControllerResume) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- mojo::Remote<mojom::MediaController> controller;
- controller_manager()->CreateMediaControllerForSession(
- controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
- controller_manager().FlushForTesting();
- controller->Suspend();
- controller.FlushForTesting();
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- controller->Resume();
- controller.FlushForTesting();
- // If enforcement is enabled then the session was previously suspended by the
- // transient session and therefore we should be suspended. Otherwise, we
- // should be active because the resume command would not have been delayed.
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- {
- // When we abandon the transient session then we will apply the last
- // controller action.
- test::MockMediaSessionMojoObserver observer(media_session_1);
- media_session_2.AbandonAudioFocusFromClient();
- observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
- }
- }
- TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayLastActionOnly) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
- GetState(&media_session_1));
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- mojo::Remote<mojom::MediaController> controller;
- controller_manager()->CreateMediaControllerForSession(
- controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
- controller_manager().FlushForTesting();
- controller->Resume();
- controller.FlushForTesting();
- // The resume action should be delayed because we were suspended by the
- // transient session.
- EXPECT_EQ(
- GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
- GetState(&media_session_1));
- // Calling suspend while we are still suspended should cancel the delayed
- // resume action so we will never resume.
- controller->Suspend();
- controller.FlushForTesting();
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- // When we abandon the transient session then we will apply the last
- // controller action.
- media_session_2.AbandonAudioFocusFromClient();
- EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
- GetState(&media_session_1));
- }
- TEST_P(AudioFocusManagerTest, RequestIdValidation) {
- test::MockMediaSession media_session_1;
- test::MockMediaSession media_session_2;
- base::UnguessableToken request_id = base::UnguessableToken::Create();
- EXPECT_TRUE(RequestGroupedAudioFocus(request_id, &media_session_1,
- mojom::AudioFocusType::kGain,
- base::UnguessableToken::Create()));
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- // The audio focus request should fail since we have already used that id.
- EXPECT_FALSE(RequestGroupedAudioFocus(request_id, &media_session_2,
- mojom::AudioFocusType::kGain,
- base::UnguessableToken::Create()));
- media_session_1.AbandonAudioFocusFromClient();
- EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
- // If we abandon focus then we should be able to use the id now.
- EXPECT_TRUE(RequestGroupedAudioFocus(request_id, &media_session_2,
- mojom::AudioFocusType::kGain,
- base::UnguessableToken::Create()));
- EXPECT_EQ(request_id, GetAudioFocusedSession());
- }
- TEST_P(AudioFocusManagerTest, SourceObservers) {
- // Create two identity observers for two different identities.
- base::UnguessableToken identity_1 = base::UnguessableToken::Create();
- base::UnguessableToken identity_2 = base::UnguessableToken::Create();
- std::unique_ptr<test::TestAudioFocusObserver> observer_1 =
- CreateSourceObserver(identity_1);
- std::unique_ptr<test::TestAudioFocusObserver> observer_2 =
- CreateSourceObserver(identity_2);
- // Request audio focus for the first identity.
- SetSource(identity_1, kExampleSourceName);
- test::MockMediaSession media_session_1;
- base::UnguessableToken request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- // The observer for the first identity should see the gained focus, while the
- // observer for the second identity should see nothing.
- EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
- EXPECT_TRUE(observer_2->focus_gained_session().is_null());
- // Request audio focus for the second identity.
- SetSource(identity_2, kExampleSourceName);
- test::MockMediaSession media_session_2;
- base::UnguessableToken request_id_2 =
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- // The observer for the first identity should still show the first request,
- // while the observer for the second identity should see the new session.
- EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
- EXPECT_EQ(request_id_2, observer_2->focus_gained_session()->request_id);
- // Make another request in the second identity.
- test::MockMediaSession media_session_3;
- base::UnguessableToken request_id_3 =
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
- // The observer for the first identity should still show the first request,
- // while the observer for the second identity should see the new session.
- EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
- EXPECT_EQ(request_id_3, observer_2->focus_gained_session()->request_id);
- // Abandon the topmost session.
- media_session_3.AbandonAudioFocusFromClient();
- FlushForTesting();
- // The observer for the second identity should get the new lost and gained
- // sessions, with no updates to the first observer.
- EXPECT_EQ(request_id_3, observer_2->focus_lost_session()->request_id);
- EXPECT_EQ(request_id_2, observer_2->focus_gained_session()->request_id);
- EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
- EXPECT_TRUE(observer_1->focus_lost_session().is_null());
- }
- TEST_P(AudioFocusManagerTest, GetSourceFocusRequests) {
- // Establish identities.
- base::UnguessableToken identity_1 = base::UnguessableToken::Create();
- base::UnguessableToken identity_2 = base::UnguessableToken::Create();
- base::UnguessableToken identity_3 = base::UnguessableToken::Create();
- // Create a focus request for the first identity.
- SetSource(identity_1, kExampleSourceName);
- test::MockMediaSession media_session_1;
- base::UnguessableToken request_id_1 =
- RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
- // Create a focus request for the second identity.
- SetSource(identity_2, kExampleSourceName);
- test::MockMediaSession media_session_2;
- base::UnguessableToken request_id_2 =
- RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
- // Create another focus request for the first identity.
- SetSource(identity_1, kExampleSourceName);
- test::MockMediaSession media_session_3;
- base::UnguessableToken request_id_3 =
- RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
- // Use the GetSourceFocusRequests API to get requests for each identity.
- std::vector<mojom::AudioFocusRequestStatePtr> identity_1_requests =
- GetSourceFocusRequests(identity_1);
- std::vector<mojom::AudioFocusRequestStatePtr> identity_2_requests =
- GetSourceFocusRequests(identity_2);
- std::vector<mojom::AudioFocusRequestStatePtr> identity_3_requests =
- GetSourceFocusRequests(identity_3);
- // Ensure that the API returned the right requests for the first identity.
- EXPECT_EQ(2u, identity_1_requests.size());
- EXPECT_EQ(request_id_1, identity_1_requests[0]->request_id);
- EXPECT_EQ(request_id_3, identity_1_requests[1]->request_id);
- // Ensure that the API returned the right requests for the second identity.
- EXPECT_EQ(1u, identity_2_requests.size());
- EXPECT_EQ(request_id_2, identity_2_requests[0]->request_id);
- // Ensure that the API returned nothing for the unused identity.
- EXPECT_TRUE(identity_3_requests.empty());
- }
- } // namespace media_session
|