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

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

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

Powered by Google App Engine
This is Rietveld 408576698