Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Unified Diff: net/base/network_change_notifier.cc

Issue 11360108: Start calculating new combined NetworkChangeNotifier signal (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/base/network_change_notifier.cc
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index e8dd1208e4127713433df6c0dfbb9836d6d46a57..43c9247fb01962eb1cff36381d3f885f445b4c56 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -35,6 +35,7 @@ NetworkChangeNotifierFactory* g_network_change_notifier_factory = NULL;
class MockNetworkChangeNotifier : public NetworkChangeNotifier {
public:
+ MockNetworkChangeNotifier() : NetworkChangeNotifier(0, 0, 0, 0) {}
virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
return CONNECTION_UNKNOWN;
}
@@ -46,12 +47,14 @@ class MockNetworkChangeNotifier : public NetworkChangeNotifier {
class HistogramWatcher
: public NetworkChangeNotifier::ConnectionTypeObserver,
public NetworkChangeNotifier::IPAddressObserver,
- public NetworkChangeNotifier::DNSObserver {
+ public NetworkChangeNotifier::DNSObserver,
+ public NetworkChangeNotifier::NetworkChangeObserver {
public:
HistogramWatcher()
: last_ip_address_change_(base::TimeTicks::Now()),
last_connection_change_(base::TimeTicks::Now()),
last_dns_change_(base::TimeTicks::Now()),
+ last_network_change_(base::TimeTicks::Now()),
last_connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN),
offline_packets_received_(0) {}
@@ -64,6 +67,7 @@ class HistogramWatcher
NetworkChangeNotifier::AddConnectionTypeObserver(this);
NetworkChangeNotifier::AddIPAddressObserver(this);
NetworkChangeNotifier::AddDNSObserver(this);
+ NetworkChangeNotifier::AddNetworkChangeObserver(this);
}
virtual ~HistogramWatcher() {}
@@ -72,6 +76,9 @@ class HistogramWatcher
virtual void OnIPAddressChanged() OVERRIDE {
UMA_HISTOGRAM_MEDIUM_TIMES("NCN.IPAddressChange",
SinceLast(&last_ip_address_change_));
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "NCN.ConnectionTypeChangeToIPAddressChange",
+ last_ip_address_change_ - last_connection_change_);
}
// NetworkChangeNotifier::ConnectionTypeObserver implementation.
@@ -98,6 +105,9 @@ class HistogramWatcher
UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineChange",
SinceLast(&last_connection_change_));
}
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "NCN.IPAddressChangeToConnectionTypeChange",
+ last_connection_change_ - last_ip_address_change_);
offline_packets_received_ = 0;
last_connection_type_ = type;
@@ -110,6 +120,18 @@ class HistogramWatcher
SinceLast(&last_dns_change_));
}
+ // NetworkChangeNotifier::NetworkChangeObserver implementation.
+ virtual void OnNetworkChanged(
+ NetworkChangeNotifier::ConnectionType type) OVERRIDE {
+ if (type != NetworkChangeNotifier::CONNECTION_NONE) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOnlineChange",
+ SinceLast(&last_network_change_));
+ } else {
+ UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOfflineChange",
+ SinceLast(&last_network_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) {
@@ -153,6 +175,7 @@ class HistogramWatcher
base::TimeTicks last_ip_address_change_;
base::TimeTicks last_connection_change_;
base::TimeTicks last_dns_change_;
+ base::TimeTicks last_network_change_;
base::TimeTicks last_offline_packet_received_;
base::TimeTicks last_polled_connection_;
// |polling_interval_| is initialized by |OnConnectionTypeChanged| on our
@@ -193,6 +216,89 @@ class NetworkChangeNotifier::NetworkState {
DnsConfig dns_config_;
};
+// Calculates NetworkChange signal from IPAddress and ConnectionType signals.
+class NetworkChangeNotifier::NetworkChangeCalculator
+ : public ConnectionTypeObserver,
+ public IPAddressObserver {
+ public:
+ // Delay arguments control how many milliseconds to delay notifications
+ // so as to combine duplicates. |ip_address_offline_delay_ms| controls
+ // delay after OnIPAddressChanged when transitioning from an offline state.
+ // |ip_address_online_delay_ms| controls delay after OnIPAddressChanged when
+ // transitioning from an online state. |connection_type_offline_delay_ms|
+ // controls delay after OnConnectionTypeChanged when transitioning from an
+ // offline state. |connection_type_online_delay_ms| controls delay after
+ // OnConnectionTypeChanged when transitioning from an online state.
szym 2012/11/25 07:37:37 This comment needs to explain that the notificatio
+ NetworkChangeCalculator(uint32 ip_address_offline_delay_ms,
+ uint32 ip_address_online_delay_ms,
+ uint32 connection_type_offline_delay_ms,
+ uint32 connection_type_online_delay_ms)
+ : ip_address_offline_delay_(base::TimeDelta::FromMilliseconds(
+ ip_address_offline_delay_ms)),
+ ip_address_online_delay_(base::TimeDelta::FromMilliseconds(
+ ip_address_online_delay_ms)),
+ connection_type_offline_delay_(base::TimeDelta::FromMilliseconds(
+ connection_type_offline_delay_ms)),
+ connection_type_online_delay_(base::TimeDelta::FromMilliseconds(
+ connection_type_online_delay_ms)),
+ have_announced_(false),
+ last_announced_connection_type_(CONNECTION_NONE),
+ pending_connection_type_(CONNECTION_NONE) {}
+ void Init() {
+ AddConnectionTypeObserver(this);
+ AddIPAddressObserver(this);
+ }
+ virtual ~NetworkChangeCalculator() {
+ RemoveConnectionTypeObserver(this);
+ RemoveIPAddressObserver(this);
+ }
+
+ // NetworkChangeNotifier::IPAddressObserver implementation.
szym 2012/11/25 07:37:37 nit: no need for "implementation"
pauljensen 2012/11/27 21:47:42 I see a lot of people using "implementation": URLR
+ virtual void OnIPAddressChanged() OVERRIDE {
+ base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
+ ? ip_address_offline_delay_ : ip_address_online_delay_;
+ timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify);
szym 2012/11/25 07:37:37 Perhaps a note (a reminder really) that this cance
+ }
+
+ // NetworkChangeNotifier::ConnectionTypeObserver implementation.
+ virtual void OnConnectionTypeChanged(ConnectionType type) OVERRIDE {
+ pending_connection_type_ = type;
+ base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
+ ? connection_type_offline_delay_ : connection_type_online_delay_;
+ timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify);
+ }
+
+ private:
+ void Notify() {
+ // Don't bother signaling about dead connections.
+ if (have_announced_ && last_announced_connection_type_ == CONNECTION_NONE &&
szym 2012/11/25 07:37:37 suggest parens for readability
+ pending_connection_type_ == CONNECTION_NONE)
szym 2012/11/25 07:37:37 Could the same logic be accomplished by initializi
pauljensen 2012/11/27 21:47:42 The timeouts are essential for all announcements;
+ return;
szym 2012/11/25 07:37:37 use braces when if condition is multiline
+ have_announced_ = true;
+ last_announced_connection_type_ = pending_connection_type_;
+ // Immediately before sending out an online signal, send out an offline
+ // signal to perform any destructive actions before constructive actions.
+ if (pending_connection_type_ != CONNECTION_NONE)
+ NetworkChangeNotifier::NotifyObserversOfNetworkChange(CONNECTION_NONE);
+ NetworkChangeNotifier::NotifyObserversOfNetworkChange(
+ pending_connection_type_);
+ }
+
+ const base::TimeDelta ip_address_offline_delay_;
+ const base::TimeDelta ip_address_online_delay_;
+ const base::TimeDelta connection_type_offline_delay_;
+ const base::TimeDelta connection_type_online_delay_;
+
+ // Indicates if NotifyObserversOfNetworkChange has been called yet.
+ bool have_announced_;
+ // Last value passed to NotifyObserversOfNetworkChange.
+ ConnectionType last_announced_connection_type_;
+ // Value to pass to NotifyObserversOfNetworkChange when Notify is called.
+ ConnectionType pending_connection_type_;
+ // Used to delay notifications so duplicates can be combined.
+ base::OneShotTimer<NetworkChangeCalculator> timer_;
+};
+
NetworkChangeNotifier::~NetworkChangeNotifier() {
DCHECK_EQ(this, g_network_change_notifier);
g_network_change_notifier = NULL;
@@ -346,6 +452,14 @@ void NetworkChangeNotifier::AddDNSObserver(DNSObserver* observer) {
}
}
+void NetworkChangeNotifier::AddNetworkChangeObserver(
+ NetworkChangeObserver* observer) {
+ if (g_network_change_notifier) {
+ g_network_change_notifier->network_change_observer_list_->AddObserver(
+ observer);
+ }
+}
+
void NetworkChangeNotifier::RemoveIPAddressObserver(
IPAddressObserver* observer) {
if (g_network_change_notifier) {
@@ -369,7 +483,19 @@ void NetworkChangeNotifier::RemoveDNSObserver(DNSObserver* observer) {
}
}
-NetworkChangeNotifier::NetworkChangeNotifier()
+void NetworkChangeNotifier::RemoveNetworkChangeObserver(
+ NetworkChangeObserver* observer) {
+ if (g_network_change_notifier) {
+ g_network_change_notifier->network_change_observer_list_->RemoveObserver(
+ observer);
+ }
+}
+
+NetworkChangeNotifier::NetworkChangeNotifier(
+ uint32 ip_address_offline_delay_ms,
+ uint32 ip_address_online_delay_ms,
+ uint32 connection_type_offline_delay_ms,
+ uint32 connection_type_online_delay_ms)
: ip_address_observer_list_(
new ObserverListThreadSafe<IPAddressObserver>(
ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)),
@@ -379,10 +505,19 @@ NetworkChangeNotifier::NetworkChangeNotifier()
resolver_state_observer_list_(
new ObserverListThreadSafe<DNSObserver>(
ObserverListBase<DNSObserver>::NOTIFY_EXISTING_ONLY)),
+ network_change_observer_list_(
+ new ObserverListThreadSafe<NetworkChangeObserver>(
+ ObserverListBase<NetworkChangeObserver>::NOTIFY_EXISTING_ONLY)),
network_state_(new NetworkState()),
- histogram_watcher_(new HistogramWatcher()) {
+ histogram_watcher_(new HistogramWatcher()),
+ network_change_calculator_(new NetworkChangeCalculator(
+ ip_address_offline_delay_ms,
+ ip_address_online_delay_ms,
+ connection_type_offline_delay_ms,
+ connection_type_online_delay_ms)) {
DCHECK(!g_network_change_notifier);
g_network_change_notifier = this;
+ network_change_calculator_->Init();
}
#if defined(OS_LINUX)
@@ -424,6 +559,15 @@ void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange() {
}
}
+void NetworkChangeNotifier::NotifyObserversOfNetworkChange(
+ ConnectionType type) {
+ if (g_network_change_notifier) {
+ g_network_change_notifier->network_change_observer_list_->Notify(
+ &NetworkChangeObserver::OnNetworkChanged,
+ type);
+ }
+}
+
NetworkChangeNotifier::DisableForTest::DisableForTest()
: network_change_notifier_(g_network_change_notifier) {
DCHECK(g_network_change_notifier);

Powered by Google App Engine
This is Rietveld 408576698