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