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_win.h" | 5 #include "net/base/network_change_notifier_win.h" |
6 | 6 |
7 #include <iphlpapi.h> | 7 #include <iphlpapi.h> |
8 #include <winsock2.h> | 8 #include <winsock2.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 private: | 48 private: |
49 scoped_ptr<DnsConfigService> service_; | 49 scoped_ptr<DnsConfigService> service_; |
50 | 50 |
51 DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread); | 51 DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread); |
52 }; | 52 }; |
53 | 53 |
54 NetworkChangeNotifierWin::NetworkChangeNotifierWin() | 54 NetworkChangeNotifierWin::NetworkChangeNotifierWin() |
55 : NetworkChangeNotifier(NetworkChangeCalculatorParamsWin()), | 55 : NetworkChangeNotifier(NetworkChangeCalculatorParamsWin()), |
56 is_watching_(false), | 56 is_watching_(false), |
57 network_change_event_handle_(NULL), | |
58 sequential_failures_(0), | 57 sequential_failures_(0), |
59 weak_factory_(this), | 58 weak_factory_(this), |
60 dns_config_service_thread_(new DnsConfigServiceThread()), | 59 dns_config_service_thread_(new DnsConfigServiceThread()), |
61 last_computed_connection_type_(RecomputeCurrentConnectionType()), | 60 last_computed_connection_type_(RecomputeCurrentConnectionType()), |
62 last_announced_offline_( | 61 last_announced_offline_( |
63 last_computed_connection_type_ == CONNECTION_NONE) { | 62 last_computed_connection_type_ == CONNECTION_NONE) { |
64 memset(&addr_overlapped_, 0, sizeof addr_overlapped_); | 63 memset(&addr_overlapped_, 0, sizeof addr_overlapped_); |
65 addr_overlapped_.hEvent = WSACreateEvent(); | 64 addr_overlapped_.hEvent = WSACreateEvent(); |
66 } | 65 } |
67 | 66 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 ConnectionType connection_type) { | 215 ConnectionType connection_type) { |
217 base::AutoLock auto_lock(last_computed_connection_type_lock_); | 216 base::AutoLock auto_lock(last_computed_connection_type_lock_); |
218 last_computed_connection_type_ = connection_type; | 217 last_computed_connection_type_ = connection_type; |
219 } | 218 } |
220 | 219 |
221 void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { | 220 void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { |
222 DCHECK(CalledOnValidThread()); | 221 DCHECK(CalledOnValidThread()); |
223 DCHECK(is_watching_); | 222 DCHECK(is_watching_); |
224 is_watching_ = false; | 223 is_watching_ = false; |
225 | 224 |
226 DWORD bytes; | |
227 BOOL network_changed = GetOverlappedResult(network_change_event_handle_, &addr
_overlapped_, &bytes, TRUE); | |
228 | |
229 // Start watching for the next address change. | 225 // Start watching for the next address change. |
230 WatchForAddressChange(); | 226 WatchForAddressChange(); |
231 | 227 |
232 // If network_changed is 0 an error occured (e.g. GetLastError() = 995 = ERROR
_OPERATION_ABORTED). | 228 NotifyObservers(); |
233 if (network_changed != 0) | |
234 NotifyObservers(); | |
235 } | 229 } |
236 | 230 |
237 void NetworkChangeNotifierWin::NotifyObservers() { | 231 void NetworkChangeNotifierWin::NotifyObservers() { |
238 DCHECK(CalledOnValidThread()); | 232 DCHECK(CalledOnValidThread()); |
239 SetCurrentConnectionType(RecomputeCurrentConnectionType()); | 233 SetCurrentConnectionType(RecomputeCurrentConnectionType()); |
240 NotifyObserversOfIPAddressChange(); | 234 NotifyObserversOfIPAddressChange(); |
241 | 235 |
242 // Calling GetConnectionType() at this very moment is likely to give | 236 // Calling GetConnectionType() at this very moment is likely to give |
243 // the wrong result, so we delay that until a little bit later. | 237 // the wrong result, so we delay that until a little bit later. |
244 // | 238 // |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 } | 288 } |
295 | 289 |
296 bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { | 290 bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { |
297 DCHECK(CalledOnValidThread()); | 291 DCHECK(CalledOnValidThread()); |
298 | 292 |
299 if (!dns_config_service_thread_->IsRunning()) { | 293 if (!dns_config_service_thread_->IsRunning()) { |
300 dns_config_service_thread_->StartWithOptions( | 294 dns_config_service_thread_->StartWithOptions( |
301 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 295 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
302 } | 296 } |
303 | 297 |
304 | 298 HANDLE handle = NULL; |
305 DWORD ret = NotifyAddrChange(&network_change_event_handle_, &addr_overlapped_)
; | 299 DWORD ret = NotifyAddrChange(&handle, &addr_overlapped_); |
306 if (ret != ERROR_IO_PENDING) | 300 if (ret != ERROR_IO_PENDING) |
307 return false; | 301 return false; |
308 | 302 |
309 addr_watcher_.StartWatching(addr_overlapped_.hEvent, this); | 303 addr_watcher_.StartWatching(addr_overlapped_.hEvent, this); |
310 return true; | 304 return true; |
311 } | 305 } |
312 | 306 |
313 void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { | 307 void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { |
314 SetCurrentConnectionType(RecomputeCurrentConnectionType()); | 308 SetCurrentConnectionType(RecomputeCurrentConnectionType()); |
315 bool current_offline = IsOffline(); | 309 bool current_offline = IsOffline(); |
316 offline_polls_++; | 310 offline_polls_++; |
317 // If we continue to appear offline, delay sending out the notification in | 311 // If we continue to appear offline, delay sending out the notification in |
318 // case we appear to go online within 20 seconds. UMA histogram data shows | 312 // case we appear to go online within 20 seconds. UMA histogram data shows |
319 // we may not detect the transition to online state after 1 second but within | 313 // we may not detect the transition to online state after 1 second but within |
320 // 20 seconds we generally do. | 314 // 20 seconds we generally do. |
321 if (last_announced_offline_ && current_offline && offline_polls_ <= 20) { | 315 if (last_announced_offline_ && current_offline && offline_polls_ <= 20) { |
322 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, | 316 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, |
323 &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange); | 317 &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange); |
324 return; | 318 return; |
325 } | 319 } |
326 if (last_announced_offline_) | 320 if (last_announced_offline_) |
327 UMA_HISTOGRAM_CUSTOM_COUNTS("NCN.OfflinePolls", offline_polls_, 1, 50, 50); | 321 UMA_HISTOGRAM_CUSTOM_COUNTS("NCN.OfflinePolls", offline_polls_, 1, 50, 50); |
328 last_announced_offline_ = current_offline; | 322 last_announced_offline_ = current_offline; |
329 | 323 |
330 NotifyObserversOfConnectionTypeChange(); | 324 NotifyObserversOfConnectionTypeChange(); |
331 } | 325 } |
332 | 326 |
333 } // namespace net | 327 } // namespace net |
OLD | NEW |