// 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