OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |