cast_channel_api.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/api/cast_channel/cast_channel_api.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <limits> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string> 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/json/json_writer.h" 110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/string_number_conversions.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/api/cast_channel/cast_socket.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/base/ip_endpoint.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/net_errors.h" 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/base/net_util.h" 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "url/gurl.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Default timeout interval for connection setup. 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Used if not otherwise specified at ConnectInfo::timeout. 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kDefaultConnectTimeoutMillis = 5000; // 5 seconds. 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace extensions { 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace Close = cast_channel::Close; 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace OnError = cast_channel::OnError; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace OnMessage = cast_channel::OnMessage; 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace Open = cast_channel::Open; 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace Send = cast_channel::Send; 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using cast_channel::CastSocket; 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochusing cast_channel::ChannelAuthType; 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using cast_channel::ChannelError; 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using cast_channel::ChannelInfo; 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochusing cast_channel::ConnectInfo; 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using cast_channel::MessageInfo; 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using cast_channel::ReadyState; 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::BrowserThread; 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// T is an extension dictionary (MessageInfo or ChannelInfo) 458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <class T> 468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string ParamToString(const T& info) { 478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<base::DictionaryValue> dict = info.ToValue(); 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string out; 498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::JSONWriter::Write(dict.get(), &out); 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return out; 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Fills |channel_info| from the destination and state of |socket|. 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid FillChannelInfo(const CastSocket& socket, ChannelInfo* channel_info) { 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(channel_info); 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->channel_id = socket.id(); 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->url = socket.CastUrl(); 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const net::IPEndPoint& ip_endpoint = socket.ip_endpoint(); 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort(); 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->connect_info.port = ip_endpoint.port(); 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->connect_info.auth = socket.channel_auth(); 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->ready_state = socket.ready_state(); 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch channel_info->error_state = socket.error_state(); 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool IsValidConnectInfoPort(const ConnectInfo& connect_info) { 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return connect_info.port > 0 && connect_info.port < 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::numeric_limits<uint16_t>::max(); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool IsValidConnectInfoAuth(const ConnectInfo& connect_info) { 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return connect_info.auth == cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED || 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) connect_info.auth == cast_channel::CHANNEL_AUTH_TYPE_SSL; 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool IsValidConnectInfoIpAddress(const ConnectInfo& connect_info) { 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::IPAddressNumber ip_address; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return net::ParseIPLiteralToNumber(connect_info.ip_address, &ip_address); 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CastChannelAPI::CastChannelAPI(content::BrowserContext* context) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : browser_context_(context) { 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(browser_context_); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CastChannelAPI* CastChannelAPI::Get(content::BrowserContext* context) { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BrowserContextKeyedAPIFactory<CastChannelAPI>::Get(context); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<CastChannelAPI> > 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<CastChannelAPI>* 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CastChannelAPI::GetFactoryInstance() { 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_factory.Pointer(); 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)scoped_ptr<CastSocket> CastChannelAPI::CreateCastSocket( 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& extension_id, const net::IPEndPoint& ip_endpoint, 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ChannelAuthType channel_auth, const base::TimeDelta& timeout) { 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (socket_for_test_.get()) { 1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return socket_for_test_.Pass(); 1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } else { 1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return scoped_ptr<CastSocket>( 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new CastSocket(extension_id, ip_endpoint, channel_auth, this, 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionsBrowserClient::Get()->GetNetLog(), 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) timeout)); 1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void CastChannelAPI::SetSocketForTest(scoped_ptr<CastSocket> socket_for_test) { 1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) socket_for_test_ = socket_for_test.Pass(); 1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelAPI::OnError(const CastSocket* socket, 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cast_channel::ChannelError error) { 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChannelInfo channel_info; 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FillChannelInfo(*socket, &channel_info); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) channel_info.error_state = error; 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::ListValue> results = OnError::Create(channel_info); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<Event> event(new Event(OnError::kEventName, results.Pass())); 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extensions::EventRouter::Get(browser_context_) 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ->DispatchEventToExtension(socket->owner_extension_id(), event.Pass()); 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelAPI::OnMessage(const CastSocket* socket, 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const MessageInfo& message_info) { 133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChannelInfo channel_info; 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FillChannelInfo(*socket, &channel_info); 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::ListValue> results = 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnMessage::Create(channel_info, message_info); 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(1) << "Sending message " << ParamToString(message_info) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " to channel " << ParamToString(channel_info); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<Event> event(new Event(OnMessage::kEventName, results.Pass())); 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extensions::EventRouter::Get(browser_context_) 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ->DispatchEventToExtension(socket->owner_extension_id(), event.Pass()); 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelAPI::~CastChannelAPI() {} 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelAsyncApiFunction::CastChannelAsyncApiFunction() 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : manager_(NULL), error_(cast_channel::CHANNEL_ERROR_NONE) { } 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelAsyncApiFunction::~CastChannelAsyncApiFunction() { } 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CastChannelAsyncApiFunction::PrePrepare() { 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_ = ApiResourceManager<CastSocket>::Get(browser_context()); 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CastChannelAsyncApiFunction::Respond() { 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return error_ != cast_channel::CHANNEL_ERROR_NONE; 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)CastSocket* CastChannelAsyncApiFunction::GetSocketOrCompleteWithError( 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int channel_id) { 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CastSocket* socket = GetSocket(channel_id); 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!socket) { 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromError(channel_id, 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID); 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AsyncWorkCompleted(); 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return socket; 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int CastChannelAsyncApiFunction::AddSocket(CastSocket* socket) { 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(socket); 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(manager_); 1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const int id = manager_->Add(socket); 1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) socket->set_id(id); 1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return id; 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void CastChannelAsyncApiFunction::RemoveSocket(int channel_id) { 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(manager_); 1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) manager_->Remove(extension_->id(), channel_id); 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CastChannelAsyncApiFunction::SetResultFromSocket( 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CastSocket& socket) { 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChannelInfo channel_info; 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FillChannelInfo(socket, &channel_info); 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error_ = socket.error_state(); 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetResultFromChannelInfo(channel_info); 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CastChannelAsyncApiFunction::SetResultFromError(int channel_id, 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ChannelError error) { 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChannelInfo channel_info; 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_info.channel_id = channel_id; 1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) channel_info.url = ""; 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) channel_info.ready_state = cast_channel::READY_STATE_CLOSED; 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) channel_info.error_state = error; 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_info.connect_info.ip_address = ""; 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_info.connect_info.port = 0; 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL; 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetResultFromChannelInfo(channel_info); 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error_ = error; 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)CastSocket* CastChannelAsyncApiFunction::GetSocket(int channel_id) { 210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(manager_); 2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return manager_->Get(extension_->id(), channel_id); 2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void CastChannelAsyncApiFunction::SetResultFromChannelInfo( 2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ChannelInfo& channel_info) { 217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SetResult(channel_info.ToValue().release()); 2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)CastChannelOpenFunction::CastChannelOpenFunction() 2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : new_channel_id_(0) { } 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelOpenFunction::~CastChannelOpenFunction() { } 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// TODO(mfoltz): Remove URL parsing when clients have converted to use 2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// ConnectInfo. 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Allowed schemes for Cast device URLs. 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char kCastInsecureScheme[] = "cast"; 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char kCastSecureScheme[] = "casts"; 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool CastChannelOpenFunction::ParseChannelUrl(const GURL& url, 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ConnectInfo* connect_info) { 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(connect_info); 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(2) << "ParseChannelUrl"; 2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool auth_required = false; 2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (url.SchemeIs(kCastSecureScheme)) { 2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch auth_required = true; 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else if (!url.SchemeIs(kCastInsecureScheme)) { 2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? 2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 2450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // link-local networks 2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& path = url.path(); 2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Shortest possible: //A:B 2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (path.size() < 5) { 2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (path.find("//") != 0) { 2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch size_t colon = path.find_last_of(':'); 2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (colon == std::string::npos || colon < 3 || colon > path.size() - 2) { 2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& ip_address_str = path.substr(2, colon - 2); 2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& port_str = path.substr(colon + 1); 2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(2) << "IP: " << ip_address_str << " Port: " << port_str; 2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int port; 2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!base::StringToInt(port_str, &port)) 2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connect_info->ip_address = ip_address_str; 2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connect_info->port = port; 2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connect_info->auth = auth_required ? 2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED : 2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cast_channel::CHANNEL_AUTH_TYPE_SSL; 2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return true; 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnet::IPEndPoint* CastChannelOpenFunction::ParseConnectInfo( 2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const ConnectInfo& connect_info) { 2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch net::IPAddressNumber ip_address; 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CHECK(net::ParseIPLiteralToNumber(connect_info.ip_address, &ip_address)); 2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return new net::IPEndPoint(ip_address, connect_info.port); 2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CastChannelOpenFunction::PrePrepare() { 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) api_ = CastChannelAPI::Get(browser_context()); 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return CastChannelAsyncApiFunction::PrePrepare(); 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CastChannelOpenFunction::Prepare() { 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) params_ = Open::Params::Create(*args_); 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params_.get()); 2870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The connect_info parameter may be a string URL like cast:// or casts:// or 2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // a ConnectInfo object. 2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string cast_url; 2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch switch (params_->connect_info->GetType()) { 2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case base::Value::TYPE_STRING: 2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(params_->connect_info->GetAsString(&cast_url)); 2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connect_info_.reset(new ConnectInfo); 2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!ParseChannelUrl(GURL(cast_url), connect_info_.get())) { 2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connect_info_.reset(); 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("Invalid connect_info (invalid Cast URL " + cast_url + ")"); 2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case base::Value::TYPE_DICTIONARY: 3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connect_info_ = ConnectInfo::FromValue(*(params_->connect_info)); 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!connect_info_.get()) { 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("connect_info.auth is required"); 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch default: 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("Invalid connect_info (unknown type)"); 3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!connect_info_.get()) { 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!IsValidConnectInfoPort(*connect_info_)) { 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("Invalid connect_info (invalid port)"); 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (!IsValidConnectInfoAuth(*connect_info_)) { 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("Invalid connect_info (invalid auth)"); 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (!IsValidConnectInfoIpAddress(*connect_info_)) { 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("Invalid connect_info (invalid IP address)"); 3180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!GetError().empty()) { 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_auth_ = connect_info_->auth; 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ip_endpoint_.reset(ParseConnectInfo(*connect_info_)); 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelOpenFunction::AsyncWorkStart() { 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(api_); 3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(ip_endpoint_.get()); 3300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<CastSocket> socket = api_->CreateCastSocket( 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_->id(), 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ip_endpoint_, 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_auth_, 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeDelta::FromMilliseconds(connect_info_->timeout.get() 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ? *connect_info_->timeout 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : kDefaultConnectTimeoutMillis)); 3370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) new_channel_id_ = AddSocket(socket.release()); 3380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) GetSocket(new_channel_id_)->Connect( 3390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&CastChannelOpenFunction::OnOpen, this)); 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelOpenFunction::OnOpen(int result) { 343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) VLOG(1) << "Connect finished, OnOpen invoked."; 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CastSocket* socket = GetSocket(new_channel_id_); 3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!socket) { 3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromError(new_channel_id_, 3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cast_channel::CHANNEL_ERROR_CONNECT_ERROR); 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromSocket(*socket); 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AsyncWorkCompleted(); 3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelSendFunction::CastChannelSendFunction() { } 3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelSendFunction::~CastChannelSendFunction() { } 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CastChannelSendFunction::Prepare() { 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) params_ = Send::Params::Create(*args_); 3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params_.get()); 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (params_->message.namespace_.empty()) { 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("message_info.namespace_ is required"); 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (params_->message.source_id.empty()) { 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("message_info.source_id is required"); 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (params_->message.destination_id.empty()) { 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("message_info.destination_id is required"); 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (params_->message.data->GetType()) { 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case base::Value::TYPE_STRING: 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case base::Value::TYPE_BINARY: 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetError("Invalid type of message_info.data"); 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelSendFunction::AsyncWorkStart() { 3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CastSocket* socket = GetSocketOrCompleteWithError( 3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) params_->channel.channel_id); 3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (socket) 3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) socket->SendMessage(params_->message, 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&CastChannelSendFunction::OnSend, this)); 3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelSendFunction::OnSend(int result) { 394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int channel_id = params_->channel.channel_id; 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CastSocket* socket = GetSocket(channel_id); 3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (result < 0 || !socket) { 3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromError(channel_id, 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cast_channel::CHANNEL_ERROR_SOCKET_ERROR); 4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromSocket(*socket); 4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AsyncWorkCompleted(); 4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelCloseFunction::CastChannelCloseFunction() { } 4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CastChannelCloseFunction::~CastChannelCloseFunction() { } 4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CastChannelCloseFunction::Prepare() { 4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) params_ = Close::Params::Create(*args_); 4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params_.get()); 4134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelCloseFunction::AsyncWorkStart() { 4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CastSocket* socket = GetSocketOrCompleteWithError( 4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) params_->channel.channel_id); 4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (socket) 4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) socket->Close(base::Bind(&CastChannelCloseFunction::OnClose, this)); 4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CastChannelCloseFunction::OnClose(int result) { 424effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(1) << "CastChannelCloseFunction::OnClose result = " << result; 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int channel_id = params_->channel.channel_id; 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CastSocket* socket = GetSocket(channel_id); 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (result < 0 || !socket) { 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromError(channel_id, 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cast_channel::CHANNEL_ERROR_SOCKET_ERROR); 4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResultFromSocket(*socket); 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // This will delete |socket|. 4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) RemoveSocket(channel_id); 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) socket = NULL; 4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AsyncWorkCompleted(); 4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace extensions 441