diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-30 06:09:40 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-30 06:09:40 +0000 |
commit | 9328443b6546402da992f1c37ee97d94667a709e (patch) | |
tree | 1531485bbbfa635479652a1eca7df85754251a6c /net/proxy/proxy_config_service_mac.cc | |
parent | 39b16c2480c50d79459bc79eaf82d51efdd619c1 (diff) | |
download | chromium_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/proxy/proxy_config_service_mac.cc')
-rw-r--r-- | net/proxy/proxy_config_service_mac.cc | 101 |
1 files changed, 98 insertions, 3 deletions
diff --git a/net/proxy/proxy_config_service_mac.cc b/net/proxy/proxy_config_service_mac.cc index 27a0426..38237a56 100644 --- a/net/proxy/proxy_config_service_mac.cc +++ b/net/proxy/proxy_config_service_mac.cc @@ -161,9 +161,104 @@ void GetCurrentProxyConfig(ProxyConfig* config) { } // namespace -ProxyConfigServiceMac::ProxyConfigServiceMac() - : PollingProxyConfigService(base::TimeDelta::FromSeconds(kPollIntervalSec), - &GetCurrentProxyConfig) { +// Reference-counted helper for posting a task to +// ProxyConfigServiceMac::OnProxyConfigChanged between the notifier and IO +// thread. This helper object may outlive the ProxyConfigServiceMac. +class ProxyConfigServiceMac::Helper + : public base::RefCountedThreadSafe<ProxyConfigServiceMac::Helper> { + public: + explicit Helper(ProxyConfigServiceMac* parent) : parent_(parent) { + DCHECK(parent); + } + + // Called when the parent is destroyed. + void Orphan() { + parent_ = NULL; + } + + void OnProxyConfigChanged(const ProxyConfig& new_config) { + if (parent_) + parent_->OnProxyConfigChanged(new_config); + } + + private: + ProxyConfigServiceMac* parent_; +}; + +ProxyConfigServiceMac::ProxyConfigServiceMac(MessageLoop* io_loop) + : has_fetched_config_(false), + helper_(new Helper(this)), + io_loop_(io_loop) { + DCHECK(io_loop); +} + +ProxyConfigServiceMac::~ProxyConfigServiceMac() { + DCHECK_EQ(io_loop_, MessageLoop::current()); + helper_->Orphan(); + io_loop_ = NULL; +} + +void ProxyConfigServiceMac::AddObserver(Observer* observer) { + DCHECK_EQ(io_loop_, MessageLoop::current()); + observers_.AddObserver(observer); +} + +void ProxyConfigServiceMac::RemoveObserver(Observer* observer) { + DCHECK_EQ(io_loop_, MessageLoop::current()); + observers_.RemoveObserver(observer); +} + +bool ProxyConfigServiceMac::GetLatestProxyConfig(ProxyConfig* config) { + DCHECK_EQ(io_loop_, MessageLoop::current()); + + // Lazy-initialize by fetching the proxy setting from this thread. + if (!has_fetched_config_) { + GetCurrentProxyConfig(&last_config_fetched_); + has_fetched_config_ = true; + } + + *config = last_config_fetched_; + return has_fetched_config_; +} + +void ProxyConfigServiceMac::SetDynamicStoreNotificationKeys( + SCDynamicStoreRef store) { + CFStringRef proxies_key = SCDynamicStoreKeyCreateProxies(NULL); + CFArrayRef key_array = CFArrayCreate( + NULL, (const void **)(&proxies_key), 1, &kCFTypeArrayCallBacks); + + bool ret = SCDynamicStoreSetNotificationKeys(store, key_array, NULL); + // TODO(willchan): Figure out a proper way to handle this rather than crash. + CHECK(ret); + + CFRelease(key_array); + CFRelease(proxies_key); +} + +void ProxyConfigServiceMac::OnNetworkConfigChange(CFArrayRef changed_keys) { + // Called on notifier thread. + + // Fetch the new system proxy configuration. + ProxyConfig new_config; + GetCurrentProxyConfig(&new_config); + + // Call OnProxyConfigChanged() on the IO thread to notify our observers. + io_loop_->PostTask( + FROM_HERE, + NewRunnableMethod( + helper_.get(), &Helper::OnProxyConfigChanged, new_config)); +} + +void ProxyConfigServiceMac::OnProxyConfigChanged( + const ProxyConfig& new_config) { + DCHECK_EQ(io_loop_, MessageLoop::current()); + + // Keep track of the last value we have seen. + has_fetched_config_ = true; + last_config_fetched_ = new_config; + + // Notify all the observers. + FOR_EACH_OBSERVER(Observer, observers_, OnProxyConfigChanged(new_config)); } } // namespace net |