pepper_network_manager.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright (c) 2012 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 "remoting/client/plugin/pepper_network_manager.h" 6 7#include "base/bind.h" 8#include "base/location.h" 9#include "base/single_thread_task_runner.h" 10#include "base/thread_task_runner_handle.h" 11#include "ppapi/cpp/module.h" 12#include "ppapi/cpp/private/network_list_private.h" 13#include "ppapi/cpp/private/net_address_private.h" 14 15namespace remoting { 16 17PepperNetworkManager::PepperNetworkManager(const pp::InstanceHandle& instance) 18 : monitor_(instance, &PepperNetworkManager::OnNetworkListCallbackHandler, 19 this), 20 start_count_(0), 21 network_list_received_(false), 22 weak_factory_(this) { 23} 24 25PepperNetworkManager::~PepperNetworkManager() { 26 DCHECK(!start_count_); 27} 28 29void PepperNetworkManager::StartUpdating() { 30 if (network_list_received_) { 31 // Post a task to avoid reentrancy. 32 base::ThreadTaskRunnerHandle::Get()->PostTask( 33 FROM_HERE, base::Bind(&PepperNetworkManager::SendNetworksChangedSignal, 34 weak_factory_.GetWeakPtr())); 35 } 36 ++start_count_; 37} 38 39void PepperNetworkManager::StopUpdating() { 40 DCHECK_GT(start_count_, 0); 41 --start_count_; 42} 43 44// static 45void PepperNetworkManager::OnNetworkListCallbackHandler( 46 void* user_data, 47 PP_Resource list_resource) { 48 PepperNetworkManager* object = static_cast<PepperNetworkManager*>(user_data); 49 pp::NetworkListPrivate list(pp::PASS_REF, list_resource); 50 object->OnNetworkList(list); 51} 52 53void PepperNetworkManager::OnNetworkList(const pp::NetworkListPrivate& list) { 54 network_list_received_ = true; 55 56 std::vector<talk_base::Network*> networks; 57 size_t count = list.GetCount(); 58 for (size_t i = 0; i < count; i++) { 59 std::vector<PP_NetAddress_Private> addresses; 60 list.GetIpAddresses(i, &addresses); 61 62 if (addresses.size() == 0) 63 continue; 64 65 char address_bytes[sizeof(in6_addr)]; 66 if (!pp::NetAddressPrivate::GetAddress( 67 addresses[0], &address_bytes, sizeof(address_bytes))) { 68 LOG(ERROR) << "Failed to get address for network interface."; 69 continue; 70 } 71 72 int prefix_length; 73 74 // TODO(sergeyu): Copy all addresses, not only the first one. 75 talk_base::IPAddress address; 76 switch (pp::NetAddressPrivate::GetFamily(addresses[0])) { 77 case PP_NETADDRESSFAMILY_IPV4: { 78 in_addr* address_ipv4 = reinterpret_cast<in_addr*>(address_bytes); 79 address = talk_base::IPAddress(*address_ipv4); 80 prefix_length = sizeof(in_addr) * 8; 81 break; 82 } 83 84 case PP_NETADDRESSFAMILY_IPV6: { 85 in6_addr* address_ipv6 = reinterpret_cast<in6_addr*>(address_bytes); 86 address = talk_base::IPAddress(*address_ipv6); 87 prefix_length = sizeof(in6_addr) * 8; 88 break; 89 } 90 91 default: 92 LOG(WARNING) << "Skipping address with unknown family: " 93 << pp::NetAddressPrivate::GetFamily(addresses[0]); 94 continue; 95 } 96 97 talk_base::Network* network = new talk_base::Network( 98 list.GetName(i), list.GetDisplayName(i), address, prefix_length); 99 network->AddIP(address); 100 networks.push_back(network); 101 } 102 103 bool changed = false; 104 MergeNetworkList(networks, &changed); 105 if (changed) 106 SignalNetworksChanged(); 107} 108 109void PepperNetworkManager::SendNetworksChangedSignal() { 110 SignalNetworksChanged(); 111} 112 113} // namespace remoting 114