1// Copyright 2013 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 "content/browser/renderer_host/pepper/pepper_network_monitor_host.h" 6 7#include "base/task_runner_util.h" 8#include "base/threading/sequenced_worker_pool.h" 9#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 10#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 11#include "content/public/browser/browser_thread.h" 12#include "content/public/common/socket_permission_request.h" 13#include "ppapi/proxy/ppapi_messages.h" 14#include "ppapi/shared_impl/private/net_address_private_impl.h" 15 16namespace content { 17 18namespace { 19 20bool CanUseNetworkMonitor(bool external_plugin, 21 int render_process_id, 22 int render_frame_id) { 23 DCHECK_CURRENTLY_ON(BrowserThread::UI); 24 25 SocketPermissionRequest request = SocketPermissionRequest( 26 SocketPermissionRequest::NETWORK_STATE, std::string(), 0); 27 return pepper_socket_utils::CanUseSocketAPIs(external_plugin, 28 false /* private_api */, 29 &request, 30 render_process_id, 31 render_frame_id); 32} 33 34scoped_ptr<net::NetworkInterfaceList> GetNetworkList() { 35 scoped_ptr<net::NetworkInterfaceList> list(new net::NetworkInterfaceList()); 36 net::GetNetworkList(list.get(), net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); 37 return list.Pass(); 38} 39 40} // namespace 41 42PepperNetworkMonitorHost::PepperNetworkMonitorHost(BrowserPpapiHostImpl* host, 43 PP_Instance instance, 44 PP_Resource resource) 45 : ResourceHost(host->GetPpapiHost(), instance, resource), 46 weak_factory_(this) { 47 int render_process_id; 48 int render_frame_id; 49 host->GetRenderFrameIDsForInstance( 50 instance, &render_process_id, &render_frame_id); 51 52 BrowserThread::PostTaskAndReplyWithResult( 53 BrowserThread::UI, 54 FROM_HERE, 55 base::Bind(&CanUseNetworkMonitor, 56 host->external_plugin(), 57 render_process_id, 58 render_frame_id), 59 base::Bind(&PepperNetworkMonitorHost::OnPermissionCheckResult, 60 weak_factory_.GetWeakPtr())); 61} 62 63PepperNetworkMonitorHost::~PepperNetworkMonitorHost() { 64 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 65} 66 67void PepperNetworkMonitorHost::OnIPAddressChanged() { GetAndSendNetworkList(); } 68 69void PepperNetworkMonitorHost::OnPermissionCheckResult( 70 bool can_use_network_monitor) { 71 if (!can_use_network_monitor) { 72 host()->SendUnsolicitedReply(pp_resource(), 73 PpapiPluginMsg_NetworkMonitor_Forbidden()); 74 return; 75 } 76 77 net::NetworkChangeNotifier::AddIPAddressObserver(this); 78 GetAndSendNetworkList(); 79} 80 81void PepperNetworkMonitorHost::GetAndSendNetworkList() { 82 DCHECK_CURRENTLY_ON(BrowserThread::IO); 83 84 // Call GetNetworkList() on a thread that allows blocking IO. 85 base::PostTaskAndReplyWithResult( 86 BrowserThread::GetBlockingPool(), 87 FROM_HERE, 88 base::Bind(&GetNetworkList), 89 base::Bind(&PepperNetworkMonitorHost::SendNetworkList, 90 weak_factory_.GetWeakPtr())); 91} 92 93void PepperNetworkMonitorHost::SendNetworkList( 94 scoped_ptr<net::NetworkInterfaceList> list) { 95 DCHECK_CURRENTLY_ON(BrowserThread::IO); 96 97 scoped_ptr<ppapi::proxy::SerializedNetworkList> list_copy( 98 new ppapi::proxy::SerializedNetworkList(list->size())); 99 for (size_t i = 0; i < list->size(); ++i) { 100 const net::NetworkInterface& network = list->at(i); 101 ppapi::proxy::SerializedNetworkInfo& network_copy = list_copy->at(i); 102 network_copy.name = network.name; 103 104 network_copy.addresses.resize( 105 1, ppapi::NetAddressPrivateImpl::kInvalidNetAddress); 106 bool result = ppapi::NetAddressPrivateImpl::IPEndPointToNetAddress( 107 network.address, 0, &(network_copy.addresses[0])); 108 DCHECK(result); 109 110 // TODO(sergeyu): Currently net::NetworkInterfaceList provides 111 // only name and one IP address. Add all other fields and copy 112 // them here. 113 network_copy.type = PP_NETWORKLIST_TYPE_UNKNOWN; 114 network_copy.state = PP_NETWORKLIST_STATE_UP; 115 network_copy.display_name = network.name; 116 network_copy.mtu = 0; 117 } 118 host()->SendUnsolicitedReply( 119 pp_resource(), PpapiPluginMsg_NetworkMonitor_NetworkList(*list_copy)); 120} 121 122} // namespace content 123