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

Side by Side Diff: mojo/services/network/udp_socket_unittest.cc

Issue 1873463003: Remove mojo network service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months 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 2014 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 <stddef.h>
6 #include <stdint.h>
7
8 #include <utility>
9
10 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "mojo/public/cpp/bindings/callback.h"
14 #include "mojo/services/network/public/cpp/udp_socket_wrapper.h"
15 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
16 #include "mojo/services/network/public/interfaces/udp_socket.mojom.h"
17 #include "mojo/shell/public/cpp/shell_test.h"
18 #include "net/base/net_errors.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace mojo {
22 namespace service {
23 namespace {
24
25 NetAddressPtr GetLocalHostWithAnyPort() {
26 NetAddressPtr addr(NetAddress::New());
27 addr->family = NetAddressFamily::IPV4;
28 addr->ipv4 = NetAddressIPv4::New();
29 addr->ipv4->port = 0;
30 addr->ipv4->addr.resize(4);
31 addr->ipv4->addr[0] = 127;
32 addr->ipv4->addr[1] = 0;
33 addr->ipv4->addr[2] = 0;
34 addr->ipv4->addr[3] = 1;
35
36 return addr;
37 }
38
39 Array<uint8_t> CreateTestMessage(uint8_t initial, size_t size) {
40 Array<uint8_t> array(size);
41 for (size_t i = 0; i < size; ++i)
42 array[i] = static_cast<uint8_t>((i + initial) % 256);
43 return array;
44 }
45
46 template <typename CallbackType>
47 class TestCallbackBase {
48 public:
49 TestCallbackBase() : state_(nullptr), run_loop_(nullptr), ran_(false) {}
50
51 ~TestCallbackBase() {
52 state_->set_test_callback(nullptr);
53 }
54
55 CallbackType callback() const { return callback_; }
56
57 void WaitForResult() {
58 if (ran_)
59 return;
60
61 base::RunLoop run_loop;
62 run_loop_ = &run_loop;
63 run_loop.Run();
64 run_loop_ = nullptr;
65 }
66
67 protected:
68 struct StateBase : public CallbackType::Runnable {
69 StateBase() : test_callback_(nullptr) {}
70 ~StateBase() override {}
71
72 void set_test_callback(TestCallbackBase* test_callback) {
73 test_callback_ = test_callback;
74 }
75
76 protected:
77 void NotifyRun() const {
78 if (test_callback_) {
79 test_callback_->ran_ = true;
80 if (test_callback_->run_loop_)
81 test_callback_->run_loop_->Quit();
82 }
83 }
84
85 TestCallbackBase* test_callback_;
86
87 private:
88 DISALLOW_COPY_AND_ASSIGN(StateBase);
89 };
90
91 // Takes ownership of |state|, and guarantees that it lives at least as long
92 // as this object.
93 void Initialize(StateBase* state) {
94 state_ = state;
95 state_->set_test_callback(this);
96 callback_ = CallbackType(
97 static_cast<typename CallbackType::Runnable*>(state_));
98 }
99
100 private:
101 // The lifespan is managed by |callback_| (and its copies).
102 StateBase* state_;
103 CallbackType callback_;
104 base::RunLoop* run_loop_;
105 bool ran_;
106
107 DISALLOW_COPY_AND_ASSIGN(TestCallbackBase);
108 };
109
110 class TestCallback : public TestCallbackBase<Callback<void(NetworkErrorPtr)>> {
111 public:
112 TestCallback() {
113 Initialize(new State());
114 }
115 ~TestCallback() {}
116
117 const NetworkErrorPtr& result() const { return result_; }
118
119 private:
120 struct State: public StateBase {
121 ~State() override {}
122
123 void Run(NetworkErrorPtr result) const override {
124 if (test_callback_) {
125 TestCallback* callback = static_cast<TestCallback*>(test_callback_);
126 callback->result_ = std::move(result);
127 }
128 NotifyRun();
129 }
130 };
131
132 NetworkErrorPtr result_;
133 };
134
135 class TestCallbackWithAddressAndReceiver
136 : public TestCallbackBase<
137 Callback<void(NetworkErrorPtr,
138 NetAddressPtr,
139 InterfaceRequest<UDPSocketReceiver>)>> {
140 public:
141 TestCallbackWithAddressAndReceiver() { Initialize(new State()); }
142 ~TestCallbackWithAddressAndReceiver() {}
143
144 const NetworkErrorPtr& result() const { return result_; }
145 const NetAddressPtr& net_address() const { return net_address_; }
146 InterfaceRequest<UDPSocketReceiver>& receiver() { return receiver_; }
147
148 private:
149 struct State : public StateBase {
150 ~State() override {}
151
152 void Run(NetworkErrorPtr result,
153 NetAddressPtr net_address,
154 InterfaceRequest<UDPSocketReceiver> receiver) const override {
155 if (test_callback_) {
156 TestCallbackWithAddressAndReceiver* callback =
157 static_cast<TestCallbackWithAddressAndReceiver*>(test_callback_);
158 callback->result_ = std::move(result);
159 callback->net_address_ = std::move(net_address);
160 callback->receiver_ = std::move(receiver);
161 }
162 NotifyRun();
163 }
164 };
165
166 NetworkErrorPtr result_;
167 NetAddressPtr net_address_;
168 InterfaceRequest<UDPSocketReceiver> receiver_;
169 };
170
171 class TestCallbackWithAddress
172 : public TestCallbackBase<Callback<void(NetworkErrorPtr, NetAddressPtr)>> {
173 public:
174 TestCallbackWithAddress() {
175 Initialize(new State());
176 }
177 ~TestCallbackWithAddress() {}
178
179 const NetworkErrorPtr& result() const { return result_; }
180 const NetAddressPtr& net_address() const { return net_address_; }
181
182 private:
183 struct State : public StateBase {
184 ~State() override {}
185
186 void Run(NetworkErrorPtr result, NetAddressPtr net_address) const override {
187 if (test_callback_) {
188 TestCallbackWithAddress* callback =
189 static_cast<TestCallbackWithAddress*>(test_callback_);
190 callback->result_ = std::move(result);
191 callback->net_address_ = std::move(net_address);
192 }
193 NotifyRun();
194 }
195 };
196
197 NetworkErrorPtr result_;
198 NetAddressPtr net_address_;
199 };
200
201 class TestCallbackWithUint32
202 : public TestCallbackBase<Callback<void(uint32_t)>> {
203 public:
204 TestCallbackWithUint32() : result_(0) {
205 Initialize(new State());
206 }
207 ~TestCallbackWithUint32() {}
208
209 uint32_t result() const { return result_; }
210
211 private:
212 struct State : public StateBase {
213 ~State() override {}
214
215 void Run(uint32_t result) const override {
216 if (test_callback_) {
217 TestCallbackWithUint32* callback =
218 static_cast<TestCallbackWithUint32*>(test_callback_);
219 callback->result_ = result;
220 }
221 NotifyRun();
222 }
223 };
224
225 uint32_t result_;
226 };
227
228 class TestReceiveCallback
229 : public TestCallbackBase<
230 Callback<void(NetworkErrorPtr, NetAddressPtr, Array<uint8_t>)>> {
231 public:
232 TestReceiveCallback() {
233 Initialize(new State());
234 }
235 ~TestReceiveCallback() {}
236
237 const NetworkErrorPtr& result() const { return result_; }
238 const NetAddressPtr& src_addr() const { return src_addr_; }
239 const Array<uint8_t>& data() const { return data_; }
240
241 private:
242 struct State : public StateBase {
243 ~State() override {}
244
245 void Run(NetworkErrorPtr result,
246 NetAddressPtr src_addr,
247 Array<uint8_t> data) const override {
248 if (test_callback_) {
249 TestReceiveCallback* callback =
250 static_cast<TestReceiveCallback*>(test_callback_);
251 callback->result_ = std::move(result);
252 callback->src_addr_ = std::move(src_addr);
253 callback->data_ = std::move(data);
254 }
255 NotifyRun();
256 }
257 };
258
259 NetworkErrorPtr result_;
260 NetAddressPtr src_addr_;
261 Array<uint8_t> data_;
262 };
263
264 struct ReceiveResult {
265 NetworkErrorPtr result;
266 NetAddressPtr addr;
267 Array<uint8_t> data;
268 };
269
270 class UDPSocketReceiverImpl : public UDPSocketReceiver {
271 public:
272 UDPSocketReceiverImpl() : run_loop_(nullptr), expected_receive_count_(0) {}
273
274 ~UDPSocketReceiverImpl() override {
275 while (!results_.empty()) {
276 delete results_.front();
277 results_.pop();
278 }
279 }
280
281 std::queue<ReceiveResult*>* results() {
282 return &results_;
283 }
284
285 void WaitForReceiveResults(size_t count) {
286 if (results_.size() == count)
287 return;
288
289 expected_receive_count_ = count;
290 base::RunLoop run_loop;
291 run_loop_ = &run_loop;
292 run_loop.Run();
293 run_loop_ = nullptr;
294 }
295
296 private:
297 void OnReceived(NetworkErrorPtr result,
298 NetAddressPtr src_addr,
299 Array<uint8_t> data) override {
300 ReceiveResult* entry = new ReceiveResult();
301 entry->result = std::move(result);
302 entry->addr = std::move(src_addr);
303 entry->data = std::move(data);
304
305 results_.push(entry);
306
307 if (results_.size() == expected_receive_count_ && run_loop_) {
308 expected_receive_count_ = 0;
309 run_loop_->Quit();
310 }
311 }
312
313 base::RunLoop* run_loop_;
314 std::queue<ReceiveResult*> results_;
315 size_t expected_receive_count_;
316
317 DISALLOW_COPY_AND_ASSIGN(UDPSocketReceiverImpl);
318 };
319
320 class UDPSocketTest : public test::ShellTest {
321 public:
322 UDPSocketTest() : ShellTest("exe:network_service_unittests"),
323 receiver_binding_(&receiver_) {}
324 ~UDPSocketTest() override {}
325
326 void SetUp() override {
327 ShellTest::SetUp();
328 connector()->ConnectToInterface("mojo:network_service", &network_service_);
329 network_service_->CreateUDPSocket(GetProxy(&socket_));
330 }
331
332 protected:
333 NetworkServicePtr network_service_;
334 UDPSocketPtr socket_;
335 UDPSocketReceiverImpl receiver_;
336 Binding<UDPSocketReceiver> receiver_binding_;
337
338 DISALLOW_COPY_AND_ASSIGN(UDPSocketTest);
339 };
340
341 } // namespace
342
343 TEST_F(UDPSocketTest, Settings) {
344 TestCallback callback1;
345 socket_->AllowAddressReuse(callback1.callback());
346 callback1.WaitForResult();
347 EXPECT_EQ(net::OK, callback1.result()->code);
348
349 // Should fail because the socket hasn't been bound.
350 TestCallback callback2;
351 socket_->SetSendBufferSize(1024, callback2.callback());
352 callback2.WaitForResult();
353 EXPECT_NE(net::OK, callback2.result()->code);
354
355 // Should fail because the socket hasn't been bound.
356 TestCallback callback3;
357 socket_->SetReceiveBufferSize(2048, callback3.callback());
358 callback3.WaitForResult();
359 EXPECT_NE(net::OK, callback3.result()->code);
360
361 TestCallbackWithAddressAndReceiver callback4;
362 socket_->Bind(GetLocalHostWithAnyPort(), callback4.callback());
363 callback4.WaitForResult();
364 EXPECT_EQ(net::OK, callback4.result()->code);
365 EXPECT_NE(0u, callback4.net_address()->ipv4->port);
366
367 // Should fail because the socket has been bound.
368 TestCallback callback5;
369 socket_->AllowAddressReuse(callback5.callback());
370 callback5.WaitForResult();
371 EXPECT_NE(net::OK, callback5.result()->code);
372
373 TestCallback callback6;
374 socket_->SetSendBufferSize(1024, callback6.callback());
375 callback6.WaitForResult();
376 EXPECT_EQ(net::OK, callback6.result()->code);
377
378 TestCallback callback7;
379 socket_->SetReceiveBufferSize(2048, callback7.callback());
380 callback7.WaitForResult();
381 EXPECT_EQ(net::OK, callback7.result()->code);
382
383 TestCallbackWithUint32 callback8;
384 socket_->NegotiateMaxPendingSendRequests(0, callback8.callback());
385 callback8.WaitForResult();
386 EXPECT_GT(callback8.result(), 0u);
387
388 TestCallbackWithUint32 callback9;
389 socket_->NegotiateMaxPendingSendRequests(16, callback9.callback());
390 callback9.WaitForResult();
391 EXPECT_GT(callback9.result(), 0u);
392 }
393
394 TEST_F(UDPSocketTest, TestReadWrite) {
395 TestCallbackWithAddressAndReceiver callback1;
396 socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback());
397 callback1.WaitForResult();
398 ASSERT_EQ(net::OK, callback1.result()->code);
399 ASSERT_NE(0u, callback1.net_address()->ipv4->port);
400
401 receiver_binding_.Bind(std::move(callback1.receiver()));
402
403 NetAddressPtr server_addr = callback1.net_address().Clone();
404
405 UDPSocketPtr client_socket;
406 network_service_->CreateUDPSocket(GetProxy(&client_socket));
407
408 TestCallbackWithAddressAndReceiver callback2;
409 client_socket->Bind(GetLocalHostWithAnyPort(), callback2.callback());
410 callback2.WaitForResult();
411 ASSERT_EQ(net::OK, callback2.result()->code);
412 ASSERT_NE(0u, callback2.net_address()->ipv4->port);
413
414 NetAddressPtr client_addr = callback2.net_address().Clone();
415
416 const size_t kDatagramCount = 6;
417 const size_t kDatagramSize = 255;
418 socket_->ReceiveMore(kDatagramCount);
419
420 for (size_t i = 0; i < kDatagramCount; ++i) {
421 TestCallback callback;
422 client_socket->SendTo(
423 server_addr.Clone(),
424 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize),
425 callback.callback());
426 callback.WaitForResult();
427 EXPECT_EQ(255, callback.result()->code);
428 }
429
430 receiver_.WaitForReceiveResults(kDatagramCount);
431 for (size_t i = 0; i < kDatagramCount; ++i) {
432 scoped_ptr<ReceiveResult> result(receiver_.results()->front());
433 receiver_.results()->pop();
434
435 EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code);
436 EXPECT_TRUE(result->addr.Equals(client_addr));
437 EXPECT_TRUE(result->data.Equals(
438 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize)));
439 }
440 }
441
442 TEST_F(UDPSocketTest, TestConnectedReadWrite) {
443 TestCallbackWithAddressAndReceiver callback1;
444 socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback());
445 callback1.WaitForResult();
446 ASSERT_EQ(net::OK, callback1.result()->code);
447 ASSERT_NE(0u, callback1.net_address()->ipv4->port);
448
449 receiver_binding_.Bind(std::move(callback1.receiver()));
450
451 NetAddressPtr server_addr = callback1.net_address().Clone();
452
453 UDPSocketPtr client_socket;
454 network_service_->CreateUDPSocket(GetProxy(&client_socket));
455
456 TestCallbackWithAddressAndReceiver callback2;
457 client_socket->Connect(server_addr.Clone(), callback2.callback());
458 callback2.WaitForResult();
459 ASSERT_EQ(net::OK, callback2.result()->code);
460 ASSERT_NE(0u, callback2.net_address()->ipv4->port);
461
462 UDPSocketReceiverImpl client_socket_receiver;
463 Binding<UDPSocketReceiver> client_receiver_binding(
464 &client_socket_receiver, std::move(callback2.receiver()));
465
466 NetAddressPtr client_addr = callback2.net_address().Clone();
467
468 const size_t kDatagramCount = 6;
469 const size_t kDatagramSize = 255;
470
471 // Test send using a connected socket.
472 socket_->ReceiveMore(kDatagramCount);
473
474 for (size_t i = 0; i < kDatagramCount; ++i) {
475 TestCallback callback;
476 client_socket->SendTo(
477 nullptr,
478 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize),
479 callback.callback());
480 callback.WaitForResult();
481 EXPECT_EQ(255, callback.result()->code);
482 }
483
484 receiver_.WaitForReceiveResults(kDatagramCount);
485 for (size_t i = 0; i < kDatagramCount; ++i) {
486 scoped_ptr<ReceiveResult> result(receiver_.results()->front());
487 receiver_.results()->pop();
488
489 EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code);
490 EXPECT_TRUE(result->addr.Equals(client_addr));
491 EXPECT_TRUE(result->data.Equals(
492 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize)));
493 }
494
495 // Test receive using a connected socket.
496 client_socket->ReceiveMore(kDatagramCount);
497
498 for (size_t i = 0; i < kDatagramCount; ++i) {
499 TestCallback callback;
500 socket_->SendTo(
501 client_addr.Clone(),
502 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize),
503 callback.callback());
504 callback.WaitForResult();
505 EXPECT_EQ(255, callback.result()->code);
506 }
507
508 client_socket_receiver.WaitForReceiveResults(kDatagramCount);
509 for (size_t i = 0; i < kDatagramCount; ++i) {
510 scoped_ptr<ReceiveResult> result(client_socket_receiver.results()->front());
511 client_socket_receiver.results()->pop();
512
513 EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code);
514 EXPECT_FALSE(result->addr);
515 EXPECT_TRUE(result->data.Equals(
516 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize)));
517 }
518 }
519
520 TEST_F(UDPSocketTest, TestWrapperReadWrite) {
521 UDPSocketWrapper socket(std::move(socket_), 4, 4);
522
523 TestCallbackWithAddress callback1;
524 socket.Bind(GetLocalHostWithAnyPort(), callback1.callback());
525 callback1.WaitForResult();
526 ASSERT_EQ(net::OK, callback1.result()->code);
527 ASSERT_NE(0u, callback1.net_address()->ipv4->port);
528
529 NetAddressPtr server_addr = callback1.net_address().Clone();
530
531 UDPSocketPtr raw_client_socket;
532 network_service_->CreateUDPSocket(GetProxy(&raw_client_socket));
533 UDPSocketWrapper client_socket(std::move(raw_client_socket), 4, 4);
534
535 TestCallbackWithAddress callback2;
536 client_socket.Bind(GetLocalHostWithAnyPort(), callback2.callback());
537 callback2.WaitForResult();
538 ASSERT_EQ(net::OK, callback2.result()->code);
539 ASSERT_NE(0u, callback2.net_address()->ipv4->port);
540
541 NetAddressPtr client_addr = callback2.net_address().Clone();
542
543 const size_t kDatagramCount = 16;
544 const size_t kDatagramSize = 255;
545
546 for (size_t i = 1; i < kDatagramCount; ++i) {
547 scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]);
548 scoped_ptr<TestReceiveCallback[]> receive_callbacks(
549 new TestReceiveCallback[i]);
550
551 for (size_t j = 0; j < i; ++j) {
552 client_socket.SendTo(
553 server_addr.Clone(),
554 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize),
555 send_callbacks[j].callback());
556
557 socket.ReceiveFrom(receive_callbacks[j].callback());
558 }
559
560 receive_callbacks[i - 1].WaitForResult();
561
562 for (size_t j = 0; j < i; ++j) {
563 EXPECT_EQ(static_cast<int>(kDatagramSize),
564 receive_callbacks[j].result()->code);
565 EXPECT_TRUE(receive_callbacks[j].src_addr().Equals(client_addr));
566 EXPECT_TRUE(receive_callbacks[j].data().Equals(
567 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize)));
568 }
569 }
570 }
571
572 TEST_F(UDPSocketTest, TestWrapperConnectedReadWrite) {
573 UDPSocketWrapper socket(std::move(socket_), 4, 4);
574
575 TestCallbackWithAddress callback1;
576 socket.Bind(GetLocalHostWithAnyPort(), callback1.callback());
577 callback1.WaitForResult();
578 ASSERT_EQ(net::OK, callback1.result()->code);
579 ASSERT_NE(0u, callback1.net_address()->ipv4->port);
580
581 NetAddressPtr server_addr = callback1.net_address().Clone();
582
583 UDPSocketPtr raw_client_socket;
584 network_service_->CreateUDPSocket(GetProxy(&raw_client_socket));
585 UDPSocketWrapper client_socket(std::move(raw_client_socket), 4, 4);
586
587 TestCallbackWithAddress callback2;
588 client_socket.Connect(std::move(server_addr), callback2.callback());
589 callback2.WaitForResult();
590 ASSERT_EQ(net::OK, callback2.result()->code);
591 ASSERT_NE(0u, callback2.net_address()->ipv4->port);
592
593 NetAddressPtr client_addr = callback2.net_address().Clone();
594
595 const size_t kDatagramCount = 16;
596 const size_t kDatagramSize = 255;
597
598 // Test send using a connected socket.
599 for (size_t i = 1; i < kDatagramCount; ++i) {
600 scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]);
601 scoped_ptr<TestReceiveCallback[]> receive_callbacks(
602 new TestReceiveCallback[i]);
603
604 for (size_t j = 0; j < i; ++j) {
605 client_socket.SendTo(
606 nullptr,
607 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize),
608 send_callbacks[j].callback());
609
610 socket.ReceiveFrom(receive_callbacks[j].callback());
611 }
612
613 receive_callbacks[i - 1].WaitForResult();
614
615 for (size_t j = 0; j < i; ++j) {
616 EXPECT_EQ(static_cast<int>(kDatagramSize),
617 receive_callbacks[j].result()->code);
618 EXPECT_TRUE(receive_callbacks[j].src_addr().Equals(client_addr));
619 EXPECT_TRUE(receive_callbacks[j].data().Equals(
620 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize)));
621 }
622 }
623
624 // Test receive using a connected socket.
625 for (size_t i = 1; i < kDatagramCount; ++i) {
626 scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]);
627 scoped_ptr<TestReceiveCallback[]> receive_callbacks(
628 new TestReceiveCallback[i]);
629
630 for (size_t j = 0; j < i; ++j) {
631 socket.SendTo(
632 client_addr.Clone(),
633 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize),
634 send_callbacks[j].callback());
635
636 client_socket.ReceiveFrom(receive_callbacks[j].callback());
637 }
638
639 receive_callbacks[i - 1].WaitForResult();
640
641 for (size_t j = 0; j < i; ++j) {
642 EXPECT_EQ(static_cast<int>(kDatagramSize),
643 receive_callbacks[j].result()->code);
644 EXPECT_FALSE(receive_callbacks[j].src_addr());
645 EXPECT_TRUE(receive_callbacks[j].data().Equals(
646 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize)));
647 }
648 }
649 }
650
651 } // namespace service
652 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/network/udp_socket_impl.cc ('k') | mojo/services/network/url_loader_factory_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698