1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include "gtest/gtest.h"
6 #include "MediaControlService.h"
7 #include "MediaController.h"
8 #include "mozilla/dom/MediaSessionBinding.h"
9 
10 using namespace mozilla::dom;
11 
12 #define CONTROLLER_ID 0
13 #define FAKE_CONTEXT_ID 0
14 
TEST(MediaController,DefaultValueCheck)15 TEST(MediaController, DefaultValueCheck)
16 {
17   RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
18   ASSERT_TRUE(!controller->IsAnyMediaBeingControlled());
19   ASSERT_TRUE(controller->Id() == CONTROLLER_ID);
20   ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::None);
21   ASSERT_TRUE(!controller->IsAudible());
22 }
23 
TEST(MediaController,IsAnyMediaBeingControlled)24 TEST(MediaController, IsAnyMediaBeingControlled)
25 {
26   RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
27   ASSERT_TRUE(!controller->IsAnyMediaBeingControlled());
28 
29   controller->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
30                                          MediaPlaybackState::eStarted);
31   ASSERT_TRUE(controller->IsAnyMediaBeingControlled());
32 
33   controller->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
34                                          MediaPlaybackState::eStarted);
35   ASSERT_TRUE(controller->IsAnyMediaBeingControlled());
36 
37   controller->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
38                                          MediaPlaybackState::eStopped);
39   ASSERT_TRUE(controller->IsAnyMediaBeingControlled());
40 
41   controller->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
42                                          MediaPlaybackState::eStopped);
43   ASSERT_TRUE(!controller->IsAnyMediaBeingControlled());
44 }
45 
46 class FakeControlledMedia final {
47  public:
FakeControlledMedia(MediaController * aController)48   explicit FakeControlledMedia(MediaController* aController)
49       : mController(aController) {
50     mController->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
51                                             MediaPlaybackState::eStarted);
52   }
53 
SetPlaying(MediaPlaybackState aState)54   void SetPlaying(MediaPlaybackState aState) {
55     if (mPlaybackState == aState) {
56       return;
57     }
58     mController->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID, aState);
59     mPlaybackState = aState;
60   }
61 
SetAudible(MediaAudibleState aState)62   void SetAudible(MediaAudibleState aState) {
63     if (mAudibleState == aState) {
64       return;
65     }
66     mController->NotifyMediaAudibleChanged(FAKE_CONTEXT_ID, aState);
67     mAudibleState = aState;
68   }
69 
~FakeControlledMedia()70   ~FakeControlledMedia() {
71     if (mPlaybackState == MediaPlaybackState::ePlayed) {
72       mController->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
73                                               MediaPlaybackState::ePaused);
74     }
75     mController->NotifyMediaPlaybackChanged(FAKE_CONTEXT_ID,
76                                             MediaPlaybackState::eStopped);
77   }
78 
79  private:
80   MediaPlaybackState mPlaybackState = MediaPlaybackState::eStopped;
81   MediaAudibleState mAudibleState = MediaAudibleState::eInaudible;
82   RefPtr<MediaController> mController;
83 };
84 
TEST(MediaController,ActiveAndDeactiveController)85 TEST(MediaController, ActiveAndDeactiveController)
86 {
87   RefPtr<MediaControlService> service = MediaControlService::GetService();
88   ASSERT_TRUE(service->GetActiveControllersNum() == 0);
89 
90   RefPtr<MediaController> controller = new MediaController(FIRST_CONTROLLER_ID);
91 
92   // In order to check active control number after FakeControlledMedia
93   // destroyed.
94   {
95     FakeControlledMedia fakeMedia(controller);
96     fakeMedia.SetPlaying(MediaPlaybackState::ePlayed);
97     ASSERT_TRUE(service->GetActiveControllersNum() == 0);
98 
99     fakeMedia.SetAudible(MediaAudibleState::eAudible);
100     ASSERT_TRUE(service->GetActiveControllersNum() == 1);
101 
102     fakeMedia.SetAudible(MediaAudibleState::eInaudible);
103     ASSERT_TRUE(service->GetActiveControllersNum() == 1);
104   }
105 
106   ASSERT_TRUE(service->GetActiveControllersNum() == 0);
107 }
108 
TEST(MediaController,AudibleChanged)109 TEST(MediaController, AudibleChanged)
110 {
111   RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
112 
113   FakeControlledMedia fakeMedia(controller);
114   fakeMedia.SetPlaying(MediaPlaybackState::ePlayed);
115   ASSERT_TRUE(!controller->IsAudible());
116 
117   fakeMedia.SetAudible(MediaAudibleState::eAudible);
118   ASSERT_TRUE(controller->IsAudible());
119 
120   fakeMedia.SetAudible(MediaAudibleState::eInaudible);
121   ASSERT_TRUE(!controller->IsAudible());
122 }
123 
TEST(MediaController,PlayingStateChangeViaControlledMedia)124 TEST(MediaController, PlayingStateChangeViaControlledMedia)
125 {
126   RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
127 
128   // In order to check playing state after FakeControlledMedia destroyed.
129   {
130     FakeControlledMedia foo(controller);
131     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::None);
132 
133     foo.SetPlaying(MediaPlaybackState::ePlayed);
134     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Playing);
135 
136     foo.SetPlaying(MediaPlaybackState::ePaused);
137     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Paused);
138 
139     foo.SetPlaying(MediaPlaybackState::ePlayed);
140     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Playing);
141   }
142 
143   // FakeControlledMedia has been destroyed, no playing media exists.
144   ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Paused);
145 }
146 
TEST(MediaController,ControllerShouldRemainPlayingIfAnyPlayingMediaExists)147 TEST(MediaController, ControllerShouldRemainPlayingIfAnyPlayingMediaExists)
148 {
149   RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
150 
151   {
152     FakeControlledMedia foo(controller);
153     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::None);
154 
155     foo.SetPlaying(MediaPlaybackState::ePlayed);
156     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Playing);
157 
158     // foo is playing, so controller is in `playing` state.
159     FakeControlledMedia bar(controller);
160     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Playing);
161 
162     bar.SetPlaying(MediaPlaybackState::ePlayed);
163     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Playing);
164 
165     // Although we paused bar, but foo is still playing, so the controller would
166     // still be in `playing`.
167     bar.SetPlaying(MediaPlaybackState::ePaused);
168     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Playing);
169 
170     foo.SetPlaying(MediaPlaybackState::ePaused);
171     ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Paused);
172   }
173 
174   // both foo and bar have been destroyed, no playing media exists.
175   ASSERT_TRUE(controller->GetState() == MediaSessionPlaybackState::Paused);
176 }
177 
TEST(MediaController,PictureInPictureMode)178 TEST(MediaController, PictureInPictureMode)
179 {
180   RefPtr<MediaController> controller = new MediaController(CONTROLLER_ID);
181   ASSERT_TRUE(!controller->IsInPictureInPictureMode());
182 
183   controller->SetIsInPictureInPictureMode(true);
184   ASSERT_TRUE(controller->IsInPictureInPictureMode());
185 
186   controller->SetIsInPictureInPictureMode(false);
187   ASSERT_TRUE(!controller->IsInPictureInPictureMode());
188 }
189