blob: b339d4b93adcddd000756500e58073e19f3c359a [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/metrics/network_metrics_provider.h"
#include "base/compiler_specific.h"
#include "base/task_runner_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/public/browser/browser_thread.h"
using metrics::SystemProfileProto;
NetworkMetricsProvider::NetworkMetricsProvider()
: connection_type_is_ambiguous_(false),
wifi_phy_layer_protocol_is_ambiguous_(false),
wifi_phy_layer_protocol_(net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN),
weak_ptr_factory_(this) {
net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
connection_type_ = net::NetworkChangeNotifier::GetConnectionType();
ProbeWifiPHYLayerProtocol();
}
NetworkMetricsProvider::~NetworkMetricsProvider() {
net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
}
void NetworkMetricsProvider::ProvideSystemProfileMetrics(
SystemProfileProto* system_profile) {
SystemProfileProto::Network* network = system_profile->mutable_network();
network->set_connection_type_is_ambiguous(connection_type_is_ambiguous_);
network->set_connection_type(GetConnectionType());
network->set_wifi_phy_layer_protocol_is_ambiguous(
wifi_phy_layer_protocol_is_ambiguous_);
network->set_wifi_phy_layer_protocol(GetWifiPHYLayerProtocol());
// Resets the "ambiguous" flags, since a new metrics log session has started.
connection_type_is_ambiguous_ = false;
// TODO(isherman): This line seems unnecessary.
connection_type_ = net::NetworkChangeNotifier::GetConnectionType();
wifi_phy_layer_protocol_is_ambiguous_ = false;
}
void NetworkMetricsProvider::OnConnectionTypeChanged(
net::NetworkChangeNotifier::ConnectionType type) {
if (type == net::NetworkChangeNotifier::CONNECTION_NONE)
return;
if (type != connection_type_ &&
connection_type_ != net::NetworkChangeNotifier::CONNECTION_NONE) {
connection_type_is_ambiguous_ = true;
}
connection_type_ = type;
ProbeWifiPHYLayerProtocol();
}
SystemProfileProto::Network::ConnectionType
NetworkMetricsProvider::GetConnectionType() const {
switch (connection_type_) {
case net::NetworkChangeNotifier::CONNECTION_NONE:
case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
return SystemProfileProto::Network::CONNECTION_UNKNOWN;
case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
return SystemProfileProto::Network::CONNECTION_ETHERNET;
case net::NetworkChangeNotifier::CONNECTION_WIFI:
return SystemProfileProto::Network::CONNECTION_WIFI;
case net::NetworkChangeNotifier::CONNECTION_2G:
return SystemProfileProto::Network::CONNECTION_2G;
case net::NetworkChangeNotifier::CONNECTION_3G:
return SystemProfileProto::Network::CONNECTION_3G;
case net::NetworkChangeNotifier::CONNECTION_4G:
return SystemProfileProto::Network::CONNECTION_4G;
case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
return SystemProfileProto::Network::CONNECTION_BLUETOOTH;
}
NOTREACHED();
return SystemProfileProto::Network::CONNECTION_UNKNOWN;
}
SystemProfileProto::Network::WifiPHYLayerProtocol
NetworkMetricsProvider::GetWifiPHYLayerProtocol() const {
switch (wifi_phy_layer_protocol_) {
case net::WIFI_PHY_LAYER_PROTOCOL_NONE:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_NONE;
case net::WIFI_PHY_LAYER_PROTOCOL_ANCIENT:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_ANCIENT;
case net::WIFI_PHY_LAYER_PROTOCOL_A:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_A;
case net::WIFI_PHY_LAYER_PROTOCOL_B:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_B;
case net::WIFI_PHY_LAYER_PROTOCOL_G:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_G;
case net::WIFI_PHY_LAYER_PROTOCOL_N:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_N;
case net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN:
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
}
NOTREACHED();
return SystemProfileProto::Network::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
}
void NetworkMetricsProvider::ProbeWifiPHYLayerProtocol() {
PostTaskAndReplyWithResult(
content::BrowserThread::GetBlockingPool(),
FROM_HERE,
base::Bind(&net::GetWifiPHYLayerProtocol),
base::Bind(&NetworkMetricsProvider::OnWifiPHYLayerProtocolResult,
weak_ptr_factory_.GetWeakPtr()));
}
void NetworkMetricsProvider::OnWifiPHYLayerProtocolResult(
net::WifiPHYLayerProtocol mode) {
if (wifi_phy_layer_protocol_ != net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN &&
mode != wifi_phy_layer_protocol_) {
wifi_phy_layer_protocol_is_ambiguous_ = true;
}
wifi_phy_layer_protocol_ = mode;
}