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
NetworkChangeNotifierMac()14 NetworkChangeNotifierMac::NetworkChangeNotifierMac()
15 : forwarder_(this),
16 config_watcher_(&forwarder_) {}
~NetworkChangeNotifierMac()17 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {}
18
IsCurrentlyOffline() const19 bool NetworkChangeNotifierMac::IsCurrentlyOffline() const {
20 // TODO(eroman): http://crbug.com/53473
21 return false;
22 }
23
SetDynamicStoreNotificationKeys(SCDynamicStoreRef store)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
OnNetworkConfigChange(CFArrayRef changed_keys)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