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