| 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..cf5557c601a47dd54da64c705a55919889f0fa20 100644
|
| --- a/net/base/network_change_notifier.cc
|
| +++ b/net/base/network_change_notifier.cc
|
| @@ -46,12 +46,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 +66,7 @@ class HistogramWatcher
|
| NetworkChangeNotifier::AddConnectionTypeObserver(this);
|
| NetworkChangeNotifier::AddIPAddressObserver(this);
|
| NetworkChangeNotifier::AddDNSObserver(this);
|
| + NetworkChangeNotifier::AddNetworkChangeObserver(this);
|
| }
|
|
|
| virtual ~HistogramWatcher() {}
|
| @@ -72,6 +75,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 +104,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 +119,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 +174,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 +215,79 @@ class NetworkChangeNotifier::NetworkState {
|
| DnsConfig dns_config_;
|
| };
|
|
|
| +NetworkChangeNotifier::NetworkChangeCalculatorParams::
|
| + NetworkChangeCalculatorParams() {
|
| +}
|
| +
|
| +// Calculates NetworkChange signal from IPAddress and ConnectionType signals.
|
| +class NetworkChangeNotifier::NetworkChangeCalculator
|
| + : public ConnectionTypeObserver,
|
| + public IPAddressObserver {
|
| + public:
|
| + NetworkChangeCalculator(const NetworkChangeCalculatorParams& params)
|
| + : params_(params),
|
| + 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.
|
| + virtual void OnIPAddressChanged() OVERRIDE {
|
| + base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
|
| + ? params_.ip_address_offline_delay_ : params_.ip_address_online_delay_;
|
| + // Cancels any previous timer.
|
| + timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify);
|
| + }
|
| +
|
| + // NetworkChangeNotifier::ConnectionTypeObserver implementation.
|
| + virtual void OnConnectionTypeChanged(ConnectionType type) OVERRIDE {
|
| + pending_connection_type_ = type;
|
| + base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
|
| + ? params_.connection_type_offline_delay_
|
| + : params_.connection_type_online_delay_;
|
| + // Cancels any previous timer.
|
| + 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) &&
|
| + (pending_connection_type_ == CONNECTION_NONE)) {
|
| + return;
|
| + }
|
| + 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 NetworkChangeCalculatorParams params_;
|
| +
|
| + // 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 +441,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 +472,17 @@ 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(
|
| + const NetworkChangeCalculatorParams& params
|
| + /*= NetworkChangeCalculatorParams()*/)
|
| : ip_address_observer_list_(
|
| new ObserverListThreadSafe<IPAddressObserver>(
|
| ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)),
|
| @@ -379,10 +492,15 @@ 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(params)) {
|
| DCHECK(!g_network_change_notifier);
|
| g_network_change_notifier = this;
|
| + network_change_calculator_->Init();
|
| }
|
|
|
| #if defined(OS_LINUX)
|
| @@ -424,6 +542,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);
|
|
|