Home | History | Annotate | Download | only in base
      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