| Index: net/base/network_change_notifier.cc
|
| diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
|
| index 8c5f4461d96b66189d8de1c1a95fa7ac002830a6..fa0ad775afa4166642802596a16a938bb3d94e43 100644
|
| --- a/net/base/network_change_notifier.cc
|
| +++ b/net/base/network_change_notifier.cc
|
| @@ -4,7 +4,10 @@
|
|
|
| #include "net/base/network_change_notifier.h"
|
| #include "net/base/network_change_notifier_factory.h"
|
| +#include "base/metrics/histogram.h"
|
| #include "build/build_config.h"
|
| +#include "googleurl/src/gurl.h"
|
| +#include "net/base/net_util.h"
|
| #if defined(OS_WIN)
|
| #include "net/base/network_change_notifier_win.h"
|
| #elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
| @@ -35,6 +38,109 @@ class MockNetworkChangeNotifier : public NetworkChangeNotifier {
|
|
|
| } // namespace
|
|
|
| +// The main observer class that records UMAs for network events.
|
| +class HistogramWatcher
|
| + : public NetworkChangeNotifier::ConnectionTypeObserver,
|
| + public NetworkChangeNotifier::IPAddressObserver,
|
| + public NetworkChangeNotifier::DNSObserver {
|
| + public:
|
| + HistogramWatcher()
|
| + : last_ip_address_change_(base::TimeTicks::Now()),
|
| + last_connection_change_(base::TimeTicks::Now()),
|
| + last_dns_change_(base::TimeTicks::Now()),
|
| + last_connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN),
|
| + offline_packets_received_(0) {}
|
| +
|
| + // Registers our three Observer implementations. This is called from the
|
| + // network thread so that our Observer implementations are also called
|
| + // from the network thread. This avoids multi-threaded race conditions
|
| + // because the only other interface, |NotifyDataReceived| is also
|
| + // only called from the network thread.
|
| + void InitHistogramWatcher() {
|
| + NetworkChangeNotifier::AddConnectionTypeObserver(this);
|
| + NetworkChangeNotifier::AddIPAddressObserver(this);
|
| + NetworkChangeNotifier::AddDNSObserver(this);
|
| + }
|
| +
|
| + virtual ~HistogramWatcher() {}
|
| +
|
| + // NetworkChangeNotifier::IPAddressObserver implementation.
|
| + virtual void OnIPAddressChanged() OVERRIDE {
|
| + UMA_HISTOGRAM_MEDIUM_TIMES("NCN.IPAddressChange",
|
| + SinceLast(&last_ip_address_change_));
|
| + }
|
| +
|
| + // NetworkChangeNotifier::ConnectionTypeObserver implementation.
|
| + virtual void OnConnectionTypeChanged(
|
| + NetworkChangeNotifier::ConnectionType type) OVERRIDE {
|
| + if (type != NetworkChangeNotifier::CONNECTION_NONE) {
|
| + UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OnlineChange",
|
| + SinceLast(&last_connection_change_));
|
| +
|
| + if (offline_packets_received_) {
|
| + if ((last_connection_change_ - last_offline_packet_received_) <
|
| + base::TimeDelta::FromSeconds(5)) {
|
| + // We can compare this sum with the sum of NCN.OfflineDataRecv.
|
| + UMA_HISTOGRAM_COUNTS_10000(
|
| + "NCN.OfflineDataRecvAny5sBeforeOnline",
|
| + offline_packets_received_);
|
| + }
|
| +
|
| + UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineDataRecvUntilOnline",
|
| + last_connection_change_ -
|
| + last_offline_packet_received_);
|
| + }
|
| + } else {
|
| + UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineChange",
|
| + SinceLast(&last_connection_change_));
|
| + }
|
| +
|
| + offline_packets_received_ = 0;
|
| + last_connection_type_ = type;
|
| + }
|
| +
|
| + // NetworkChangeNotifier::DNSObserver implementation.
|
| + virtual void OnDNSChanged(unsigned detail) OVERRIDE {
|
| + if (detail == NetworkChangeNotifier::CHANGE_DNS_SETTINGS) {
|
| + UMA_HISTOGRAM_MEDIUM_TIMES("NCN.DNSConfigChange",
|
| + SinceLast(&last_dns_change_));
|
| + }
|
| + }
|
| +
|
| + // Record histogram data whenever we receive a packet but think we're
|
| + // offline. Should only be called from the network thread.
|
| + void NotifyDataReceived(const GURL& source) {
|
| + if (last_connection_type_ != NetworkChangeNotifier::CONNECTION_NONE ||
|
| + IsLocalhost(source.host()) ||
|
| + !(source.SchemeIs("http") || source.SchemeIs("https"))) {
|
| + return;
|
| + }
|
| +
|
| + base::TimeTicks current_time = base::TimeTicks::Now();
|
| + UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineDataRecv",
|
| + current_time - last_connection_change_);
|
| + offline_packets_received_++;
|
| + last_offline_packet_received_ = current_time;
|
| + }
|
| +
|
| + private:
|
| + static base::TimeDelta SinceLast(base::TimeTicks *last_time) {
|
| + base::TimeTicks current_time = base::TimeTicks::Now();
|
| + base::TimeDelta delta = current_time - *last_time;
|
| + *last_time = current_time;
|
| + return delta;
|
| + }
|
| +
|
| + base::TimeTicks last_ip_address_change_;
|
| + base::TimeTicks last_connection_change_;
|
| + base::TimeTicks last_dns_change_;
|
| + base::TimeTicks last_offline_packet_received_;
|
| + NetworkChangeNotifier::ConnectionType last_connection_type_;
|
| + int32 offline_packets_received_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(HistogramWatcher);
|
| +};
|
| +
|
| NetworkChangeNotifier::~NetworkChangeNotifier() {
|
| DCHECK_EQ(this, g_network_change_notifier);
|
| g_network_change_notifier = NULL;
|
| @@ -84,6 +190,20 @@ NetworkChangeNotifier::GetConnectionType() {
|
| CONNECTION_UNKNOWN;
|
| }
|
|
|
| +// static
|
| +void NetworkChangeNotifier::NotifyDataReceived(const GURL& source) {
|
| + if (!g_network_change_notifier)
|
| + return;
|
| + g_network_change_notifier->histogram_watcher_->NotifyDataReceived(source);
|
| +}
|
| +
|
| +// static
|
| +void NetworkChangeNotifier::InitHistogramWatcher() {
|
| + if (!g_network_change_notifier)
|
| + return;
|
| + g_network_change_notifier->histogram_watcher_->InitHistogramWatcher();
|
| +}
|
| +
|
| #if defined(OS_LINUX)
|
| // static
|
| const internal::AddressTrackerLinux*
|
| @@ -162,6 +282,7 @@ NetworkChangeNotifier::NetworkChangeNotifier()
|
| watching_dns_(false) {
|
| DCHECK(!g_network_change_notifier);
|
| g_network_change_notifier = this;
|
| + histogram_watcher_.reset(new HistogramWatcher());
|
| }
|
|
|
| #if defined(OS_LINUX)
|
|
|