Home | History | Annotate | Download | only in pepper
      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 
     16 namespace content {
     17 
     18 namespace {
     19 
     20 bool 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 
     34 scoped_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 
     42 PepperNetworkMonitorHost::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 
     63 PepperNetworkMonitorHost::~PepperNetworkMonitorHost() {
     64   net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
     65 }
     66 
     67 void PepperNetworkMonitorHost::OnIPAddressChanged() { GetAndSendNetworkList(); }
     68 
     69 void 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 
     81 void 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 
     93 void 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