Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 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/cros/cros_library.h" | |
| 11 #include "chrome/browser/chromeos/cros/network_library.h" | |
| 12 #include "chrome/browser/chromeos/cros/network_property_ui_data.h" | |
| 13 #include "chrome/browser/chromeos/proxy_config_service_impl.h" | |
| 14 #include "chromeos/network/onc/onc_utils.h" | |
| 15 #include "grit/generated_resources.h" | |
| 16 #include "net/proxy/proxy_config.h" | |
| 17 #include "ui/base/l10n/l10n_util.h" | |
| 18 | |
| 19 namespace chromeos { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 // Shoud we try to push this to base? | |
| 24 // Helper comparator functor for the find_if call in |findIfEqual| | |
|
stevenjb
2013/05/15 17:44:14
I don't think "Equals" is generic enough for a hel
pneubeck (no reviews)
2013/05/15 20:24:48
I don't like the complexity here about Callbacks a
| |
| 25 template <class T> | |
| 26 class EqualsComparator{ | |
| 27 public: | |
| 28 explicit EqualsComparator(const T& key) : key_(key) { } | |
| 29 bool operator() (const T& element) { | |
| 30 return element.Equals(key_); | |
| 31 } | |
| 32 private: | |
| 33 const T& key_; | |
| 34 }; | |
| 35 | |
| 36 // Tiny STL helper function to allow using the find_if syntax on objects that | |
| 37 // doesn't use the operator== but implement the Equals function which is the | |
| 38 // quasi standard with the coding style we have. | |
| 39 template<class InputIterator, class T> | |
| 40 InputIterator findIfEqual(InputIterator first, | |
| 41 InputIterator last, | |
| 42 const T& key) { | |
| 43 return std::find_if(first, last, EqualsComparator<T>(key)); | |
| 44 } | |
|
stevenjb
2013/05/15 17:44:14
This doesn't seem to add much clarity than just in
pneubeck (no reviews)
2013/05/15 20:24:48
Done.
| |
| 45 | |
| 46 const char* ModeToString(UIProxyConfig::Mode mode) { | |
| 47 switch (mode) { | |
|
stevenjb
2013/05/15 17:44:14
FWIW, this (imho) is a good use of 'switch'.
| |
| 48 case UIProxyConfig::MODE_DIRECT: | |
| 49 return "direct"; | |
| 50 case UIProxyConfig::MODE_AUTO_DETECT: | |
| 51 return "auto-detect"; | |
| 52 case UIProxyConfig::MODE_PAC_SCRIPT: | |
| 53 return "pacurl"; | |
| 54 case UIProxyConfig::MODE_SINGLE_PROXY: | |
| 55 return "single-proxy"; | |
| 56 case UIProxyConfig::MODE_PROXY_PER_SCHEME: | |
| 57 return "proxy-per-scheme"; | |
| 58 } | |
| 59 NOTREACHED() << "Unrecognized mode type"; | |
| 60 return ""; | |
| 61 } | |
| 62 | |
| 63 bool ParseProxyConfig(const std::string& pref_proxy_config, | |
| 64 net::ProxyConfig* proxy_config) { | |
| 65 if (pref_proxy_config.empty()) | |
| 66 return false; | |
| 67 | |
| 68 scoped_ptr<base::DictionaryValue> proxy_config_dict( | |
| 69 chromeos::onc::ReadDictionaryFromJson(pref_proxy_config)); | |
| 70 if (!proxy_config_dict) { | |
| 71 LOG(WARNING) << "Failed to parse proxy config."; | |
| 72 return false; | |
| 73 } | |
| 74 | |
| 75 if (proxy_config_dict->empty()) | |
| 76 return false; | |
| 77 | |
| 78 ProxyConfigDictionary proxy_config_dict_wrapper(proxy_config_dict.get()); | |
| 79 return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig( | |
| 80 proxy_config_dict_wrapper, | |
| 81 proxy_config); | |
| 82 } | |
| 83 | |
| 84 // Returns true if proxy settings of |network| are editable. | |
| 85 bool IsNetworkProxySettingsEditable(const Network& network) { | |
| 86 NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary(); | |
| 87 const base::DictionaryValue* onc = | |
| 88 network_library->FindOncForNetwork(network.unique_id()); | |
| 89 if (!onc) | |
| 90 return true; | |
| 91 | |
| 92 NetworkPropertyUIData proxy_settings_ui_data; | |
| 93 proxy_settings_ui_data.ParseOncProperty( | |
| 94 network.ui_data().onc_source(), | |
| 95 onc, | |
| 96 onc::network_config::kProxySettings); | |
| 97 return proxy_settings_ui_data.editable(); | |
| 98 } | |
| 99 | |
| 100 } // namespace | |
| 101 | |
| 102 UIProxyConfigService::UIProxyConfigService(PrefService* pref_service) | |
| 103 : pref_service_(pref_service) { | |
| 104 } | |
| 105 | |
| 106 UIProxyConfigService::~UIProxyConfigService() { | |
| 107 } | |
| 108 | |
| 109 void UIProxyConfigService::SetCurrentNetwork( | |
| 110 const std::string& current_network) { | |
| 111 Network* network = NULL; | |
| 112 if (!current_network.empty()) { | |
| 113 network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 114 current_network); | |
| 115 LOG_IF(ERROR, !network) | |
| 116 << "Can't find requested network " << current_network; | |
| 117 } | |
| 118 current_ui_network_ = current_network; | |
| 119 if (!network) { | |
| 120 current_ui_network_.clear(); | |
| 121 current_ui_config_ = UIProxyConfig(); | |
| 122 return; | |
| 123 } | |
| 124 | |
| 125 DetermineEffectiveConfig(*network); | |
| 126 VLOG(1) << "Current ui network: " | |
| 127 << network->name() | |
| 128 << ", " << ModeToString(current_ui_config_.mode) | |
| 129 << ", " << ProxyPrefs::ConfigStateToString(current_ui_config_.state) | |
| 130 << ", modifiable:" << current_ui_config_.user_modifiable; | |
| 131 // Notify observers. | |
| 132 std::vector<base::Closure>::iterator iter = callbacks_.begin(); | |
| 133 while (iter != callbacks_.end()) { | |
| 134 if (iter->is_null()) { | |
| 135 iter = callbacks_.erase(iter); | |
| 136 } else { | |
| 137 iter->Run(); | |
| 138 ++iter; | |
| 139 } | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 void UIProxyConfigService::MakeActiveNetworkCurrent() { | |
| 144 const Network* network = | |
| 145 CrosLibrary::Get()->GetNetworkLibrary()->active_network(); | |
| 146 SetCurrentNetwork(network ? network->service_path() : std::string()); | |
| 147 } | |
| 148 | |
| 149 void UIProxyConfigService::GetCurrentNetworkName(std::string* network_name) { | |
| 150 if (!network_name) | |
| 151 return; | |
| 152 network_name->clear(); | |
| 153 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 154 current_ui_network_); | |
| 155 if (!network) { | |
| 156 LOG(ERROR) << "Can't find requested network " << current_ui_network_; | |
| 157 return; | |
| 158 } | |
| 159 if (network->name().empty() && network->type() == chromeos::TYPE_ETHERNET) { | |
| 160 *network_name = | |
| 161 l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); | |
| 162 } else { | |
| 163 *network_name = network->name(); | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 void UIProxyConfigService::GetProxyConfig(UIProxyConfig* config) { | |
| 168 *config = current_ui_config_; | |
| 169 } | |
| 170 | |
| 171 void UIProxyConfigService::SetProxyConfig(const UIProxyConfig& config) { | |
| 172 current_ui_config_ = config; | |
| 173 if (current_ui_network_.empty()) | |
| 174 return; | |
| 175 | |
| 176 // Update config to shill. | |
| 177 std::string value; | |
| 178 if (!current_ui_config_.SerializeForNetwork(&value)) | |
| 179 return; | |
| 180 | |
| 181 VLOG(1) << "Set proxy (mode=" << current_ui_config_.mode | |
| 182 << ") for " << current_ui_network_; | |
| 183 current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; | |
| 184 | |
| 185 // Set ProxyConfig of the current network. | |
| 186 Network* network = CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath( | |
| 187 current_ui_network_); | |
| 188 if (!network) { | |
| 189 NOTREACHED() << "Can't find requested network " << current_ui_network_; | |
| 190 return; | |
| 191 } | |
| 192 network->SetProxyConfig(value); | |
| 193 VLOG(1) << "Set proxy for " | |
| 194 << (network->name().empty() ? current_ui_network_ : network->name()) | |
| 195 << ", value=" << value; | |
| 196 } | |
| 197 | |
| 198 void UIProxyConfigService::AddNotificationCallback(base::Closure callback) { | |
| 199 std::vector<base::Closure>::iterator iter = | |
| 200 findIfEqual(callbacks_.begin(), callbacks_.end(), callback); | |
| 201 if (iter == callbacks_.end()) | |
| 202 callbacks_.push_back(callback); | |
| 203 } | |
| 204 | |
| 205 void UIProxyConfigService::RemoveNotificationCallback(base::Closure callback) { | |
| 206 std::vector<base::Closure>::iterator iter = | |
| 207 findIfEqual(callbacks_.begin(), callbacks_.end(), callback); | |
| 208 if (iter != callbacks_.end()) | |
| 209 callbacks_.erase(iter); | |
| 210 } | |
| 211 | |
| 212 void UIProxyConfigService::DetermineEffectiveConfig(const Network& network) { | |
| 213 // Get prefs proxy config if available. | |
| 214 net::ProxyConfig pref_config; | |
| 215 ProxyPrefs::ConfigState pref_state = ProxyConfigServiceImpl::ReadPrefConfig( | |
| 216 pref_service_, | |
| 217 &pref_config); | |
| 218 | |
| 219 // Get network proxy config if available. | |
| 220 net::ProxyConfig network_config; | |
| 221 net::ProxyConfigService::ConfigAvailability network_availability = | |
| 222 net::ProxyConfigService::CONFIG_UNSET; | |
| 223 if (ParseProxyConfig(network.proxy_config(), &network_config)) { | |
| 224 // Network is private or shared with user using shared proxies. | |
| 225 VLOG(1) << this << ": using network proxy: " << network.proxy_config(); | |
| 226 network_availability = net::ProxyConfigService::CONFIG_VALID; | |
| 227 } | |
| 228 | |
| 229 // Determine effective proxy config, either from prefs or network. | |
| 230 ProxyPrefs::ConfigState effective_config_state; | |
| 231 net::ProxyConfig effective_config; | |
| 232 ProxyConfigServiceImpl::GetEffectiveProxyConfig( | |
| 233 pref_state, pref_config, | |
| 234 network_availability, network_config, false, | |
| 235 &effective_config_state, &effective_config); | |
| 236 | |
| 237 // Store effective proxy into |current_ui_config_|. | |
| 238 current_ui_config_.FromNetProxyConfig(effective_config); | |
| 239 current_ui_config_.state = effective_config_state; | |
| 240 if (ProxyConfigServiceImpl::PrefPrecedes(effective_config_state)) { | |
| 241 LOG(ERROR) << "PrefPrecedes"; | |
|
stevenjb
2013/05/15 17:44:14
Debugging? VLOG? (Here and below)
pneubeck (no reviews)
2013/05/15 20:24:48
Oops. Yes, debugging.
| |
| 242 current_ui_config_.user_modifiable = false; | |
| 243 } else if (!IsNetworkProxySettingsEditable(network)) { | |
| 244 LOG(ERROR) << "!IsNetworkProxySettingsEditable"; | |
| 245 // TODO(xiyuan): Figure out the right way to set config state for managed | |
| 246 // network. | |
| 247 current_ui_config_.state = ProxyPrefs::CONFIG_POLICY; | |
| 248 current_ui_config_.user_modifiable = false; | |
| 249 } else { | |
| 250 LOG(ERROR) << "Path: " << network.profile_path() | |
| 251 << ", source: " << network.ui_data().onc_source(); | |
| 252 current_ui_config_.user_modifiable = | |
| 253 !ProxyConfigServiceImpl::IgnoreProxy(pref_service_, | |
| 254 network.profile_path(), | |
| 255 network.ui_data().onc_source()); | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 } // namespace chromeos | |
| OLD | NEW |