OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "media/remoting/remoting_renderer_controller.h" | |
6 | |
7 #include "base/callback.h" | |
8 #include "base/memory/ptr_util.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/run_loop.h" | |
11 #include "media/base/audio_decoder_config.h" | |
12 #include "media/base/cdm_config.h" | |
13 #include "media/base/limits.h" | |
14 #include "media/base/media_util.h" | |
15 #include "media/base/test_helpers.h" | |
16 #include "media/base/video_decoder_config.h" | |
17 #include "media/remoting/fake_remoting_controller.h" | |
18 #include "media/remoting/remoting_cdm.h" | |
19 #include "mojo/public/cpp/bindings/strong_binding.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | |
21 | |
22 namespace media { | |
23 namespace { | |
24 | |
25 constexpr mojom::RemotingSinkCapabilities kAllCapabilities = | |
26 mojom::RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING; | |
27 | |
28 PipelineMetadata DefaultMetadata() { | |
29 PipelineMetadata data; | |
30 data.has_audio = true; | |
31 data.has_video = true; | |
32 data.video_decoder_config = TestVideoConfig::Normal(); | |
33 return data; | |
34 } | |
35 | |
36 PipelineMetadata EncryptedMetadata() { | |
37 PipelineMetadata data; | |
38 data.has_audio = true; | |
39 data.has_video = true; | |
40 data.video_decoder_config = TestVideoConfig::NormalEncrypted(); | |
41 return data; | |
42 } | |
43 | |
44 } // namespace | |
45 | |
46 class RemotingRendererControllerTest : public ::testing::Test { | |
47 public: | |
48 RemotingRendererControllerTest() {} | |
49 ~RemotingRendererControllerTest() override {} | |
50 | |
51 void TearDown() final { RunUntilIdle(); } | |
52 | |
53 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } | |
54 | |
55 void ToggleRenderer() { | |
56 is_rendering_remotely_ = | |
57 remoting_renderer_controller_->remote_rendering_started(); | |
58 } | |
59 | |
60 void CreateCdm(bool is_remoting) { is_remoting_cdm_ = is_remoting; } | |
61 | |
62 base::MessageLoop message_loop_; | |
63 | |
64 protected: | |
65 std::unique_ptr<RemotingRendererController> remoting_renderer_controller_; | |
66 bool is_rendering_remotely_ = false; | |
67 bool is_remoting_cdm_ = false; | |
68 | |
69 private: | |
70 DISALLOW_COPY_AND_ASSIGN(RemotingRendererControllerTest); | |
71 }; | |
72 | |
73 TEST_F(RemotingRendererControllerTest, ToggleRendererOnFullscreenChange) { | |
74 EXPECT_FALSE(is_rendering_remotely_); | |
75 scoped_refptr<RemotingSourceImpl> remoting_source_impl = | |
76 CreateRemotingSourceImpl(false); | |
77 remoting_renderer_controller_ = | |
78 base::MakeUnique<RemotingRendererController>(remoting_source_impl); | |
79 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
80 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
81 RunUntilIdle(); | |
82 EXPECT_FALSE(is_rendering_remotely_); | |
83 remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
84 RunUntilIdle(); | |
85 EXPECT_FALSE(is_rendering_remotely_); | |
86 remoting_renderer_controller_->OnEnteredFullscreen(); | |
87 RunUntilIdle(); | |
88 EXPECT_FALSE(is_rendering_remotely_); | |
89 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata()); | |
90 RunUntilIdle(); | |
91 EXPECT_FALSE(is_rendering_remotely_); | |
92 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
93 RunUntilIdle(); | |
94 EXPECT_FALSE(is_rendering_remotely_); | |
95 remoting_renderer_controller_->OnPlaying(); | |
96 RunUntilIdle(); | |
97 EXPECT_TRUE(is_rendering_remotely_); // All requirements now satisfied. | |
98 | |
99 // Leaving fullscreen should shut down remoting. | |
100 remoting_renderer_controller_->OnExitedFullscreen(); | |
101 RunUntilIdle(); | |
102 EXPECT_FALSE(is_rendering_remotely_); | |
103 } | |
104 | |
105 TEST_F(RemotingRendererControllerTest, ToggleRendererOnSinkCapabilities) { | |
106 EXPECT_FALSE(is_rendering_remotely_); | |
107 scoped_refptr<RemotingSourceImpl> remoting_source_impl = | |
108 CreateRemotingSourceImpl(false); | |
109 remoting_renderer_controller_ = | |
110 base::MakeUnique<RemotingRendererController>(remoting_source_impl); | |
111 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
112 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
113 RunUntilIdle(); | |
114 EXPECT_FALSE(is_rendering_remotely_); | |
115 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata()); | |
116 RunUntilIdle(); | |
117 EXPECT_FALSE(is_rendering_remotely_); | |
118 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
119 RunUntilIdle(); | |
120 EXPECT_FALSE(is_rendering_remotely_); | |
121 remoting_renderer_controller_->OnPlaying(); | |
122 RunUntilIdle(); | |
123 EXPECT_FALSE(is_rendering_remotely_); | |
124 remoting_renderer_controller_->OnEnteredFullscreen(); | |
125 RunUntilIdle(); | |
126 EXPECT_FALSE(is_rendering_remotely_); | |
127 // An available sink that does not support remote rendering should not cause | |
128 // the controller to toggle remote rendering on. | |
129 remoting_source_impl->OnSinkAvailable(mojom::RemotingSinkCapabilities::NONE); | |
130 RunUntilIdle(); | |
131 EXPECT_FALSE(is_rendering_remotely_); | |
132 remoting_source_impl->OnSinkGone(); // Bye-bye useless sink! | |
133 RunUntilIdle(); | |
134 EXPECT_FALSE(is_rendering_remotely_); | |
135 // A sink that *does* support remote rendering *does* cause the controller to | |
136 // toggle remote rendering on. | |
137 remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
138 RunUntilIdle(); | |
139 EXPECT_TRUE(is_rendering_remotely_); | |
140 remoting_renderer_controller_->OnExitedFullscreen(); | |
141 RunUntilIdle(); | |
142 EXPECT_FALSE(is_rendering_remotely_); | |
143 } | |
144 | |
145 TEST_F(RemotingRendererControllerTest, ToggleRendererOnDisableChange) { | |
146 EXPECT_FALSE(is_rendering_remotely_); | |
147 scoped_refptr<RemotingSourceImpl> remoting_source_impl = | |
148 CreateRemotingSourceImpl(false); | |
149 remoting_renderer_controller_ = | |
150 base::MakeUnique<RemotingRendererController>(remoting_source_impl); | |
151 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
152 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
153 RunUntilIdle(); | |
154 EXPECT_FALSE(is_rendering_remotely_); | |
155 remoting_renderer_controller_->OnRemotePlaybackDisabled(true); | |
156 RunUntilIdle(); | |
157 EXPECT_FALSE(is_rendering_remotely_); | |
158 remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
159 RunUntilIdle(); | |
160 EXPECT_FALSE(is_rendering_remotely_); | |
161 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata()); | |
162 RunUntilIdle(); | |
163 EXPECT_FALSE(is_rendering_remotely_); | |
164 remoting_renderer_controller_->OnEnteredFullscreen(); | |
165 RunUntilIdle(); | |
166 EXPECT_FALSE(is_rendering_remotely_); | |
167 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
168 RunUntilIdle(); | |
169 EXPECT_FALSE(is_rendering_remotely_); | |
170 remoting_renderer_controller_->OnPlaying(); | |
171 RunUntilIdle(); | |
172 EXPECT_TRUE(is_rendering_remotely_); // All requirements now satisfied. | |
173 | |
174 // If the page disables remote playback (e.g., by setting the | |
175 // disableRemotePlayback attribute), this should shut down remoting. | |
176 remoting_renderer_controller_->OnRemotePlaybackDisabled(true); | |
177 RunUntilIdle(); | |
178 EXPECT_FALSE(is_rendering_remotely_); | |
179 } | |
180 | |
181 TEST_F(RemotingRendererControllerTest, StartFailed) { | |
182 EXPECT_FALSE(is_rendering_remotely_); | |
183 scoped_refptr<RemotingSourceImpl> remoting_source_impl = | |
184 CreateRemotingSourceImpl(true); | |
185 remoting_renderer_controller_ = | |
186 base::MakeUnique<RemotingRendererController>(remoting_source_impl); | |
187 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
188 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
189 RunUntilIdle(); | |
190 EXPECT_FALSE(is_rendering_remotely_); | |
191 remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
192 RunUntilIdle(); | |
193 EXPECT_FALSE(is_rendering_remotely_); | |
194 remoting_renderer_controller_->OnEnteredFullscreen(); | |
195 RunUntilIdle(); | |
196 EXPECT_FALSE(is_rendering_remotely_); | |
197 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata()); | |
198 RunUntilIdle(); | |
199 EXPECT_FALSE(is_rendering_remotely_); | |
200 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
201 RunUntilIdle(); | |
202 EXPECT_FALSE(is_rendering_remotely_); | |
203 remoting_renderer_controller_->OnPlaying(); | |
204 RunUntilIdle(); | |
205 EXPECT_FALSE(is_rendering_remotely_); | |
206 } | |
207 | |
208 TEST_F(RemotingRendererControllerTest, EncryptedWithRemotingCdm) { | |
209 EXPECT_FALSE(is_rendering_remotely_); | |
210 remoting_renderer_controller_ = base::MakeUnique<RemotingRendererController>( | |
211 CreateRemotingSourceImpl(false)); | |
212 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
213 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
214 RunUntilIdle(); | |
215 EXPECT_FALSE(is_rendering_remotely_); | |
216 remoting_renderer_controller_->OnMetadataChanged(EncryptedMetadata()); | |
217 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
218 remoting_renderer_controller_->OnPlaying(); | |
219 RunUntilIdle(); | |
220 EXPECT_FALSE(is_rendering_remotely_); | |
221 scoped_refptr<RemotingSourceImpl> cdm_remoting_source_impl = | |
222 CreateRemotingSourceImpl(false); | |
223 std::unique_ptr<RemotingCdmController> remoting_cdm_controller = | |
224 base::MakeUnique<RemotingCdmController>(cdm_remoting_source_impl); | |
225 cdm_remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
226 remoting_cdm_controller->ShouldCreateRemotingCdm(base::Bind( | |
227 &RemotingRendererControllerTest::CreateCdm, base::Unretained(this))); | |
228 RunUntilIdle(); | |
229 EXPECT_FALSE(is_rendering_remotely_); | |
230 EXPECT_TRUE(is_remoting_cdm_); | |
231 | |
232 // Create a RemotingCdm with |remoting_cdm_controller|. | |
233 scoped_refptr<RemotingCdm> remoting_cdm = new RemotingCdm( | |
234 std::string(), GURL(), CdmConfig(), SessionMessageCB(), SessionClosedCB(), | |
235 SessionKeysChangeCB(), SessionExpirationUpdateCB(), CdmCreatedCB(), | |
236 std::move(remoting_cdm_controller)); | |
237 std::unique_ptr<RemotingCdmContext> remoting_cdm_context = | |
238 base::MakeUnique<RemotingCdmContext>(remoting_cdm.get()); | |
239 remoting_renderer_controller_->OnSetCdm(remoting_cdm_context.get()); | |
240 RunUntilIdle(); | |
241 EXPECT_TRUE(is_rendering_remotely_); | |
242 | |
243 // For encrypted contents, entering/exiting full screen has no effect. | |
244 remoting_renderer_controller_->OnEnteredFullscreen(); | |
245 RunUntilIdle(); | |
246 EXPECT_TRUE(is_rendering_remotely_); | |
247 remoting_renderer_controller_->OnExitedFullscreen(); | |
248 RunUntilIdle(); | |
249 EXPECT_TRUE(is_rendering_remotely_); | |
250 | |
251 EXPECT_NE(RemotingSessionState::SESSION_PERMANENTLY_STOPPED, | |
252 remoting_renderer_controller_->remoting_source()->state()); | |
253 cdm_remoting_source_impl->OnSinkGone(); | |
254 RunUntilIdle(); | |
255 EXPECT_EQ(RemotingSessionState::SESSION_PERMANENTLY_STOPPED, | |
256 remoting_renderer_controller_->remoting_source()->state()); | |
257 // Don't switch renderer in this case. Still using the remoting renderer to | |
258 // show the failure interstitial. | |
259 EXPECT_TRUE(is_rendering_remotely_); | |
260 } | |
261 | |
262 TEST_F(RemotingRendererControllerTest, EncryptedWithLocalCdm) { | |
263 EXPECT_FALSE(is_rendering_remotely_); | |
264 scoped_refptr<RemotingSourceImpl> renderer_remoting_source_impl = | |
265 CreateRemotingSourceImpl(false); | |
266 remoting_renderer_controller_ = base::MakeUnique<RemotingRendererController>( | |
267 renderer_remoting_source_impl); | |
268 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
269 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
270 RunUntilIdle(); | |
271 EXPECT_FALSE(is_rendering_remotely_); | |
272 renderer_remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
273 RunUntilIdle(); | |
274 EXPECT_FALSE(is_rendering_remotely_); | |
275 remoting_renderer_controller_->OnEnteredFullscreen(); | |
276 RunUntilIdle(); | |
277 EXPECT_FALSE(is_rendering_remotely_); | |
278 remoting_renderer_controller_->OnMetadataChanged(EncryptedMetadata()); | |
279 RunUntilIdle(); | |
280 EXPECT_FALSE(is_rendering_remotely_); | |
281 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
282 RunUntilIdle(); | |
283 EXPECT_FALSE(is_rendering_remotely_); | |
284 remoting_renderer_controller_->OnPlaying(); | |
285 RunUntilIdle(); | |
286 EXPECT_FALSE(is_rendering_remotely_); | |
287 | |
288 scoped_refptr<RemotingSourceImpl> cdm_remoting_source_impl = | |
289 CreateRemotingSourceImpl(true); | |
290 std::unique_ptr<RemotingCdmController> remoting_cdm_controller = | |
291 base::MakeUnique<RemotingCdmController>(cdm_remoting_source_impl); | |
292 cdm_remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
293 remoting_cdm_controller->ShouldCreateRemotingCdm(base::Bind( | |
294 &RemotingRendererControllerTest::CreateCdm, base::Unretained(this))); | |
295 RunUntilIdle(); | |
296 EXPECT_FALSE(is_rendering_remotely_); | |
297 EXPECT_FALSE(is_remoting_cdm_); | |
298 } | |
299 | |
300 TEST_F(RemotingRendererControllerTest, EncryptedWithFailedRemotingCdm) { | |
301 EXPECT_FALSE(is_rendering_remotely_); | |
302 remoting_renderer_controller_ = base::MakeUnique<RemotingRendererController>( | |
303 CreateRemotingSourceImpl(false)); | |
304 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind( | |
305 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this))); | |
306 RunUntilIdle(); | |
307 EXPECT_FALSE(is_rendering_remotely_); | |
308 remoting_renderer_controller_->OnEnteredFullscreen(); | |
309 RunUntilIdle(); | |
310 EXPECT_FALSE(is_rendering_remotely_); | |
311 remoting_renderer_controller_->OnMetadataChanged(EncryptedMetadata()); | |
312 RunUntilIdle(); | |
313 EXPECT_FALSE(is_rendering_remotely_); | |
314 remoting_renderer_controller_->OnRemotePlaybackDisabled(false); | |
315 RunUntilIdle(); | |
316 EXPECT_FALSE(is_rendering_remotely_); | |
317 remoting_renderer_controller_->OnPlaying(); | |
318 RunUntilIdle(); | |
319 EXPECT_FALSE(is_rendering_remotely_); | |
320 | |
321 scoped_refptr<RemotingSourceImpl> cdm_remoting_source_impl = | |
322 CreateRemotingSourceImpl(false); | |
323 std::unique_ptr<RemotingCdmController> remoting_cdm_controller = | |
324 base::MakeUnique<RemotingCdmController>(cdm_remoting_source_impl); | |
325 cdm_remoting_source_impl->OnSinkAvailable(kAllCapabilities); | |
326 remoting_cdm_controller->ShouldCreateRemotingCdm(base::Bind( | |
327 &RemotingRendererControllerTest::CreateCdm, base::Unretained(this))); | |
328 RunUntilIdle(); | |
329 EXPECT_FALSE(is_rendering_remotely_); | |
330 EXPECT_TRUE(is_remoting_cdm_); | |
331 | |
332 cdm_remoting_source_impl->OnSinkGone(); | |
333 RunUntilIdle(); | |
334 EXPECT_FALSE(is_rendering_remotely_); | |
335 EXPECT_NE(RemotingSessionState::SESSION_PERMANENTLY_STOPPED, | |
336 remoting_renderer_controller_->remoting_source()->state()); | |
337 | |
338 scoped_refptr<RemotingCdm> remoting_cdm = new RemotingCdm( | |
339 std::string(), GURL(), CdmConfig(), SessionMessageCB(), SessionClosedCB(), | |
340 SessionKeysChangeCB(), SessionExpirationUpdateCB(), CdmCreatedCB(), | |
341 std::move(remoting_cdm_controller)); | |
342 std::unique_ptr<RemotingCdmContext> remoting_cdm_context = | |
343 base::MakeUnique<RemotingCdmContext>(remoting_cdm.get()); | |
344 remoting_renderer_controller_->OnSetCdm(remoting_cdm_context.get()); | |
345 RunUntilIdle(); | |
346 // Switch to using the remoting renderer, even when the remoting CDM session | |
347 // was already terminated, to show the failure interstitial. | |
348 EXPECT_TRUE(is_rendering_remotely_); | |
349 EXPECT_EQ(RemotingSessionState::SESSION_PERMANENTLY_STOPPED, | |
350 remoting_renderer_controller_->remoting_source()->state()); | |
351 } | |
352 | |
353 } // namespace media | |
OLD | NEW |