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

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

Powered by Google App Engine
This is Rietveld 408576698