| Index: net/base/network_change_notifier_mac.cc
|
| diff --git a/net/base/network_change_notifier_mac.cc b/net/base/network_change_notifier_mac.cc
|
| deleted file mode 100644
|
| index 14ec5542c51cfa0f479e65192f8ab217f0c344c3..0000000000000000000000000000000000000000
|
| --- a/net/base/network_change_notifier_mac.cc
|
| +++ /dev/null
|
| @@ -1,268 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/base/network_change_notifier_mac.h"
|
| -
|
| -#include <netinet/in.h>
|
| -#include <resolv.h>
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/threading/thread.h"
|
| -#include "net/dns/dns_config_service.h"
|
| -
|
| -namespace net {
|
| -
|
| -static bool CalculateReachability(SCNetworkConnectionFlags flags) {
|
| - bool reachable = flags & kSCNetworkFlagsReachable;
|
| - bool connection_required = flags & kSCNetworkFlagsConnectionRequired;
|
| - return reachable && !connection_required;
|
| -}
|
| -
|
| -NetworkChangeNotifier::ConnectionType CalculateConnectionType(
|
| - SCNetworkConnectionFlags flags) {
|
| - bool reachable = CalculateReachability(flags);
|
| - if (reachable) {
|
| -#if defined(OS_IOS)
|
| - return (flags & kSCNetworkReachabilityFlagsIsWWAN) ?
|
| - NetworkChangeNotifier::CONNECTION_3G :
|
| - NetworkChangeNotifier::CONNECTION_WIFI;
|
| -#else
|
| - // TODO(droger): Get something more detailed than CONNECTION_UNKNOWN.
|
| - // http://crbug.com/112937
|
| - return NetworkChangeNotifier::CONNECTION_UNKNOWN;
|
| -#endif // defined(OS_IOS)
|
| - } else {
|
| - return NetworkChangeNotifier::CONNECTION_NONE;
|
| - }
|
| -}
|
| -
|
| -// Thread on which we can run DnsConfigService, which requires a TYPE_IO
|
| -// message loop.
|
| -class NetworkChangeNotifierMac::DnsConfigServiceThread : public base::Thread {
|
| - public:
|
| - DnsConfigServiceThread() : base::Thread("DnsConfigService") {}
|
| -
|
| - ~DnsConfigServiceThread() override { Stop(); }
|
| -
|
| - void Init() override {
|
| - service_ = DnsConfigService::CreateSystemService();
|
| - service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig));
|
| - }
|
| -
|
| - void CleanUp() override { service_.reset(); }
|
| -
|
| - private:
|
| - scoped_ptr<DnsConfigService> service_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread);
|
| -};
|
| -
|
| -NetworkChangeNotifierMac::NetworkChangeNotifierMac()
|
| - : NetworkChangeNotifier(NetworkChangeCalculatorParamsMac()),
|
| - connection_type_(CONNECTION_UNKNOWN),
|
| - connection_type_initialized_(false),
|
| - initial_connection_type_cv_(&connection_type_lock_),
|
| - forwarder_(this),
|
| - dns_config_service_thread_(new DnsConfigServiceThread()) {
|
| - // Must be initialized after the rest of this object, as it may call back into
|
| - // SetInitialConnectionType().
|
| - config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_));
|
| - dns_config_service_thread_->StartWithOptions(
|
| - base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
|
| -}
|
| -
|
| -NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {
|
| - // Delete the ConfigWatcher to join the notifier thread, ensuring that
|
| - // StartReachabilityNotifications() has an opportunity to run to completion.
|
| - config_watcher_.reset();
|
| -
|
| - // Now that StartReachabilityNotifications() has either run to completion or
|
| - // never run at all, unschedule reachability_ if it was previously scheduled.
|
| - if (reachability_.get() && run_loop_.get()) {
|
| - SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(),
|
| - run_loop_.get(),
|
| - kCFRunLoopCommonModes);
|
| - }
|
| -}
|
| -
|
| -// static
|
| -NetworkChangeNotifier::NetworkChangeCalculatorParams
|
| -NetworkChangeNotifierMac::NetworkChangeCalculatorParamsMac() {
|
| - NetworkChangeCalculatorParams params;
|
| - // Delay values arrived at by simple experimentation and adjusted so as to
|
| - // produce a single signal when switching between network connections.
|
| - params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(500);
|
| - params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(500);
|
| - params.connection_type_offline_delay_ =
|
| - base::TimeDelta::FromMilliseconds(1000);
|
| - params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500);
|
| - return params;
|
| -}
|
| -
|
| -NetworkChangeNotifier::ConnectionType
|
| -NetworkChangeNotifierMac::GetCurrentConnectionType() const {
|
| - base::AutoLock lock(connection_type_lock_);
|
| - // Make sure the initial connection type is set before returning.
|
| - while (!connection_type_initialized_) {
|
| - initial_connection_type_cv_.Wait();
|
| - }
|
| - return connection_type_;
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::Forwarder::Init() {
|
| - net_config_watcher_->SetInitialConnectionType();
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::Forwarder::StartReachabilityNotifications() {
|
| - net_config_watcher_->StartReachabilityNotifications();
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::Forwarder::SetDynamicStoreNotificationKeys(
|
| - SCDynamicStoreRef store) {
|
| - net_config_watcher_->SetDynamicStoreNotificationKeys(store);
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::Forwarder::OnNetworkConfigChange(
|
| - CFArrayRef changed_keys) {
|
| - net_config_watcher_->OnNetworkConfigChange(changed_keys);
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::SetInitialConnectionType() {
|
| - // Called on notifier thread.
|
| -
|
| - // Try to reach 0.0.0.0. This is the approach taken by Firefox:
|
| - //
|
| - // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkService.mm
|
| - //
|
| - // From my (adamk) testing on Snow Leopard, 0.0.0.0
|
| - // seems to be reachable if any network connection is available.
|
| - struct sockaddr_in addr = {0};
|
| - addr.sin_len = sizeof(addr);
|
| - addr.sin_family = AF_INET;
|
| - reachability_.reset(SCNetworkReachabilityCreateWithAddress(
|
| - kCFAllocatorDefault, reinterpret_cast<struct sockaddr*>(&addr)));
|
| -
|
| - SCNetworkConnectionFlags flags;
|
| - ConnectionType connection_type = CONNECTION_UNKNOWN;
|
| - if (SCNetworkReachabilityGetFlags(reachability_, &flags)) {
|
| - connection_type = CalculateConnectionType(flags);
|
| - } else {
|
| - LOG(ERROR) << "Could not get initial network connection type,"
|
| - << "assuming online.";
|
| - }
|
| - {
|
| - base::AutoLock lock(connection_type_lock_);
|
| - connection_type_ = connection_type;
|
| - connection_type_initialized_ = true;
|
| - initial_connection_type_cv_.Signal();
|
| - }
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::StartReachabilityNotifications() {
|
| - // Called on notifier thread.
|
| - run_loop_.reset(CFRunLoopGetCurrent());
|
| - CFRetain(run_loop_.get());
|
| -
|
| - DCHECK(reachability_);
|
| - SCNetworkReachabilityContext reachability_context = {
|
| - 0, // version
|
| - this, // user data
|
| - NULL, // retain
|
| - NULL, // release
|
| - NULL // description
|
| - };
|
| - if (!SCNetworkReachabilitySetCallback(
|
| - reachability_,
|
| - &NetworkChangeNotifierMac::ReachabilityCallback,
|
| - &reachability_context)) {
|
| - LOG(DFATAL) << "Could not set network reachability callback";
|
| - reachability_.reset();
|
| - } else if (!SCNetworkReachabilityScheduleWithRunLoop(reachability_,
|
| - run_loop_,
|
| - kCFRunLoopCommonModes)) {
|
| - LOG(DFATAL) << "Could not schedule network reachability on run loop";
|
| - reachability_.reset();
|
| - }
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys(
|
| - SCDynamicStoreRef store) {
|
| -#if defined(OS_IOS)
|
| - // SCDynamicStore API does not exist on iOS.
|
| - NOTREACHED();
|
| -#else
|
| - base::ScopedCFTypeRef<CFMutableArrayRef> notification_keys(
|
| - CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
|
| - base::ScopedCFTypeRef<CFStringRef> key(
|
| - SCDynamicStoreKeyCreateNetworkGlobalEntity(
|
| - NULL, kSCDynamicStoreDomainState, kSCEntNetInterface));
|
| - CFArrayAppendValue(notification_keys.get(), key.get());
|
| - key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity(
|
| - NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4));
|
| - CFArrayAppendValue(notification_keys.get(), key.get());
|
| - key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity(
|
| - NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6));
|
| - CFArrayAppendValue(notification_keys.get(), key.get());
|
| -
|
| - // Set the notification keys. This starts us receiving notifications.
|
| - bool ret = SCDynamicStoreSetNotificationKeys(
|
| - store, notification_keys.get(), NULL);
|
| - // TODO(willchan): Figure out a proper way to handle this rather than crash.
|
| - CHECK(ret);
|
| -#endif // defined(OS_IOS)
|
| -}
|
| -
|
| -void NetworkChangeNotifierMac::OnNetworkConfigChange(CFArrayRef changed_keys) {
|
| -#if defined(OS_IOS)
|
| - // SCDynamicStore API does not exist on iOS.
|
| - NOTREACHED();
|
| -#else
|
| - DCHECK_EQ(run_loop_.get(), CFRunLoopGetCurrent());
|
| -
|
| - for (CFIndex i = 0; i < CFArrayGetCount(changed_keys); ++i) {
|
| - CFStringRef key = static_cast<CFStringRef>(
|
| - CFArrayGetValueAtIndex(changed_keys, i));
|
| - if (CFStringHasSuffix(key, kSCEntNetIPv4) ||
|
| - CFStringHasSuffix(key, kSCEntNetIPv6)) {
|
| - NotifyObserversOfIPAddressChange();
|
| - return;
|
| - }
|
| - if (CFStringHasSuffix(key, kSCEntNetInterface)) {
|
| - // TODO(willchan): Does not appear to be working. Look into this.
|
| - // Perhaps this isn't needed anyway.
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - }
|
| -#endif // defined(OS_IOS)
|
| -}
|
| -
|
| -// static
|
| -void NetworkChangeNotifierMac::ReachabilityCallback(
|
| - SCNetworkReachabilityRef target,
|
| - SCNetworkConnectionFlags flags,
|
| - void* notifier) {
|
| - NetworkChangeNotifierMac* notifier_mac =
|
| - static_cast<NetworkChangeNotifierMac*>(notifier);
|
| -
|
| - DCHECK_EQ(notifier_mac->run_loop_.get(), CFRunLoopGetCurrent());
|
| -
|
| - ConnectionType new_type = CalculateConnectionType(flags);
|
| - ConnectionType old_type;
|
| - {
|
| - base::AutoLock lock(notifier_mac->connection_type_lock_);
|
| - old_type = notifier_mac->connection_type_;
|
| - notifier_mac->connection_type_ = new_type;
|
| - }
|
| - if (old_type != new_type)
|
| - NotifyObserversOfConnectionTypeChange();
|
| -
|
| -#if defined(OS_IOS)
|
| - // On iOS, the SCDynamicStore API does not exist, and we use the reachability
|
| - // API to detect IP address changes instead.
|
| - NotifyObserversOfIPAddressChange();
|
| -#endif // defined(OS_IOS)
|
| -}
|
| -
|
| -} // namespace net
|
|
|