pepper_network_manager.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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/private/network_list_private.h"
14#include "remoting/client/plugin/pepper_util.h"
15#include "third_party/libjingle/source/talk/base/socketaddress.h"
16
17namespace remoting {
18
19PepperNetworkManager::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::NetworkListPrivate> callback =
26      callback_factory_.NewCallbackWithOutput(
27          &PepperNetworkManager::OnNetworkList);
28  monitor_.UpdateNetworkList(callback);
29}
30
31PepperNetworkManager::~PepperNetworkManager() {
32  DCHECK(!start_count_);
33}
34
35void 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
45void PepperNetworkManager::StopUpdating() {
46  DCHECK_GT(start_count_, 0);
47  --start_count_;
48}
49
50
51void PepperNetworkManager::OnNetworkList(int32_t result,
52                                         const pp::NetworkListPrivate& list) {
53  if (result != PP_OK) {
54    SignalError();
55    return;
56  }
57  DCHECK(!list.is_null());
58
59  network_list_received_ = true;
60
61  // Request for the next update.
62  pp::CompletionCallbackWithOutput<pp::NetworkListPrivate> callback =
63      callback_factory_.NewCallbackWithOutput(
64          &PepperNetworkManager::OnNetworkList);
65  monitor_.UpdateNetworkList(callback);
66
67  // Convert the networks to talk_base::Network.
68  std::vector<talk_base::Network*> networks;
69  size_t count = list.GetCount();
70  for (size_t i = 0; i < count; i++) {
71    std::vector<pp::NetAddress> addresses;
72    list.GetIpAddresses(i, &addresses);
73
74    if (addresses.size() == 0)
75      continue;
76
77    for (size_t i = 0; i < addresses.size(); ++i) {
78      talk_base::SocketAddress address;
79      PpNetAddressToSocketAddress(addresses[i], &address);
80      talk_base::Network* network = new talk_base::Network(
81          list.GetName(i), list.GetDisplayName(i), address.ipaddr(), 0);
82      network->AddIP(address.ipaddr());
83      networks.push_back(network);
84    }
85  }
86
87  bool changed = false;
88  MergeNetworkList(networks, &changed);
89  if (changed)
90    SignalNetworksChanged();
91}
92
93void PepperNetworkManager::SendNetworksChangedSignal() {
94  SignalNetworksChanged();
95}
96
97}  // namespace remoting
98