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

Side by Side 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: Switch to default argument constructor Created 8 years 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/network_change_notifier.h ('k') | net/base/network_change_notifier_linux.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/network_change_notifier.h" 5 #include "net/base/network_change_notifier.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/synchronization/lock.h" 8 #include "base/synchronization/lock.h"
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "googleurl/src/gurl.h" 10 #include "googleurl/src/gurl.h"
(...skipping 28 matching lines...) Expand all
39 return CONNECTION_UNKNOWN; 39 return CONNECTION_UNKNOWN;
40 } 40 }
41 }; 41 };
42 42
43 } // namespace 43 } // namespace
44 44
45 // The main observer class that records UMAs for network events. 45 // The main observer class that records UMAs for network events.
46 class HistogramWatcher 46 class HistogramWatcher
47 : public NetworkChangeNotifier::ConnectionTypeObserver, 47 : public NetworkChangeNotifier::ConnectionTypeObserver,
48 public NetworkChangeNotifier::IPAddressObserver, 48 public NetworkChangeNotifier::IPAddressObserver,
49 public NetworkChangeNotifier::DNSObserver { 49 public NetworkChangeNotifier::DNSObserver,
50 public NetworkChangeNotifier::NetworkChangeObserver {
50 public: 51 public:
51 HistogramWatcher() 52 HistogramWatcher()
52 : last_ip_address_change_(base::TimeTicks::Now()), 53 : last_ip_address_change_(base::TimeTicks::Now()),
53 last_connection_change_(base::TimeTicks::Now()), 54 last_connection_change_(base::TimeTicks::Now()),
54 last_dns_change_(base::TimeTicks::Now()), 55 last_dns_change_(base::TimeTicks::Now()),
56 last_network_change_(base::TimeTicks::Now()),
55 last_connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), 57 last_connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN),
56 offline_packets_received_(0) {} 58 offline_packets_received_(0) {}
57 59
58 // Registers our three Observer implementations. This is called from the 60 // Registers our three Observer implementations. This is called from the
59 // network thread so that our Observer implementations are also called 61 // network thread so that our Observer implementations are also called
60 // from the network thread. This avoids multi-threaded race conditions 62 // from the network thread. This avoids multi-threaded race conditions
61 // because the only other interface, |NotifyDataReceived| is also 63 // because the only other interface, |NotifyDataReceived| is also
62 // only called from the network thread. 64 // only called from the network thread.
63 void Init() { 65 void Init() {
64 NetworkChangeNotifier::AddConnectionTypeObserver(this); 66 NetworkChangeNotifier::AddConnectionTypeObserver(this);
65 NetworkChangeNotifier::AddIPAddressObserver(this); 67 NetworkChangeNotifier::AddIPAddressObserver(this);
66 NetworkChangeNotifier::AddDNSObserver(this); 68 NetworkChangeNotifier::AddDNSObserver(this);
69 NetworkChangeNotifier::AddNetworkChangeObserver(this);
67 } 70 }
68 71
69 virtual ~HistogramWatcher() {} 72 virtual ~HistogramWatcher() {}
70 73
71 // NetworkChangeNotifier::IPAddressObserver implementation. 74 // NetworkChangeNotifier::IPAddressObserver implementation.
72 virtual void OnIPAddressChanged() OVERRIDE { 75 virtual void OnIPAddressChanged() OVERRIDE {
73 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.IPAddressChange", 76 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.IPAddressChange",
74 SinceLast(&last_ip_address_change_)); 77 SinceLast(&last_ip_address_change_));
78 UMA_HISTOGRAM_MEDIUM_TIMES(
79 "NCN.ConnectionTypeChangeToIPAddressChange",
80 last_ip_address_change_ - last_connection_change_);
75 } 81 }
76 82
77 // NetworkChangeNotifier::ConnectionTypeObserver implementation. 83 // NetworkChangeNotifier::ConnectionTypeObserver implementation.
78 virtual void OnConnectionTypeChanged( 84 virtual void OnConnectionTypeChanged(
79 NetworkChangeNotifier::ConnectionType type) OVERRIDE { 85 NetworkChangeNotifier::ConnectionType type) OVERRIDE {
80 if (type != NetworkChangeNotifier::CONNECTION_NONE) { 86 if (type != NetworkChangeNotifier::CONNECTION_NONE) {
81 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OnlineChange", 87 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OnlineChange",
82 SinceLast(&last_connection_change_)); 88 SinceLast(&last_connection_change_));
83 89
84 if (offline_packets_received_) { 90 if (offline_packets_received_) {
85 if ((last_connection_change_ - last_offline_packet_received_) < 91 if ((last_connection_change_ - last_offline_packet_received_) <
86 base::TimeDelta::FromSeconds(5)) { 92 base::TimeDelta::FromSeconds(5)) {
87 // We can compare this sum with the sum of NCN.OfflineDataRecv. 93 // We can compare this sum with the sum of NCN.OfflineDataRecv.
88 UMA_HISTOGRAM_COUNTS_10000( 94 UMA_HISTOGRAM_COUNTS_10000(
89 "NCN.OfflineDataRecvAny5sBeforeOnline", 95 "NCN.OfflineDataRecvAny5sBeforeOnline",
90 offline_packets_received_); 96 offline_packets_received_);
91 } 97 }
92 98
93 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineDataRecvUntilOnline", 99 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineDataRecvUntilOnline",
94 last_connection_change_ - 100 last_connection_change_ -
95 last_offline_packet_received_); 101 last_offline_packet_received_);
96 } 102 }
97 } else { 103 } else {
98 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineChange", 104 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineChange",
99 SinceLast(&last_connection_change_)); 105 SinceLast(&last_connection_change_));
100 } 106 }
107 UMA_HISTOGRAM_MEDIUM_TIMES(
108 "NCN.IPAddressChangeToConnectionTypeChange",
109 last_connection_change_ - last_ip_address_change_);
101 110
102 offline_packets_received_ = 0; 111 offline_packets_received_ = 0;
103 last_connection_type_ = type; 112 last_connection_type_ = type;
104 polling_interval_ = base::TimeDelta::FromSeconds(1); 113 polling_interval_ = base::TimeDelta::FromSeconds(1);
105 } 114 }
106 115
107 // NetworkChangeNotifier::DNSObserver implementation. 116 // NetworkChangeNotifier::DNSObserver implementation.
108 virtual void OnDNSChanged() OVERRIDE { 117 virtual void OnDNSChanged() OVERRIDE {
109 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.DNSConfigChange", 118 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.DNSConfigChange",
110 SinceLast(&last_dns_change_)); 119 SinceLast(&last_dns_change_));
111 } 120 }
112 121
122 // NetworkChangeNotifier::NetworkChangeObserver implementation.
123 virtual void OnNetworkChanged(
124 NetworkChangeNotifier::ConnectionType type) OVERRIDE {
125 if (type != NetworkChangeNotifier::CONNECTION_NONE) {
126 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOnlineChange",
127 SinceLast(&last_network_change_));
128 } else {
129 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOfflineChange",
130 SinceLast(&last_network_change_));
131 }
132 }
133
113 // Record histogram data whenever we receive a packet but think we're 134 // Record histogram data whenever we receive a packet but think we're
114 // offline. Should only be called from the network thread. 135 // offline. Should only be called from the network thread.
115 void NotifyDataReceived(const GURL& source) { 136 void NotifyDataReceived(const GURL& source) {
116 if (last_connection_type_ != NetworkChangeNotifier::CONNECTION_NONE || 137 if (last_connection_type_ != NetworkChangeNotifier::CONNECTION_NONE ||
117 IsLocalhost(source.host()) || 138 IsLocalhost(source.host()) ||
118 !(source.SchemeIs("http") || source.SchemeIs("https"))) { 139 !(source.SchemeIs("http") || source.SchemeIs("https"))) {
119 return; 140 return;
120 } 141 }
121 142
122 base::TimeTicks current_time = base::TimeTicks::Now(); 143 base::TimeTicks current_time = base::TimeTicks::Now();
(...skipping 23 matching lines...) Expand all
146 static base::TimeDelta SinceLast(base::TimeTicks *last_time) { 167 static base::TimeDelta SinceLast(base::TimeTicks *last_time) {
147 base::TimeTicks current_time = base::TimeTicks::Now(); 168 base::TimeTicks current_time = base::TimeTicks::Now();
148 base::TimeDelta delta = current_time - *last_time; 169 base::TimeDelta delta = current_time - *last_time;
149 *last_time = current_time; 170 *last_time = current_time;
150 return delta; 171 return delta;
151 } 172 }
152 173
153 base::TimeTicks last_ip_address_change_; 174 base::TimeTicks last_ip_address_change_;
154 base::TimeTicks last_connection_change_; 175 base::TimeTicks last_connection_change_;
155 base::TimeTicks last_dns_change_; 176 base::TimeTicks last_dns_change_;
177 base::TimeTicks last_network_change_;
156 base::TimeTicks last_offline_packet_received_; 178 base::TimeTicks last_offline_packet_received_;
157 base::TimeTicks last_polled_connection_; 179 base::TimeTicks last_polled_connection_;
158 // |polling_interval_| is initialized by |OnConnectionTypeChanged| on our 180 // |polling_interval_| is initialized by |OnConnectionTypeChanged| on our
159 // first transition to offline and on subsequent transitions. Once offline, 181 // first transition to offline and on subsequent transitions. Once offline,
160 // |polling_interval_| doubles as offline data is received and we poll 182 // |polling_interval_| doubles as offline data is received and we poll
161 // with |NetworkChangeNotifier::GetConnectionType| to verify the connection 183 // with |NetworkChangeNotifier::GetConnectionType| to verify the connection
162 // state. 184 // state.
163 base::TimeDelta polling_interval_; 185 base::TimeDelta polling_interval_;
164 // |last_connection_type_| is the last value passed to 186 // |last_connection_type_| is the last value passed to
165 // |OnConnectionTypeChanged|. 187 // |OnConnectionTypeChanged|.
(...skipping 20 matching lines...) Expand all
186 void SetDnsConfig(const DnsConfig& dns_config) { 208 void SetDnsConfig(const DnsConfig& dns_config) {
187 base::AutoLock lock(lock_); 209 base::AutoLock lock(lock_);
188 dns_config_ = dns_config; 210 dns_config_ = dns_config;
189 } 211 }
190 212
191 private: 213 private:
192 mutable base::Lock lock_; 214 mutable base::Lock lock_;
193 DnsConfig dns_config_; 215 DnsConfig dns_config_;
194 }; 216 };
195 217
218 NetworkChangeNotifier::NetworkChangeCalculatorParams::
219 NetworkChangeCalculatorParams() {
220 }
221
222 // Calculates NetworkChange signal from IPAddress and ConnectionType signals.
223 class NetworkChangeNotifier::NetworkChangeCalculator
224 : public ConnectionTypeObserver,
225 public IPAddressObserver {
226 public:
227 NetworkChangeCalculator(const NetworkChangeCalculatorParams& params)
228 : params_(params),
229 have_announced_(false),
230 last_announced_connection_type_(CONNECTION_NONE),
231 pending_connection_type_(CONNECTION_NONE) {}
232
233 void Init() {
234 AddConnectionTypeObserver(this);
235 AddIPAddressObserver(this);
236 }
237
238 virtual ~NetworkChangeCalculator() {
239 RemoveConnectionTypeObserver(this);
240 RemoveIPAddressObserver(this);
241 }
242
243 // NetworkChangeNotifier::IPAddressObserver implementation.
244 virtual void OnIPAddressChanged() OVERRIDE {
245 base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
246 ? params_.ip_address_offline_delay_ : params_.ip_address_online_delay_;
247 // Cancels any previous timer.
248 timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify);
249 }
250
251 // NetworkChangeNotifier::ConnectionTypeObserver implementation.
252 virtual void OnConnectionTypeChanged(ConnectionType type) OVERRIDE {
253 pending_connection_type_ = type;
254 base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
255 ? params_.connection_type_offline_delay_
256 : params_.connection_type_online_delay_;
257 // Cancels any previous timer.
258 timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify);
259 }
260
261 private:
262 void Notify() {
263 // Don't bother signaling about dead connections.
264 if (have_announced_ &&
265 (last_announced_connection_type_ == CONNECTION_NONE) &&
266 (pending_connection_type_ == CONNECTION_NONE)) {
267 return;
268 }
269 have_announced_ = true;
270 last_announced_connection_type_ = pending_connection_type_;
271 // Immediately before sending out an online signal, send out an offline
272 // signal to perform any destructive actions before constructive actions.
273 if (pending_connection_type_ != CONNECTION_NONE)
274 NetworkChangeNotifier::NotifyObserversOfNetworkChange(CONNECTION_NONE);
275 NetworkChangeNotifier::NotifyObserversOfNetworkChange(
276 pending_connection_type_);
277 }
278
279 const NetworkChangeCalculatorParams params_;
280
281 // Indicates if NotifyObserversOfNetworkChange has been called yet.
282 bool have_announced_;
283 // Last value passed to NotifyObserversOfNetworkChange.
284 ConnectionType last_announced_connection_type_;
285 // Value to pass to NotifyObserversOfNetworkChange when Notify is called.
286 ConnectionType pending_connection_type_;
287 // Used to delay notifications so duplicates can be combined.
288 base::OneShotTimer<NetworkChangeCalculator> timer_;
289 };
290
196 NetworkChangeNotifier::~NetworkChangeNotifier() { 291 NetworkChangeNotifier::~NetworkChangeNotifier() {
197 DCHECK_EQ(this, g_network_change_notifier); 292 DCHECK_EQ(this, g_network_change_notifier);
198 g_network_change_notifier = NULL; 293 g_network_change_notifier = NULL;
199 } 294 }
200 295
201 // static 296 // static
202 void NetworkChangeNotifier::SetFactory( 297 void NetworkChangeNotifier::SetFactory(
203 NetworkChangeNotifierFactory* factory) { 298 NetworkChangeNotifierFactory* factory) {
204 CHECK(!g_network_change_notifier_factory); 299 CHECK(!g_network_change_notifier_factory);
205 g_network_change_notifier_factory = factory; 300 g_network_change_notifier_factory = factory;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 } 434 }
340 } 435 }
341 436
342 void NetworkChangeNotifier::AddDNSObserver(DNSObserver* observer) { 437 void NetworkChangeNotifier::AddDNSObserver(DNSObserver* observer) {
343 if (g_network_change_notifier) { 438 if (g_network_change_notifier) {
344 g_network_change_notifier->resolver_state_observer_list_->AddObserver( 439 g_network_change_notifier->resolver_state_observer_list_->AddObserver(
345 observer); 440 observer);
346 } 441 }
347 } 442 }
348 443
444 void NetworkChangeNotifier::AddNetworkChangeObserver(
445 NetworkChangeObserver* observer) {
446 if (g_network_change_notifier) {
447 g_network_change_notifier->network_change_observer_list_->AddObserver(
448 observer);
449 }
450 }
451
349 void NetworkChangeNotifier::RemoveIPAddressObserver( 452 void NetworkChangeNotifier::RemoveIPAddressObserver(
350 IPAddressObserver* observer) { 453 IPAddressObserver* observer) {
351 if (g_network_change_notifier) { 454 if (g_network_change_notifier) {
352 g_network_change_notifier->ip_address_observer_list_->RemoveObserver( 455 g_network_change_notifier->ip_address_observer_list_->RemoveObserver(
353 observer); 456 observer);
354 } 457 }
355 } 458 }
356 459
357 void NetworkChangeNotifier::RemoveConnectionTypeObserver( 460 void NetworkChangeNotifier::RemoveConnectionTypeObserver(
358 ConnectionTypeObserver* observer) { 461 ConnectionTypeObserver* observer) {
359 if (g_network_change_notifier) { 462 if (g_network_change_notifier) {
360 g_network_change_notifier->connection_type_observer_list_->RemoveObserver( 463 g_network_change_notifier->connection_type_observer_list_->RemoveObserver(
361 observer); 464 observer);
362 } 465 }
363 } 466 }
364 467
365 void NetworkChangeNotifier::RemoveDNSObserver(DNSObserver* observer) { 468 void NetworkChangeNotifier::RemoveDNSObserver(DNSObserver* observer) {
366 if (g_network_change_notifier) { 469 if (g_network_change_notifier) {
367 g_network_change_notifier->resolver_state_observer_list_->RemoveObserver( 470 g_network_change_notifier->resolver_state_observer_list_->RemoveObserver(
368 observer); 471 observer);
369 } 472 }
370 } 473 }
371 474
372 NetworkChangeNotifier::NetworkChangeNotifier() 475 void NetworkChangeNotifier::RemoveNetworkChangeObserver(
476 NetworkChangeObserver* observer) {
477 if (g_network_change_notifier) {
478 g_network_change_notifier->network_change_observer_list_->RemoveObserver(
479 observer);
480 }
481 }
482
483 NetworkChangeNotifier::NetworkChangeNotifier(
484 const NetworkChangeCalculatorParams& params
485 /*= NetworkChangeCalculatorParams()*/)
373 : ip_address_observer_list_( 486 : ip_address_observer_list_(
374 new ObserverListThreadSafe<IPAddressObserver>( 487 new ObserverListThreadSafe<IPAddressObserver>(
375 ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)), 488 ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)),
376 connection_type_observer_list_( 489 connection_type_observer_list_(
377 new ObserverListThreadSafe<ConnectionTypeObserver>( 490 new ObserverListThreadSafe<ConnectionTypeObserver>(
378 ObserverListBase<ConnectionTypeObserver>::NOTIFY_EXISTING_ONLY)), 491 ObserverListBase<ConnectionTypeObserver>::NOTIFY_EXISTING_ONLY)),
379 resolver_state_observer_list_( 492 resolver_state_observer_list_(
380 new ObserverListThreadSafe<DNSObserver>( 493 new ObserverListThreadSafe<DNSObserver>(
381 ObserverListBase<DNSObserver>::NOTIFY_EXISTING_ONLY)), 494 ObserverListBase<DNSObserver>::NOTIFY_EXISTING_ONLY)),
495 network_change_observer_list_(
496 new ObserverListThreadSafe<NetworkChangeObserver>(
497 ObserverListBase<NetworkChangeObserver>::NOTIFY_EXISTING_ONLY)),
382 network_state_(new NetworkState()), 498 network_state_(new NetworkState()),
383 histogram_watcher_(new HistogramWatcher()) { 499 histogram_watcher_(new HistogramWatcher()),
500 network_change_calculator_(new NetworkChangeCalculator(params)) {
384 DCHECK(!g_network_change_notifier); 501 DCHECK(!g_network_change_notifier);
385 g_network_change_notifier = this; 502 g_network_change_notifier = this;
503 network_change_calculator_->Init();
386 } 504 }
387 505
388 #if defined(OS_LINUX) 506 #if defined(OS_LINUX)
389 const internal::AddressTrackerLinux* 507 const internal::AddressTrackerLinux*
390 NetworkChangeNotifier::GetAddressTrackerInternal() const { 508 NetworkChangeNotifier::GetAddressTrackerInternal() const {
391 return NULL; 509 return NULL;
392 } 510 }
393 #endif 511 #endif
394 512
395 // static 513 // static
(...skipping 21 matching lines...) Expand all
417 } 535 }
418 536
419 void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange() { 537 void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange() {
420 if (g_network_change_notifier) { 538 if (g_network_change_notifier) {
421 g_network_change_notifier->connection_type_observer_list_->Notify( 539 g_network_change_notifier->connection_type_observer_list_->Notify(
422 &ConnectionTypeObserver::OnConnectionTypeChanged, 540 &ConnectionTypeObserver::OnConnectionTypeChanged,
423 GetConnectionType()); 541 GetConnectionType());
424 } 542 }
425 } 543 }
426 544
545 void NetworkChangeNotifier::NotifyObserversOfNetworkChange(
546 ConnectionType type) {
547 if (g_network_change_notifier) {
548 g_network_change_notifier->network_change_observer_list_->Notify(
549 &NetworkChangeObserver::OnNetworkChanged,
550 type);
551 }
552 }
553
427 NetworkChangeNotifier::DisableForTest::DisableForTest() 554 NetworkChangeNotifier::DisableForTest::DisableForTest()
428 : network_change_notifier_(g_network_change_notifier) { 555 : network_change_notifier_(g_network_change_notifier) {
429 DCHECK(g_network_change_notifier); 556 DCHECK(g_network_change_notifier);
430 g_network_change_notifier = NULL; 557 g_network_change_notifier = NULL;
431 } 558 }
432 559
433 NetworkChangeNotifier::DisableForTest::~DisableForTest() { 560 NetworkChangeNotifier::DisableForTest::~DisableForTest() {
434 DCHECK(!g_network_change_notifier); 561 DCHECK(!g_network_change_notifier);
435 g_network_change_notifier = network_change_notifier_; 562 g_network_change_notifier = network_change_notifier_;
436 } 563 }
437 564
438 } // namespace net 565 } // namespace net
OLDNEW
« no previous file with comments | « net/base/network_change_notifier.h ('k') | net/base/network_change_notifier_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698