Fix emulator build error
[platform/framework/web/chromium-efl.git] / services / media_session / audio_focus_manager_unittest.cc
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "services/media_session/audio_focus_manager.h"
6
7 #include <memory>
8 #include <utility>
9 #include <vector>
10
11 #include "base/containers/adapters.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/ranges/algorithm.h"
15 #include "base/run_loop.h"
16 #include "base/test/power_monitor_test.h"
17 #include "base/test/task_environment.h"
18 #include "build/build_config.h"
19 #include "build/chromeos_buildflags.h"
20 #include "mojo/public/cpp/bindings/remote.h"
21 #include "services/media_session/audio_focus_request.h"
22 #include "services/media_session/media_session_service_impl.h"
23 #include "services/media_session/public/cpp/test/audio_focus_test_util.h"
24 #include "services/media_session/public/cpp/test/mock_media_session.h"
25 #include "services/media_session/public/mojom/audio_focus.mojom.h"
26 #include "services/media_session/public/mojom/media_session.mojom.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace media_session {
30
31 namespace {
32
33 const char kExampleSourceName[] = "test";
34 const char kExampleSourceName2[] = "test2";
35
36 }  // anonymous namespace
37
38 // This tests the Audio Focus Manager API. The parameter determines whether
39 // audio focus is enabled or not. If it is not enabled it should track the media
40 // sessions but not enforce single session focus.
41 class AudioFocusManagerTest
42     : public testing::TestWithParam<mojom::EnforcementMode> {
43  public:
44   AudioFocusManagerTest() = default;
45
46   AudioFocusManagerTest(const AudioFocusManagerTest&) = delete;
47   AudioFocusManagerTest& operator=(const AudioFocusManagerTest&) = delete;
48
49   void SetUp() override {
50     // Create an instance of the MediaSessionService.
51     service_ = std::make_unique<MediaSessionServiceImpl>();
52     service_->BindAudioFocusManager(
53         audio_focus_remote_.BindNewPipeAndPassReceiver());
54     service_->BindAudioFocusManagerDebug(
55         audio_focus_debug_remote_.BindNewPipeAndPassReceiver());
56     service_->BindMediaControllerManager(
57         controller_manager_remote_.BindNewPipeAndPassReceiver());
58
59     audio_focus_remote_->SetEnforcementMode(GetParam());
60     audio_focus_remote_.FlushForTesting();
61   }
62
63   void TearDown() override {
64     // Run pending tasks.
65     base::RunLoop().RunUntilIdle();
66
67     service_.reset();
68   }
69
70   AudioFocusManager::RequestId GetAudioFocusedSession() {
71     const auto audio_focus_requests = GetRequests();
72     for (const auto& request : base::Reversed(audio_focus_requests)) {
73       if (request->audio_focus_type == mojom::AudioFocusType::kGain)
74         return request->request_id.value();
75     }
76     return base::UnguessableToken::Null();
77   }
78
79   int GetTransientCount() {
80     return GetCountForType(mojom::AudioFocusType::kGainTransient);
81   }
82
83   int GetTransientMaybeDuckCount() {
84     return GetCountForType(mojom::AudioFocusType::kGainTransientMayDuck);
85   }
86
87   int GetAmbientCount() {
88     return GetCountForType(mojom::AudioFocusType::kAmbient);
89   }
90
91   void AbandonAudioFocusNoReset(test::MockMediaSession* session) {
92     session->audio_focus_request()->AbandonAudioFocus();
93     session->FlushForTesting();
94     audio_focus_remote_.FlushForTesting();
95   }
96
97   AudioFocusManager::RequestId RequestAudioFocus(
98       test::MockMediaSession* session,
99       mojom::AudioFocusType audio_focus_type) {
100     return session->RequestAudioFocusFromService(audio_focus_remote_,
101                                                  audio_focus_type);
102   }
103
104   bool RequestGroupedAudioFocus(const base::UnguessableToken& request_id,
105                                 test::MockMediaSession* session,
106                                 mojom::AudioFocusType audio_focus_type,
107                                 const base::UnguessableToken& group_id) {
108     return session->RequestGroupedAudioFocusFromService(
109         request_id, audio_focus_remote_, audio_focus_type, group_id);
110   }
111
112   mojom::MediaSessionDebugInfoPtr GetDebugInfo(
113       AudioFocusManager::RequestId request_id) {
114     mojom::MediaSessionDebugInfoPtr result;
115     base::OnceCallback<void(mojom::MediaSessionDebugInfoPtr)> callback =
116         base::BindOnce(
117             [](mojom::MediaSessionDebugInfoPtr* out_result,
118                mojom::MediaSessionDebugInfoPtr result) {
119               *out_result = std::move(result);
120             },
121             &result);
122
123     GetDebugService()->GetDebugInfoForRequest(request_id, std::move(callback));
124
125     audio_focus_remote_.FlushForTesting();
126     audio_focus_debug_remote_.FlushForTesting();
127
128     return result;
129   }
130
131   mojom::MediaSessionInfo::SessionState GetState(
132       test::MockMediaSession* session) {
133     mojom::MediaSessionInfo::SessionState state = session->GetState();
134
135     if (!IsEnforcementEnabled()) {
136       // If audio focus enforcement is disabled then we should never see ducking
137       // in the tests.
138       EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking, state);
139     }
140
141     return state;
142   }
143
144   std::unique_ptr<test::TestAudioFocusObserver> CreateObserver() {
145     std::unique_ptr<test::TestAudioFocusObserver> observer =
146         std::make_unique<test::TestAudioFocusObserver>();
147
148     GetService()->AddObserver(observer->BindNewPipeAndPassRemote());
149
150     audio_focus_remote_.FlushForTesting();
151     return observer;
152   }
153
154   std::unique_ptr<test::TestAudioFocusObserver> CreateSourceObserver(
155       const base::UnguessableToken& source_id) {
156     std::unique_ptr<test::TestAudioFocusObserver> observer =
157         std::make_unique<test::TestAudioFocusObserver>();
158
159     GetService()->AddSourceObserver(source_id,
160                                     observer->BindNewPipeAndPassRemote());
161
162     audio_focus_remote_.FlushForTesting();
163     return observer;
164   }
165
166   mojom::MediaSessionInfo::SessionState GetStateFromParam(
167       mojom::MediaSessionInfo::SessionState state) {
168     // If enforcement is enabled then returns the provided state, otherwise
169     // returns kActive because without enforcement we did not change state.
170     if (IsEnforcementEnabled())
171       return state;
172     return mojom::MediaSessionInfo::SessionState::kActive;
173   }
174
175   void SetSource(const base::UnguessableToken& identity,
176                  const std::string& name) {
177     GetService()->SetSource(identity, name);
178     audio_focus_remote_.FlushForTesting();
179   }
180
181   mojo::Remote<mojom::AudioFocusManager> CreateAudioFocusManagerRemote() {
182     mojo::Remote<mojom::AudioFocusManager> remote;
183     service_->BindAudioFocusManager(remote.BindNewPipeAndPassReceiver());
184     return remote;
185   }
186
187   const std::string GetSourceNameForLastRequest() {
188     std::vector<mojom::AudioFocusRequestStatePtr> requests = GetRequests();
189     EXPECT_TRUE(requests.back());
190     return requests.back()->source_name.value();
191   }
192
193   bool IsEnforcementEnabled() const {
194     return GetParam() == mojom::EnforcementMode::kSingleSession ||
195            GetParam() == mojom::EnforcementMode::kSingleGroup;
196   }
197
198   bool IsGroupingEnabled() const {
199     return GetParam() != mojom::EnforcementMode::kSingleSession;
200   }
201
202   void GenerateSuspendEvent() { power_source_.GenerateSuspendEvent(); }
203
204   mojo::Remote<mojom::MediaControllerManager>& controller_manager() {
205     return controller_manager_remote_;
206   }
207
208   std::vector<mojom::AudioFocusRequestStatePtr> GetSourceFocusRequests(
209       const base::UnguessableToken& source_id) {
210     std::vector<mojom::AudioFocusRequestStatePtr> result;
211
212     GetService()->GetSourceFocusRequests(
213         source_id,
214         base::BindOnce(
215             [](std::vector<mojom::AudioFocusRequestStatePtr>* out,
216                std::vector<mojom::AudioFocusRequestStatePtr> requests) {
217               *out = std::move(requests);
218             },
219             &result));
220
221     audio_focus_remote_.FlushForTesting();
222     return result;
223   }
224
225   const base::UnguessableToken& GetIdentityForLastRequest() const {
226     return service_->audio_focus_manager_for_testing()
227         .audio_focus_stack_.back()
228         ->identity();
229   }
230
231   void FlushForTesting() { audio_focus_remote_.FlushForTesting(); }
232
233  private:
234   int GetCountForType(mojom::AudioFocusType type) {
235     const auto audio_focus_requests = GetRequests();
236     return base::ranges::count(
237         audio_focus_requests, type,
238         &mojom::AudioFocusRequestState::audio_focus_type);
239   }
240
241   std::vector<mojom::AudioFocusRequestStatePtr> GetRequests() {
242     std::vector<mojom::AudioFocusRequestStatePtr> result;
243
244     GetService()->GetFocusRequests(base::BindOnce(
245         [](std::vector<mojom::AudioFocusRequestStatePtr>* out,
246            std::vector<mojom::AudioFocusRequestStatePtr> requests) {
247           for (auto& request : requests)
248             out->push_back(request.Clone());
249         },
250         &result));
251
252     audio_focus_remote_.FlushForTesting();
253     return result;
254   }
255
256   mojom::AudioFocusManager* GetService() const {
257     return audio_focus_remote_.get();
258   }
259
260   mojom::AudioFocusManagerDebug* GetDebugService() const {
261     return audio_focus_debug_remote_.get();
262   }
263
264   void FlushForTestingIfEnabled() {
265     if (!IsEnforcementEnabled())
266       return;
267
268     audio_focus_remote_.FlushForTesting();
269   }
270
271   base::test::TaskEnvironment task_environment_;
272
273   std::unique_ptr<MediaSessionServiceImpl> service_;
274
275   mojo::Remote<mojom::AudioFocusManager> audio_focus_remote_;
276   mojo::Remote<mojom::AudioFocusManagerDebug> audio_focus_debug_remote_;
277   mojo::Remote<mojom::MediaControllerManager> controller_manager_remote_;
278
279   base::test::ScopedPowerMonitorTestSource power_source_;
280 };
281
282 INSTANTIATE_TEST_SUITE_P(
283     All,
284     AudioFocusManagerTest,
285     testing::Values(mojom::EnforcementMode::kDefault,
286                     mojom::EnforcementMode::kNone,
287                     mojom::EnforcementMode::kSingleGroup,
288                     mojom::EnforcementMode::kSingleSession));
289
290 TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_ReplaceFocusedEntry) {
291   test::MockMediaSession media_session_1;
292   test::MockMediaSession media_session_2;
293   test::MockMediaSession media_session_3;
294
295   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
296   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kInactive,
297             GetState(&media_session_1));
298   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kInactive,
299             GetState(&media_session_2));
300   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kInactive,
301             GetState(&media_session_3));
302
303   AudioFocusManager::RequestId request_id_1 =
304       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
305   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
306   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
307             GetState(&media_session_1));
308
309   AudioFocusManager::RequestId request_id_2 =
310       RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
311   EXPECT_EQ(request_id_2, GetAudioFocusedSession());
312   EXPECT_EQ(
313       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
314       GetState(&media_session_1));
315
316   AudioFocusManager::RequestId request_id_3 =
317       RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
318   EXPECT_EQ(request_id_3, GetAudioFocusedSession());
319   EXPECT_EQ(
320       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
321       GetState(&media_session_2));
322 }
323
324 TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_Duplicate) {
325   test::MockMediaSession media_session;
326
327   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
328
329   AudioFocusManager::RequestId request_id =
330       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
331   EXPECT_EQ(request_id, GetAudioFocusedSession());
332
333   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
334   EXPECT_EQ(request_id, GetAudioFocusedSession());
335 }
336
337 TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_FromTransient) {
338   test::MockMediaSession media_session;
339
340   AudioFocusManager::RequestId request_id =
341       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
342   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
343   EXPECT_EQ(1, GetTransientCount());
344
345   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
346   EXPECT_EQ(request_id, GetAudioFocusedSession());
347   EXPECT_EQ(0, GetTransientCount());
348 }
349
350 TEST_P(AudioFocusManagerTest, RequestAudioFocusGain_FromTransientMayDuck) {
351   test::MockMediaSession media_session;
352
353   AudioFocusManager::RequestId request_id = RequestAudioFocus(
354       &media_session, mojom::AudioFocusType::kGainTransientMayDuck);
355   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
356   EXPECT_EQ(1, GetTransientMaybeDuckCount());
357
358   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
359   EXPECT_EQ(request_id, GetAudioFocusedSession());
360   EXPECT_EQ(0, GetTransientMaybeDuckCount());
361 }
362
363 TEST_P(AudioFocusManagerTest, RequestAudioFocusTransient_FromGain) {
364   test::MockMediaSession media_session;
365
366   AudioFocusManager::RequestId request_id =
367       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
368
369   EXPECT_EQ(request_id, GetAudioFocusedSession());
370   EXPECT_EQ(0, GetTransientCount());
371
372   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
373   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
374   EXPECT_EQ(1, GetTransientCount());
375   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kSuspended,
376             GetState(&media_session));
377 }
378
379 TEST_P(AudioFocusManagerTest, RequestAudioFocusTransientMayDuck_FromGain) {
380   test::MockMediaSession media_session;
381
382   AudioFocusManager::RequestId request_id =
383       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
384
385   EXPECT_EQ(request_id, GetAudioFocusedSession());
386   EXPECT_EQ(0, GetTransientMaybeDuckCount());
387
388   RequestAudioFocus(&media_session,
389                     mojom::AudioFocusType::kGainTransientMayDuck);
390   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
391   EXPECT_EQ(1, GetTransientMaybeDuckCount());
392   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
393             GetState(&media_session));
394 }
395
396 TEST_P(AudioFocusManagerTest, RequestAudioFocusTransient_FromGainWhileDucking) {
397   test::MockMediaSession media_session_1;
398   test::MockMediaSession media_session_2;
399
400   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
401   EXPECT_EQ(0, GetTransientMaybeDuckCount());
402   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
403             GetState(&media_session_1));
404
405   RequestAudioFocus(&media_session_2,
406                     mojom::AudioFocusType::kGainTransientMayDuck);
407   EXPECT_EQ(0, GetTransientCount());
408   EXPECT_EQ(1, GetTransientMaybeDuckCount());
409   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
410             GetState(&media_session_1));
411
412   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGainTransient);
413   EXPECT_EQ(1, GetTransientCount());
414   EXPECT_EQ(1, GetTransientMaybeDuckCount());
415   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
416             GetState(&media_session_1));
417 }
418
419 TEST_P(AudioFocusManagerTest,
420        RequestAudioFocusTransientMayDuck_FromGainWhileDucking) {
421   test::MockMediaSession media_session_1;
422   test::MockMediaSession media_session_2;
423
424   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
425   EXPECT_EQ(0, GetTransientMaybeDuckCount());
426   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
427             GetState(&media_session_1));
428
429   RequestAudioFocus(&media_session_2,
430                     mojom::AudioFocusType::kGainTransientMayDuck);
431   EXPECT_EQ(1, GetTransientMaybeDuckCount());
432   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
433             GetState(&media_session_1));
434
435   RequestAudioFocus(&media_session_1,
436                     mojom::AudioFocusType::kGainTransientMayDuck);
437   EXPECT_EQ(2, GetTransientMaybeDuckCount());
438   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
439             GetState(&media_session_1));
440 }
441
442 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_RemovesFocusedEntry) {
443   test::MockMediaSession media_session;
444
445   AudioFocusManager::RequestId request_id =
446       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
447   EXPECT_EQ(request_id, GetAudioFocusedSession());
448
449   media_session.AbandonAudioFocusFromClient();
450   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
451 }
452
453 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_MultipleCalls) {
454   test::MockMediaSession media_session;
455
456   AudioFocusManager::RequestId request_id =
457       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
458   EXPECT_EQ(request_id, GetAudioFocusedSession());
459
460   AbandonAudioFocusNoReset(&media_session);
461
462   std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
463   media_session.AbandonAudioFocusFromClient();
464
465   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
466   EXPECT_TRUE(observer->focus_lost_session().is_null());
467 }
468
469 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_RemovesTransientMayDuckEntry) {
470   test::MockMediaSession media_session;
471
472   RequestAudioFocus(&media_session,
473                     mojom::AudioFocusType::kGainTransientMayDuck);
474   EXPECT_EQ(1, GetTransientMaybeDuckCount());
475
476   {
477     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
478     media_session.AbandonAudioFocusFromClient();
479
480     EXPECT_EQ(0, GetTransientMaybeDuckCount());
481     EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
482         test::GetMediaSessionInfoSync(&media_session)));
483   }
484 }
485
486 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_RemovesTransientEntry) {
487   test::MockMediaSession media_session;
488
489   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
490   EXPECT_EQ(1, GetTransientCount());
491
492   {
493     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
494     media_session.AbandonAudioFocusFromClient();
495
496     EXPECT_EQ(0, GetTransientCount());
497     EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
498         test::GetMediaSessionInfoSync(&media_session)));
499   }
500 }
501
502 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_WhileDuckingThenResume) {
503   test::MockMediaSession media_session_1;
504   test::MockMediaSession media_session_2;
505
506   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
507   EXPECT_EQ(0, GetTransientMaybeDuckCount());
508   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
509             GetState(&media_session_1));
510
511   RequestAudioFocus(&media_session_2,
512                     mojom::AudioFocusType::kGainTransientMayDuck);
513   EXPECT_EQ(1, GetTransientMaybeDuckCount());
514   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
515             GetState(&media_session_1));
516
517   media_session_1.AbandonAudioFocusFromClient();
518   EXPECT_EQ(1, GetTransientMaybeDuckCount());
519
520   media_session_2.AbandonAudioFocusFromClient();
521   EXPECT_EQ(0, GetTransientMaybeDuckCount());
522
523   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
524   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
525             GetState(&media_session_1));
526 }
527
528 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_StopsDucking) {
529   test::MockMediaSession media_session_1;
530   test::MockMediaSession media_session_2;
531
532   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
533   EXPECT_EQ(0, GetTransientMaybeDuckCount());
534   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
535             GetState(&media_session_1));
536
537   RequestAudioFocus(&media_session_2,
538                     mojom::AudioFocusType::kGainTransientMayDuck);
539   EXPECT_EQ(1, GetTransientMaybeDuckCount());
540   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
541             GetState(&media_session_1));
542
543   media_session_2.AbandonAudioFocusFromClient();
544   EXPECT_EQ(0, GetTransientMaybeDuckCount());
545   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
546             GetState(&media_session_1));
547 }
548
549 TEST_P(AudioFocusManagerTest, AbandonAudioFocus_ResumesPlayback) {
550   test::MockMediaSession media_session_1;
551   test::MockMediaSession media_session_2;
552
553   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
554   EXPECT_EQ(0, GetTransientCount());
555   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
556             GetState(&media_session_1));
557
558   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
559   EXPECT_EQ(1, GetTransientCount());
560   EXPECT_EQ(
561       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
562       GetState(&media_session_1));
563
564   media_session_2.AbandonAudioFocusFromClient();
565   EXPECT_EQ(0, GetTransientCount());
566   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
567             GetState(&media_session_1));
568 }
569
570 TEST_P(AudioFocusManagerTest, DuckWhilePlaying) {
571   test::MockMediaSession media_session_1;
572   test::MockMediaSession media_session_2;
573
574   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
575   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
576             GetState(&media_session_1));
577
578   RequestAudioFocus(&media_session_2,
579                     mojom::AudioFocusType::kGainTransientMayDuck);
580   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
581             GetState(&media_session_1));
582 }
583
584 TEST_P(AudioFocusManagerTest, GainSuspendsTransient) {
585   test::MockMediaSession media_session_1;
586   test::MockMediaSession media_session_2;
587
588   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
589
590   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
591   EXPECT_EQ(
592       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
593       GetState(&media_session_2));
594 }
595
596 TEST_P(AudioFocusManagerTest, GainSuspendsTransientMayDuck) {
597   test::MockMediaSession media_session_1;
598   test::MockMediaSession media_session_2;
599
600   RequestAudioFocus(&media_session_2,
601                     mojom::AudioFocusType::kGainTransientMayDuck);
602
603   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
604   EXPECT_EQ(
605       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
606       GetState(&media_session_2));
607 }
608
609 TEST_P(AudioFocusManagerTest, DuckWithMultipleTransientMayDucks) {
610   test::MockMediaSession media_session_1;
611   test::MockMediaSession media_session_2;
612   test::MockMediaSession media_session_3;
613   test::MockMediaSession media_session_4;
614
615   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
616   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
617             GetState(&media_session_1));
618
619   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
620   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
621             GetState(&media_session_2));
622
623   RequestAudioFocus(&media_session_3,
624                     mojom::AudioFocusType::kGainTransientMayDuck);
625   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
626             GetState(&media_session_1));
627   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
628             GetState(&media_session_2));
629
630   RequestAudioFocus(&media_session_4,
631                     mojom::AudioFocusType::kGainTransientMayDuck);
632   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
633             GetState(&media_session_1));
634   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
635             GetState(&media_session_2));
636
637   media_session_3.AbandonAudioFocusFromClient();
638   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
639             GetState(&media_session_1));
640   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
641             GetState(&media_session_2));
642
643   media_session_4.AbandonAudioFocusFromClient();
644   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
645             GetState(&media_session_1));
646   EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking,
647             GetState(&media_session_2));
648 }
649
650 TEST_P(AudioFocusManagerTest, MediaSessionDestroyed_ReleasesFocus) {
651   {
652     test::MockMediaSession media_session;
653
654     AudioFocusManager::RequestId request_id =
655         RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
656     EXPECT_EQ(request_id, GetAudioFocusedSession());
657   }
658
659   // If the media session is destroyed without abandoning audio focus we do not
660   // know until we next interact with the manager.
661   test::MockMediaSession media_session;
662   RequestAudioFocus(&media_session,
663                     mojom::AudioFocusType::kGainTransientMayDuck);
664   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
665 }
666
667 TEST_P(AudioFocusManagerTest, MediaSessionDestroyed_ReleasesTransient) {
668   {
669     test::MockMediaSession media_session;
670     RequestAudioFocus(&media_session, mojom::AudioFocusType::kGainTransient);
671     EXPECT_EQ(1, GetTransientCount());
672   }
673
674   // If the media session is destroyed without abandoning audio focus we do not
675   // know until we next interact with the manager.
676   test::MockMediaSession media_session;
677   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
678   EXPECT_EQ(0, GetTransientCount());
679 }
680
681 TEST_P(AudioFocusManagerTest, MediaSessionDestroyed_ReleasesTransientMayDucks) {
682   {
683     test::MockMediaSession media_session;
684     RequestAudioFocus(&media_session,
685                       mojom::AudioFocusType::kGainTransientMayDuck);
686     EXPECT_EQ(1, GetTransientMaybeDuckCount());
687   }
688
689   // If the media session is destroyed without abandoning audio focus we do not
690   // know until we next interact with the manager.
691   test::MockMediaSession media_session;
692   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
693   EXPECT_EQ(0, GetTransientMaybeDuckCount());
694 }
695
696 TEST_P(AudioFocusManagerTest, GainDucksForceDuck) {
697   test::MockMediaSession media_session_1(true /* force_duck */);
698   test::MockMediaSession media_session_2;
699
700   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
701
702   AudioFocusManager::RequestId request_id_2 =
703       RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
704
705   EXPECT_EQ(request_id_2, GetAudioFocusedSession());
706   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
707             GetState(&media_session_1));
708 }
709
710 TEST_P(AudioFocusManagerTest, ForceDuckSessionShouldAlwaysBeDuckedFromGain) {
711   test::MockMediaSession media_session_1(true /* force_duck */);
712   test::MockMediaSession media_session_2;
713   test::MockMediaSession media_session_3;
714
715   AudioFocusManager::RequestId request_id_1 =
716       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
717   AudioFocusManager::RequestId request_id_2 =
718       RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
719
720   AudioFocusManager::RequestId request_id_3 =
721       RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
722   EXPECT_EQ(request_id_3, GetAudioFocusedSession());
723
724   EXPECT_EQ(
725       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
726       GetState(&media_session_2));
727   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
728             GetState(&media_session_1));
729
730   media_session_3.AbandonAudioFocusFromClient();
731   EXPECT_EQ(request_id_2, GetAudioFocusedSession());
732   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
733             GetState(&media_session_1));
734
735   media_session_2.AbandonAudioFocusFromClient();
736   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
737   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
738             GetState(&media_session_1));
739 }
740
741 TEST_P(AudioFocusManagerTest,
742        ForceDuckSessionShouldAlwaysBeDuckedFromTransient) {
743   test::MockMediaSession media_session_1(true /* force_duck */);
744   test::MockMediaSession media_session_2;
745
746   AudioFocusManager::RequestId request_id_1 =
747       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
748   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
749
750   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
751             GetState(&media_session_2));
752   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
753             GetState(&media_session_1));
754
755   media_session_2.AbandonAudioFocusFromClient();
756   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
757   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
758             GetState(&media_session_1));
759 }
760
761 TEST_P(AudioFocusManagerTest, AudioFocusObserver_RequestNoop) {
762   test::MockMediaSession media_session;
763   AudioFocusManager::RequestId request_id;
764
765   {
766     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
767     request_id =
768         RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
769
770     EXPECT_EQ(request_id, GetAudioFocusedSession());
771     EXPECT_EQ(mojom::AudioFocusType::kGain,
772               observer->focus_gained_session()->audio_focus_type);
773   }
774
775   {
776     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
777     RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
778
779     EXPECT_EQ(request_id, GetAudioFocusedSession());
780     EXPECT_TRUE(observer->focus_gained_session().is_null());
781   }
782 }
783
784 TEST_P(AudioFocusManagerTest, AudioFocusObserver_TransientMayDuck) {
785   test::MockMediaSession media_session;
786
787   {
788     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
789     RequestAudioFocus(&media_session,
790                       mojom::AudioFocusType::kGainTransientMayDuck);
791
792     EXPECT_EQ(1, GetTransientMaybeDuckCount());
793     EXPECT_EQ(mojom::AudioFocusType::kGainTransientMayDuck,
794               observer->focus_gained_session()->audio_focus_type);
795   }
796
797   {
798     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
799     media_session.AbandonAudioFocusFromClient();
800
801     EXPECT_EQ(0, GetTransientMaybeDuckCount());
802     EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
803         test::GetMediaSessionInfoSync(&media_session)));
804   }
805 }
806
807 TEST_P(AudioFocusManagerTest, GetDebugInfo) {
808   test::MockMediaSession media_session;
809   AudioFocusManager::RequestId request_id =
810       RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
811
812   mojom::MediaSessionDebugInfoPtr debug_info = GetDebugInfo(request_id);
813   EXPECT_FALSE(debug_info->name.empty());
814   EXPECT_FALSE(debug_info->owner.empty());
815   EXPECT_FALSE(debug_info->state.empty());
816 }
817
818 TEST_P(AudioFocusManagerTest, GetDebugInfo_BadRequestId) {
819   mojom::MediaSessionDebugInfoPtr debug_info =
820       GetDebugInfo(base::UnguessableToken::Create());
821   EXPECT_TRUE(debug_info->name.empty());
822 }
823
824 TEST_P(AudioFocusManagerTest,
825        RequestAudioFocusTransient_FromGainWhileSuspended) {
826   test::MockMediaSession media_session_1;
827   test::MockMediaSession media_session_2;
828
829   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
830   EXPECT_EQ(0, GetTransientCount());
831   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
832             GetState(&media_session_1));
833
834   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
835   EXPECT_EQ(1, GetTransientCount());
836   EXPECT_EQ(
837       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
838       GetState(&media_session_1));
839
840   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGainTransient);
841   EXPECT_EQ(2, GetTransientCount());
842   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
843             GetState(&media_session_1));
844 }
845
846 TEST_P(AudioFocusManagerTest,
847        RequestAudioFocusTransientMayDuck_FromGainWhileSuspended) {
848   test::MockMediaSession media_session_1;
849   test::MockMediaSession media_session_2;
850
851   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
852   EXPECT_EQ(0, GetTransientCount());
853   EXPECT_EQ(0, GetTransientMaybeDuckCount());
854   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
855             GetState(&media_session_1));
856
857   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
858   EXPECT_EQ(1, GetTransientCount());
859   EXPECT_EQ(0, GetTransientMaybeDuckCount());
860   EXPECT_EQ(
861       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
862       GetState(&media_session_1));
863
864   RequestAudioFocus(&media_session_1,
865                     mojom::AudioFocusType::kGainTransientMayDuck);
866   EXPECT_EQ(1, GetTransientCount());
867   EXPECT_EQ(1, GetTransientMaybeDuckCount());
868   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
869             GetState(&media_session_1));
870 }
871
872 TEST_P(AudioFocusManagerTest, Source_AssociatedWithBinding) {
873   base::UnguessableToken identity = base::UnguessableToken::Create();
874   SetSource(identity, kExampleSourceName);
875
876   base::UnguessableToken new_identity = base::UnguessableToken::Create();
877   mojo::Remote<mojom::AudioFocusManager> new_ptr =
878       CreateAudioFocusManagerRemote();
879   new_ptr->SetSource(new_identity, kExampleSourceName2);
880   new_ptr.FlushForTesting();
881
882   test::MockMediaSession media_session_1;
883   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
884   EXPECT_EQ(kExampleSourceName, GetSourceNameForLastRequest());
885   EXPECT_EQ(identity, GetIdentityForLastRequest());
886
887   test::MockMediaSession media_session_2;
888   media_session_2.RequestAudioFocusFromService(new_ptr,
889                                                mojom::AudioFocusType::kGain);
890   EXPECT_EQ(kExampleSourceName2, GetSourceNameForLastRequest());
891   EXPECT_EQ(new_identity, GetIdentityForLastRequest());
892 }
893
894 TEST_P(AudioFocusManagerTest, Source_Empty) {
895   test::MockMediaSession media_session;
896   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
897   EXPECT_TRUE(GetSourceNameForLastRequest().empty());
898   EXPECT_EQ(base::UnguessableToken::Null(), GetIdentityForLastRequest());
899 }
900
901 TEST_P(AudioFocusManagerTest, Source_Updated) {
902   base::UnguessableToken identity = base::UnguessableToken::Create();
903   SetSource(identity, kExampleSourceName);
904
905   test::MockMediaSession media_session;
906   RequestAudioFocus(&media_session, mojom::AudioFocusType::kGain);
907   EXPECT_EQ(kExampleSourceName, GetSourceNameForLastRequest());
908   EXPECT_EQ(identity, GetIdentityForLastRequest());
909
910   base::UnguessableToken new_identity = base::UnguessableToken::Create();
911   SetSource(new_identity, kExampleSourceName2);
912   EXPECT_EQ(kExampleSourceName, GetSourceNameForLastRequest());
913   EXPECT_EQ(identity, GetIdentityForLastRequest());
914 }
915
916 TEST_P(AudioFocusManagerTest,
917        AbandonAudioFocus_ObserverFocusGain_NoTopSession) {
918   test::MockMediaSession media_session;
919
920   RequestAudioFocus(&media_session,
921                     mojom::AudioFocusType::kGainTransientMayDuck);
922   EXPECT_EQ(1, GetTransientMaybeDuckCount());
923   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
924             GetState(&media_session));
925
926   {
927     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
928     media_session.AbandonAudioFocusFromClient();
929
930     EXPECT_EQ(0, GetTransientMaybeDuckCount());
931     EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
932         test::GetMediaSessionInfoSync(&media_session)));
933     EXPECT_TRUE(observer->focus_gained_session().is_null());
934
935     auto notifications = observer->notifications();
936     EXPECT_EQ(1u, notifications.size());
937     EXPECT_EQ(test::TestAudioFocusObserver::NotificationType::kFocusLost,
938               notifications[0]);
939   }
940 }
941
942 TEST_P(AudioFocusManagerTest,
943        AbandonAudioFocus_ObserverFocusGain_NewTopSession) {
944   test::MockMediaSession media_session_1;
945   test::MockMediaSession media_session_2;
946
947   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
948   EXPECT_EQ(0, GetTransientMaybeDuckCount());
949   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
950             GetState(&media_session_1));
951
952   RequestAudioFocus(&media_session_2,
953                     mojom::AudioFocusType::kGainTransientMayDuck);
954   EXPECT_EQ(1, GetTransientMaybeDuckCount());
955   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
956             GetState(&media_session_1));
957
958   mojom::MediaSessionInfoPtr media_session_1_info =
959       test::GetMediaSessionInfoSync(&media_session_1);
960
961   {
962     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
963     media_session_2.AbandonAudioFocusFromClient();
964
965     EXPECT_EQ(0, GetTransientMaybeDuckCount());
966     EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
967         test::GetMediaSessionInfoSync(&media_session_2)));
968     EXPECT_TRUE(observer->focus_gained_session()->session_info.Equals(
969         media_session_1_info));
970
971     // FocusLost should always come before FocusGained so observers always know
972     // the current session that has focus.
973     auto notifications = observer->notifications();
974     EXPECT_EQ(2u, notifications.size());
975     EXPECT_EQ(test::TestAudioFocusObserver::NotificationType::kFocusLost,
976               notifications[0]);
977     EXPECT_EQ(test::TestAudioFocusObserver::NotificationType::kFocusGained,
978               notifications[1]);
979   }
980 }
981
982 TEST_P(AudioFocusManagerTest, AudioFocusGrouping_LayeredFocus) {
983   test::MockMediaSession media_session_1;
984   test::MockMediaSession media_session_2;
985   test::MockMediaSession media_session_3;
986
987   base::UnguessableToken group_id = base::UnguessableToken::Create();
988
989   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
990                                        &media_session_1,
991                                        mojom::AudioFocusType::kGain, group_id));
992   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
993             GetState(&media_session_1));
994
995   RequestAudioFocus(&media_session_2,
996                     mojom::AudioFocusType::kGainTransientMayDuck);
997   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
998             GetState(&media_session_1));
999
1000   // When we request audio focus for media_session_3 the group will take audio
1001   // focus and we suspend the ducking session.
1002   ASSERT_TRUE(RequestGroupedAudioFocus(
1003       base::UnguessableToken::Create(), &media_session_3,
1004       mojom::AudioFocusType::kGainTransient, group_id));
1005   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1006             GetState(&media_session_3));
1007
1008   EXPECT_EQ(
1009       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1010       GetState(&media_session_2));
1011   EXPECT_EQ(GetStateFromParam(
1012                 IsGroupingEnabled()
1013                     ? mojom::MediaSessionInfo::SessionState::kActive
1014                     : mojom::MediaSessionInfo::SessionState::kSuspended),
1015             GetState(&media_session_1));
1016 }
1017
1018 TEST_P(AudioFocusManagerTest, AudioFocusGrouping_TransientResume) {
1019   test::MockMediaSession media_session_1;
1020   test::MockMediaSession media_session_2;
1021   test::MockMediaSession media_session_3;
1022   test::MockMediaSession media_session_4;
1023
1024   base::UnguessableToken group_id = base::UnguessableToken::Create();
1025
1026   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
1027                                        &media_session_1,
1028                                        mojom::AudioFocusType::kGain, group_id));
1029   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1030             GetState(&media_session_1));
1031
1032   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1033   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1034             GetState(&media_session_2));
1035
1036   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
1037                                        &media_session_3,
1038                                        mojom::AudioFocusType::kGain, group_id));
1039   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1040             GetState(&media_session_3));
1041
1042   RequestAudioFocus(&media_session_4, mojom::AudioFocusType::kGainTransient);
1043   EXPECT_EQ(
1044       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1045       GetState(&media_session_1));
1046   EXPECT_EQ(
1047       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1048       GetState(&media_session_2));
1049   EXPECT_EQ(
1050       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1051       GetState(&media_session_3));
1052
1053   media_session_4.AbandonAudioFocusFromClient();
1054
1055   // TODO(https://crbug.com/916177): This should wait on a more precise
1056   // condition than RunLoop idling, but it's not clear exactly what that
1057   // should be.
1058   base::RunLoop().RunUntilIdle();
1059
1060   EXPECT_EQ(IsGroupingEnabled()
1061                 ? mojom::MediaSessionInfo::SessionState::kActive
1062                 : mojom::MediaSessionInfo::SessionState::kSuspended,
1063             GetState(&media_session_1));
1064   EXPECT_EQ(
1065       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1066       GetState(&media_session_2));
1067   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1068             GetState(&media_session_3));
1069 }
1070
1071 TEST_P(AudioFocusManagerTest, AudioFocusGrouping_DoNotSuspendSameGroup) {
1072   test::MockMediaSession media_session_1;
1073   test::MockMediaSession media_session_2;
1074
1075   base::UnguessableToken group_id = base::UnguessableToken::Create();
1076
1077   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
1078                                        &media_session_1,
1079                                        mojom::AudioFocusType::kGain, group_id));
1080   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1081             GetState(&media_session_1));
1082
1083   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
1084                                        &media_session_2,
1085                                        mojom::AudioFocusType::kGain, group_id));
1086   EXPECT_EQ(IsGroupingEnabled()
1087                 ? mojom::MediaSessionInfo::SessionState::kActive
1088                 : mojom::MediaSessionInfo::SessionState::kSuspended,
1089             GetState(&media_session_1));
1090   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1091             GetState(&media_session_2));
1092 }
1093
1094 TEST_P(AudioFocusManagerTest, AudioFocusGrouping_DuckSameGroup) {
1095   test::MockMediaSession media_session_1;
1096   test::MockMediaSession media_session_2;
1097
1098   base::UnguessableToken group_id = base::UnguessableToken::Create();
1099
1100   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
1101                                        &media_session_1,
1102                                        mojom::AudioFocusType::kGain, group_id));
1103   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1104             GetState(&media_session_1));
1105
1106   ASSERT_TRUE(RequestGroupedAudioFocus(
1107       base::UnguessableToken::Create(), &media_session_2,
1108       mojom::AudioFocusType::kGainTransientMayDuck, group_id));
1109   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
1110             GetState(&media_session_1));
1111 }
1112
1113 TEST_P(AudioFocusManagerTest, AudioFocusGrouping_TransientSameGroup) {
1114   test::MockMediaSession media_session_1;
1115   test::MockMediaSession media_session_2;
1116
1117   base::UnguessableToken group_id = base::UnguessableToken::Create();
1118
1119   ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(),
1120                                        &media_session_1,
1121                                        mojom::AudioFocusType::kGain, group_id));
1122   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1123             GetState(&media_session_1));
1124
1125   ASSERT_TRUE(RequestGroupedAudioFocus(
1126       base::UnguessableToken::Create(), &media_session_2,
1127       mojom::AudioFocusType::kGainTransient, group_id));
1128   EXPECT_EQ(IsGroupingEnabled()
1129                 ? mojom::MediaSessionInfo::SessionState::kActive
1130                 : mojom::MediaSessionInfo::SessionState::kSuspended,
1131             GetState(&media_session_1));
1132   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1133             GetState(&media_session_2));
1134 }
1135
1136 TEST_P(AudioFocusManagerTest, RequestAudioFocus_PreferStop_LossToGain) {
1137   test::MockMediaSession media_session_1;
1138   test::MockMediaSession media_session_2;
1139
1140   media_session_1.SetPreferStop(true);
1141
1142   AudioFocusManager::RequestId request_id_1 =
1143       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1144   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1145   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1146             GetState(&media_session_1));
1147
1148   AudioFocusManager::RequestId request_id_2 =
1149       RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1150   EXPECT_EQ(request_id_2, GetAudioFocusedSession());
1151   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kInactive),
1152             GetState(&media_session_1));
1153 }
1154
1155 TEST_P(AudioFocusManagerTest,
1156        RequestAudioFocus_PreferStop_LossToGainTransient) {
1157   test::MockMediaSession media_session_1;
1158   test::MockMediaSession media_session_2;
1159
1160   media_session_1.SetPreferStop(true);
1161
1162   AudioFocusManager::RequestId request_id_1 =
1163       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1164   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1165   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1166             GetState(&media_session_1));
1167
1168   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1169   EXPECT_EQ(
1170       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1171       GetState(&media_session_1));
1172 }
1173
1174 TEST_P(AudioFocusManagerTest, GainFocusTypeHasEffectEvenIfSuspended) {
1175   test::MockMediaSession media_session_1;
1176   test::MockMediaSession media_session_2;
1177   test::MockMediaSession media_session_3;
1178
1179   AudioFocusManager::RequestId request_id_1 =
1180       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1181   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1182
1183   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1184   EXPECT_EQ(
1185       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1186       GetState(&media_session_1));
1187
1188   // When the second session becomes suspended and that event originated from
1189   // the session itself then we should keep the other session suspended.
1190   media_session_2.Suspend(mojom::MediaSession::SuspendType::kUI);
1191   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1192             GetState(&media_session_2));
1193
1194   {
1195     test::MockMediaSessionMojoObserver observer(media_session_1);
1196     observer.WaitForState(
1197         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1198   }
1199
1200   // When the second session is resumed then we should still keep the other
1201   // session suspended.
1202   media_session_2.Resume(mojom::MediaSession::SuspendType::kUI);
1203   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1204             GetState(&media_session_2));
1205
1206   {
1207     test::MockMediaSessionMojoObserver observer(media_session_1);
1208     observer.WaitForState(
1209         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1210   }
1211
1212   // If a new session takes focus then this should suspend all sessions.
1213   RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGainTransient);
1214
1215   {
1216     test::MockMediaSessionMojoObserver observer(media_session_2);
1217     observer.WaitForState(
1218         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1219   }
1220
1221   {
1222     test::MockMediaSessionMojoObserver observer(media_session_1);
1223     observer.WaitForState(
1224         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1225   }
1226
1227   // If the second session regains focus then it should suspend all sessions.
1228   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1229   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1230             GetState(&media_session_2));
1231
1232   {
1233     test::MockMediaSessionMojoObserver observer(media_session_1);
1234     observer.WaitForState(
1235         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1236   }
1237
1238   {
1239     test::MockMediaSessionMojoObserver observer(media_session_3);
1240     observer.WaitForState(
1241         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1242   }
1243 }
1244
1245 TEST_P(AudioFocusManagerTest, TransientFocusTypeHasNoEffectIfSuspended) {
1246   test::MockMediaSession media_session_1;
1247   test::MockMediaSession media_session_2;
1248   test::MockMediaSession media_session_3;
1249
1250   AudioFocusManager::RequestId request_id_1 =
1251       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1252   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1253
1254   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1255   EXPECT_EQ(
1256       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1257       GetState(&media_session_1));
1258
1259   // When the transient session becomes suspended and that event originates from
1260   // the session itself then we should stop pausing the other session.
1261   media_session_2.Suspend(mojom::MediaSession::SuspendType::kUI);
1262   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1263             GetState(&media_session_2));
1264
1265   {
1266     test::MockMediaSessionMojoObserver observer(media_session_1);
1267     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1268   }
1269
1270   // When the transient session is resumed then we should pause the other
1271   // session again.
1272   media_session_2.Resume(mojom::MediaSession::SuspendType::kUI);
1273   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1274             GetState(&media_session_2));
1275
1276   {
1277     test::MockMediaSessionMojoObserver observer(media_session_1);
1278     observer.WaitForState(
1279         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1280   }
1281
1282   // If we have a new session take focus then this should suspend all the other
1283   // sessions and the transient session should have no effect.
1284   RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGainTransient);
1285
1286   {
1287     test::MockMediaSessionMojoObserver observer(media_session_2);
1288     observer.WaitForState(
1289         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1290   }
1291
1292   {
1293     test::MockMediaSessionMojoObserver observer(media_session_1);
1294     observer.WaitForState(
1295         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1296   }
1297
1298   // If the second session regains focus then it should start pausing again.
1299   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1300   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1301             GetState(&media_session_2));
1302
1303   {
1304     test::MockMediaSessionMojoObserver observer(media_session_1);
1305     observer.WaitForState(
1306         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1307   }
1308
1309   {
1310     test::MockMediaSessionMojoObserver observer(media_session_3);
1311     observer.WaitForState(
1312         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1313   }
1314 }
1315
1316 TEST_P(AudioFocusManagerTest, TransientDuckFocusTypeHasNoEffectIfSuspended) {
1317   test::MockMediaSession media_session_1;
1318   test::MockMediaSession media_session_2;
1319   test::MockMediaSession media_session_3;
1320
1321   AudioFocusManager::RequestId request_id_1 =
1322       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1323   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1324
1325   RequestAudioFocus(&media_session_2,
1326                     mojom::AudioFocusType::kGainTransientMayDuck);
1327   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
1328             GetState(&media_session_1));
1329
1330   // When the ducking session becomes suspended and that event originates from
1331   // the session itself then we should stop ducking.
1332   media_session_2.Suspend(mojom::MediaSession::SuspendType::kUI);
1333   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1334             GetState(&media_session_2));
1335
1336   {
1337     test::MockMediaSessionMojoObserver observer(media_session_1);
1338     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1339   }
1340
1341   // When the ducking session is resumed then we should resume ducking.
1342   media_session_2.Resume(mojom::MediaSession::SuspendType::kUI);
1343   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1344             GetState(&media_session_2));
1345
1346   {
1347     test::MockMediaSessionMojoObserver observer(media_session_1);
1348     observer.WaitForState(
1349         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking));
1350   }
1351
1352   // If we have a new session take focus then this should suspend all the other
1353   // sessions and we should not have any ducking from the ducking session (since
1354   // it is suspended).
1355   RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGainTransient);
1356
1357   {
1358     test::MockMediaSessionMojoObserver observer(media_session_2);
1359     observer.WaitForState(
1360         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1361   }
1362
1363   {
1364     test::MockMediaSessionMojoObserver observer(media_session_1);
1365     observer.WaitForState(
1366         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended));
1367   }
1368
1369   // If the ducking session regains focus then it should start ducking again.
1370   RequestAudioFocus(&media_session_2,
1371                     mojom::AudioFocusType::kGainTransientMayDuck);
1372   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1373             GetState(&media_session_2));
1374
1375   {
1376     test::MockMediaSessionMojoObserver observer(media_session_1);
1377     observer.WaitForState(
1378         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking));
1379   }
1380
1381   {
1382     test::MockMediaSessionMojoObserver observer(media_session_3);
1383     observer.WaitForState(
1384         GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking));
1385   }
1386 }
1387
1388 TEST_P(AudioFocusManagerTest, AmbientFocusHasNoEffect) {
1389   test::MockMediaSession media_session_1;
1390   test::MockMediaSession media_session_2;
1391
1392   AudioFocusManager::RequestId request_id_1 =
1393       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1394   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1395   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1396             GetState(&media_session_1));
1397
1398   EXPECT_EQ(0, GetAmbientCount());
1399   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kAmbient);
1400
1401   EXPECT_EQ(1, GetAmbientCount());
1402   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1403             GetState(&media_session_1));
1404   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1405             GetState(&media_session_2));
1406
1407   media_session_2.AbandonAudioFocusFromClient();
1408
1409   EXPECT_EQ(0, GetAmbientCount());
1410   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1411             GetState(&media_session_1));
1412 }
1413
1414 TEST_P(AudioFocusManagerTest, AudioFocusObserver_NotTopMost) {
1415   test::MockMediaSession media_session_1;
1416   test::MockMediaSession media_session_2;
1417
1418   AudioFocusManager::RequestId request_id_1 =
1419       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1420   EXPECT_EQ(request_id_1, GetAudioFocusedSession());
1421   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1422             GetState(&media_session_1));
1423
1424   RequestAudioFocus(&media_session_2,
1425                     mojom::AudioFocusType::kGainTransientMayDuck);
1426   EXPECT_EQ(GetStateFromParam(mojom::MediaSessionInfo::SessionState::kDucking),
1427             GetState(&media_session_1));
1428   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1429             GetState(&media_session_2));
1430
1431   {
1432     std::unique_ptr<test::TestAudioFocusObserver> observer = CreateObserver();
1433     media_session_1.AbandonAudioFocusFromClient();
1434
1435     EXPECT_TRUE(observer->focus_lost_session()->session_info.Equals(
1436         test::GetMediaSessionInfoSync(&media_session_1)));
1437   }
1438 }
1439
1440 TEST_P(AudioFocusManagerTest, SuspendAllSessionOnPowerSuspend) {
1441   test::MockMediaSession media_session_1;
1442   test::MockMediaSession media_session_2;
1443
1444   {
1445     test::MockMediaSessionMojoObserver observer(media_session_1);
1446     RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1447     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1448   }
1449
1450   {
1451     test::MockMediaSessionMojoObserver observer(media_session_2);
1452     RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1453     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1454   }
1455
1456   test::MockMediaSessionMojoObserver observer_1(media_session_1);
1457   test::MockMediaSessionMojoObserver observer_2(media_session_2);
1458
1459   GenerateSuspendEvent();
1460
1461   observer_1.WaitForState(mojom::MediaSessionInfo::SessionState::kSuspended);
1462   observer_2.WaitForState(mojom::MediaSessionInfo::SessionState::kSuspended);
1463 }
1464
1465 TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayControllerPause) {
1466   test::MockMediaSession media_session_1;
1467   test::MockMediaSession media_session_2;
1468
1469   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1470   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1471             GetState(&media_session_1));
1472
1473   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1474   EXPECT_EQ(
1475       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1476       GetState(&media_session_1));
1477
1478   mojo::Remote<mojom::MediaController> controller;
1479   controller_manager()->CreateMediaControllerForSession(
1480       controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
1481   controller_manager().FlushForTesting();
1482
1483   controller->Suspend();
1484   controller.FlushForTesting();
1485   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1486             GetState(&media_session_1));
1487
1488   // When we abandon the transient session then we will apply the last
1489   // controller action.
1490   media_session_2.AbandonAudioFocusFromClient();
1491   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1492             GetState(&media_session_1));
1493 }
1494
1495 TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayControllerStop) {
1496   test::MockMediaSession media_session_1;
1497   test::MockMediaSession media_session_2;
1498
1499   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1500   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1501             GetState(&media_session_1));
1502
1503   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1504   EXPECT_EQ(
1505       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1506       GetState(&media_session_1));
1507
1508   mojo::Remote<mojom::MediaController> controller;
1509   controller_manager()->CreateMediaControllerForSession(
1510       controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
1511   controller_manager().FlushForTesting();
1512
1513   controller->Stop();
1514   controller.FlushForTesting();
1515
1516   // If enforcement is enabled then the session was previously suspended by the
1517   // transient session and therefore we should be suspended. Otherwise, we
1518   // should be inactive because the stop command would not have been delayed.
1519   EXPECT_EQ(IsEnforcementEnabled()
1520                 ? mojom::MediaSessionInfo::SessionState::kSuspended
1521                 : mojom::MediaSessionInfo::SessionState::kInactive,
1522             GetState(&media_session_1));
1523
1524   {
1525     // When we abandon the transient session then we will apply the last
1526     // controller action.
1527     test::MockMediaSessionMojoObserver observer(media_session_1);
1528     media_session_2.AbandonAudioFocusFromClient();
1529     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kInactive);
1530   }
1531 }
1532
1533 TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayControllerResume) {
1534   test::MockMediaSession media_session_1;
1535   test::MockMediaSession media_session_2;
1536
1537   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1538   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1539             GetState(&media_session_1));
1540
1541   mojo::Remote<mojom::MediaController> controller;
1542   controller_manager()->CreateMediaControllerForSession(
1543       controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
1544   controller_manager().FlushForTesting();
1545
1546   controller->Suspend();
1547   controller.FlushForTesting();
1548   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1549             GetState(&media_session_1));
1550
1551   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1552   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1553             GetState(&media_session_1));
1554
1555   controller->Resume();
1556   controller.FlushForTesting();
1557
1558   // If enforcement is enabled then the session was previously suspended by the
1559   // transient session and therefore we should be suspended. Otherwise, we
1560   // should be active because the resume command would not have been delayed.
1561   EXPECT_EQ(
1562       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1563       GetState(&media_session_1));
1564
1565   {
1566     // When we abandon the transient session then we will apply the last
1567     // controller action.
1568     test::MockMediaSessionMojoObserver observer(media_session_1);
1569     media_session_2.AbandonAudioFocusFromClient();
1570     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1571   }
1572 }
1573
1574 TEST_P(AudioFocusManagerTest, TransientPauseShouldDelayLastActionOnly) {
1575   test::MockMediaSession media_session_1;
1576   test::MockMediaSession media_session_2;
1577
1578   RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1579   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
1580             GetState(&media_session_1));
1581
1582   RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGainTransient);
1583   EXPECT_EQ(
1584       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1585       GetState(&media_session_1));
1586
1587   mojo::Remote<mojom::MediaController> controller;
1588   controller_manager()->CreateMediaControllerForSession(
1589       controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
1590   controller_manager().FlushForTesting();
1591
1592   controller->Resume();
1593   controller.FlushForTesting();
1594
1595   // The resume action should be delayed because we were suspended by the
1596   // transient session.
1597   EXPECT_EQ(
1598       GetStateFromParam(mojom::MediaSessionInfo::SessionState::kSuspended),
1599       GetState(&media_session_1));
1600
1601   // Calling suspend while we are still suspended should cancel the delayed
1602   // resume action so we will never resume.
1603   controller->Suspend();
1604   controller.FlushForTesting();
1605   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1606             GetState(&media_session_1));
1607
1608   // When we abandon the transient session then we will apply the last
1609   // controller action.
1610   media_session_2.AbandonAudioFocusFromClient();
1611   EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kSuspended,
1612             GetState(&media_session_1));
1613 }
1614
1615 TEST_P(AudioFocusManagerTest, RequestIdValidation) {
1616   test::MockMediaSession media_session_1;
1617   test::MockMediaSession media_session_2;
1618
1619   base::UnguessableToken request_id = base::UnguessableToken::Create();
1620
1621   EXPECT_TRUE(RequestGroupedAudioFocus(request_id, &media_session_1,
1622                                        mojom::AudioFocusType::kGain,
1623                                        base::UnguessableToken::Create()));
1624   EXPECT_EQ(request_id, GetAudioFocusedSession());
1625
1626   // The audio focus request should fail since we have already used that id.
1627   EXPECT_FALSE(RequestGroupedAudioFocus(request_id, &media_session_2,
1628                                         mojom::AudioFocusType::kGain,
1629                                         base::UnguessableToken::Create()));
1630
1631   media_session_1.AbandonAudioFocusFromClient();
1632   EXPECT_EQ(base::UnguessableToken::Null(), GetAudioFocusedSession());
1633
1634   // If we abandon focus then we should be able to use the id now.
1635   EXPECT_TRUE(RequestGroupedAudioFocus(request_id, &media_session_2,
1636                                        mojom::AudioFocusType::kGain,
1637                                        base::UnguessableToken::Create()));
1638   EXPECT_EQ(request_id, GetAudioFocusedSession());
1639 }
1640
1641 TEST_P(AudioFocusManagerTest, SourceObservers) {
1642   // Create two identity observers for two different identities.
1643   base::UnguessableToken identity_1 = base::UnguessableToken::Create();
1644   base::UnguessableToken identity_2 = base::UnguessableToken::Create();
1645   std::unique_ptr<test::TestAudioFocusObserver> observer_1 =
1646       CreateSourceObserver(identity_1);
1647   std::unique_ptr<test::TestAudioFocusObserver> observer_2 =
1648       CreateSourceObserver(identity_2);
1649
1650   // Request audio focus for the first identity.
1651   SetSource(identity_1, kExampleSourceName);
1652   test::MockMediaSession media_session_1;
1653   base::UnguessableToken request_id_1 =
1654       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1655
1656   // The observer for the first identity should see the gained focus, while the
1657   // observer for the second identity should see nothing.
1658   EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
1659   EXPECT_TRUE(observer_2->focus_gained_session().is_null());
1660
1661   // Request audio focus for the second identity.
1662   SetSource(identity_2, kExampleSourceName);
1663   test::MockMediaSession media_session_2;
1664   base::UnguessableToken request_id_2 =
1665       RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1666
1667   // The observer for the first identity should still show the first request,
1668   // while the observer for the second identity should see the new session.
1669   EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
1670   EXPECT_EQ(request_id_2, observer_2->focus_gained_session()->request_id);
1671
1672   // Make another request in the second identity.
1673   test::MockMediaSession media_session_3;
1674   base::UnguessableToken request_id_3 =
1675       RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
1676
1677   // The observer for the first identity should still show the first request,
1678   // while the observer for the second identity should see the new session.
1679   EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
1680   EXPECT_EQ(request_id_3, observer_2->focus_gained_session()->request_id);
1681
1682   // Abandon the topmost session.
1683   media_session_3.AbandonAudioFocusFromClient();
1684   FlushForTesting();
1685
1686   // The observer for the second identity should get the new lost and gained
1687   // sessions, with no updates to the first observer.
1688   EXPECT_EQ(request_id_3, observer_2->focus_lost_session()->request_id);
1689   EXPECT_EQ(request_id_2, observer_2->focus_gained_session()->request_id);
1690   EXPECT_EQ(request_id_1, observer_1->focus_gained_session()->request_id);
1691   EXPECT_TRUE(observer_1->focus_lost_session().is_null());
1692 }
1693
1694 TEST_P(AudioFocusManagerTest, GetSourceFocusRequests) {
1695   // Establish identities.
1696   base::UnguessableToken identity_1 = base::UnguessableToken::Create();
1697   base::UnguessableToken identity_2 = base::UnguessableToken::Create();
1698   base::UnguessableToken identity_3 = base::UnguessableToken::Create();
1699
1700   // Create a focus request for the first identity.
1701   SetSource(identity_1, kExampleSourceName);
1702   test::MockMediaSession media_session_1;
1703   base::UnguessableToken request_id_1 =
1704       RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
1705
1706   // Create a focus request for the second identity.
1707   SetSource(identity_2, kExampleSourceName);
1708   test::MockMediaSession media_session_2;
1709   base::UnguessableToken request_id_2 =
1710       RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kGain);
1711
1712   // Create another focus request for the first identity.
1713   SetSource(identity_1, kExampleSourceName);
1714   test::MockMediaSession media_session_3;
1715   base::UnguessableToken request_id_3 =
1716       RequestAudioFocus(&media_session_3, mojom::AudioFocusType::kGain);
1717
1718   // Use the GetSourceFocusRequests API to get requests for each identity.
1719   std::vector<mojom::AudioFocusRequestStatePtr> identity_1_requests =
1720       GetSourceFocusRequests(identity_1);
1721   std::vector<mojom::AudioFocusRequestStatePtr> identity_2_requests =
1722       GetSourceFocusRequests(identity_2);
1723   std::vector<mojom::AudioFocusRequestStatePtr> identity_3_requests =
1724       GetSourceFocusRequests(identity_3);
1725
1726   // Ensure that the API returned the right requests for the first identity.
1727   EXPECT_EQ(2u, identity_1_requests.size());
1728   EXPECT_EQ(request_id_1, identity_1_requests[0]->request_id);
1729   EXPECT_EQ(request_id_3, identity_1_requests[1]->request_id);
1730
1731   // Ensure that the API returned the right requests for the second identity.
1732   EXPECT_EQ(1u, identity_2_requests.size());
1733   EXPECT_EQ(request_id_2, identity_2_requests[0]->request_id);
1734
1735   // Ensure that the API returned nothing for the unused identity.
1736   EXPECT_TRUE(identity_3_requests.empty());
1737 }
1738
1739 }  // namespace media_session