1 // Copyright 2018 The Chromium Authors. All rights reserved.
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/media_controller.h"
6 
7 #include <memory>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/run_loop.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/task_environment.h"
14 #include "base/time/time.h"
15 #include "base/unguessable_token.h"
16 #include "mojo/public/cpp/bindings/remote.h"
17 #include "services/media_session/media_session_service.h"
18 #include "services/media_session/public/cpp/media_metadata.h"
19 #include "services/media_session/public/cpp/test/mock_media_session.h"
20 #include "services/media_session/public/cpp/test/test_media_controller.h"
21 #include "services/media_session/public/mojom/constants.mojom.h"
22 #include "services/media_session/public/mojom/media_session.mojom.h"
23 #include "services/media_session/public/mojom/media_session_service.mojom.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 namespace media_session {
27 
28 class MediaControllerTest : public testing::Test {
29  public:
30   MediaControllerTest() = default;
31 
SetUp()32   void SetUp() override {
33     // Create an instance of the MediaSessionService and bind some interfaces.
34     service_ = std::make_unique<MediaSessionService>(
35         service_remote_.BindNewPipeAndPassReceiver());
36     service_remote_->BindAudioFocusManager(
37         audio_focus_remote_.BindNewPipeAndPassReceiver());
38     service_remote_->BindMediaControllerManager(
39         controller_manager_remote_.BindNewPipeAndPassReceiver());
40 
41     controller_manager_remote_->CreateActiveMediaController(
42         media_controller_remote_.BindNewPipeAndPassReceiver());
43     controller_manager_remote_.FlushForTesting();
44 
45     audio_focus_remote_->SetEnforcementMode(
46         mojom::EnforcementMode::kSingleSession);
47     audio_focus_remote_.FlushForTesting();
48   }
49 
TearDown()50   void TearDown() override {
51     // Run pending tasks.
52     base::RunLoop().RunUntilIdle();
53   }
54 
RequestAudioFocus(test::MockMediaSession & session,mojom::AudioFocusType type)55   void RequestAudioFocus(test::MockMediaSession& session,
56                          mojom::AudioFocusType type) {
57     session.RequestAudioFocusFromService(audio_focus_remote_, type);
58   }
59 
controller()60   mojo::Remote<mojom::MediaController>& controller() {
61     return media_controller_remote_;
62   }
63 
manager()64   mojo::Remote<mojom::MediaControllerManager>& manager() {
65     return controller_manager_remote_;
66   }
67 
GetImageObserverCount(const MediaController & controller)68   static size_t GetImageObserverCount(const MediaController& controller) {
69     return controller.image_observers_.size();
70   }
71 
72  private:
73   base::test::TaskEnvironment task_environment_;
74   std::unique_ptr<MediaSessionService> service_;
75   mojo::Remote<mojom::MediaSessionService> service_remote_;
76   mojo::Remote<mojom::AudioFocusManager> audio_focus_remote_;
77   mojo::Remote<mojom::MediaController> media_controller_remote_;
78   mojo::Remote<mojom::MediaControllerManager> controller_manager_remote_;
79 
80   DISALLOW_COPY_AND_ASSIGN(MediaControllerTest);
81 };
82 
TEST_F(MediaControllerTest,ActiveController_Suspend)83 TEST_F(MediaControllerTest, ActiveController_Suspend) {
84   test::MockMediaSession media_session;
85   media_session.SetIsControllable(true);
86 
87   {
88     test::MockMediaSessionMojoObserver observer(media_session);
89     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
90     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
91   }
92 
93   {
94     test::MockMediaSessionMojoObserver observer(media_session);
95     controller()->Suspend();
96     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
97   }
98 }
99 
TEST_F(MediaControllerTest,ActiveController_Multiple_Abandon_Top)100 TEST_F(MediaControllerTest, ActiveController_Multiple_Abandon_Top) {
101   test::MockMediaSession media_session_1;
102   test::MockMediaSession media_session_2;
103 
104   media_session_1.SetIsControllable(true);
105   media_session_2.SetIsControllable(true);
106 
107   {
108     test::MockMediaSessionMojoObserver observer(media_session_1);
109     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
110     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
111   }
112 
113   {
114     test::MockMediaSessionMojoObserver observer_1(media_session_1);
115     test::MockMediaSessionMojoObserver observer_2(media_session_2);
116 
117     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
118 
119     observer_1.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
120     observer_2.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
121   }
122 
123   media_session_2.AbandonAudioFocusFromClient();
124 
125   {
126     test::MockMediaSessionMojoObserver observer(media_session_1);
127     controller()->Resume();
128     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
129   }
130 }
131 
TEST_F(MediaControllerTest,ActiveController_Multiple_Abandon_UnderNonControllable)132 TEST_F(MediaControllerTest,
133        ActiveController_Multiple_Abandon_UnderNonControllable) {
134   test::MockMediaSession media_session_1;
135   test::MockMediaSession media_session_2;
136   test::MockMediaSession media_session_3;
137 
138   media_session_1.SetIsControllable(true);
139   media_session_2.SetIsControllable(true);
140 
141   {
142     test::MockMediaSessionMojoObserver observer(media_session_1);
143     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
144     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
145   }
146 
147   {
148     test::MockMediaSessionMojoObserver observer_1(media_session_1);
149     test::MockMediaSessionMojoObserver observer_2(media_session_2);
150 
151     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
152 
153     observer_1.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
154     observer_2.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
155   }
156 
157   {
158     test::MockMediaSessionMojoObserver observer_2(media_session_2);
159     test::MockMediaSessionMojoObserver observer_3(media_session_3);
160 
161     RequestAudioFocus(media_session_3, mojom::AudioFocusType::kGain);
162 
163     observer_2.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
164     observer_3.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
165   }
166 
167   media_session_2.AbandonAudioFocusFromClient();
168 
169   {
170     test::MockMediaSessionMojoObserver observer(media_session_1);
171     controller()->Resume();
172     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
173   }
174 }
175 
TEST_F(MediaControllerTest,ActiveController_Multiple_Controllable)176 TEST_F(MediaControllerTest, ActiveController_Multiple_Controllable) {
177   test::MockMediaSession media_session_1;
178   test::MockMediaSession media_session_2;
179 
180   media_session_1.SetIsControllable(true);
181   media_session_2.SetIsControllable(true);
182 
183   {
184     test::MockMediaSessionMojoObserver observer(media_session_1);
185     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
186     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
187   }
188 
189   {
190     test::MockMediaSessionMojoObserver observer_1(media_session_1);
191     test::MockMediaSessionMojoObserver observer_2(media_session_2);
192 
193     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
194 
195     observer_1.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
196     observer_2.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
197   }
198 
199   {
200     test::MockMediaSessionMojoObserver observer(media_session_2);
201     controller()->Suspend();
202     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
203   }
204 }
205 
TEST_F(MediaControllerTest,ActiveController_Multiple_NonControllable)206 TEST_F(MediaControllerTest, ActiveController_Multiple_NonControllable) {
207   test::MockMediaSession media_session_1;
208   test::MockMediaSession media_session_2;
209 
210   media_session_1.SetIsControllable(true);
211 
212   {
213     test::MockMediaSessionMojoObserver observer(media_session_1);
214     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
215     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
216   }
217 
218   EXPECT_EQ(2, media_session_1.add_observer_count());
219 
220   {
221     test::MockMediaSessionMojoObserver observer_1(media_session_1);
222     test::MockMediaSessionMojoObserver observer_2(media_session_2);
223 
224     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
225 
226     observer_1.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
227     observer_2.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
228   }
229 
230   // The top session has changed but the controller is still bound to
231   // |media_session_1|. We should make sure we do not add an observer if we
232   // already have one.
233   EXPECT_EQ(3, media_session_1.add_observer_count());
234 
235   {
236     test::MockMediaSessionMojoObserver observer(media_session_1);
237     controller()->Resume();
238     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
239   }
240 
241   EXPECT_EQ(4, media_session_1.add_observer_count());
242 }
243 
TEST_F(MediaControllerTest,ActiveController_Multiple_UpdateControllable)244 TEST_F(MediaControllerTest, ActiveController_Multiple_UpdateControllable) {
245   test::MockMediaSession media_session_1;
246   test::MockMediaSession media_session_2;
247 
248   media_session_1.SetIsControllable(true);
249   media_session_2.SetIsControllable(true);
250 
251   EXPECT_EQ(0, media_session_1.add_observer_count());
252   EXPECT_EQ(0, media_session_2.add_observer_count());
253 
254   {
255     test::MockMediaSessionMojoObserver observer(media_session_1);
256     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
257     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
258   }
259 
260   EXPECT_EQ(2, media_session_1.add_observer_count());
261   EXPECT_EQ(0, media_session_2.add_observer_count());
262 
263   {
264     test::MockMediaSessionMojoObserver observer(media_session_2);
265     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGainTransient);
266     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
267   }
268 
269   EXPECT_EQ(2, media_session_1.add_observer_count());
270   EXPECT_EQ(2, media_session_2.add_observer_count());
271 
272   media_session_2.SetIsControllable(false);
273   media_session_2.FlushForTesting();
274 
275   EXPECT_EQ(3, media_session_1.add_observer_count());
276   EXPECT_EQ(2, media_session_2.add_observer_count());
277 
278   media_session_1.SetIsControllable(false);
279   media_session_1.FlushForTesting();
280 
281   EXPECT_EQ(3, media_session_1.add_observer_count());
282   EXPECT_EQ(2, media_session_2.add_observer_count());
283 }
284 
TEST_F(MediaControllerTest,ActiveController_Suspend_Noop)285 TEST_F(MediaControllerTest, ActiveController_Suspend_Noop) {
286   controller()->Suspend();
287 }
288 
TEST_F(MediaControllerTest,ActiveController_Suspend_Noop_Abandoned)289 TEST_F(MediaControllerTest, ActiveController_Suspend_Noop_Abandoned) {
290   test::MockMediaSession media_session;
291   media_session.SetIsControllable(true);
292 
293   {
294     test::MockMediaSessionMojoObserver observer(media_session);
295     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
296     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
297   }
298 
299   media_session.AbandonAudioFocusFromClient();
300 
301   controller()->Suspend();
302 
303   {
304     test::MockMediaSessionMojoObserver observer(media_session);
305     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
306     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
307   }
308 }
309 
TEST_F(MediaControllerTest,ActiveController_SuspendResume)310 TEST_F(MediaControllerTest, ActiveController_SuspendResume) {
311   test::MockMediaSession media_session;
312   media_session.SetIsControllable(true);
313 
314   {
315     test::MockMediaSessionMojoObserver observer(media_session);
316     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
317     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
318   }
319 
320   {
321     test::MockMediaSessionMojoObserver observer(media_session);
322     controller()->Suspend();
323     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
324   }
325 
326   {
327     test::MockMediaSessionMojoObserver observer(media_session);
328     controller()->Resume();
329     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
330   }
331 }
332 
TEST_F(MediaControllerTest,ActiveController_ToggleSuspendResume_Playing)333 TEST_F(MediaControllerTest, ActiveController_ToggleSuspendResume_Playing) {
334   test::MockMediaSession media_session;
335   media_session.SetIsControllable(true);
336 
337   {
338     test::MockMediaSessionMojoObserver observer(media_session);
339     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
340     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
341   }
342 
343   {
344     test::MockMediaSessionMojoObserver observer(media_session);
345     controller()->ToggleSuspendResume();
346     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
347   }
348 }
349 
TEST_F(MediaControllerTest,ActiveController_ToggleSuspendResume_Ducked)350 TEST_F(MediaControllerTest, ActiveController_ToggleSuspendResume_Ducked) {
351   test::MockMediaSession media_session;
352   media_session.SetIsControllable(true);
353 
354   {
355     test::MockMediaSessionMojoObserver observer(media_session);
356     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
357     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
358   }
359 
360   {
361     test::MockMediaSessionMojoObserver observer(media_session);
362     media_session.StartDucking();
363     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kDucking);
364   }
365 
366   {
367     test::MockMediaSessionMojoObserver observer(media_session);
368     controller()->ToggleSuspendResume();
369     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
370   }
371 }
372 
TEST_F(MediaControllerTest,ActiveController_ToggleSuspendResume_Inactive)373 TEST_F(MediaControllerTest, ActiveController_ToggleSuspendResume_Inactive) {
374   test::MockMediaSession media_session;
375   media_session.SetIsControllable(true);
376 
377   {
378     test::MockMediaSessionMojoObserver observer(media_session);
379     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
380     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
381   }
382 
383   {
384     test::MockMediaSessionMojoObserver observer(media_session);
385     media_session.Stop(mojom::MediaSession::SuspendType::kUI);
386     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kInactive);
387   }
388 
389   {
390     test::MockMediaSessionMojoObserver observer(media_session);
391     controller()->ToggleSuspendResume();
392     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
393   }
394 }
395 
TEST_F(MediaControllerTest,ActiveController_ToggleSuspendResume_Paused)396 TEST_F(MediaControllerTest, ActiveController_ToggleSuspendResume_Paused) {
397   test::MockMediaSession media_session;
398   media_session.SetIsControllable(true);
399 
400   {
401     test::MockMediaSessionMojoObserver observer(media_session);
402     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
403     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
404   }
405 
406   {
407     test::MockMediaSessionMojoObserver observer(media_session);
408     controller()->Suspend();
409     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
410   }
411 
412   {
413     test::MockMediaSessionMojoObserver observer(media_session);
414     controller()->ToggleSuspendResume();
415     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
416   }
417 }
418 
TEST_F(MediaControllerTest,ActiveController_Observer_StateTransition)419 TEST_F(MediaControllerTest, ActiveController_Observer_StateTransition) {
420   test::MockMediaSession media_session_1;
421   test::MockMediaSession media_session_2;
422 
423   media_session_1.SetIsControllable(true);
424   media_session_2.SetIsControllable(true);
425 
426   {
427     test::MockMediaSessionMojoObserver observer(media_session_1);
428     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
429     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
430   }
431 
432   {
433     test::TestMediaControllerObserver observer(controller());
434     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
435   }
436 
437   {
438     test::TestMediaControllerObserver observer(controller());
439     controller()->Suspend();
440     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kSuspended);
441   }
442 
443   {
444     test::TestMediaControllerObserver observer(controller());
445     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
446     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
447   }
448 
449   {
450     test::MockMediaSessionMojoObserver observer(media_session_1);
451     media_session_1.StartDucking();
452     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kDucking);
453   }
454 
455   {
456     test::TestMediaControllerObserver observer(controller());
457     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
458   }
459 }
460 
TEST_F(MediaControllerTest,ActiveController_PreviousTrack)461 TEST_F(MediaControllerTest, ActiveController_PreviousTrack) {
462   test::MockMediaSession media_session;
463   media_session.SetIsControllable(true);
464 
465   EXPECT_EQ(0, media_session.prev_track_count());
466 
467   {
468     test::MockMediaSessionMojoObserver observer(media_session);
469     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
470     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
471     EXPECT_EQ(0, media_session.prev_track_count());
472   }
473 
474   controller()->PreviousTrack();
475   controller().FlushForTesting();
476 
477   EXPECT_EQ(1, media_session.prev_track_count());
478 }
479 
TEST_F(MediaControllerTest,ActiveController_NextTrack)480 TEST_F(MediaControllerTest, ActiveController_NextTrack) {
481   test::MockMediaSession media_session;
482   media_session.SetIsControllable(true);
483 
484   EXPECT_EQ(0, media_session.next_track_count());
485 
486   {
487     test::MockMediaSessionMojoObserver observer(media_session);
488     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
489     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
490     EXPECT_EQ(0, media_session.next_track_count());
491   }
492 
493   controller()->NextTrack();
494   controller().FlushForTesting();
495 
496   EXPECT_EQ(1, media_session.next_track_count());
497 }
498 
TEST_F(MediaControllerTest,ActiveController_Seek)499 TEST_F(MediaControllerTest, ActiveController_Seek) {
500   test::MockMediaSession media_session;
501   media_session.SetIsControllable(true);
502 
503   EXPECT_EQ(0, media_session.seek_count());
504 
505   {
506     test::MockMediaSessionMojoObserver observer(media_session);
507     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
508     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
509     EXPECT_EQ(0, media_session.seek_count());
510   }
511 
512   controller()->Seek(
513       base::TimeDelta::FromSeconds(mojom::kDefaultSeekTimeSeconds));
514   controller().FlushForTesting();
515 
516   EXPECT_EQ(1, media_session.seek_count());
517 }
518 
TEST_F(MediaControllerTest,ActiveController_SeekTo)519 TEST_F(MediaControllerTest, ActiveController_SeekTo) {
520   test::MockMediaSession media_session;
521   media_session.SetIsControllable(true);
522 
523   EXPECT_EQ(0, media_session.seek_to_count());
524 
525   {
526     test::MockMediaSessionMojoObserver observer(media_session);
527     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
528     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
529 
530     EXPECT_EQ(0, media_session.seek_to_count());
531   }
532 
533   controller()->SeekTo(
534       base::TimeDelta::FromSeconds(mojom::kDefaultSeekTimeSeconds));
535   controller().FlushForTesting();
536 
537   EXPECT_EQ(1, media_session.seek_to_count());
538 }
539 
TEST_F(MediaControllerTest,ActiveController_ScrubTo)540 TEST_F(MediaControllerTest, ActiveController_ScrubTo) {
541   test::MockMediaSession media_session;
542   media_session.SetIsControllable(true);
543 
544   EXPECT_FALSE(media_session.is_scrubbing());
545   EXPECT_EQ(0, media_session.seek_to_count());
546 
547   {
548     test::MockMediaSessionMojoObserver observer(media_session);
549     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
550     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
551 
552     EXPECT_FALSE(media_session.is_scrubbing());
553     EXPECT_EQ(0, media_session.seek_to_count());
554   }
555 
556   controller()->ScrubTo(
557       base::TimeDelta::FromSeconds(mojom::kDefaultSeekTimeSeconds));
558   controller().FlushForTesting();
559 
560   EXPECT_TRUE(media_session.is_scrubbing());
561   EXPECT_EQ(0, media_session.seek_to_count());
562 
563   controller()->ScrubTo(
564       base::TimeDelta::FromSeconds(mojom::kDefaultSeekTimeSeconds));
565   controller().FlushForTesting();
566 
567   EXPECT_TRUE(media_session.is_scrubbing());
568   EXPECT_EQ(0, media_session.seek_to_count());
569 
570   controller()->SeekTo(
571       base::TimeDelta::FromSeconds(mojom::kDefaultSeekTimeSeconds));
572   controller().FlushForTesting();
573 
574   EXPECT_FALSE(media_session.is_scrubbing());
575   EXPECT_EQ(1, media_session.seek_to_count());
576 }
577 
TEST_F(MediaControllerTest,ActiveController_Metadata_Observer_Abandoned)578 TEST_F(MediaControllerTest, ActiveController_Metadata_Observer_Abandoned) {
579   MediaMetadata metadata;
580   metadata.title = base::ASCIIToUTF16("title");
581   metadata.artist = base::ASCIIToUTF16("artist");
582   metadata.album = base::ASCIIToUTF16("album");
583 
584   test::MockMediaSession media_session;
585   media_session.SetIsControllable(true);
586 
587   base::Optional<MediaMetadata> test_metadata(metadata);
588 
589   {
590     test::MockMediaSessionMojoObserver observer(media_session);
591     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
592     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
593   }
594 
595   media_session.SimulateMetadataChanged(test_metadata);
596   media_session.AbandonAudioFocusFromClient();
597 
598   {
599     test::TestMediaControllerObserver observer(controller());
600     observer.WaitForEmptyMetadata();
601   }
602 }
603 
TEST_F(MediaControllerTest,ActiveController_Metadata_Observer_Empty)604 TEST_F(MediaControllerTest, ActiveController_Metadata_Observer_Empty) {
605   test::MockMediaSession media_session;
606   media_session.SetIsControllable(true);
607 
608   base::Optional<MediaMetadata> test_metadata;
609 
610   {
611     test::MockMediaSessionMojoObserver observer(media_session);
612     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
613     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
614   }
615 
616   {
617     test::TestMediaControllerObserver observer(controller());
618     media_session.SimulateMetadataChanged(test_metadata);
619     observer.WaitForEmptyMetadata();
620   }
621 }
622 
TEST_F(MediaControllerTest,ActiveController_Metadata_Observer_WithInfo)623 TEST_F(MediaControllerTest, ActiveController_Metadata_Observer_WithInfo) {
624   MediaMetadata metadata;
625   metadata.title = base::ASCIIToUTF16("title");
626   metadata.artist = base::ASCIIToUTF16("artist");
627   metadata.album = base::ASCIIToUTF16("album");
628 
629   test::MockMediaSession media_session;
630   media_session.SetIsControllable(true);
631 
632   base::Optional<MediaMetadata> test_metadata(metadata);
633 
634   {
635     test::MockMediaSessionMojoObserver observer(media_session);
636     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
637     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
638   }
639 
640   {
641     test::TestMediaControllerObserver observer(controller());
642     media_session.SimulateMetadataChanged(test_metadata);
643     observer.WaitForExpectedMetadata(metadata);
644   }
645 }
646 
TEST_F(MediaControllerTest,ActiveController_Metadata_AddObserver_Empty)647 TEST_F(MediaControllerTest, ActiveController_Metadata_AddObserver_Empty) {
648   test::MockMediaSession media_session;
649   media_session.SetIsControllable(true);
650 
651   base::Optional<MediaMetadata> test_metadata;
652 
653   {
654     test::MockMediaSessionMojoObserver observer(media_session);
655     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
656     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
657   }
658 
659   media_session.SimulateMetadataChanged(test_metadata);
660 
661   {
662     test::TestMediaControllerObserver observer(controller());
663     observer.WaitForEmptyMetadata();
664   }
665 }
666 
TEST_F(MediaControllerTest,ActiveController_Metadata_AddObserver_WithInfo)667 TEST_F(MediaControllerTest, ActiveController_Metadata_AddObserver_WithInfo) {
668   MediaMetadata metadata;
669   metadata.title = base::ASCIIToUTF16("title");
670   metadata.artist = base::ASCIIToUTF16("artist");
671   metadata.album = base::ASCIIToUTF16("album");
672 
673   test::MockMediaSession media_session;
674   media_session.SetIsControllable(true);
675 
676   base::Optional<MediaMetadata> test_metadata(metadata);
677 
678   {
679     test::MockMediaSessionMojoObserver observer(media_session);
680     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
681     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
682   }
683 
684   media_session.SimulateMetadataChanged(test_metadata);
685 
686   {
687     test::TestMediaControllerObserver observer(controller());
688     observer.WaitForExpectedMetadata(metadata);
689   }
690 }
691 
TEST_F(MediaControllerTest,ActiveController_Stop)692 TEST_F(MediaControllerTest, ActiveController_Stop) {
693   test::MockMediaSession media_session;
694   media_session.SetIsControllable(true);
695 
696   {
697     test::MockMediaSessionMojoObserver observer(media_session);
698     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
699     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
700   }
701 
702   {
703     test::MockMediaSessionMojoObserver observer(media_session);
704     controller()->Stop();
705     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kInactive);
706   }
707 }
708 
TEST_F(MediaControllerTest,BoundController_Routing)709 TEST_F(MediaControllerTest, BoundController_Routing) {
710   test::MockMediaSession media_session_1;
711   test::MockMediaSession media_session_2;
712 
713   media_session_1.SetIsControllable(true);
714   media_session_2.SetIsControllable(true);
715 
716   {
717     test::MockMediaSessionMojoObserver observer(media_session_1);
718     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
719     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
720   }
721 
722   mojo::Remote<mojom::MediaController> controller;
723   manager()->CreateMediaControllerForSession(
724       controller.BindNewPipeAndPassReceiver(), media_session_1.request_id());
725   manager().FlushForTesting();
726 
727   EXPECT_EQ(0, media_session_1.next_track_count());
728 
729   controller->NextTrack();
730   controller.FlushForTesting();
731 
732   EXPECT_EQ(1, media_session_1.next_track_count());
733 
734   {
735     test::MockMediaSessionMojoObserver observer(media_session_2);
736     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
737     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
738   }
739 
740   EXPECT_EQ(1, media_session_1.next_track_count());
741   EXPECT_EQ(0, media_session_2.next_track_count());
742 
743   controller->NextTrack();
744   controller.FlushForTesting();
745 
746   EXPECT_EQ(2, media_session_1.next_track_count());
747   EXPECT_EQ(0, media_session_2.next_track_count());
748 }
749 
TEST_F(MediaControllerTest,BoundController_BadRequestId)750 TEST_F(MediaControllerTest, BoundController_BadRequestId) {
751   test::MockMediaSession media_session;
752   media_session.SetIsControllable(true);
753 
754   {
755     test::MockMediaSessionMojoObserver observer(media_session);
756     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
757     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
758   }
759 
760   mojo::Remote<mojom::MediaController> controller;
761   manager()->CreateMediaControllerForSession(
762       controller.BindNewPipeAndPassReceiver(),
763       base::UnguessableToken::Create());
764   manager().FlushForTesting();
765 
766   EXPECT_EQ(0, media_session.next_track_count());
767 
768   controller->NextTrack();
769   controller.FlushForTesting();
770 
771   EXPECT_EQ(0, media_session.next_track_count());
772 }
773 
TEST_F(MediaControllerTest,BoundController_DropOnAbandon)774 TEST_F(MediaControllerTest, BoundController_DropOnAbandon) {
775   test::MockMediaSession media_session;
776   media_session.SetIsControllable(true);
777 
778   {
779     test::MockMediaSessionMojoObserver observer(media_session);
780     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
781     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
782   }
783 
784   mojo::Remote<mojom::MediaController> controller;
785   manager()->CreateMediaControllerForSession(
786       controller.BindNewPipeAndPassReceiver(), media_session.request_id());
787   manager().FlushForTesting();
788 
789   EXPECT_EQ(0, media_session.next_track_count());
790 
791   controller->NextTrack();
792   controller.FlushForTesting();
793 
794   EXPECT_EQ(1, media_session.next_track_count());
795 
796   media_session.AbandonAudioFocusFromClient();
797 
798   EXPECT_EQ(1, media_session.next_track_count());
799 
800   controller->NextTrack();
801   controller.FlushForTesting();
802 
803   EXPECT_EQ(1, media_session.next_track_count());
804 }
805 
TEST_F(MediaControllerTest,ActiveController_Actions_AddObserver_Empty)806 TEST_F(MediaControllerTest, ActiveController_Actions_AddObserver_Empty) {
807   test::MockMediaSession media_session;
808   media_session.SetIsControllable(true);
809 
810   {
811     test::MockMediaSessionMojoObserver observer(media_session);
812     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
813     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
814   }
815 
816   {
817     test::TestMediaControllerObserver observer(controller());
818     observer.WaitForEmptyActions();
819   }
820 }
821 
TEST_F(MediaControllerTest,ActiveController_Actions_AddObserver_WithInfo)822 TEST_F(MediaControllerTest, ActiveController_Actions_AddObserver_WithInfo) {
823   test::MockMediaSession media_session;
824   media_session.SetIsControllable(true);
825 
826   {
827     test::MockMediaSessionMojoObserver observer(media_session);
828     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
829     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
830   }
831 
832   media_session.EnableAction(mojom::MediaSessionAction::kPlay);
833 
834   {
835     test::TestMediaControllerObserver observer(controller());
836 
837     std::set<mojom::MediaSessionAction> expected_actions;
838     expected_actions.insert(mojom::MediaSessionAction::kPlay);
839     observer.WaitForExpectedActions(expected_actions);
840   }
841 }
842 
TEST_F(MediaControllerTest,ActiveController_Actions_Observer_Empty)843 TEST_F(MediaControllerTest, ActiveController_Actions_Observer_Empty) {
844   test::MockMediaSession media_session;
845   media_session.EnableAction(mojom::MediaSessionAction::kPlay);
846   media_session.SetIsControllable(true);
847 
848   {
849     test::MockMediaSessionMojoObserver observer(media_session);
850     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
851     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
852   }
853 
854   {
855     test::TestMediaControllerObserver observer(controller());
856     media_session.DisableAction(mojom::MediaSessionAction::kPlay);
857     observer.WaitForEmptyActions();
858   }
859 }
860 
TEST_F(MediaControllerTest,ActiveController_Actions_Observer_WithInfo)861 TEST_F(MediaControllerTest, ActiveController_Actions_Observer_WithInfo) {
862   test::MockMediaSession media_session;
863   media_session.SetIsControllable(true);
864 
865   {
866     test::MockMediaSessionMojoObserver observer(media_session);
867     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
868     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
869   }
870 
871   {
872     test::TestMediaControllerObserver observer(controller());
873     media_session.EnableAction(mojom::MediaSessionAction::kPlay);
874 
875     std::set<mojom::MediaSessionAction> expected_actions;
876     expected_actions.insert(mojom::MediaSessionAction::kPlay);
877     observer.WaitForExpectedActions(expected_actions);
878   }
879 }
880 
TEST_F(MediaControllerTest,ActiveController_Actions_Observer_Abandoned)881 TEST_F(MediaControllerTest, ActiveController_Actions_Observer_Abandoned) {
882   test::MockMediaSession media_session;
883   media_session.EnableAction(mojom::MediaSessionAction::kPlay);
884   media_session.SetIsControllable(true);
885 
886   {
887     test::MockMediaSessionMojoObserver observer(media_session);
888     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
889     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
890   }
891 
892   media_session.AbandonAudioFocusFromClient();
893 
894   {
895     test::TestMediaControllerObserver observer(controller());
896     observer.WaitForEmptyActions();
897   }
898 }
899 
TEST_F(MediaControllerTest,ActiveController_Position_Observer_Empty)900 TEST_F(MediaControllerTest, ActiveController_Position_Observer_Empty) {
901   test::MockMediaSession media_session;
902   media_session.SetIsControllable(true);
903 
904   base::Optional<MediaPosition> test_position;
905 
906   {
907     test::MockMediaSessionMojoObserver observer(media_session);
908     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
909     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
910   }
911 
912   {
913     test::TestMediaControllerObserver observer(controller());
914     media_session.SimulatePositionChanged(test_position);
915     observer.WaitForEmptyPosition();
916   }
917 }
918 
TEST_F(MediaControllerTest,ActiveController_Position_Observer_WithInfo)919 TEST_F(MediaControllerTest, ActiveController_Position_Observer_WithInfo) {
920   MediaPosition position(1 /* playback_rate */,
921                          base::TimeDelta::FromSeconds(600) /* duration */,
922                          base::TimeDelta::FromSeconds(300) /* position */);
923 
924   test::MockMediaSession media_session;
925   media_session.SetIsControllable(true);
926 
927   base::Optional<MediaPosition> test_position(position);
928 
929   {
930     test::MockMediaSessionMojoObserver observer(media_session);
931     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
932     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
933   }
934 
935   {
936     test::TestMediaControllerObserver observer(controller());
937     media_session.SimulatePositionChanged(test_position);
938     observer.WaitForNonEmptyPosition();
939   }
940 }
941 
TEST_F(MediaControllerTest,ActiveController_Position_AddObserver_Empty)942 TEST_F(MediaControllerTest, ActiveController_Position_AddObserver_Empty) {
943   test::MockMediaSession media_session;
944   media_session.SetIsControllable(true);
945 
946   base::Optional<MediaPosition> test_position;
947 
948   {
949     test::MockMediaSessionMojoObserver observer(media_session);
950     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
951     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
952   }
953 
954   media_session.SimulatePositionChanged(test_position);
955 
956   {
957     test::TestMediaControllerObserver observer(controller());
958     observer.WaitForEmptyPosition();
959   }
960 }
961 
TEST_F(MediaControllerTest,ActiveController_Position_AddObserver_WithInfo)962 TEST_F(MediaControllerTest, ActiveController_Position_AddObserver_WithInfo) {
963   MediaPosition position(1 /* playback_rate */,
964                          base::TimeDelta::FromSeconds(600) /* duration */,
965                          base::TimeDelta::FromSeconds(300) /* position */);
966 
967   test::MockMediaSession media_session;
968   media_session.SetIsControllable(true);
969 
970   base::Optional<MediaPosition> test_position(position);
971 
972   {
973     test::MockMediaSessionMojoObserver observer(media_session);
974     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
975     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
976   }
977 
978   media_session.SimulatePositionChanged(test_position);
979 
980   {
981     test::TestMediaControllerObserver observer(controller());
982     observer.WaitForNonEmptyPosition();
983   }
984 }
985 
TEST_F(MediaControllerTest,ActiveController_Position_Observer_Abandoned)986 TEST_F(MediaControllerTest, ActiveController_Position_Observer_Abandoned) {
987   MediaPosition position(1 /* playback_rate */,
988                          base::TimeDelta::FromSeconds(600) /* duration */,
989                          base::TimeDelta::FromSeconds(300) /* position */);
990 
991   test::MockMediaSession media_session;
992   media_session.SetIsControllable(true);
993 
994   base::Optional<MediaPosition> test_position(position);
995 
996   {
997     test::MockMediaSessionMojoObserver observer(media_session);
998     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
999     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1000   }
1001 
1002   media_session.SimulatePositionChanged(test_position);
1003   media_session.AbandonAudioFocusFromClient();
1004 
1005   {
1006     test::TestMediaControllerObserver observer(controller());
1007     observer.WaitForEmptyPosition();
1008   }
1009 }
1010 
TEST_F(MediaControllerTest,ActiveController_Observer_Abandoned)1011 TEST_F(MediaControllerTest, ActiveController_Observer_Abandoned) {
1012   test::MockMediaSession media_session;
1013   media_session.SetIsControllable(true);
1014 
1015   {
1016     test::MockMediaSessionMojoObserver observer(media_session);
1017     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1018     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1019   }
1020 
1021   {
1022     test::TestMediaControllerObserver observer(controller());
1023     media_session.AbandonAudioFocusFromClient();
1024 
1025     // We should see empty info, metadata, actions, and position flushed since
1026     // the active controller is no longer bound to a media session.
1027     observer.WaitForEmptyInfo();
1028     observer.WaitForEmptyMetadata();
1029     observer.WaitForEmptyActions();
1030     observer.WaitForEmptyPosition();
1031   }
1032 }
1033 
TEST_F(MediaControllerTest,ActiveController_AddObserver_Abandoned)1034 TEST_F(MediaControllerTest, ActiveController_AddObserver_Abandoned) {
1035   test::MockMediaSession media_session;
1036   media_session.SetIsControllable(true);
1037 
1038   {
1039     test::MockMediaSessionMojoObserver observer(media_session);
1040     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1041     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1042   }
1043 
1044   media_session.AbandonAudioFocusFromClient();
1045 
1046   {
1047     test::TestMediaControllerObserver observer(controller());
1048 
1049     // We should see empty info, metadata, actions, and position since the
1050     // active controller is no longer bound to a media session.
1051     observer.WaitForEmptyInfo();
1052     observer.WaitForEmptyMetadata();
1053     observer.WaitForEmptyActions();
1054     observer.WaitForEmptyPosition();
1055   }
1056 }
1057 
TEST_F(MediaControllerTest,ClearImageObserverOnError)1058 TEST_F(MediaControllerTest, ClearImageObserverOnError) {
1059   MediaController controller;
1060 
1061   mojo::Remote<mojom::MediaController> controller_remote;
1062   controller.BindToInterface(controller_remote.BindNewPipeAndPassReceiver());
1063   EXPECT_EQ(0u, GetImageObserverCount(controller));
1064 
1065   {
1066     test::TestMediaControllerImageObserver observer(controller_remote, 0, 0);
1067     EXPECT_EQ(1u, GetImageObserverCount(controller));
1068   }
1069 
1070   EXPECT_EQ(1u, GetImageObserverCount(controller));
1071 
1072   base::RunLoop().RunUntilIdle();
1073 
1074   EXPECT_EQ(0u, GetImageObserverCount(controller));
1075 }
1076 
TEST_F(MediaControllerTest,ActiveController_SimulateImagesChanged)1077 TEST_F(MediaControllerTest, ActiveController_SimulateImagesChanged) {
1078   test::MockMediaSession media_session;
1079   media_session.SetIsControllable(true);
1080 
1081   {
1082     test::MockMediaSessionMojoObserver observer(media_session);
1083     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1084     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1085   }
1086 
1087   std::vector<MediaImage> images;
1088   MediaImage image;
1089   image.src = GURL("https://www.google.com");
1090   images.push_back(image);
1091 
1092   {
1093     test::TestMediaControllerImageObserver observer(controller(), 0, 0);
1094 
1095     // By default, the image is empty but no notification should be received.
1096     EXPECT_TRUE(media_session.last_image_src().is_empty());
1097 
1098     // Check that we receive the correct image and that it was requested from
1099     // |media_session| by the controller.
1100     media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork,
1101                                   images);
1102     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1103                                         false);
1104     EXPECT_EQ(image.src, media_session.last_image_src());
1105 
1106     // Check that we flush the observer with an empty image. Since the image is
1107     // empty the last downloaded image by |media_session| should still be the
1108     // previous image.
1109     media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork,
1110                                   std::vector<MediaImage>());
1111     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1112                                         true);
1113     EXPECT_EQ(image.src, media_session.last_image_src());
1114   }
1115 }
1116 
TEST_F(MediaControllerTest,ActiveController_SimulateImagesChanged_ToggleControllable)1117 TEST_F(MediaControllerTest,
1118        ActiveController_SimulateImagesChanged_ToggleControllable) {
1119   test::MockMediaSession media_session;
1120   media_session.SetIsControllable(true);
1121 
1122   {
1123     test::MockMediaSessionMojoObserver observer(media_session);
1124     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1125     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1126   }
1127 
1128   std::vector<MediaImage> images;
1129   MediaImage image;
1130   image.src = GURL("https://www.google.com");
1131   images.push_back(image);
1132   media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork, images);
1133 
1134   {
1135     test::TestMediaControllerImageObserver observer(controller(), 0, 0);
1136     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1137                                         false);
1138     EXPECT_EQ(image.src, media_session.last_image_src());
1139 
1140     // When the |media_session| becomes uncontrollable it is unbound from the
1141     // media controller and we should flush the observer with an empty image.
1142     media_session.SetIsControllable(false);
1143     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1144                                         true);
1145 
1146     // When the |media_session| becomes controllable again it will be bound to
1147     // the media controller and we should flush the observer with the current
1148     // images.
1149     media_session.SetIsControllable(true);
1150     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1151                                         false);
1152     EXPECT_EQ(image.src, media_session.last_image_src());
1153   }
1154 }
1155 
TEST_F(MediaControllerTest,ActiveController_SimulateImagesChanged_TypeChanged)1156 TEST_F(MediaControllerTest,
1157        ActiveController_SimulateImagesChanged_TypeChanged) {
1158   test::MockMediaSession media_session;
1159   media_session.SetIsControllable(true);
1160 
1161   {
1162     test::MockMediaSessionMojoObserver observer(media_session);
1163     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1164     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1165   }
1166 
1167   std::vector<MediaImage> images;
1168   MediaImage image;
1169   image.src = GURL("https://www.google.com");
1170   images.push_back(image);
1171   media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork, images);
1172 
1173   {
1174     test::TestMediaControllerImageObserver observer(controller(), 0, 0);
1175     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1176                                         false);
1177     EXPECT_EQ(image.src, media_session.last_image_src());
1178 
1179     // If we clear all the images associated with the media session we should
1180     // flush all the observers.
1181     media_session.ClearAllImages();
1182     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1183                                         true);
1184     EXPECT_EQ(image.src, media_session.last_image_src());
1185   }
1186 }
1187 
TEST_F(MediaControllerTest,ActiveController_SimulateImagesChanged_MinSizeCutoff)1188 TEST_F(MediaControllerTest,
1189        ActiveController_SimulateImagesChanged_MinSizeCutoff) {
1190   test::MockMediaSession media_session;
1191   media_session.SetIsControllable(true);
1192 
1193   {
1194     test::MockMediaSessionMojoObserver observer(media_session);
1195     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1196     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1197   }
1198 
1199   std::vector<MediaImage> images;
1200   MediaImage image1;
1201   image1.src = GURL("https://www.google.com");
1202   image1.sizes.push_back(gfx::Size(1, 1));
1203 
1204   media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork,
1205                                 {image1});
1206 
1207   {
1208     test::TestMediaControllerImageObserver observer(controller(), 5, 10);
1209 
1210     // The observer requires an image that is at least 5px but the only image
1211     // we have is 1px so the observer will not be notified.
1212     EXPECT_TRUE(media_session.last_image_src().is_empty());
1213 
1214     MediaImage image2;
1215     image2.src = GURL("https://www.example.com");
1216     image2.sizes.push_back(gfx::Size(10, 10));
1217 
1218     // Update the media session with two images, one that is too small and one
1219     // that is the right size. We should receive the second image through the
1220     // observer.
1221     media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork,
1222                                   {image1, image2});
1223     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1224                                         false);
1225     EXPECT_EQ(image2.src, media_session.last_image_src());
1226 
1227     // Use the first set of images again.
1228     media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork,
1229                                   {image1});
1230     // The observer requires as image that is at least 5px and should now be
1231     // notified that the image was cleared.
1232     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1233                                         true);
1234   }
1235 }
1236 
TEST_F(MediaControllerTest,ActiveController_SimulateImagesChanged_DesiredSize)1237 TEST_F(MediaControllerTest,
1238        ActiveController_SimulateImagesChanged_DesiredSize) {
1239   test::MockMediaSession media_session;
1240   media_session.SetIsControllable(true);
1241 
1242   {
1243     test::MockMediaSessionMojoObserver observer(media_session);
1244     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1245     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1246   }
1247 
1248   std::vector<MediaImage> images;
1249   MediaImage image1;
1250   image1.src = GURL("https://www.google.com");
1251   image1.sizes.push_back(gfx::Size(10, 10));
1252   images.push_back(image1);
1253 
1254   MediaImage image2;
1255   image2.src = GURL("https://www.example.com");
1256   image2.sizes.push_back(gfx::Size(9, 9));
1257   images.push_back(image2);
1258 
1259   media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork, images);
1260 
1261   {
1262     test::TestMediaControllerImageObserver observer(controller(), 5, 10);
1263 
1264     // The media session has two images, but the first one is closer to the 10px
1265     // desired size that the observer has specified. Therefore, the observer
1266     // should receive that image.
1267     media_session.SetImagesOfType(mojom::MediaSessionImageType::kArtwork,
1268                                   images);
1269     observer.WaitForExpectedImageOfType(mojom::MediaSessionImageType::kArtwork,
1270                                         false);
1271     EXPECT_EQ(image1.src, media_session.last_image_src());
1272   }
1273 }
1274 
TEST_F(MediaControllerTest,ActiveController_Observer_SessionChanged)1275 TEST_F(MediaControllerTest, ActiveController_Observer_SessionChanged) {
1276   test::MockMediaSession media_session_1;
1277   test::MockMediaSession media_session_2;
1278 
1279   media_session_1.SetIsControllable(true);
1280   media_session_2.SetIsControllable(true);
1281 
1282   {
1283     test::TestMediaControllerObserver observer(controller());
1284     observer.WaitForSession(base::nullopt);
1285   }
1286 
1287   {
1288     test::MockMediaSessionMojoObserver observer(media_session_1);
1289     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
1290     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1291   }
1292 
1293   {
1294     test::TestMediaControllerObserver observer(controller());
1295     observer.WaitForSession(media_session_1.request_id());
1296   }
1297 
1298   {
1299     test::TestMediaControllerObserver observer(controller());
1300     RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain);
1301     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1302   }
1303 
1304   {
1305     test::TestMediaControllerObserver observer(controller());
1306     observer.WaitForSession(media_session_2.request_id());
1307   }
1308 
1309   {
1310     test::TestMediaControllerObserver observer(controller());
1311     media_session_2.AbandonAudioFocusFromClient();
1312     observer.WaitForSession(media_session_1.request_id());
1313   }
1314 
1315   {
1316     test::TestMediaControllerObserver observer(controller());
1317     media_session_1.SetIsControllable(false);
1318     observer.WaitForSession(base::nullopt);
1319   }
1320 }
1321 
TEST_F(MediaControllerTest,BoundController_Observer_SessionChanged)1322 TEST_F(MediaControllerTest, BoundController_Observer_SessionChanged) {
1323   test::MockMediaSession media_session;
1324 
1325   {
1326     test::MockMediaSessionMojoObserver observer(media_session);
1327     RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
1328     observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
1329   }
1330 
1331   mojo::Remote<mojom::MediaController> controller;
1332   manager()->CreateMediaControllerForSession(
1333       controller.BindNewPipeAndPassReceiver(), media_session.request_id());
1334   manager().FlushForTesting();
1335 
1336   {
1337     test::TestMediaControllerObserver observer(controller);
1338     observer.WaitForSession(media_session.request_id());
1339   }
1340 }
1341 
TEST_F(MediaControllerTest,Manager_SuspendAllSessions)1342 TEST_F(MediaControllerTest, Manager_SuspendAllSessions) {
1343   test::MockMediaSession media_session_1;
1344   test::MockMediaSession media_session_2;
1345 
1346   {
1347     test::MockMediaSessionMojoObserver observer(media_session_1);
1348     RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain);
1349     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
1350   }
1351 
1352   {
1353     test::MockMediaSessionMojoObserver observer(media_session_2);
1354     RequestAudioFocus(media_session_2,
1355                       mojom::AudioFocusType::kGainTransientMayDuck);
1356     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying);
1357   }
1358 
1359   manager()->SuspendAllSessions();
1360 
1361   {
1362     test::MockMediaSessionMojoObserver observer(media_session_1);
1363     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
1364   }
1365 
1366   {
1367     test::MockMediaSessionMojoObserver observer(media_session_2);
1368     observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPaused);
1369   }
1370 }
1371 
1372 }  // namespace media_session
1373