1 // Copyright 2013 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 "chrome/browser/chromeos/ui_proxy_config_service.h" 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/values.h" 10 #include "chrome/browser/chromeos/net/proxy_config_handler.h" 11 #include "chrome/browser/chromeos/proxy_config_service_impl.h" 12 #include "chromeos/network/favorite_state.h" 13 #include "chromeos/network/network_state_handler.h" 14 #include "grit/generated_resources.h" 15 #include "net/proxy/proxy_config.h" 16 17 namespace chromeos { 18 19 namespace { 20 21 const char* ModeToString(UIProxyConfig::Mode mode) { 22 switch (mode) { 23 case UIProxyConfig::MODE_DIRECT: 24 return "direct"; 25 case UIProxyConfig::MODE_AUTO_DETECT: 26 return "auto-detect"; 27 case UIProxyConfig::MODE_PAC_SCRIPT: 28 return "pacurl"; 29 case UIProxyConfig::MODE_SINGLE_PROXY: 30 return "single-proxy"; 31 case UIProxyConfig::MODE_PROXY_PER_SCHEME: 32 return "proxy-per-scheme"; 33 } 34 NOTREACHED() << "Unrecognized mode type"; 35 return ""; 36 } 37 38 // Writes the proxy config of |network| to |proxy_config|. Sets |onc_source| to 39 // the source of this configuration. Returns false if no proxy was configured 40 // for this network. 41 bool GetProxyConfig(const PrefService* profile_prefs, 42 const PrefService* local_state_prefs, 43 const FavoriteState& network, 44 net::ProxyConfig* proxy_config, 45 onc::ONCSource* onc_source) { 46 scoped_ptr<ProxyConfigDictionary> proxy_dict = 47 proxy_config::GetProxyConfigForFavoriteNetwork( 48 profile_prefs, local_state_prefs, network, onc_source); 49 if (!proxy_dict) 50 return false; 51 return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(*proxy_dict, 52 proxy_config); 53 } 54 55 // Returns true if proxy settings from |onc_source| are editable. 56 bool IsNetworkProxySettingsEditable(const onc::ONCSource onc_source) { 57 return onc_source != onc::ONC_SOURCE_DEVICE_POLICY && 58 onc_source != onc::ONC_SOURCE_USER_POLICY; 59 } 60 61 } // namespace 62 63 UIProxyConfigService::UIProxyConfigService() 64 : profile_prefs_(NULL), local_state_prefs_(NULL) { 65 } 66 67 UIProxyConfigService::~UIProxyConfigService() { 68 } 69 70 void UIProxyConfigService::SetPrefs(PrefService* profile_prefs, 71 PrefService* local_state_prefs) { 72 profile_prefs_ = profile_prefs; 73 local_state_prefs_ = local_state_prefs; 74 } 75 76 void UIProxyConfigService::SetCurrentNetwork( 77 const std::string& current_network) { 78 current_ui_network_ = current_network; 79 } 80 81 void UIProxyConfigService::UpdateFromPrefs() { 82 const FavoriteState* network = NULL; 83 if (!current_ui_network_.empty()) { 84 network = NetworkHandler::Get()->network_state_handler()->GetFavoriteState( 85 current_ui_network_); 86 LOG_IF(ERROR, !network) << "Couldn't find FavoriteState for network " 87 << current_ui_network_; 88 } 89 if (!network) { 90 current_ui_network_.clear(); 91 current_ui_config_ = UIProxyConfig(); 92 return; 93 } 94 95 DetermineEffectiveConfig(*network); 96 VLOG(1) << "Current ui network: " << network->name() << ", " 97 << ModeToString(current_ui_config_.mode) << ", " 98 << ProxyPrefs::ConfigStateToDebugString(current_ui_config_.state) 99 << ", modifiable:" << current_ui_config_.user_modifiable; 100 } 101 102 void UIProxyConfigService::GetProxyConfig(UIProxyConfig* config) const { 103 *config = current_ui_config_; 104 } 105 106 void UIProxyConfigService::SetProxyConfig(const UIProxyConfig& config) { 107 current_ui_config_ = config; 108 if (current_ui_network_.empty()) 109 return; 110 111 const FavoriteState* network = 112 NetworkHandler::Get()->network_state_handler()->GetFavoriteState( 113 current_ui_network_); 114 if (!network) { 115 LOG(ERROR) << "Couldn't find FavoriteState for network " 116 << current_ui_network_; 117 return; 118 } 119 120 // Store config for this network. 121 scoped_ptr<base::DictionaryValue> proxy_config_value( 122 config.ToPrefProxyConfig()); 123 ProxyConfigDictionary proxy_config_dict(proxy_config_value.get()); 124 125 VLOG(1) << "Set proxy for " << current_ui_network_ 126 << " to " << *proxy_config_value; 127 128 proxy_config::SetProxyConfigForFavoriteNetwork(proxy_config_dict, *network); 129 current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; 130 } 131 132 void UIProxyConfigService::DetermineEffectiveConfig( 133 const FavoriteState& network) { 134 DCHECK(local_state_prefs_); 135 136 // The pref service to read proxy settings that apply to all networks. 137 // Settings from the profile overrule local state. 138 PrefService* top_pref_service = 139 profile_prefs_ ? profile_prefs_ : local_state_prefs_; 140 141 // Get prefs proxy config if available. 142 net::ProxyConfig pref_config; 143 ProxyPrefs::ConfigState pref_state = ProxyConfigServiceImpl::ReadPrefConfig( 144 top_pref_service, &pref_config); 145 146 // Get network proxy config if available. 147 net::ProxyConfig network_config; 148 net::ProxyConfigService::ConfigAvailability network_availability = 149 net::ProxyConfigService::CONFIG_UNSET; 150 onc::ONCSource onc_source = onc::ONC_SOURCE_NONE; 151 if (chromeos::GetProxyConfig(profile_prefs_, 152 local_state_prefs_, 153 network, 154 &network_config, 155 &onc_source)) { 156 // Network is private or shared with user using shared proxies. 157 VLOG(1) << this << ": using proxy of network: " << network.path(); 158 network_availability = net::ProxyConfigService::CONFIG_VALID; 159 } 160 161 // Determine effective proxy config, either from prefs or network. 162 ProxyPrefs::ConfigState effective_config_state; 163 net::ProxyConfig effective_config; 164 ProxyConfigServiceImpl::GetEffectiveProxyConfig( 165 pref_state, pref_config, 166 network_availability, network_config, false, 167 &effective_config_state, &effective_config); 168 169 // Store effective proxy into |current_ui_config_|. 170 current_ui_config_.FromNetProxyConfig(effective_config); 171 current_ui_config_.state = effective_config_state; 172 if (ProxyConfigServiceImpl::PrefPrecedes(effective_config_state)) { 173 current_ui_config_.user_modifiable = false; 174 } else if (!IsNetworkProxySettingsEditable(onc_source)) { 175 current_ui_config_.state = ProxyPrefs::CONFIG_POLICY; 176 current_ui_config_.user_modifiable = false; 177 } else { 178 current_ui_config_.user_modifiable = !ProxyConfigServiceImpl::IgnoreProxy( 179 profile_prefs_, network.profile_path(), onc_source); 180 } 181 } 182 183 } // namespace chromeos 184