summaryrefslogtreecommitdiffstats
path: root/net/base/network_config_watcher_mac.cc
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-30 06:09:40 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-30 06:09:40 +0000
commit9328443b6546402da992f1c37ee97d94667a709e (patch)
tree1531485bbbfa635479652a1eca7df85754251a6c /net/base/network_config_watcher_mac.cc
parent39b16c2480c50d79459bc79eaf82d51efdd619c1 (diff)
downloadchromium_src-9328443b6546402da992f1c37ee97d94667a709e.zip
chromium_src-9328443b6546402da992f1c37ee97d94667a709e.tar.gz
chromium_src-9328443b6546402da992f1c37ee97d94667a709e.tar.bz2
Use notification-based API for getting system proxy settings on Mac rather than polling.
BUG=50587 Review URL: http://codereview.chromium.org/3078009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54288 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/network_config_watcher_mac.cc')
-rw-r--r--net/base/network_config_watcher_mac.cc86
1 files changed, 86 insertions, 0 deletions
diff --git a/net/base/network_config_watcher_mac.cc b/net/base/network_config_watcher_mac.cc
new file mode 100644
index 0000000..8767dff
--- /dev/null
+++ b/net/base/network_config_watcher_mac.cc
@@ -0,0 +1,86 @@
+// 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_config_watcher_mac.h"
+
+#include <SystemConfiguration/SCDynamicStoreKey.h>
+#include <SystemConfiguration/SCSchemaDefinitions.h>
+#include <algorithm>
+
+#include "base/thread.h"
+
+// We only post tasks to a child thread we own, so we don't need refcounting.
+DISABLE_RUNNABLE_METHOD_REFCOUNT(net::NetworkConfigWatcherMac);
+
+namespace net {
+
+NetworkConfigWatcherMac::NetworkConfigWatcherMac()
+ : notifier_thread_(new base::Thread("NetworkConfigWatcher")) {
+ // We create this notifier thread because the notification implementation
+ // needs a thread with a CFRunLoop, and there's no guarantee that
+ // MessageLoop::current() meets that criterion.
+ base::Thread::Options thread_options(MessageLoop::TYPE_UI, 0);
+ notifier_thread_->StartWithOptions(thread_options);
+ // TODO(willchan): Look to see if there's a better signal for when it's ok to
+ // initialize this, rather than just delaying it by a fixed time.
+ const int kNotifierThreadInitializationDelayMS = 1000;
+ notifier_thread_->message_loop()->PostDelayedTask(FROM_HERE,
+ NewRunnableMethod(this, &NetworkConfigWatcherMac::Init),
+ kNotifierThreadInitializationDelayMS);
+}
+
+NetworkConfigWatcherMac::~NetworkConfigWatcherMac() {
+ // We don't need to explicitly Stop(), but doing so allows us to sanity-
+ // check that the notifier thread shut down properly.
+ notifier_thread_->Stop();
+ DCHECK(run_loop_source_ == NULL);
+}
+
+// static
+void NetworkConfigWatcherMac::DynamicStoreCallback(
+ SCDynamicStoreRef /* store */,
+ CFArrayRef changed_keys,
+ void* config) {
+ NetworkConfigWatcherMac* net_config =
+ static_cast<NetworkConfigWatcherMac*>(config);
+ net_config->OnNetworkConfigChange(changed_keys);
+}
+
+void NetworkConfigWatcherMac::WillDestroyCurrentMessageLoop() {
+ DCHECK(notifier_thread_ != NULL);
+ // We can't check the notifier_thread_'s message_loop(), as it's now 0.
+ // DCHECK_EQ(notifier_thread_->message_loop(), MessageLoop::current());
+
+ DCHECK(run_loop_source_ != NULL);
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_source_.get(),
+ kCFRunLoopCommonModes);
+ run_loop_source_.reset();
+}
+
+void NetworkConfigWatcherMac::Init() {
+ DCHECK(notifier_thread_ != NULL);
+ DCHECK_EQ(notifier_thread_->message_loop(), MessageLoop::current());
+
+ // Add a run loop source for a dynamic store to the current run loop.
+ SCDynamicStoreContext context = {
+ 0, // Version 0.
+ this, // User data.
+ NULL, // This is not reference counted. No retain function.
+ NULL, // This is not reference counted. No release function.
+ NULL, // No description for this.
+ };
+ scoped_cftyperef<SCDynamicStoreRef> store(SCDynamicStoreCreate(
+ NULL, CFSTR("org.chromium"), DynamicStoreCallback, &context));
+ run_loop_source_.reset(SCDynamicStoreCreateRunLoopSource(
+ NULL, store.get(), 0));
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source_.get(),
+ kCFRunLoopCommonModes);
+
+ // Set up notifications for interface and IP address changes.
+ SetDynamicStoreNotificationKeys(store.get());
+
+ MessageLoop::current()->AddDestructionObserver(this);
+}
+
+} // namespace net