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