blob: 9717d1d837236d1067bff08a32626a3571acfad3 [file] [log] [blame]
// Copyright (c) 2013 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/metrics_network_observer.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"
MetricsNetworkObserver::MetricsNetworkObserver()
: weak_ptr_factory_(this),
connection_type_is_ambiguous_(false),
wifi_phy_layer_protocol_is_ambiguous_(false),
wifi_phy_layer_protocol_(net::WIFI_PHY_LAYER_PROTOCOL_UNKNOWN) {
net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
connection_type_ = net::NetworkChangeNotifier::GetConnectionType();
ProbeWifiPHYLayerProtocol();
}
MetricsNetworkObserver::~MetricsNetworkObserver() {
net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
}
void MetricsNetworkObserver::Reset() {
connection_type_is_ambiguous_ = false;
connection_type_ = net::NetworkChangeNotifier::GetConnectionType();
wifi_phy_layer_protocol_is_ambiguous_ = false;
}
void MetricsNetworkObserver::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
MetricsNetworkObserver::connection_type() 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;
}
NOTREACHED();
return SystemProfileProto::Network::CONNECTION_UNKNOWN;
}
SystemProfileProto::Network::WifiPHYLayerProtocol
MetricsNetworkObserver::wifi_phy_layer_protocol() 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 MetricsNetworkObserver::ProbeWifiPHYLayerProtocol() {
PostTaskAndReplyWithResult(
content::BrowserThread::GetBlockingPool(),
FROM_HERE,
base::Bind(&net::GetWifiPHYLayerProtocol),
base::Bind(&MetricsNetworkObserver::OnWifiPHYLayerProtocolResult,
weak_ptr_factory_.GetWeakPtr()));
}
void MetricsNetworkObserver::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;
}