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

Side by Side Diff: extensions/browser/api/cast_channel/cast_channel_api.cc

Issue 2891923004: [cast_channel] Make cast_channel related files not depend on "cast_channel.h" (Closed)
Patch Set: fix windows compile errors Created 3 years, 6 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "extensions/browser/api/cast_channel/cast_channel_api.h" 5 #include "extensions/browser/api/cast_channel/cast_channel_api.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <limits> 10 #include <limits>
11 #include <memory> 11 #include <memory>
12 #include <string> 12 #include <string>
13 #include <utility> 13 #include <utility>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/json/json_writer.h" 16 #include "base/json/json_writer.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
19 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
20 #include "base/values.h" 20 #include "base/values.h"
21 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
22 #include "extensions/browser/api/cast_channel/cast_channel_enum_util.h"
22 #include "extensions/browser/api/cast_channel/cast_message_util.h" 23 #include "extensions/browser/api/cast_channel/cast_message_util.h"
23 #include "extensions/browser/api/cast_channel/cast_socket.h" 24 #include "extensions/browser/api/cast_channel/cast_socket.h"
24 #include "extensions/browser/api/cast_channel/cast_socket_service.h" 25 #include "extensions/browser/api/cast_channel/cast_socket_service.h"
25 #include "extensions/browser/api/cast_channel/cast_socket_service_factory.h" 26 #include "extensions/browser/api/cast_channel/cast_socket_service_factory.h"
26 #include "extensions/browser/api/cast_channel/keep_alive_delegate.h" 27 #include "extensions/browser/api/cast_channel/keep_alive_delegate.h"
27 #include "extensions/browser/api/cast_channel/logger.h" 28 #include "extensions/browser/api/cast_channel/logger.h"
28 #include "extensions/browser/event_router.h" 29 #include "extensions/browser/event_router.h"
29 #include "extensions/common/api/cast_channel/cast_channel.pb.h" 30 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
30 #include "extensions/common/api/cast_channel/logging.pb.h" 31 #include "extensions/common/api/cast_channel/logging.pb.h"
31 #include "net/base/ip_address.h" 32 #include "net/base/ip_address.h"
32 #include "net/base/ip_endpoint.h" 33 #include "net/base/ip_endpoint.h"
33 #include "net/base/net_errors.h" 34 #include "net/base/net_errors.h"
34 35
35 // Default timeout interval for connection setup. 36 // Default timeout interval for connection setup.
36 // Used if not otherwise specified at ConnectInfo::timeout. 37 // Used if not otherwise specified at ConnectInfo::timeout.
37 const int kDefaultConnectTimeoutMillis = 5000; // 5 seconds. 38 const int kDefaultConnectTimeoutMillis = 5000; // 5 seconds.
38 39
39 namespace extensions { 40 namespace extensions {
40 41
41 namespace Close = cast_channel::Close; 42 namespace Close = cast_channel::Close;
42 namespace OnError = cast_channel::OnError; 43 namespace OnError = cast_channel::OnError;
43 namespace OnMessage = cast_channel::OnMessage; 44 namespace OnMessage = cast_channel::OnMessage;
44 namespace Open = cast_channel::Open; 45 namespace Open = cast_channel::Open;
45 namespace Send = cast_channel::Send; 46 namespace Send = cast_channel::Send;
47 using ::cast_channel::ChannelError;
46 using cast_channel::CastDeviceCapability; 48 using cast_channel::CastDeviceCapability;
47 using cast_channel::CastMessage; 49 using cast_channel::CastMessage;
48 using cast_channel::CastSocket; 50 using cast_channel::CastSocket;
49 using cast_channel::ChannelAuthType; 51 using cast_channel::CastSocketImpl;
50 using cast_channel::ChannelError; 52 using cast_channel::CastTransport;
51 using cast_channel::ChannelInfo; 53 using cast_channel::ChannelInfo;
52 using cast_channel::ConnectInfo; 54 using cast_channel::ConnectInfo;
53 using cast_channel::ErrorInfo; 55 using cast_channel::ErrorInfo;
56 using cast_channel::KeepAliveDelegate;
54 using cast_channel::LastErrors; 57 using cast_channel::LastErrors;
55 using cast_channel::Logger; 58 using cast_channel::Logger;
56 using cast_channel::MessageInfo; 59 using cast_channel::MessageInfo;
57 using cast_channel::ReadyState;
58 using content::BrowserThread; 60 using content::BrowserThread;
59 61
60 namespace { 62 namespace {
61 63
62 // T is an extension dictionary (MessageInfo or ChannelInfo) 64 // T is an extension dictionary (MessageInfo or ChannelInfo)
63 template <class T> 65 template <class T>
64 std::string ParamToString(const T& info) { 66 std::string ParamToString(const T& info) {
65 std::unique_ptr<base::DictionaryValue> dict = info.ToValue(); 67 std::unique_ptr<base::DictionaryValue> dict = info.ToValue();
66 std::string out; 68 std::string out;
67 base::JSONWriter::Write(*dict, &out); 69 base::JSONWriter::Write(*dict, &out);
68 return out; 70 return out;
69 } 71 }
70 72
71 // Fills |channel_info| from the destination and state of |socket|. 73 // Fills |channel_info| from the destination and state of |socket|.
72 void FillChannelInfo(const CastSocket& socket, ChannelInfo* channel_info) { 74 void FillChannelInfo(const CastSocket& socket, ChannelInfo* channel_info) {
73 DCHECK(channel_info); 75 DCHECK(channel_info);
74 channel_info->channel_id = socket.id(); 76 channel_info->channel_id = socket.id();
75 const net::IPEndPoint& ip_endpoint = socket.ip_endpoint(); 77 const net::IPEndPoint& ip_endpoint = socket.ip_endpoint();
76 channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort(); 78 channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort();
77 channel_info->connect_info.port = ip_endpoint.port(); 79 channel_info->connect_info.port = ip_endpoint.port();
78 channel_info->connect_info.auth = socket.channel_auth(); 80 channel_info->connect_info.auth =
79 channel_info->ready_state = socket.ready_state(); 81 cast_channel::ToChannelAuthType(socket.channel_auth());
80 channel_info->error_state = socket.error_state(); 82 channel_info->ready_state = cast_channel::ToReadyState(socket.ready_state());
83 channel_info->error_state =
84 cast_channel::ToChannelError(socket.error_state());
81 channel_info->keep_alive = socket.keep_alive(); 85 channel_info->keep_alive = socket.keep_alive();
82 channel_info->audio_only = socket.audio_only(); 86 channel_info->audio_only = socket.audio_only();
83 } 87 }
84 88
85 // Fills |error_info| from |error_state| and |last_errors|. 89 // Fills |error_info| from |error_state| and |last_errors|.
86 void FillErrorInfo(ChannelError error_state, 90 void FillErrorInfo(cast_channel::ChannelError error_state,
87 const LastErrors& last_errors, 91 const LastErrors& last_errors,
88 ErrorInfo* error_info) { 92 ErrorInfo* error_info) {
89 error_info->error_state = error_state; 93 error_info->error_state = error_state;
90 if (last_errors.event_type != cast_channel::proto::EVENT_TYPE_UNKNOWN) 94 if (last_errors.event_type != cast_channel::proto::EVENT_TYPE_UNKNOWN)
91 error_info->event_type.reset(new int(last_errors.event_type)); 95 error_info->event_type.reset(new int(last_errors.event_type));
92 if (last_errors.challenge_reply_error_type != 96 if (last_errors.challenge_reply_error_type !=
93 cast_channel::proto::CHALLENGE_REPLY_ERROR_NONE) { 97 cast_channel::proto::CHALLENGE_REPLY_ERROR_NONE) {
94 error_info->challenge_reply_error_type.reset( 98 error_info->challenge_reply_error_type.reset(
95 new int(last_errors.challenge_reply_error_type)); 99 new int(last_errors.challenge_reply_error_type));
96 } 100 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 206
203 void CastChannelAsyncApiFunction::RemoveSocket(int channel_id) { 207 void CastChannelAsyncApiFunction::RemoveSocket(int channel_id) {
204 auto* sockets = cast_socket_service_->GetOrCreateSocketRegistry(); 208 auto* sockets = cast_socket_service_->GetOrCreateSocketRegistry();
205 sockets->RemoveSocket(channel_id); 209 sockets->RemoveSocket(channel_id);
206 } 210 }
207 211
208 void CastChannelAsyncApiFunction::SetResultFromSocket( 212 void CastChannelAsyncApiFunction::SetResultFromSocket(
209 const CastSocket& socket) { 213 const CastSocket& socket) {
210 ChannelInfo channel_info; 214 ChannelInfo channel_info;
211 FillChannelInfo(socket, &channel_info); 215 FillChannelInfo(socket, &channel_info);
212 ChannelError error = socket.error_state(); 216 cast_channel::ChannelError error =
217 cast_channel::ToChannelError(socket.error_state());
213 if (error != cast_channel::CHANNEL_ERROR_NONE) { 218 if (error != cast_channel::CHANNEL_ERROR_NONE) {
214 SetError("Channel socket error = " + base::IntToString(error)); 219 SetError("Channel socket error = " + base::IntToString(error));
215 } 220 }
216 SetResultFromChannelInfo(channel_info); 221 SetResultFromChannelInfo(channel_info);
217 } 222 }
218 223
219 void CastChannelAsyncApiFunction::SetResultFromError(int channel_id, 224 void CastChannelAsyncApiFunction::SetResultFromError(
220 ChannelError error) { 225 int channel_id,
226 cast_channel::ChannelError error) {
221 ChannelInfo channel_info; 227 ChannelInfo channel_info;
222 channel_info.channel_id = channel_id; 228 channel_info.channel_id = channel_id;
223 channel_info.ready_state = cast_channel::READY_STATE_CLOSED; 229 channel_info.ready_state = cast_channel::READY_STATE_CLOSED;
224 channel_info.error_state = error; 230 channel_info.error_state = error;
225 channel_info.connect_info.ip_address = ""; 231 channel_info.connect_info.ip_address = "";
226 channel_info.connect_info.port = 0; 232 channel_info.connect_info.port = 0;
227 channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED; 233 channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED;
228 SetResultFromChannelInfo(channel_info); 234 SetResultFromChannelInfo(channel_info);
229 SetError("Channel error = " + base::IntToString(error)); 235 SetError("Channel error = " + base::IntToString(error));
230 } 236 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 SetError("livenessTimeout and pingInterval must be set together."); 293 SetError("livenessTimeout and pingInterval must be set together.");
288 } else if (liveness_timeout_ < ping_interval_) { 294 } else if (liveness_timeout_ < ping_interval_) {
289 SetError("livenessTimeout must be longer than pingTimeout."); 295 SetError("livenessTimeout must be longer than pingTimeout.");
290 } 296 }
291 } 297 }
292 298
293 if (!GetError().empty()) { 299 if (!GetError().empty()) {
294 return false; 300 return false;
295 } 301 }
296 302
297 channel_auth_ = connect_info.auth; 303 channel_auth_ = cast_channel::ToChannelAuthTypeInternal(connect_info.auth);
298 ip_endpoint_.reset(ParseConnectInfo(connect_info)); 304 ip_endpoint_.reset(ParseConnectInfo(connect_info));
299 return true; 305 return true;
300 } 306 }
301 307
302 void CastChannelOpenFunction::AsyncWorkStart() { 308 void CastChannelOpenFunction::AsyncWorkStart() {
303 DCHECK(api_); 309 DCHECK(api_);
304 DCHECK(ip_endpoint_.get()); 310 DCHECK(ip_endpoint_.get());
305 const ConnectInfo& connect_info = params_->connect_info; 311 const ConnectInfo& connect_info = params_->connect_info;
306 CastSocket* socket; 312 CastSocket* socket;
307 std::unique_ptr<CastSocket> test_socket = api_->GetSocketForTest(); 313 std::unique_ptr<CastSocket> test_socket = api_->GetSocketForTest();
308 if (test_socket.get()) { 314 if (test_socket.get()) {
309 socket = test_socket.release(); 315 socket = test_socket.release();
310 } else { 316 } else {
311 socket = new cast_channel::CastSocketImpl( 317 socket = new CastSocketImpl(
312 extension_->id(), *ip_endpoint_, channel_auth_, 318 extension_->id(), *ip_endpoint_, channel_auth_,
313 ExtensionsBrowserClient::Get()->GetNetLog(), 319 ExtensionsBrowserClient::Get()->GetNetLog(),
314 base::TimeDelta::FromMilliseconds(connect_info.timeout.get() 320 base::TimeDelta::FromMilliseconds(connect_info.timeout.get()
315 ? *connect_info.timeout 321 ? *connect_info.timeout
316 : kDefaultConnectTimeoutMillis), 322 : kDefaultConnectTimeoutMillis),
317 liveness_timeout_ > base::TimeDelta(), api_->GetLogger(), 323 liveness_timeout_ > base::TimeDelta(), api_->GetLogger(),
318 connect_info.capabilities.get() ? *connect_info.capabilities 324 connect_info.capabilities.get() ? *connect_info.capabilities
319 : CastDeviceCapability::NONE); 325 : CastDeviceCapability::NONE);
320 } 326 }
321 new_channel_id_ = AddSocket(base::WrapUnique(socket)); 327 new_channel_id_ = AddSocket(base::WrapUnique(socket));
322 328
323 // Construct read delegates. 329 // Construct read delegates.
324 std::unique_ptr<api::cast_channel::CastTransport::Delegate> delegate( 330 std::unique_ptr<CastTransport::Delegate> delegate(
325 base::MakeUnique<CastMessageHandler>( 331 base::MakeUnique<CastMessageHandler>(
326 base::Bind(&CastChannelAPI::SendEvent, api_->AsWeakPtr(), 332 base::Bind(&CastChannelAPI::SendEvent, api_->AsWeakPtr(),
327 extension_->id()), 333 extension_->id()),
328 socket, api_->GetLogger())); 334 socket, api_->GetLogger()));
329 if (socket->keep_alive()) { 335 if (socket->keep_alive()) {
330 // Wrap read delegate in a KeepAliveDelegate for timeout handling. 336 // Wrap read delegate in a KeepAliveDelegate for timeout handling.
331 api::cast_channel::KeepAliveDelegate* keep_alive = 337 KeepAliveDelegate* keep_alive =
332 new api::cast_channel::KeepAliveDelegate( 338 new KeepAliveDelegate(socket, api_->GetLogger(), std::move(delegate),
333 socket, api_->GetLogger(), std::move(delegate), ping_interval_, 339 ping_interval_, liveness_timeout_);
334 liveness_timeout_);
335 std::unique_ptr<base::Timer> injected_timer = 340 std::unique_ptr<base::Timer> injected_timer =
336 api_->GetInjectedTimeoutTimerForTest(); 341 api_->GetInjectedTimeoutTimerForTest();
337 if (injected_timer) { 342 if (injected_timer) {
338 keep_alive->SetTimersForTest(base::MakeUnique<base::Timer>(false, false), 343 keep_alive->SetTimersForTest(base::MakeUnique<base::Timer>(false, false),
339 std::move(injected_timer)); 344 std::move(injected_timer));
340 } 345 }
341 delegate.reset(keep_alive); 346 delegate.reset(keep_alive);
342 } 347 }
343 348
344 socket->Connect(std::move(delegate), 349 socket->Connect(std::move(delegate),
345 base::Bind(&CastChannelOpenFunction::OnOpen, this)); 350 base::Bind(&CastChannelOpenFunction::OnOpen, this));
346 } 351 }
347 352
348 void CastChannelOpenFunction::OnOpen(cast_channel::ChannelError result) { 353 void CastChannelOpenFunction::OnOpen(ChannelError result) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO); 354 DCHECK_CURRENTLY_ON(BrowserThread::IO);
350 VLOG(1) << "Connect finished, OnOpen invoked."; 355 VLOG(1) << "Connect finished, OnOpen invoked.";
351 // TODO: If we failed to open the CastSocket, we may want to clean up here, 356 // TODO: If we failed to open the CastSocket, we may want to clean up here,
352 // rather than relying on the extension to call close(). This can be done by 357 // rather than relying on the extension to call close(). This can be done by
353 // calling RemoveSocket() and api_->GetLogger()->ClearLastErrors(channel_id). 358 // calling RemoveSocket() and api_->GetLogger()->ClearLastErrors(channel_id).
354 if (result != cast_channel::CHANNEL_ERROR_UNKNOWN) { 359 if (result != ChannelError::UNKNOWN) {
355 CastSocket* socket = GetSocket(new_channel_id_); 360 CastSocket* socket = GetSocket(new_channel_id_);
356 CHECK(socket); 361 CHECK(socket);
357 SetResultFromSocket(*socket); 362 SetResultFromSocket(*socket);
358 } else { 363 } else {
359 // The socket is being destroyed. 364 // The socket is being destroyed.
360 SetResultFromError(new_channel_id_, result); 365 SetResultFromError(new_channel_id_, cast_channel::CHANNEL_ERROR_UNKNOWN);
361 } 366 }
362 367
363 AsyncWorkCompleted(); 368 AsyncWorkCompleted();
364 } 369 }
365 370
366 CastChannelSendFunction::CastChannelSendFunction() { } 371 CastChannelSendFunction::CastChannelSendFunction() { }
367 372
368 CastChannelSendFunction::~CastChannelSendFunction() { } 373 CastChannelSendFunction::~CastChannelSendFunction() { }
369 374
370 bool CastChannelSendFunction::Prepare() { 375 bool CastChannelSendFunction::Prepare() {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 SetResultFromSocket(*socket); 468 SetResultFromSocket(*socket);
464 // This will delete |socket|. 469 // This will delete |socket|.
465 RemoveSocket(channel_id); 470 RemoveSocket(channel_id);
466 api_->GetLogger()->ClearLastErrors(channel_id); 471 api_->GetLogger()->ClearLastErrors(channel_id);
467 } 472 }
468 AsyncWorkCompleted(); 473 AsyncWorkCompleted();
469 } 474 }
470 475
471 CastChannelOpenFunction::CastMessageHandler::CastMessageHandler( 476 CastChannelOpenFunction::CastMessageHandler::CastMessageHandler(
472 const EventDispatchCallback& ui_dispatch_cb, 477 const EventDispatchCallback& ui_dispatch_cb,
473 cast_channel::CastSocket* socket, 478 CastSocket* socket,
474 scoped_refptr<Logger> logger) 479 scoped_refptr<Logger> logger)
475 : ui_dispatch_cb_(ui_dispatch_cb), socket_(socket), logger_(logger) { 480 : ui_dispatch_cb_(ui_dispatch_cb), socket_(socket), logger_(logger) {
476 DCHECK(socket_); 481 DCHECK(socket_);
477 DCHECK(logger_); 482 DCHECK(logger_);
478 } 483 }
479 484
480 CastChannelOpenFunction::CastMessageHandler::~CastMessageHandler() { 485 CastChannelOpenFunction::CastMessageHandler::~CastMessageHandler() {
481 } 486 }
482 487
483 void CastChannelOpenFunction::CastMessageHandler::OnError( 488 void CastChannelOpenFunction::CastMessageHandler::OnError(
484 cast_channel::ChannelError error_state) { 489 ChannelError error_state) {
485 DCHECK_CURRENTLY_ON(BrowserThread::IO); 490 DCHECK_CURRENTLY_ON(BrowserThread::IO);
486 491
487 ChannelInfo channel_info; 492 ChannelInfo channel_info;
488 FillChannelInfo(*socket_, &channel_info); 493 FillChannelInfo(*socket_, &channel_info);
489 channel_info.error_state = error_state; 494 channel_info.error_state = cast_channel::ToChannelError(error_state);
490 ErrorInfo error_info; 495 ErrorInfo error_info;
491 FillErrorInfo(error_state, logger_->GetLastErrors(socket_->id()), 496 FillErrorInfo(channel_info.error_state, logger_->GetLastErrors(socket_->id()),
492 &error_info); 497 &error_info);
493 498
494 std::unique_ptr<base::ListValue> results = 499 std::unique_ptr<base::ListValue> results =
495 OnError::Create(channel_info, error_info); 500 OnError::Create(channel_info, error_info);
496 std::unique_ptr<Event> event(new Event( 501 std::unique_ptr<Event> event(new Event(
497 events::CAST_CHANNEL_ON_ERROR, OnError::kEventName, std::move(results))); 502 events::CAST_CHANNEL_ON_ERROR, OnError::kEventName, std::move(results)));
498 BrowserThread::PostTask( 503 BrowserThread::PostTask(
499 BrowserThread::UI, FROM_HERE, 504 BrowserThread::UI, FROM_HERE,
500 base::Bind(ui_dispatch_cb_, base::Passed(std::move(event)))); 505 base::Bind(ui_dispatch_cb_, base::Passed(std::move(event))));
501 } 506 }
502 507
503 void CastChannelOpenFunction::CastMessageHandler::OnMessage( 508 void CastChannelOpenFunction::CastMessageHandler::OnMessage(
504 const CastMessage& message) { 509 const CastMessage& message) {
505 DCHECK_CURRENTLY_ON(BrowserThread::IO); 510 DCHECK_CURRENTLY_ON(BrowserThread::IO);
506 511
507 MessageInfo message_info; 512 MessageInfo message_info;
508 cast_channel::CastMessageToMessageInfo(message, &message_info); 513 CastMessageToMessageInfo(message, &message_info);
509 ChannelInfo channel_info; 514 ChannelInfo channel_info;
510 FillChannelInfo(*socket_, &channel_info); 515 FillChannelInfo(*socket_, &channel_info);
511 VLOG(1) << "Received message " << ParamToString(message_info) 516 VLOG(1) << "Received message " << ParamToString(message_info)
512 << " on channel " << ParamToString(channel_info); 517 << " on channel " << ParamToString(channel_info);
513 518
514 std::unique_ptr<base::ListValue> results = 519 std::unique_ptr<base::ListValue> results =
515 OnMessage::Create(channel_info, message_info); 520 OnMessage::Create(channel_info, message_info);
516 std::unique_ptr<Event> event(new Event(events::CAST_CHANNEL_ON_MESSAGE, 521 std::unique_ptr<Event> event(new Event(events::CAST_CHANNEL_ON_MESSAGE,
517 OnMessage::kEventName, 522 OnMessage::kEventName,
518 std::move(results))); 523 std::move(results)));
519 BrowserThread::PostTask( 524 BrowserThread::PostTask(
520 BrowserThread::UI, FROM_HERE, 525 BrowserThread::UI, FROM_HERE,
521 base::Bind(ui_dispatch_cb_, base::Passed(std::move(event)))); 526 base::Bind(ui_dispatch_cb_, base::Passed(std::move(event))));
522 } 527 }
523 528
524 void CastChannelOpenFunction::CastMessageHandler::Start() { 529 void CastChannelOpenFunction::CastMessageHandler::Start() {
525 } 530 }
526 531
527 } // namespace extensions 532 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/cast_channel/cast_channel_api.h ('k') | extensions/browser/api/cast_channel/cast_channel_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698