1 // Copyright 2014 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 "chrome/browser/metrics/network_metrics_provider.h" 6 7 #include "base/compiler_specific.h" 8 #include "base/task_runner_util.h" 9 #include "base/threading/sequenced_worker_pool.h" 10 #include "content/public/browser/browser_thread.h" 11 12 using metrics::SystemProfileProto; 13 14 NetworkMetricsProvider::NetworkMetricsProvider() 15 : connection_type_is_ambiguous_(false), 16 wifi_phy_layer_protocol_is_ambiguous_(false), 17 wifi_phy_layer_protocol_(net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN), 18 weak_ptr_factory_(this) { 19 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 20 connection_type_ = net::NetworkChangeNotifier::GetConnectionType(); 21 ProbeWifiPHYLayerProtocol(); 22 } 23 24 NetworkMetricsProvider::~NetworkMetricsProvider() { 25 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 26 } 27 28 void NetworkMetricsProvider::ProvideSystemProfileMetrics( 29 SystemProfileProto* system_profile) { 30 SystemProfileProto::Network* network = system_profile->mutable_network(); 31 network->set_connection_type_is_ambiguous(connection_type_is_ambiguous_); 32 network->set_connection_type(GetConnectionType()); 33 network->set_wifi_phy_layer_protocol_is_ambiguous( 34 wifi_phy_layer_protocol_is_ambiguous_); 35 network->set_wifi_phy_layer_protocol(GetWifiPHYLayerProtocol()); 36 37 // Resets the "ambiguous" flags, since a new metrics log session has started. 38 connection_type_is_ambiguous_ = false; 39 // TODO(isherman): This line seems unnecessary. 40 connection_type_ = net::NetworkChangeNotifier::GetConnectionType(); 41 wifi_phy_layer_protocol_is_ambiguous_ = false; 42 } 43 44 void NetworkMetricsProvider::OnConnectionTypeChanged( 45 net::NetworkChangeNotifier::ConnectionType type) { 46 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) 47 return; 48 if (type != connection_type_ && 49 connection_type_ != net::NetworkChangeNotifier::CONNECTION_NONE) { 50 connection_type_is_ambiguous_ = true; 51 } 52 connection_type_ = type; 53 54 ProbeWifiPHYLayerProtocol(); 55 } 56 57 SystemProfileProto::Network::ConnectionType 58 NetworkMetricsProvider::GetConnectionType() const { 59 switch (connection_type_) { 60 case net::NetworkChangeNotifier::CONNECTION_NONE: 61 case net::NetworkChangeNotifier::CONNECTION_UNKNOWN: 62 return SystemProfileProto::Network::CONNECTION_UNKNOWN; 63 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: 64 return SystemProfileProto::Network::CONNECTION_ETHERNET; 65 case net::NetworkChangeNotifier::CONNECTION_WIFI: 66 return SystemProfileProto::Network::CONNECTION_WIFI; 67 case net::NetworkChangeNotifier::CONNECTION_2G: 68 return SystemProfileProto::Network::CONNECTION_2G; 69 case net::NetworkChangeNotifier::CONNECTION_3G: 70 return SystemProfileProto::Network::CONNECTION_3G; 71 case net::NetworkChangeNotifier::CONNECTION_4G: 72 return SystemProfileProto::Network::CONNECTION_4G; 73 case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: 74 return SystemProfileProto::Network::CONNECTION_BLUETOOTH; 75 } 76 NOTREACHED(); 77 return SystemProfileProto::Network::CONNECTION_UNKNOWN; 78 } 79 80 SystemProfileProto::Network::WifiPHYLayerProtocol 81 NetworkMetricsProvider::GetWifiPHYLayerProtocol() const { 82 switch (wifi_phy_layer_protocol_) { 83 case net::WIFI_PHY_LAYER_PROTOCOL_NONE: 84 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_NONE; 85 case net::WIFI_PHY_LAYER_PROTOCOL_ANCIENT: 86 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_ANCIENT; 87 case net::WIFI_PHY_LAYER_PROTOCOL_A: 88 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_A; 89 case net::WIFI_PHY_LAYER_PROTOCOL_B: 90 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_B; 91 case net::WIFI_PHY_LAYER_PROTOCOL_G: 92 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_G; 93 case net::WIFI_PHY_LAYER_PROTOCOL_N: 94 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_N; 95 case net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN: 96 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; 97 } 98 NOTREACHED(); 99 return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; 100 } 101 102 void NetworkMetricsProvider::ProbeWifiPHYLayerProtocol() { 103 PostTaskAndReplyWithResult( 104 content::BrowserThread::GetBlockingPool(), 105 FROM_HERE, 106 base::Bind(&net::GetWifiPHYLayerProtocol), 107 base::Bind(&NetworkMetricsProvider::OnWifiPHYLayerProtocolResult, 108 weak_ptr_factory_.GetWeakPtr())); 109 } 110 111 void NetworkMetricsProvider::OnWifiPHYLayerProtocolResult( 112 net::WifiPHYLayerProtocol mode) { 113 if (wifi_phy_layer_protocol_ != net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN && 114 mode != wifi_phy_layer_protocol_) { 115 wifi_phy_layer_protocol_is_ambiguous_ = true; 116 } 117 wifi_phy_layer_protocol_ = mode; 118 } 119