| // Copyright (c) 2010 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 <SystemConfiguration/SCDynamicStoreKey.h> |
| #include <SystemConfiguration/SCSchemaDefinitions.h> |
| |
| #include "base/mac/scoped_cftyperef.h" |
| |
| namespace net { |
| |
| NetworkChangeNotifierMac::NetworkChangeNotifierMac() |
| : forwarder_(this), |
| config_watcher_(&forwarder_) {} |
| NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {} |
| |
| bool NetworkChangeNotifierMac::IsCurrentlyOffline() const { |
| // TODO(eroman): http://crbug.com/53473 |
| return false; |
| } |
| |
| void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys( |
| SCDynamicStoreRef store) { |
| // Called on notifier thread. |
| base::mac::ScopedCFTypeRef<CFMutableArrayRef> notification_keys( |
| CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); |
| base::mac::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); |
| } |
| |
| void NetworkChangeNotifierMac::OnNetworkConfigChange(CFArrayRef changed_keys) { |
| // Called on notifier thread. |
| |
| 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(); |
| } |
| } |
| } |
| |
| } // namespace net |