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

Side by Side Diff: net/base/network_change_notifier_mac.cc

Issue 9147026: API for connection type (Ethernet/WIFI/WWAN ...) in NetworkChangeNotifier. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: sync Created 8 years, 7 months 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
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_mac.h" 5 #include "net/base/network_change_notifier_mac.h"
6 6
7 #include <netinet/in.h> 7 #include <netinet/in.h>
8 8
9 namespace net { 9 namespace net {
10 10
11 static bool CalculateReachability(SCNetworkConnectionFlags flags) { 11 static NetworkChangeNotifier::ConnectionType
wtc 2012/05/11 01:35:05 Nit: NetworkChangeNotifier::ConnectionType is very
12 CalculateReachability(SCNetworkConnectionFlags flags) {
wtc 2012/05/11 01:35:05 IMPORTANT: It seems wrong for a function named Cal
12 bool reachable = flags & kSCNetworkFlagsReachable; 13 bool reachable = flags & kSCNetworkFlagsReachable;
13 bool connection_required = flags & kSCNetworkFlagsConnectionRequired; 14 bool connection_required = flags & kSCNetworkFlagsConnectionRequired;
14 return reachable && !connection_required; 15 // TODO: Return something more detailed than CONNECTION_UNKNOWN.
16 return (reachable && !connection_required) ?
17 NetworkChangeNotifier::CONNECTION_UNKNOWN :
18 NetworkChangeNotifier::CONNECTION_NONE;
15 } 19 }
16 20
17 NetworkChangeNotifierMac::NetworkChangeNotifierMac() 21 NetworkChangeNotifierMac::NetworkChangeNotifierMac()
18 : online_state_(UNINITIALIZED), 22 : connection_type_(CONNECTION_UNKNOWN),
19 initial_state_cv_(&online_state_lock_), 23 initialized_(false),
24 initial_state_cv_(&connection_type_lock_),
20 forwarder_(this) { 25 forwarder_(this) {
21 // Must be initialized after the rest of this object, as it may call back into 26 // Must be initialized after the rest of this object, as it may call back into
22 // SetInitialState(). 27 // SetInitialState().
23 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); 28 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_));
24 } 29 }
25 30
26 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { 31 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {
27 // Delete the ConfigWatcher to join the notifier thread, ensuring that 32 // Delete the ConfigWatcher to join the notifier thread, ensuring that
28 // StartReachabilityNotifications() has an opportunity to run to completion. 33 // StartReachabilityNotifications() has an opportunity to run to completion.
29 config_watcher_.reset(); 34 config_watcher_.reset();
30 35
31 // Now that StartReachabilityNotifications() has either run to completion or 36 // Now that StartReachabilityNotifications() has either run to completion or
32 // never run at all, unschedule reachability_ if it was previously scheduled. 37 // never run at all, unschedule reachability_ if it was previously scheduled.
33 if (reachability_.get() && run_loop_.get()) { 38 if (reachability_.get() && run_loop_.get()) {
34 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(), 39 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(),
35 run_loop_.get(), 40 run_loop_.get(),
36 kCFRunLoopCommonModes); 41 kCFRunLoopCommonModes);
37 } 42 }
38 } 43 }
39 44
40 bool NetworkChangeNotifierMac::IsCurrentlyOffline() const { 45 NetworkChangeNotifier::ConnectionType
41 base::AutoLock lock(online_state_lock_); 46 NetworkChangeNotifierMac::GetCurrentConnectionType() const {
47 base::AutoLock lock(connection_type_lock_);
42 // Make sure the initial state is set before returning. 48 // Make sure the initial state is set before returning.
43 while (online_state_ == UNINITIALIZED) { 49 while (!initialized_) {
44 initial_state_cv_.Wait(); 50 initial_state_cv_.Wait();
45 } 51 }
46 return online_state_ == OFFLINE; 52 return connection_type_;
47 } 53 }
48 54
49 void NetworkChangeNotifierMac::SetInitialState() { 55 void NetworkChangeNotifierMac::SetInitialState() {
50 // Called on notifier thread. 56 // Called on notifier thread.
51 57
52 // Try to reach 0.0.0.0. This is the approach taken by Firefox: 58 // Try to reach 0.0.0.0. This is the approach taken by Firefox:
53 // 59 //
54 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm 60 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm
55 // 61 //
56 // From my (adamk) testing on Snow Leopard, 0.0.0.0 62 // From my (adamk) testing on Snow Leopard, 0.0.0.0
57 // seems to be reachable if any network connection is available. 63 // seems to be reachable if any network connection is available.
58 struct sockaddr_in addr = {0}; 64 struct sockaddr_in addr = {0};
59 addr.sin_len = sizeof(addr); 65 addr.sin_len = sizeof(addr);
60 addr.sin_family = AF_INET; 66 addr.sin_family = AF_INET;
61 reachability_.reset(SCNetworkReachabilityCreateWithAddress( 67 reachability_.reset(SCNetworkReachabilityCreateWithAddress(
62 kCFAllocatorDefault, reinterpret_cast<struct sockaddr*>(&addr))); 68 kCFAllocatorDefault, reinterpret_cast<struct sockaddr*>(&addr)));
63 69
64 SCNetworkConnectionFlags flags; 70 SCNetworkConnectionFlags flags;
65 bool reachable = true; 71 ConnectionType reachable = CONNECTION_UNKNOWN;
66 if (SCNetworkReachabilityGetFlags(reachability_, &flags)) 72 if (SCNetworkReachabilityGetFlags(reachability_, &flags))
67 reachable = CalculateReachability(flags); 73 reachable = CalculateReachability(flags);
68 else 74 else
69 LOG(ERROR) << "Could not get initial network state, assuming online."; 75 LOG(ERROR) << "Could not get initial network state, assuming online.";
70 { 76 {
71 base::AutoLock lock(online_state_lock_); 77 base::AutoLock lock(connection_type_lock_);
72 online_state_ = reachable ? ONLINE : OFFLINE; 78 connection_type_ = reachable;
79 initialized_ = true;
73 initial_state_cv_.Signal(); 80 initial_state_cv_.Signal();
74 } 81 }
75 } 82 }
76 83
77 void NetworkChangeNotifierMac::StartReachabilityNotifications() { 84 void NetworkChangeNotifierMac::StartReachabilityNotifications() {
78 // Called on notifier thread. 85 // Called on notifier thread.
79 run_loop_.reset(CFRunLoopGetCurrent()); 86 run_loop_.reset(CFRunLoopGetCurrent());
80 CFRetain(run_loop_.get()); 87 CFRetain(run_loop_.get());
81 88
82 DCHECK(reachability_); 89 DCHECK(reachability_);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 // static 153 // static
147 void NetworkChangeNotifierMac::ReachabilityCallback( 154 void NetworkChangeNotifierMac::ReachabilityCallback(
148 SCNetworkReachabilityRef target, 155 SCNetworkReachabilityRef target,
149 SCNetworkConnectionFlags flags, 156 SCNetworkConnectionFlags flags,
150 void* notifier) { 157 void* notifier) {
151 NetworkChangeNotifierMac* notifier_mac = 158 NetworkChangeNotifierMac* notifier_mac =
152 static_cast<NetworkChangeNotifierMac*>(notifier); 159 static_cast<NetworkChangeNotifierMac*>(notifier);
153 160
154 DCHECK_EQ(notifier_mac->run_loop_.get(), CFRunLoopGetCurrent()); 161 DCHECK_EQ(notifier_mac->run_loop_.get(), CFRunLoopGetCurrent());
155 162
156 OnlineState new_state = CalculateReachability(flags) ? ONLINE : OFFLINE; 163 ConnectionType new_type = CalculateReachability(flags);
157 OnlineState old_state; 164 ConnectionType old_type;
158 { 165 {
159 base::AutoLock lock(notifier_mac->online_state_lock_); 166 base::AutoLock lock(notifier_mac->connection_type_lock_);
160 old_state = notifier_mac->online_state_; 167 old_type = notifier_mac->connection_type_;
161 notifier_mac->online_state_ = new_state; 168 notifier_mac->connection_type_ = new_type;
162 } 169 }
163 if (old_state != new_state) 170 if (old_type != new_type)
164 NotifyObserversOfOnlineStateChange(); 171 NotifyObserversOfConnectionTypeChange();
165 } 172 }
166 173
167 } // namespace net 174 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698