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/net_address.h" 13 #include "ppapi/cpp/network_list.h" 14 #include "remoting/client/plugin/pepper_util.h" 15 #include "third_party/libjingle/source/talk/base/socketaddress.h" 16 17 namespace remoting { 18 19 PepperNetworkManager::PepperNetworkManager(const pp::InstanceHandle& instance) 20 : monitor_(instance), 21 start_count_(0), 22 network_list_received_(false), 23 callback_factory_(this), 24 weak_factory_(this) { 25 pp::CompletionCallbackWithOutput<pp::NetworkList> callback = 26 callback_factory_.NewCallbackWithOutput( 27 &PepperNetworkManager::OnNetworkList); 28 monitor_.UpdateNetworkList(callback); 29 } 30 31 PepperNetworkManager::~PepperNetworkManager() { 32 DCHECK(!start_count_); 33 } 34 35 void PepperNetworkManager::StartUpdating() { 36 if (network_list_received_) { 37 // Post a task to avoid reentrancy. 38 base::ThreadTaskRunnerHandle::Get()->PostTask( 39 FROM_HERE, base::Bind(&PepperNetworkManager::SendNetworksChangedSignal, 40 weak_factory_.GetWeakPtr())); 41 } 42 ++start_count_; 43 } 44 45 void PepperNetworkManager::StopUpdating() { 46 DCHECK_GT(start_count_, 0); 47 --start_count_; 48 } 49 50 void PepperNetworkManager::OnNetworkList(int32_t result, 51 const pp::NetworkList& list) { 52 if (result != PP_OK) { 53 SignalError(); 54 return; 55 } 56 DCHECK(!list.is_null()); 57 58 network_list_received_ = true; 59 60 // Request for the next update. 61 pp::CompletionCallbackWithOutput<pp::NetworkList> callback = 62 callback_factory_.NewCallbackWithOutput( 63 &PepperNetworkManager::OnNetworkList); 64 monitor_.UpdateNetworkList(callback); 65 66 // Convert the networks to talk_base::Network. 67 std::vector<talk_base::Network*> networks; 68 size_t count = list.GetCount(); 69 for (size_t i = 0; i < count; i++) { 70 std::vector<pp::NetAddress> addresses; 71 list.GetIpAddresses(i, &addresses); 72 73 if (addresses.size() == 0) 74 continue; 75 76 for (size_t i = 0; i < addresses.size(); ++i) { 77 talk_base::SocketAddress address; 78 PpNetAddressToSocketAddress(addresses[i], &address); 79 talk_base::Network* network = new talk_base::Network( 80 list.GetName(i), list.GetDisplayName(i), address.ipaddr(), 0); 81 network->AddIP(address.ipaddr()); 82 networks.push_back(network); 83 } 84 } 85 86 bool changed = false; 87 MergeNetworkList(networks, &changed); 88 if (changed) 89 SignalNetworksChanged(); 90 } 91 92 void PepperNetworkManager::SendNetworksChangedSignal() { 93 SignalNetworksChanged(); 94 } 95 96 } // namespace remoting 97