Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: media/remoting/remoting_renderer_controller_unittest.cc

Issue 2457563002: Media Remoting: Add remoting control logic for encrypted contents. (Closed)
Patch Set: Addressed comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "media/base/audio_decoder_config.h"
11 #include "media/base/cdm_config.h"
12 #include "media/base/limits.h"
13 #include "media/base/media_util.h"
14 #include "media/base/video_decoder_config.h"
15 #include "media/remoting/remoting_cdm.h"
16 #include "mojo/public/cpp/bindings/strong_binding.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace media {
20 namespace {
21
22 constexpr gfx::Size kCodedSize(320, 240);
23 constexpr gfx::Rect kVisibleRect(320, 240);
24 constexpr gfx::Size kNaturalSize(320, 240);
25
26 PipelineMetadata DefaultMetadata() {
27 PipelineMetadata data;
28 data.has_audio = true;
29 data.has_video = true;
30 data.video_decoder_config = VideoDecoderConfig(
31 kCodecVP8, VP8PROFILE_ANY, VideoPixelFormat::PIXEL_FORMAT_I420,
32 ColorSpace::COLOR_SPACE_SD_REC601, kCodedSize, kVisibleRect, kNaturalSize,
33 EmptyExtraData(), Unencrypted());
34 data.audio_decoder_config = AudioDecoderConfig(
35 kCodecOpus, SampleFormat::kSampleFormatU8,
36 ChannelLayout::CHANNEL_LAYOUT_MONO, limits::kMinSampleRate,
37 EmptyExtraData(), Unencrypted());
38 return data;
39 }
40
41 PipelineMetadata EncryptedMetadata() {
42 PipelineMetadata data;
43 data.has_audio = true;
44 data.has_video = true;
45 data.video_decoder_config = VideoDecoderConfig(
46 kCodecVP8, VP8PROFILE_ANY, VideoPixelFormat::PIXEL_FORMAT_I420,
47 ColorSpace::COLOR_SPACE_SD_REC601, kCodedSize, kVisibleRect, kNaturalSize,
48 EmptyExtraData(), AesCtrEncryptionScheme());
49 data.audio_decoder_config = AudioDecoderConfig(
50 kCodecOpus, SampleFormat::kSampleFormatU8,
51 ChannelLayout::CHANNEL_LAYOUT_MONO, limits::kMinSampleRate,
52 EmptyExtraData(), Unencrypted());
53 return data;
54 }
55
56 class FakeRemoter final : public mojom::Remoter {
57 public:
58 // |start_will_fail| indicates whether starting remoting will fail.
59 FakeRemoter(mojom::RemotingSourcePtr source, bool start_will_fail)
60 : source_(std::move(source)),
61 start_will_fail_(start_will_fail),
62 weak_factory_(this) {}
63 ~FakeRemoter() override {}
64
65 // mojom::Remoter implementations.
66 void Start() override {
67 if (start_will_fail_) {
68 base::ThreadTaskRunnerHandle::Get()->PostTask(
69 FROM_HERE,
70 base::Bind(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr()));
71 } else {
72 base::ThreadTaskRunnerHandle::Get()->PostTask(
73 FROM_HERE,
74 base::Bind(&FakeRemoter::Started, weak_factory_.GetWeakPtr()));
75 }
76 }
77
78 void StartDataStreams(
79 mojo::ScopedDataPipeConsumerHandle audio_pipe,
80 mojo::ScopedDataPipeConsumerHandle video_pipe,
81 mojom::RemotingDataStreamSenderRequest audio_sender_request,
82 mojom::RemotingDataStreamSenderRequest video_sender_request) override {}
83
84 void Stop(mojom::RemotingStopReason reason) override {
85 base::ThreadTaskRunnerHandle::Get()->PostTask(
86 FROM_HERE,
87 base::Bind(&FakeRemoter::Stopped, weak_factory_.GetWeakPtr(), reason));
88 }
89
90 void SendMessageToSink(const std::vector<uint8_t>& message) override {}
91
92 private:
93 void Started() { source_->OnStarted(); }
94 void StartFailed() {
95 source_->OnStartFailed(mojom::RemotingStartFailReason::ROUTE_TERMINATED);
96 }
97 void Stopped(mojom::RemotingStopReason reason) { source_->OnStopped(reason); }
98
99 const mojom::RemotingSourcePtr source_;
100 bool start_will_fail_;
101
102 base::WeakPtrFactory<FakeRemoter> weak_factory_;
103
104 DISALLOW_COPY_AND_ASSIGN(FakeRemoter);
105 };
106
107 class FakeRemoterFactory final : public mojom::RemoterFactory {
108 public:
109 // |start_will_fail| indicates whether starting remoting will fail.
110 explicit FakeRemoterFactory(bool start_will_fail)
111 : start_will_fail_(start_will_fail) {}
112 ~FakeRemoterFactory() override {}
113
114 void Create(mojom::RemotingSourcePtr source,
115 mojom::RemoterRequest request) override {
116 mojo::MakeStrongBinding(
117 base::MakeUnique<FakeRemoter>(std::move(source), start_will_fail_),
118 std::move(request));
119 }
120
121 private:
122 bool start_will_fail_;
123
124 DISALLOW_COPY_AND_ASSIGN(FakeRemoterFactory);
125 };
126
127 scoped_refptr<RemotingSourceImpl> CreateRemotingSourceImpl(
128 bool start_will_fail) {
129 mojom::RemotingSourcePtr remoting_source;
130 mojom::RemotingSourceRequest remoting_source_request =
131 mojo::GetProxy(&remoting_source);
132 mojom::RemoterPtr remoter;
133 std::unique_ptr<mojom::RemoterFactory> remoter_factory =
134 base::MakeUnique<FakeRemoterFactory>(start_will_fail);
135 remoter_factory->Create(std::move(remoting_source), mojo::GetProxy(&remoter));
136 return new RemotingSourceImpl(std::move(remoting_source_request),
137 std::move(remoter));
138 }
139
140 } // namespace
141
142 class RemotingRendererControllerTest : public ::testing::Test {
143 public:
144 RemotingRendererControllerTest() {}
145 ~RemotingRendererControllerTest() override {}
146
147 void TearDown() final { RunUntilIdle(); }
148
149 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
150
151 void ToggleRenderer() {
152 is_mirroring_ = remoting_renderer_controller_->remote_rendering_started();
153 }
154
155 void CreateCdm(bool is_remoting) { is_remoting_cdm_ = is_remoting; }
156
157 base::MessageLoop message_loop_;
158
159 protected:
160 std::unique_ptr<RemotingRendererController> remoting_renderer_controller_;
161 bool is_mirroring_ = false;
miu 2016/10/29 02:22:16 naming: The name you had before was much better: I
xjz 2016/10/31 17:24:00 Done.
162 bool is_remoting_cdm_ = false;
163
164 private:
165 DISALLOW_COPY_AND_ASSIGN(RemotingRendererControllerTest);
166 };
167
168 TEST_F(RemotingRendererControllerTest, ToggleRenderer) {
169 EXPECT_FALSE(is_mirroring_);
170 scoped_refptr<RemotingSourceImpl> remoting_source_impl =
171 CreateRemotingSourceImpl(false);
172 remoting_renderer_controller_ =
173 base::MakeUnique<RemotingRendererController>(remoting_source_impl);
174 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind(
175 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this)));
176 RunUntilIdle();
177 EXPECT_FALSE(is_mirroring_);
178 remoting_source_impl->OnSinkAvailable();
179 RunUntilIdle();
180 EXPECT_FALSE(is_mirroring_);
181 remoting_renderer_controller_->OnEnteredFullscreen();
182 RunUntilIdle();
183 EXPECT_FALSE(is_mirroring_);
184 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata());
185 RunUntilIdle();
186 EXPECT_TRUE(is_mirroring_);
187 remoting_renderer_controller_->OnExitedFullscreen();
188 RunUntilIdle();
189 EXPECT_FALSE(is_mirroring_);
190 }
191
192 TEST_F(RemotingRendererControllerTest, StartFailed) {
193 EXPECT_FALSE(is_mirroring_);
194 scoped_refptr<RemotingSourceImpl> remoting_source_impl =
195 CreateRemotingSourceImpl(true);
196 remoting_renderer_controller_ =
197 base::MakeUnique<RemotingRendererController>(remoting_source_impl);
198 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind(
199 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this)));
200 RunUntilIdle();
201 EXPECT_FALSE(is_mirroring_);
202 remoting_source_impl->OnSinkAvailable();
203 RunUntilIdle();
204 EXPECT_FALSE(is_mirroring_);
205 remoting_renderer_controller_->OnEnteredFullscreen();
206 RunUntilIdle();
207 EXPECT_FALSE(is_mirroring_);
208 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata());
209 RunUntilIdle();
210 EXPECT_FALSE(is_mirroring_);
211 }
212
213 TEST_F(RemotingRendererControllerTest, EncryptedWithRemotingCdm) {
214 EXPECT_FALSE(is_mirroring_);
215 remoting_renderer_controller_ = base::MakeUnique<RemotingRendererController>(
216 CreateRemotingSourceImpl(false));
217 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind(
218 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this)));
219 RunUntilIdle();
220 EXPECT_FALSE(is_mirroring_);
221 remoting_renderer_controller_->OnMetadataChanged(EncryptedMetadata());
222 RunUntilIdle();
223 EXPECT_FALSE(is_mirroring_);
224 scoped_refptr<RemotingSourceImpl> cdm_remoting_source_impl =
225 CreateRemotingSourceImpl(false);
226 std::unique_ptr<RemotingCdmController> remoting_cdm_controller =
227 base::MakeUnique<RemotingCdmController>(cdm_remoting_source_impl);
228 cdm_remoting_source_impl->OnSinkAvailable();
229 remoting_cdm_controller->ShouldCreateRemotingCdm(base::Bind(
230 &RemotingRendererControllerTest::CreateCdm, base::Unretained(this)));
231 RunUntilIdle();
232 EXPECT_FALSE(is_mirroring_);
233 EXPECT_TRUE(is_remoting_cdm_);
234
235 // Create a RemotingCdm with |remoting_cdm_controller|.
236 CdmConfig cdm_config;
237 GURL gurl;
238 std::string empty_string;
239 scoped_refptr<RemotingCdm> remoting_cdm = new RemotingCdm(
240 empty_string, gurl, cdm_config, SessionMessageCB(), SessionClosedCB(),
241 SessionKeysChangeCB(), SessionExpirationUpdateCB(), CdmCreatedCB(),
242 std::move(remoting_cdm_controller));
243 remoting_renderer_controller_->OnSetCdm(remoting_cdm.get());
244 RunUntilIdle();
245 EXPECT_TRUE(is_mirroring_);
246
247 // For encrypted contents, entering/exiting full screen has no effect.
248 remoting_renderer_controller_->OnEnteredFullscreen();
249 RunUntilIdle();
250 EXPECT_TRUE(is_mirroring_);
251 remoting_renderer_controller_->OnExitedFullscreen();
252 RunUntilIdle();
253 EXPECT_TRUE(is_mirroring_);
254
255 EXPECT_NE(RemotingSessionState::SESSION_PERMANENTLY_STOPPED,
256 remoting_renderer_controller_->remoting_source()->state());
257 cdm_remoting_source_impl->OnSinkGone();
258 RunUntilIdle();
259 EXPECT_EQ(RemotingSessionState::SESSION_PERMANENTLY_STOPPED,
260 remoting_renderer_controller_->remoting_source()->state());
261 // Don't switch renderer in this case. Still in remoting.
262 EXPECT_TRUE(is_mirroring_);
263 }
264
265 TEST_F(RemotingRendererControllerTest, EncryptedWithLocalCdm) {
266 EXPECT_FALSE(is_mirroring_);
267 scoped_refptr<RemotingSourceImpl> renderer_remoting_source_impl =
268 CreateRemotingSourceImpl(false);
269 remoting_renderer_controller_ = base::MakeUnique<RemotingRendererController>(
270 renderer_remoting_source_impl);
271 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind(
272 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this)));
273 RunUntilIdle();
274 EXPECT_FALSE(is_mirroring_);
275 renderer_remoting_source_impl->OnSinkAvailable();
276 RunUntilIdle();
277 EXPECT_FALSE(is_mirroring_);
278 remoting_renderer_controller_->OnEnteredFullscreen();
279 RunUntilIdle();
280 EXPECT_FALSE(is_mirroring_);
281 remoting_renderer_controller_->OnMetadataChanged(EncryptedMetadata());
282 RunUntilIdle();
283 EXPECT_FALSE(is_mirroring_);
284
285 scoped_refptr<RemotingSourceImpl> cdm_remoting_source_impl =
286 CreateRemotingSourceImpl(true);
287 std::unique_ptr<RemotingCdmController> remoting_cdm_controller =
288 base::MakeUnique<RemotingCdmController>(cdm_remoting_source_impl);
289 cdm_remoting_source_impl->OnSinkAvailable();
290 remoting_cdm_controller->ShouldCreateRemotingCdm(base::Bind(
291 &RemotingRendererControllerTest::CreateCdm, base::Unretained(this)));
292 RunUntilIdle();
293 EXPECT_FALSE(is_mirroring_);
294 EXPECT_FALSE(is_remoting_cdm_);
295 }
296
297 TEST_F(RemotingRendererControllerTest, EncryptedWithFailedRemotingCdm) {
298 EXPECT_FALSE(is_mirroring_);
299 remoting_renderer_controller_ = base::MakeUnique<RemotingRendererController>(
300 CreateRemotingSourceImpl(false));
301 remoting_renderer_controller_->SetSwitchRendererCallback(base::Bind(
302 &RemotingRendererControllerTest::ToggleRenderer, base::Unretained(this)));
303 RunUntilIdle();
304 EXPECT_FALSE(is_mirroring_);
305 remoting_renderer_controller_->OnEnteredFullscreen();
306 RunUntilIdle();
307 EXPECT_FALSE(is_mirroring_);
308 remoting_renderer_controller_->OnMetadataChanged(EncryptedMetadata());
309 RunUntilIdle();
310 EXPECT_FALSE(is_mirroring_);
311
312 scoped_refptr<RemotingSourceImpl> cdm_remoting_source_impl =
313 CreateRemotingSourceImpl(false);
314 std::unique_ptr<RemotingCdmController> remoting_cdm_controller =
315 base::MakeUnique<RemotingCdmController>(cdm_remoting_source_impl);
316 cdm_remoting_source_impl->OnSinkAvailable();
317 remoting_cdm_controller->ShouldCreateRemotingCdm(base::Bind(
318 &RemotingRendererControllerTest::CreateCdm, base::Unretained(this)));
319 RunUntilIdle();
320 EXPECT_FALSE(is_mirroring_);
321 EXPECT_TRUE(is_remoting_cdm_);
322
323 cdm_remoting_source_impl->OnSinkGone();
324 RunUntilIdle();
325 EXPECT_FALSE(is_mirroring_);
326 EXPECT_NE(RemotingSessionState::SESSION_PERMANENTLY_STOPPED,
327 remoting_renderer_controller_->remoting_source()->state());
328
329 CdmConfig cdm_config;
330 GURL gurl;
331 std::string empty_string;
332 scoped_refptr<RemotingCdm> remoting_cdm = new RemotingCdm(
333 empty_string, gurl, cdm_config, SessionMessageCB(), SessionClosedCB(),
334 SessionKeysChangeCB(), SessionExpirationUpdateCB(), CdmCreatedCB(),
335 std::move(remoting_cdm_controller));
336 remoting_renderer_controller_->OnSetCdm(remoting_cdm.get());
337 RunUntilIdle();
338 // Switch to remoting renderer even when the remoting CDM session was already
339 // terminated.
340 EXPECT_TRUE(is_mirroring_);
341 EXPECT_EQ(RemotingSessionState::SESSION_PERMANENTLY_STOPPED,
342 remoting_renderer_controller_->remoting_source()->state());
343 }
344
345 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698