15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/client/plugin/pepper_network_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/cpp/net_address.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ppapi/cpp/network_list.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "remoting/client/plugin/pepper_util.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/webrtc/base/socketaddress.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PepperNetworkManager::PepperNetworkManager(const pp::InstanceHandle& instance)
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : monitor_(instance),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      start_count_(0),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_list_received_(false),
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      callback_factory_(this),
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pp::CompletionCallbackWithOutput<pp::NetworkList> callback =
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      callback_factory_.NewCallbackWithOutput(
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &PepperNetworkManager::OnNetworkList);
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  monitor_.UpdateNetworkList(callback);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PepperNetworkManager::~PepperNetworkManager() {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!start_count_);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PepperNetworkManager::StartUpdating() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_list_received_) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Post a task to avoid reentrancy.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ThreadTaskRunnerHandle::Get()->PostTask(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&PepperNetworkManager::SendNetworksChangedSignal,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              weak_factory_.GetWeakPtr()));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++start_count_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PepperNetworkManager::StopUpdating() {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(start_count_, 0);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --start_count_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperNetworkManager::OnNetworkList(int32_t result,
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         const pp::NetworkList& list) {
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (result != PP_OK) {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SignalError();
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!list.is_null());
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  network_list_received_ = true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Request for the next update.
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pp::CompletionCallbackWithOutput<pp::NetworkList> callback =
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      callback_factory_.NewCallbackWithOutput(
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &PepperNetworkManager::OnNetworkList);
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  monitor_.UpdateNetworkList(callback);
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Convert the networks to rtc::Network.
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<rtc::Network*> networks;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = list.GetCount();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < count; i++) {
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::vector<pp::NetAddress> addresses;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.GetIpAddresses(i, &addresses);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (addresses.size() == 0)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (size_t i = 0; i < addresses.size(); ++i) {
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      rtc::SocketAddress address;
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      PpNetAddressToSocketAddress(addresses[i], &address);
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (address.family() == AF_INET6 && IPIsSiteLocal(address.ipaddr())) {
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // Link-local IPv6 addresses can't be bound via the current PPAPI
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // Bind() interface as designed (see crbug.com/384854); trying to do so
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // would fail.
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        continue;
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      rtc::Network* network = new rtc::Network(
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          list.GetName(i), list.GetDisplayName(i), address.ipaddr(), 0);
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      network->AddIP(address.ipaddr());
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      networks.push_back(network);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool changed = false;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MergeNetworkList(networks, &changed);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (changed)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SignalNetworksChanged();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PepperNetworkManager::SendNetworksChangedSignal() {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SignalNetworksChanged();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
105