1// Copyright 2013 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 <stdio.h> 6#include <string.h> 7#include <sstream> 8 9#include "ppapi/cpp/instance.h" 10#include "ppapi/cpp/module.h" 11#include "ppapi/cpp/net_address.h" 12#include "ppapi/cpp/network_list.h" 13#include "ppapi/cpp/network_monitor.h" 14#include "ppapi/cpp/var.h" 15#include "ppapi/cpp/var_array.h" 16#include "ppapi/cpp/var_dictionary.h" 17#include "ppapi/utility/completion_callback_factory.h" 18 19#ifdef WIN32 20#undef PostMessage 21// Allow 'this' in initializer list 22#pragma warning(disable : 4355) 23#endif 24 25class NetworkMonitorInstance : public pp::Instance { 26 public: 27 explicit NetworkMonitorInstance(PP_Instance instance) 28 : pp::Instance(instance), 29 callback_factory_(this), 30 network_monitor_(this) {} 31 32 virtual ~NetworkMonitorInstance() {} 33 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); 34 35 private: 36 virtual void OnUpdateNetworkList(int32_t result, 37 pp::NetworkList network_list); 38 static std::string GetNetworkStateAsString(PP_NetworkList_State state); 39 static std::string GetNetworkTypeAsString(PP_NetworkList_Type type); 40 static std::string GetNetAddressAsString(pp::NetAddress address); 41 42 pp::CompletionCallbackFactory<NetworkMonitorInstance> callback_factory_; 43 pp::NetworkMonitor network_monitor_; 44}; 45 46bool NetworkMonitorInstance::Init(uint32_t argc, 47 const char* argn[], 48 const char* argv[]) { 49 // Start listing for network updates. 50 int32_t result = network_monitor_.UpdateNetworkList( 51 callback_factory_.NewCallbackWithOutput( 52 &NetworkMonitorInstance::OnUpdateNetworkList)); 53 if (result != PP_OK_COMPLETIONPENDING) { 54 std::ostringstream status; 55 status << "UpdateNetworkList failed: " << result; 56 PostMessage(status.str()); 57 } 58 59 return true; 60} 61 62void NetworkMonitorInstance::OnUpdateNetworkList(int32_t result, 63 pp::NetworkList network_list) { 64 // Send the new network list to JavaScript. 65 if (result < 0) { 66 std::ostringstream status; 67 status << "UpdateNetworkList failed: " << result; 68 PostMessage(status.str()); 69 return; 70 } 71 72 pp::VarArray var_network_list; 73 uint32_t count = network_list.GetCount(); 74 for (uint32_t i = 0; i < count; ++i) { 75 pp::VarDictionary var_network; 76 var_network.Set("displayName", network_list.GetDisplayName(i)); 77 var_network.Set("name", network_list.GetName(i)); 78 var_network.Set("state", GetNetworkStateAsString(network_list.GetState(i))); 79 var_network.Set("type", GetNetworkTypeAsString(network_list.GetType(i))); 80 var_network.Set("MTU", static_cast<int32_t>(network_list.GetMTU(i))); 81 82 pp::VarArray var_ip_addresses; 83 std::vector<pp::NetAddress> ip_addresses; 84 result = network_list.GetIpAddresses(i, &ip_addresses); 85 if (result == PP_OK) { 86 for (size_t i = 0; i < ip_addresses.size(); ++i) { 87 var_ip_addresses.Set(i, GetNetAddressAsString(ip_addresses[i])); 88 } 89 } else { 90 // Call to GetIpAddresses failed, just give an empty list. 91 } 92 93 var_network.Set("ipAddresses", var_ip_addresses); 94 var_network_list.Set(i, var_network); 95 } 96 97 PostMessage(var_network_list); 98} 99 100// static 101std::string NetworkMonitorInstance::GetNetworkStateAsString( 102 PP_NetworkList_State state) { 103 switch (state) { 104 case PP_NETWORKLIST_STATE_UP: 105 return "up"; 106 107 case PP_NETWORKLIST_STATE_DOWN: 108 return "down"; 109 110 default: 111 return "invalid"; 112 } 113} 114 115// static 116std::string NetworkMonitorInstance::GetNetworkTypeAsString( 117 PP_NetworkList_Type type) { 118 switch (type) { 119 case PP_NETWORKLIST_TYPE_ETHERNET: 120 return "ethernet"; 121 122 case PP_NETWORKLIST_TYPE_WIFI: 123 return "wifi"; 124 125 case PP_NETWORKLIST_TYPE_CELLULAR: 126 return "cellular"; 127 128 case PP_NETWORKLIST_TYPE_UNKNOWN: 129 return "unknown"; 130 131 default: 132 return "invalid"; 133 } 134} 135 136// static 137std::string NetworkMonitorInstance::GetNetAddressAsString( 138 pp::NetAddress address) { 139 bool include_port = true; 140 return address.DescribeAsString(include_port).AsString(); 141} 142 143class NetworkMonitorModule : public pp::Module { 144 public: 145 NetworkMonitorModule() : pp::Module() {} 146 virtual ~NetworkMonitorModule() {} 147 148 virtual pp::Instance* CreateInstance(PP_Instance instance) { 149 return new NetworkMonitorInstance(instance); 150 } 151}; 152 153namespace pp { 154Module* CreateModule() { return new NetworkMonitorModule(); } 155} // namespace pp 156