1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service_mac.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <CoreFoundation/CoreFoundation.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <SystemConfiguration/SystemConfiguration.h> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/mac/mac_util.h" 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/mac/scoped_cftyperef.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/sys_string_conversions.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_info.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_server.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace net { 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kPollIntervalSec = 5; 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Utility function to pull out a boolean value from a dictionary and return it, 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// returning a default value if the key is not present. 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetBoolFromDictionary(CFDictionaryRef dict, 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CFStringRef key, 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool default_value) { 303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CFNumberRef number = (CFNumberRef)base::mac::GetValueFromDictionary( 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dict, key, CFNumberGetTypeID()); 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!number) 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return default_value; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int int_value; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (CFNumberGetValue(number, kCFNumberIntType, &int_value)) 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return int_value; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return default_value; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid GetCurrentProxyConfig(ProxyConfig* config) { 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::mac::ScopedCFTypeRef<CFDictionaryRef> config_dict( 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SCDynamicStoreCopyProxies(NULL)); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(config_dict); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // auto-detect 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // There appears to be no UI for this configuration option, and we're not sure 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // if Apple's proxy code even takes it into account. But the constant is in 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the header file so we'll use it. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->set_auto_detect( 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GetBoolFromDictionary(config_dict.get(), 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesProxyAutoDiscoveryEnable, 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false)); 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // PAC file 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetBoolFromDictionary(config_dict.get(), 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesProxyAutoConfigEnable, 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott false)) { 623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CFStringRef pac_url_ref = (CFStringRef)base::mac::GetValueFromDictionary( 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_dict.get(), 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesProxyAutoConfigURLString, 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CFStringGetTypeID()); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (pac_url_ref) 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref))); 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // proxies (for now ftp, http, https, and SOCKS) 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetBoolFromDictionary(config_dict.get(), 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesFTPEnable, 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott false)) { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer proxy_server = 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP, 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_dict.get(), 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesFTPProxy, 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesFTPPort); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_server.is_valid()) { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().type = 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().proxy_for_ftp = proxy_server; 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetBoolFromDictionary(config_dict.get(), 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesHTTPEnable, 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott false)) { 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer proxy_server = 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP, 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_dict.get(), 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesHTTPProxy, 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesHTTPPort); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_server.is_valid()) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().type = 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().proxy_for_http = proxy_server; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetBoolFromDictionary(config_dict.get(), 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesHTTPSEnable, 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott false)) { 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer proxy_server = 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP, 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_dict.get(), 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesHTTPSProxy, 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesHTTPSPort); 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_server.is_valid()) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().type = 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().proxy_for_https = proxy_server; 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetBoolFromDictionary(config_dict.get(), 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesSOCKSEnable, 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott false)) { 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer proxy_server = 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyServer::FromDictionary(ProxyServer::SCHEME_SOCKS5, 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_dict.get(), 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesSOCKSProxy, 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesSOCKSPort); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_server.is_valid()) { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().type = 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config->proxy_rules().fallback_proxy = proxy_server; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // proxy bypass list 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CFArrayRef bypass_array_ref = 1323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen (CFArrayRef)base::mac::GetValueFromDictionary( 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_dict.get(), 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesExceptionsList, 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CFArrayGetTypeID()); 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bypass_array_ref) { 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CFIndex bypass_array_count = CFArrayGetCount(bypass_array_ref); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (CFIndex i = 0; i < bypass_array_count; ++i) { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CFStringRef bypass_item_ref = 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (CFStringRef)CFArrayGetValueAtIndex(bypass_array_ref, i); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (CFGetTypeID(bypass_item_ref) != CFStringGetTypeID()) { 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(WARNING) << "Expected value for item " << i 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << " in the kSCPropNetProxiesExceptionsList" 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " to be a CFStringRef but it was not"; 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().bypass_rules.AddRuleFromString( 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::SysCFStringRefToUTF8(bypass_item_ref)); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // proxy bypass boolean 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetBoolFromDictionary(config_dict.get(), 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kSCPropNetProxiesExcludeSimpleHostnames, 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false)) { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config->proxy_rules().bypass_rules.AddRuleToBypassLocal(); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} // namespace 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Reference-counted helper for posting a task to 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ProxyConfigServiceMac::OnProxyConfigChanged between the notifier and IO 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// thread. This helper object may outlive the ProxyConfigServiceMac. 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ProxyConfigServiceMac::Helper 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : public base::RefCountedThreadSafe<ProxyConfigServiceMac::Helper> { 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit Helper(ProxyConfigServiceMac* parent) : parent_(parent) { 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(parent); 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Called when the parent is destroyed. 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void Orphan() { 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parent_ = NULL; 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void OnProxyConfigChanged(const ProxyConfig& new_config) { 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (parent_) 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parent_->OnProxyConfigChanged(new_config); 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyConfigServiceMac* parent_; 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProxyConfigServiceMac::ProxyConfigServiceMac(MessageLoop* io_loop) 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : forwarder_(this), 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_watcher_(&forwarder_), 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick has_fetched_config_(false), 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_(new Helper(this)), 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick io_loop_(io_loop) { 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(io_loop); 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProxyConfigServiceMac::~ProxyConfigServiceMac() { 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(io_loop_, MessageLoop::current()); 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_->Orphan(); 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick io_loop_ = NULL; 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyConfigServiceMac::AddObserver(Observer* observer) { 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(io_loop_, MessageLoop::current()); 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick observers_.AddObserver(observer); 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyConfigServiceMac::RemoveObserver(Observer* observer) { 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(io_loop_, MessageLoop::current()); 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick observers_.RemoveObserver(observer); 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennet::ProxyConfigService::ConfigAvailability 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyConfigServiceMac::GetLatestProxyConfig(ProxyConfig* config) { 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(io_loop_, MessageLoop::current()); 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Lazy-initialize by fetching the proxy setting from this thread. 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!has_fetched_config_) { 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetCurrentProxyConfig(&last_config_fetched_); 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick has_fetched_config_ = true; 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *config = last_config_fetched_; 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return has_fetched_config_ ? CONFIG_VALID : CONFIG_PENDING; 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyConfigServiceMac::SetDynamicStoreNotificationKeys( 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SCDynamicStoreRef store) { 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Called on notifier thread. 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CFStringRef proxies_key = SCDynamicStoreKeyCreateProxies(NULL); 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CFArrayRef key_array = CFArrayCreate( 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, (const void **)(&proxies_key), 1, &kCFTypeArrayCallBacks); 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool ret = SCDynamicStoreSetNotificationKeys(store, key_array, NULL); 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(willchan): Figure out a proper way to handle this rather than crash. 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CHECK(ret); 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CFRelease(key_array); 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CFRelease(proxies_key); 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyConfigServiceMac::OnNetworkConfigChange(CFArrayRef changed_keys) { 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Called on notifier thread. 2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fetch the new system proxy configuration. 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyConfig new_config; 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetCurrentProxyConfig(&new_config); 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Call OnProxyConfigChanged() on the IO thread to notify our observers. 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick io_loop_->PostTask( 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FROM_HERE, 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NewRunnableMethod( 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_.get(), &Helper::OnProxyConfigChanged, new_config)); 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyConfigServiceMac::OnProxyConfigChanged( 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ProxyConfig& new_config) { 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(io_loop_, MessageLoop::current()); 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Keep track of the last value we have seen. 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick has_fetched_config_ = true; 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick last_config_fetched_ = new_config; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Notify all the observers. 266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FOR_EACH_OBSERVER(Observer, observers_, 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnProxyConfigChanged(new_config, CONFIG_VALID)); 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 271