1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/base/network_change_notifier_mac.h" 6 7 #include <SystemConfiguration/SCDynamicStoreKey.h> 8 #include <SystemConfiguration/SCSchemaDefinitions.h> 9 10 #include "base/mac/scoped_cftyperef.h" 11 12 namespace net { 13 14 NetworkChangeNotifierMac::NetworkChangeNotifierMac() 15 : forwarder_(this), 16 config_watcher_(&forwarder_) {} 17 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {} 18 19 bool NetworkChangeNotifierMac::IsCurrentlyOffline() const { 20 // TODO(eroman): http://crbug.com/53473 21 return false; 22 } 23 24 void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys( 25 SCDynamicStoreRef store) { 26 // Called on notifier thread. 27 base::mac::ScopedCFTypeRef<CFMutableArrayRef> notification_keys( 28 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); 29 base::mac::ScopedCFTypeRef<CFStringRef> key( 30 SCDynamicStoreKeyCreateNetworkGlobalEntity( 31 NULL, kSCDynamicStoreDomainState, kSCEntNetInterface)); 32 CFArrayAppendValue(notification_keys.get(), key.get()); 33 key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity( 34 NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4)); 35 CFArrayAppendValue(notification_keys.get(), key.get()); 36 key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity( 37 NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6)); 38 CFArrayAppendValue(notification_keys.get(), key.get()); 39 40 // Set the notification keys. This starts us receiving notifications. 41 bool ret = SCDynamicStoreSetNotificationKeys( 42 store, notification_keys.get(), NULL); 43 // TODO(willchan): Figure out a proper way to handle this rather than crash. 44 CHECK(ret); 45 } 46 47 void NetworkChangeNotifierMac::OnNetworkConfigChange(CFArrayRef changed_keys) { 48 // Called on notifier thread. 49 50 for (CFIndex i = 0; i < CFArrayGetCount(changed_keys); ++i) { 51 CFStringRef key = static_cast<CFStringRef>( 52 CFArrayGetValueAtIndex(changed_keys, i)); 53 if (CFStringHasSuffix(key, kSCEntNetIPv4) || 54 CFStringHasSuffix(key, kSCEntNetIPv6)) { 55 NotifyObserversOfIPAddressChange(); 56 return; 57 } 58 if (CFStringHasSuffix(key, kSCEntNetInterface)) { 59 // TODO(willchan): Does not appear to be working. Look into this. 60 // Perhaps this isn't needed anyway. 61 } else { 62 NOTREACHED(); 63 } 64 } 65 } 66 67 } // namespace net 68