Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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::ConnectionState |
| 12 CalculateReachability(SCNetworkConnectionFlags flags) { | |
| 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 return (reachable && !connection_required) ? |
| 16 NetworkChangeNotifier::ETHERNET : NetworkChangeNotifier::NONE; | |
| 15 } | 17 } |
| 16 | 18 |
| 17 NetworkChangeNotifierMac::NetworkChangeNotifierMac() | 19 NetworkChangeNotifierMac::NetworkChangeNotifierMac() |
| 18 : online_state_(UNINITIALIZED), | 20 : connection_state_(UNKNOWN), |
| 19 initial_state_cv_(&online_state_lock_), | 21 initial_state_cv_(&connection_state_lock_), |
| 20 forwarder_(this) { | 22 forwarder_(this) { |
| 21 // Must be initialized after the rest of this object, as it may call back into | 23 // Must be initialized after the rest of this object, as it may call back into |
| 22 // SetInitialState(). | 24 // SetInitialState(). |
| 23 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); | 25 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); |
| 24 } | 26 } |
| 25 | 27 |
| 26 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { | 28 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { |
| 27 // Delete the ConfigWatcher to join the notifier thread, ensuring that | 29 // Delete the ConfigWatcher to join the notifier thread, ensuring that |
| 28 // SetDynamicStoreNotificationKeys() has an opportunity to run to completion. | 30 // SetDynamicStoreNotificationKeys() has an opportunity to run to completion. |
| 29 config_watcher_.reset(); | 31 config_watcher_.reset(); |
| 30 | 32 |
| 31 // Now that SetDynamicStoreNotificationKeys has either run to completion or | 33 // Now that SetDynamicStoreNotificationKeys has either run to completion or |
| 32 // never run at all, unschedule reachability_ if it was previously scheduled. | 34 // never run at all, unschedule reachability_ if it was previously scheduled. |
| 33 if (reachability_.get() && run_loop_.get()) { | 35 if (reachability_.get() && run_loop_.get()) { |
| 34 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(), | 36 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(), |
| 35 run_loop_.get(), | 37 run_loop_.get(), |
| 36 kCFRunLoopCommonModes); | 38 kCFRunLoopCommonModes); |
| 37 } | 39 } |
| 38 } | 40 } |
| 39 | 41 |
| 40 bool NetworkChangeNotifierMac::IsCurrentlyOffline() const { | 42 NetworkChangeNotifier::ConnectionState |
| 41 base::AutoLock lock(online_state_lock_); | 43 NetworkChangeNotifierMac::GetCurrentConnectionState() const { |
| 44 base::AutoLock lock(connection_state_lock_); | |
| 42 // Make sure the initial state is set before returning. | 45 // Make sure the initial state is set before returning. |
| 43 while (online_state_ == UNINITIALIZED) { | 46 while (connection_state_ == UNKNOWN) { |
|
droger_google
2012/01/10 11:48:26
Here, the Mac implementation uses UNKNOWN with a U
| |
| 44 initial_state_cv_.Wait(); | 47 initial_state_cv_.Wait(); |
| 45 } | 48 } |
| 46 return online_state_ == OFFLINE; | 49 return connection_state_; |
| 47 } | 50 } |
| 48 | 51 |
| 49 void NetworkChangeNotifierMac::SetInitialState() { | 52 void NetworkChangeNotifierMac::SetInitialState() { |
| 50 // Called on notifier thread. | 53 // Called on notifier thread. |
| 51 | 54 |
| 52 // Try to reach 0.0.0.0. This is the approach taken by Firefox: | 55 // Try to reach 0.0.0.0. This is the approach taken by Firefox: |
| 53 // | 56 // |
| 54 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm | 57 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm |
| 55 // | 58 // |
| 56 // From my (adamk) testing on Snow Leopard, 0.0.0.0 | 59 // From my (adamk) testing on Snow Leopard, 0.0.0.0 |
| 57 // seems to be reachable if any network connection is available. | 60 // seems to be reachable if any network connection is available. |
| 58 struct sockaddr_in addr = {0}; | 61 struct sockaddr_in addr = {0}; |
| 59 addr.sin_len = sizeof(addr); | 62 addr.sin_len = sizeof(addr); |
| 60 addr.sin_family = AF_INET; | 63 addr.sin_family = AF_INET; |
| 61 reachability_.reset(SCNetworkReachabilityCreateWithAddress( | 64 reachability_.reset(SCNetworkReachabilityCreateWithAddress( |
| 62 kCFAllocatorDefault, reinterpret_cast<struct sockaddr*>(&addr))); | 65 kCFAllocatorDefault, reinterpret_cast<struct sockaddr*>(&addr))); |
| 63 | 66 |
| 64 SCNetworkConnectionFlags flags; | 67 SCNetworkConnectionFlags flags; |
| 65 bool reachable = true; | 68 ConnectionState reachable = ETHERNET; |
| 66 if (SCNetworkReachabilityGetFlags(reachability_, &flags)) | 69 if (SCNetworkReachabilityGetFlags(reachability_, &flags)) |
| 67 reachable = CalculateReachability(flags); | 70 reachable = CalculateReachability(flags); |
| 68 else | 71 else |
| 69 LOG(ERROR) << "Could not get initial network state, assuming online."; | 72 LOG(ERROR) << "Could not get initial network state, assuming online."; |
| 70 { | 73 { |
| 71 base::AutoLock lock(online_state_lock_); | 74 base::AutoLock lock(connection_state_lock_); |
| 72 online_state_ = reachable ? ONLINE : OFFLINE; | 75 connection_state_ = reachable; |
| 73 initial_state_cv_.Signal(); | 76 initial_state_cv_.Signal(); |
| 74 } | 77 } |
| 75 } | 78 } |
| 76 | 79 |
| 77 void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys( | 80 void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys( |
| 78 SCDynamicStoreRef store) { | 81 SCDynamicStoreRef store) { |
| 79 // Called on notifier thread. | 82 // Called on notifier thread. |
| 80 run_loop_.reset(CFRunLoopGetCurrent()); | 83 run_loop_.reset(CFRunLoopGetCurrent()); |
| 81 CFRetain(run_loop_.get()); | 84 CFRetain(run_loop_.get()); |
| 82 | 85 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 // static | 147 // static |
| 145 void NetworkChangeNotifierMac::ReachabilityCallback( | 148 void NetworkChangeNotifierMac::ReachabilityCallback( |
| 146 SCNetworkReachabilityRef target, | 149 SCNetworkReachabilityRef target, |
| 147 SCNetworkConnectionFlags flags, | 150 SCNetworkConnectionFlags flags, |
| 148 void* notifier) { | 151 void* notifier) { |
| 149 NetworkChangeNotifierMac* notifier_mac = | 152 NetworkChangeNotifierMac* notifier_mac = |
| 150 static_cast<NetworkChangeNotifierMac*>(notifier); | 153 static_cast<NetworkChangeNotifierMac*>(notifier); |
| 151 | 154 |
| 152 DCHECK_EQ(notifier_mac->run_loop_.get(), CFRunLoopGetCurrent()); | 155 DCHECK_EQ(notifier_mac->run_loop_.get(), CFRunLoopGetCurrent()); |
| 153 | 156 |
| 154 OnlineState new_state = CalculateReachability(flags) ? ONLINE : OFFLINE; | 157 ConnectionState new_state = CalculateReachability(flags) ? ETHERNET : NONE; |
| 155 OnlineState old_state; | 158 ConnectionState old_state; |
| 156 { | 159 { |
| 157 base::AutoLock lock(notifier_mac->online_state_lock_); | 160 base::AutoLock lock(notifier_mac->connection_state_lock_); |
| 158 old_state = notifier_mac->online_state_; | 161 old_state = notifier_mac->connection_state_; |
| 159 notifier_mac->online_state_ = new_state; | 162 notifier_mac->connection_state_ = new_state; |
| 160 } | 163 } |
| 161 if (old_state != new_state) | 164 if (old_state != new_state) |
| 162 NotifyObserversOfOnlineStateChange(); | 165 NotifyObserversOfConnectionStateChange(); |
| 163 } | 166 } |
| 164 | 167 |
| 165 } // namespace net | 168 } // namespace net |
| OLD | NEW |