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 |