summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorgunsch <gunsch@chromium.org>2014-09-11 14:05:03 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-11 21:15:16 +0000
commit043f36003d1d0a36be39f7eb071eeab5970d6300 (patch)
treecf8b1530a98649131561160aee9e79a45fc4601f /components
parent9c3546acc0e122455ba8d9f7452d25b8cd1370cd (diff)
downloadchromium_src-043f36003d1d0a36be39f7eb071eeab5970d6300.zip
chromium_src-043f36003d1d0a36be39f7eb071eeab5970d6300.tar.gz
chromium_src-043f36003d1d0a36be39f7eb071eeab5970d6300.tar.bz2
Moves NetworkMetricsProvider to //components/metrics.
R=stevenjb@chromium.org,asvitkine@chromium.org,benchan@chromium.org BUG=404791 Review URL: https://codereview.chromium.org/558873002 Cr-Commit-Position: refs/heads/master@{#294466}
Diffstat (limited to 'components')
-rw-r--r--components/metrics.gypi7
-rw-r--r--components/metrics/BUILD.gn6
-rw-r--r--components/metrics/net/DEPS2
-rw-r--r--components/metrics/net/network_metrics_provider.cc228
-rw-r--r--components/metrics/net/network_metrics_provider.h77
-rw-r--r--components/metrics/net/wifi_access_point_info_provider.cc21
-rw-r--r--components/metrics/net/wifi_access_point_info_provider.h49
-rw-r--r--components/metrics/net/wifi_access_point_info_provider_chromeos.cc118
-rw-r--r--components/metrics/net/wifi_access_point_info_provider_chromeos.h42
9 files changed, 550 insertions, 0 deletions
diff --git a/components/metrics.gypi b/components/metrics.gypi
index 945d1c16..8d053f4 100644
--- a/components/metrics.gypi
+++ b/components/metrics.gypi
@@ -73,11 +73,18 @@
],
'dependencies': [
'../net/net.gyp:net',
+ 'component_metrics_proto',
'metrics',
],
'sources': [
+ 'metrics/net/network_metrics_provider.cc',
+ 'metrics/net/network_metrics_provider.h',
'metrics/net/net_metrics_log_uploader.cc',
'metrics/net/net_metrics_log_uploader.h',
+ 'metrics/net/wifi_access_point_info_provider.cc',
+ 'metrics/net/wifi_access_point_info_provider.h',
+ 'metrics/net/wifi_access_point_info_provider_chromeos.cc',
+ 'metrics/net/wifi_access_point_info_provider_chromeos.h',
],
},
{
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 92f9e89..fc3483d 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -52,8 +52,14 @@ source_set("metrics") {
# GYP version: components/metrics.gypi:metrics_net
static_library("net") {
sources = [
+ "net/network_metrics_provider.cc",
+ "net/network_metrics_provider.h",
"net/net_metrics_log_uploader.cc",
"net/net_metrics_log_uploader.h",
+ "net/wifi_access_point_info_provider.cc",
+ "net/wifi_access_point_info_provider.h",
+ "net/wifi_access_point_info_provider_chromeos.cc",
+ "net/wifi_access_point_info_provider_chromeos.h",
]
deps = [
diff --git a/components/metrics/net/DEPS b/components/metrics/net/DEPS
index ede766a..54226d4 100644
--- a/components/metrics/net/DEPS
+++ b/components/metrics/net/DEPS
@@ -1,3 +1,5 @@
include_rules = [
+ "+chromeos/network",
"+net",
+ "+third_party/cros_system_api",
]
diff --git a/components/metrics/net/network_metrics_provider.cc b/components/metrics/net/network_metrics_provider.cc
new file mode 100644
index 0000000..c0b38d7
--- /dev/null
+++ b/components/metrics/net/network_metrics_provider.cc
@@ -0,0 +1,228 @@
+// 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 "components/metrics/net/network_metrics_provider.h"
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/task_runner_util.h"
+
+#if defined(OS_CHROMEOS)
+#include "components/metrics/net/wifi_access_point_info_provider_chromeos.h"
+#endif // OS_CHROMEOS
+
+using metrics::SystemProfileProto;
+
+NetworkMetricsProvider::NetworkMetricsProvider(
+ base::TaskRunner* io_task_runner)
+ : io_task_runner_(io_task_runner),
+ 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::OnDidCreateMetricsLog() {
+ net::NetworkChangeNotifier::LogOperatorCodeHistogram(
+ net::NetworkChangeNotifier::GetConnectionType());
+}
+
+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;
+
+ if (!wifi_access_point_info_provider_.get()) {
+#if defined(OS_CHROMEOS)
+ wifi_access_point_info_provider_.reset(
+ new WifiAccessPointInfoProviderChromeos());
+#else
+ wifi_access_point_info_provider_.reset(
+ new WifiAccessPointInfoProvider());
+#endif // OS_CHROMEOS
+ }
+
+ // Connected wifi access point information.
+ WifiAccessPointInfoProvider::WifiAccessPointInfo info;
+ if (wifi_access_point_info_provider_->GetInfo(&info))
+ WriteWifiAccessPointProto(info, network);
+}
+
+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(
+ io_task_runner_,
+ 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;
+}
+
+void NetworkMetricsProvider::WriteWifiAccessPointProto(
+ const WifiAccessPointInfoProvider::WifiAccessPointInfo& info,
+ SystemProfileProto::Network* network_proto) {
+ SystemProfileProto::Network::WifiAccessPoint* access_point_info =
+ network_proto->mutable_access_point_info();
+ SystemProfileProto::Network::WifiAccessPoint::SecurityMode security =
+ SystemProfileProto::Network::WifiAccessPoint::SECURITY_UNKNOWN;
+ switch (info.security) {
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_NONE:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_NONE;
+ break;
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_WPA:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_WPA;
+ break;
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_WEP:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_WEP;
+ break;
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_RSN:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_RSN;
+ break;
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_802_1X:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_802_1X;
+ break;
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_PSK:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_PSK;
+ break;
+ case WifiAccessPointInfoProvider::WIFI_SECURITY_UNKNOWN:
+ security = SystemProfileProto::Network::WifiAccessPoint::SECURITY_UNKNOWN;
+ break;
+ }
+ access_point_info->set_security_mode(security);
+
+ // |bssid| is xx:xx:xx:xx:xx:xx, extract the first three components and
+ // pack into a uint32.
+ std::string bssid = info.bssid;
+ if (bssid.size() == 17 && bssid[2] == ':' && bssid[5] == ':' &&
+ bssid[8] == ':' && bssid[11] == ':' && bssid[14] == ':') {
+ std::string vendor_prefix_str;
+ uint32 vendor_prefix;
+
+ base::RemoveChars(bssid.substr(0, 9), ":", &vendor_prefix_str);
+ DCHECK_EQ(6U, vendor_prefix_str.size());
+ if (base::HexStringToUInt(vendor_prefix_str, &vendor_prefix))
+ access_point_info->set_vendor_prefix(vendor_prefix);
+ else
+ NOTREACHED();
+ }
+
+ // Return if vendor information is not provided.
+ if (info.model_number.empty() && info.model_name.empty() &&
+ info.device_name.empty() && info.oui_list.empty())
+ return;
+
+ SystemProfileProto::Network::WifiAccessPoint::VendorInformation* vendor =
+ access_point_info->mutable_vendor_info();
+ if (!info.model_number.empty())
+ vendor->set_model_number(info.model_number);
+ if (!info.model_name.empty())
+ vendor->set_model_name(info.model_name);
+ if (!info.device_name.empty())
+ vendor->set_device_name(info.device_name);
+
+ // Return if OUI list is not provided.
+ if (info.oui_list.empty())
+ return;
+
+ // Parse OUI list.
+ std::vector<std::string> oui_list;
+ base::SplitString(info.oui_list, ' ', &oui_list);
+ for (std::vector<std::string>::const_iterator it = oui_list.begin();
+ it != oui_list.end();
+ ++it) {
+ uint32 oui;
+ if (base::HexStringToUInt(*it, &oui))
+ vendor->add_element_identifier(oui);
+ else
+ NOTREACHED();
+ }
+}
diff --git a/components/metrics/net/network_metrics_provider.h b/components/metrics/net/network_metrics_provider.h
new file mode 100644
index 0000000..43a0318
--- /dev/null
+++ b/components/metrics/net/network_metrics_provider.h
@@ -0,0 +1,77 @@
+// 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.
+
+#ifndef COMPONENTS_METRICS_NET_NETWORK_METRICS_PROVIDER_H_
+#define COMPONENTS_METRICS_NET_NETWORK_METRICS_PROVIDER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "components/metrics/metrics_provider.h"
+#include "components/metrics/net/wifi_access_point_info_provider.h"
+#include "components/metrics/proto/system_profile.pb.h"
+#include "net/base/net_util.h"
+#include "net/base/network_change_notifier.h"
+
+// Registers as observer with net::NetworkChangeNotifier and keeps track of
+// the network environment.
+class NetworkMetricsProvider
+ : public metrics::MetricsProvider,
+ public net::NetworkChangeNotifier::ConnectionTypeObserver {
+ public:
+ // Creates a NetworkMetricsProvider, where |io_task_runner| is used to post
+ // network info collection tasks.
+ explicit NetworkMetricsProvider(base::TaskRunner* io_task_runner);
+ virtual ~NetworkMetricsProvider();
+
+ private:
+ // metrics::MetricsProvider:
+ virtual void OnDidCreateMetricsLog() OVERRIDE;
+ virtual void ProvideSystemProfileMetrics(
+ metrics::SystemProfileProto* system_profile) OVERRIDE;
+
+ // ConnectionTypeObserver:
+ virtual void OnConnectionTypeChanged(
+ net::NetworkChangeNotifier::ConnectionType type) OVERRIDE;
+
+ metrics::SystemProfileProto::Network::ConnectionType
+ GetConnectionType() const;
+ metrics::SystemProfileProto::Network::WifiPHYLayerProtocol
+ GetWifiPHYLayerProtocol() const;
+
+ // Posts a call to net::GetWifiPHYLayerProtocol on the blocking pool.
+ void ProbeWifiPHYLayerProtocol();
+ // Callback from the blocking pool with the result of
+ // net::GetWifiPHYLayerProtocol.
+ void OnWifiPHYLayerProtocolResult(net::WifiPHYLayerProtocol mode);
+
+ // Writes info about the wireless access points that this system is
+ // connected to.
+ void WriteWifiAccessPointProto(
+ const WifiAccessPointInfoProvider::WifiAccessPointInfo& info,
+ metrics::SystemProfileProto::Network* network_proto);
+
+ // Task runner used for blocking file I/O.
+ base::TaskRunner* io_task_runner_;
+
+ // True if |connection_type_| changed during the lifetime of the log.
+ bool connection_type_is_ambiguous_;
+ // The connection type according to net::NetworkChangeNotifier.
+ net::NetworkChangeNotifier::ConnectionType connection_type_;
+
+ // True if |wifi_phy_layer_protocol_| changed during the lifetime of the log.
+ bool wifi_phy_layer_protocol_is_ambiguous_;
+ // The PHY mode of the currently associated access point obtained via
+ // net::GetWifiPHYLayerProtocol.
+ net::WifiPHYLayerProtocol wifi_phy_layer_protocol_;
+
+ base::WeakPtrFactory<NetworkMetricsProvider> weak_ptr_factory_;
+
+ // Helper object for retrieving connected wifi access point information.
+ scoped_ptr<WifiAccessPointInfoProvider> wifi_access_point_info_provider_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkMetricsProvider);
+};
+
+#endif // COMPONENTS_METRICS_NET_NETWORK_METRICS_PROVIDER_H_
diff --git a/components/metrics/net/wifi_access_point_info_provider.cc b/components/metrics/net/wifi_access_point_info_provider.cc
new file mode 100644
index 0000000..c8f07a4
--- /dev/null
+++ b/components/metrics/net/wifi_access_point_info_provider.cc
@@ -0,0 +1,21 @@
+// 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 "components/metrics/net/wifi_access_point_info_provider.h"
+
+WifiAccessPointInfoProvider::WifiAccessPointInfo::WifiAccessPointInfo() {
+}
+
+WifiAccessPointInfoProvider::WifiAccessPointInfo::~WifiAccessPointInfo() {
+}
+
+WifiAccessPointInfoProvider::WifiAccessPointInfoProvider() {
+}
+
+WifiAccessPointInfoProvider::~WifiAccessPointInfoProvider() {
+}
+
+bool WifiAccessPointInfoProvider::GetInfo(WifiAccessPointInfo *info) {
+ return false;
+}
diff --git a/components/metrics/net/wifi_access_point_info_provider.h b/components/metrics/net/wifi_access_point_info_provider.h
new file mode 100644
index 0000000..5d74c3c
--- /dev/null
+++ b/components/metrics/net/wifi_access_point_info_provider.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_H_
+#define COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_H_
+
+#include <string>
+#include "base/basictypes.h"
+
+// Interface for accessing connected wireless access point information.
+class WifiAccessPointInfoProvider {
+ public:
+ // Wifi access point security mode definitions.
+ enum WifiSecurityMode {
+ WIFI_SECURITY_UNKNOWN = 0,
+ WIFI_SECURITY_WPA = 1,
+ WIFI_SECURITY_WEP = 2,
+ WIFI_SECURITY_RSN = 3,
+ WIFI_SECURITY_802_1X = 4,
+ WIFI_SECURITY_PSK = 5,
+ WIFI_SECURITY_NONE
+ };
+
+ // Information of the currently connected wifi access point.
+ struct WifiAccessPointInfo {
+ WifiAccessPointInfo();
+ ~WifiAccessPointInfo();
+ WifiSecurityMode security;
+ std::string bssid;
+ std::string model_number;
+ std::string model_name;
+ std::string device_name;
+ std::string oui_list;
+ };
+
+ WifiAccessPointInfoProvider();
+ virtual ~WifiAccessPointInfoProvider();
+
+ // Fill in the wifi access point info if device is currently connected to a
+ // wifi access point. Return true if device is connected to a wifi access
+ // point, false otherwise.
+ virtual bool GetInfo(WifiAccessPointInfo *info);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WifiAccessPointInfoProvider);
+};
+
+#endif // COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_H_
diff --git a/components/metrics/net/wifi_access_point_info_provider_chromeos.cc b/components/metrics/net/wifi_access_point_info_provider_chromeos.cc
new file mode 100644
index 0000000..c05829b
--- /dev/null
+++ b/components/metrics/net/wifi_access_point_info_provider_chromeos.cc
@@ -0,0 +1,118 @@
+// 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 "components/metrics/net/wifi_access_point_info_provider_chromeos.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/strings/string_number_conversions.h"
+#include "chromeos/network/network_configuration_handler.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/shill_property_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+using chromeos::NetworkHandler;
+
+WifiAccessPointInfoProviderChromeos::WifiAccessPointInfoProviderChromeos() {
+ NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
+
+ // Update initial connection state.
+ DefaultNetworkChanged(
+ NetworkHandler::Get()->network_state_handler()->DefaultNetwork());
+}
+
+WifiAccessPointInfoProviderChromeos::~WifiAccessPointInfoProviderChromeos() {
+ NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
+ FROM_HERE);
+}
+
+bool WifiAccessPointInfoProviderChromeos::GetInfo(WifiAccessPointInfo* info) {
+ // Wifi access point information is not provided if the BSSID is empty.
+ // This assumes the BSSID is never empty when access point information exists.
+ if (wifi_access_point_info_.bssid.empty())
+ return false;
+
+ *info = wifi_access_point_info_;
+ return true;
+}
+
+void WifiAccessPointInfoProviderChromeos::DefaultNetworkChanged(
+ const chromeos::NetworkState* default_network) {
+ // Reset access point info to prevent reporting of out-dated data.
+ wifi_access_point_info_ = WifiAccessPointInfo();
+
+ // Skip non-wifi connections
+ if (!default_network || default_network->type() != shill::kTypeWifi)
+ return;
+
+ // Retrieve access point info for wifi connection.
+ NetworkHandler::Get()->network_configuration_handler()->GetProperties(
+ default_network->path(),
+ base::Bind(&WifiAccessPointInfoProviderChromeos::ParseInfo,
+ AsWeakPtr()),
+ chromeos::network_handler::ErrorCallback());
+}
+
+void WifiAccessPointInfoProviderChromeos::ParseInfo(
+ const std::string &service_path,
+ const base::DictionaryValue& properties) {
+ // Skip services that contain "_nomap" in the SSID.
+ std::string ssid =
+ chromeos::shill_property_util::GetSSIDFromProperties(properties, NULL);
+ if (ssid.find("_nomap", 0) != std::string::npos)
+ return;
+
+ std::string bssid;
+ if (!properties.GetStringWithoutPathExpansion(shill::kWifiBSsid, &bssid) ||
+ bssid.empty())
+ return;
+
+ // Filter out BSSID with local bit set in the first byte.
+ uint32 first_octet;
+ if (!base::HexStringToUInt(bssid.substr(0, 2), &first_octet))
+ NOTREACHED();
+ if (first_octet & 0x2)
+ return;
+ wifi_access_point_info_.bssid = bssid;
+
+ // Parse security info.
+ std::string security;
+ properties.GetStringWithoutPathExpansion(
+ shill::kSecurityProperty, &security);
+ wifi_access_point_info_.security = WIFI_SECURITY_UNKNOWN;
+ if (security == shill::kSecurityWpa)
+ wifi_access_point_info_.security = WIFI_SECURITY_WPA;
+ else if (security == shill::kSecurityWep)
+ wifi_access_point_info_.security = WIFI_SECURITY_WEP;
+ else if (security == shill::kSecurityRsn)
+ wifi_access_point_info_.security = WIFI_SECURITY_RSN;
+ else if (security == shill::kSecurity8021x)
+ wifi_access_point_info_.security = WIFI_SECURITY_802_1X;
+ else if (security == shill::kSecurityPsk)
+ wifi_access_point_info_.security = WIFI_SECURITY_PSK;
+ else if (security == shill::kSecurityNone)
+ wifi_access_point_info_.security = WIFI_SECURITY_NONE;
+
+ properties.GetStringWithoutPathExpansion(
+ shill::kWifiBSsid, &wifi_access_point_info_.bssid);
+ const base::DictionaryValue* vendor_dict = NULL;
+ if (!properties.GetDictionaryWithoutPathExpansion(
+ shill::kWifiVendorInformationProperty,
+ &vendor_dict))
+ return;
+
+ vendor_dict->GetStringWithoutPathExpansion(
+ shill::kVendorWPSModelNumberProperty,
+ &wifi_access_point_info_.model_number);
+ vendor_dict->GetStringWithoutPathExpansion(
+ shill::kVendorWPSModelNameProperty,
+ &wifi_access_point_info_.model_name);
+ vendor_dict->GetStringWithoutPathExpansion(
+ shill::kVendorWPSDeviceNameProperty,
+ &wifi_access_point_info_.device_name);
+ vendor_dict->GetStringWithoutPathExpansion(shill::kVendorOUIListProperty,
+ &wifi_access_point_info_.oui_list);
+}
diff --git a/components/metrics/net/wifi_access_point_info_provider_chromeos.h b/components/metrics/net/wifi_access_point_info_provider_chromeos.h
new file mode 100644
index 0000000..6eaebab
--- /dev/null
+++ b/components/metrics/net/wifi_access_point_info_provider_chromeos.h
@@ -0,0 +1,42 @@
+// 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.
+
+#ifndef COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_CHROMEOS_H_
+#define COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_CHROMEOS_H_
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
+#include "chromeos/network/network_state_handler_observer.h"
+#include "components/metrics/net/wifi_access_point_info_provider.h"
+
+// WifiAccessPointInfoProviderChromeos provides the connected wifi
+// acccess point information for chromeos.
+class WifiAccessPointInfoProviderChromeos
+ : public WifiAccessPointInfoProvider,
+ public chromeos::NetworkStateHandlerObserver,
+ public base::SupportsWeakPtr<WifiAccessPointInfoProviderChromeos> {
+ public:
+ WifiAccessPointInfoProviderChromeos();
+ virtual ~WifiAccessPointInfoProviderChromeos();
+
+ // WifiAccessPointInfoProvider
+ virtual bool GetInfo(WifiAccessPointInfo* info) OVERRIDE;
+
+ // NetworkStateHandlerObserver overrides.
+ virtual void DefaultNetworkChanged(
+ const chromeos::NetworkState* default_network) OVERRIDE;
+
+ private:
+ // Callback from Shill.Service.GetProperties. Parses |properties| to obtain
+ // the wifi access point information.
+ void ParseInfo(const std::string& service_path,
+ const base::DictionaryValue& properties);
+
+ WifiAccessPointInfo wifi_access_point_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiAccessPointInfoProviderChromeos);
+};
+
+#endif // COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_CHROMEOS_H_