Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / search_engines / default_search_policy_handler.cc
blob05018780f290709fb9d8a183e13a7f935d0b8894
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.
5 #include "chrome/browser/search_engines/default_search_policy_handler.h"
7 #include "base/prefs/pref_value_map.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/search_engines/search_terms_data.h"
12 #include "chrome/browser/search_engines/template_url.h"
13 #include "chrome/common/pref_names.h"
14 #include "components/policy/core/browser/policy_error_map.h"
15 #include "components/policy/core/common/policy_map.h"
16 #include "content/public/browser/notification_service.h"
17 #include "grit/component_strings.h"
18 #include "policy/policy_constants.h"
20 namespace policy {
22 // List of policy types to preference names, for policies affecting the default
23 // search provider.
24 const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[] = {
25 { key::kDefaultSearchProviderEnabled,
26 prefs::kDefaultSearchProviderEnabled,
27 base::Value::TYPE_BOOLEAN },
28 { key::kDefaultSearchProviderName,
29 prefs::kDefaultSearchProviderName,
30 base::Value::TYPE_STRING },
31 { key::kDefaultSearchProviderKeyword,
32 prefs::kDefaultSearchProviderKeyword,
33 base::Value::TYPE_STRING },
34 { key::kDefaultSearchProviderSearchURL,
35 prefs::kDefaultSearchProviderSearchURL,
36 base::Value::TYPE_STRING },
37 { key::kDefaultSearchProviderSuggestURL,
38 prefs::kDefaultSearchProviderSuggestURL,
39 base::Value::TYPE_STRING },
40 { key::kDefaultSearchProviderInstantURL,
41 prefs::kDefaultSearchProviderInstantURL,
42 base::Value::TYPE_STRING },
43 { key::kDefaultSearchProviderIconURL,
44 prefs::kDefaultSearchProviderIconURL,
45 base::Value::TYPE_STRING },
46 { key::kDefaultSearchProviderEncodings,
47 prefs::kDefaultSearchProviderEncodings,
48 base::Value::TYPE_LIST },
49 { key::kDefaultSearchProviderAlternateURLs,
50 prefs::kDefaultSearchProviderAlternateURLs,
51 base::Value::TYPE_LIST },
52 { key::kDefaultSearchProviderSearchTermsReplacementKey,
53 prefs::kDefaultSearchProviderSearchTermsReplacementKey,
54 base::Value::TYPE_STRING },
55 { key::kDefaultSearchProviderImageURL,
56 prefs::kDefaultSearchProviderImageURL,
57 base::Value::TYPE_STRING },
58 { key::kDefaultSearchProviderNewTabURL,
59 prefs::kDefaultSearchProviderNewTabURL,
60 base::Value::TYPE_STRING },
61 { key::kDefaultSearchProviderSearchURLPostParams,
62 prefs::kDefaultSearchProviderSearchURLPostParams,
63 base::Value::TYPE_STRING },
64 { key::kDefaultSearchProviderSuggestURLPostParams,
65 prefs::kDefaultSearchProviderSuggestURLPostParams,
66 base::Value::TYPE_STRING },
67 { key::kDefaultSearchProviderInstantURLPostParams,
68 prefs::kDefaultSearchProviderInstantURLPostParams,
69 base::Value::TYPE_STRING },
70 { key::kDefaultSearchProviderImageURLPostParams,
71 prefs::kDefaultSearchProviderImageURLPostParams,
72 base::Value::TYPE_STRING },
75 // DefaultSearchEncodingsPolicyHandler implementation --------------------------
77 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler()
78 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings,
79 base::Value::TYPE_LIST) {}
81 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() {
84 void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings(
85 const PolicyMap& policies, PrefValueMap* prefs) {
86 // The DefaultSearchProviderEncodings policy has type list, but the related
87 // preference has type string. Convert one into the other here, using
88 // ';' as a separator.
89 const base::Value* value = policies.GetValue(policy_name());
90 const base::ListValue* list;
91 if (!value || !value->GetAsList(&list))
92 return;
94 base::ListValue::const_iterator iter(list->begin());
95 base::ListValue::const_iterator end(list->end());
96 std::vector<std::string> string_parts;
97 for (; iter != end; ++iter) {
98 std::string s;
99 if ((*iter)->GetAsString(&s)) {
100 string_parts.push_back(s);
103 std::string encodings = JoinString(string_parts, ';');
104 prefs->SetValue(prefs::kDefaultSearchProviderEncodings,
105 base::Value::CreateStringValue(encodings));
109 // DefaultSearchPolicyHandler implementation -----------------------------------
111 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {
112 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
113 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
114 if (policy_name == key::kDefaultSearchProviderEncodings) {
115 handlers_.push_back(new DefaultSearchEncodingsPolicyHandler());
116 } else {
117 handlers_.push_back(new SimplePolicyHandler(
118 policy_name,
119 kDefaultSearchPolicyMap[i].preference_path,
120 kDefaultSearchPolicyMap[i].value_type));
125 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {
126 STLDeleteElements(&handlers_);
129 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
130 PolicyErrorMap* errors) {
131 if (!CheckIndividualPolicies(policies, errors))
132 return false;
134 if (DefaultSearchProviderIsDisabled(policies)) {
135 // Add an error for all specified default search policies except
136 // DefaultSearchProviderEnabled.
138 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
139 handlers_.begin();
140 handler != handlers_.end(); ++handler) {
141 const char* policy_name = (*handler)->policy_name();
142 if (policy_name != key::kDefaultSearchProviderEnabled &&
143 HasDefaultSearchPolicy(policies, policy_name)) {
144 errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED);
147 return true;
150 const base::Value* url;
151 std::string dummy;
152 if (DefaultSearchURLIsValid(policies, &url, &dummy) ||
153 !AnyDefaultSearchPoliciesSpecified(policies))
154 return true;
155 errors->AddError(key::kDefaultSearchProviderSearchURL, url ?
156 IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR);
157 return false;
160 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
161 PrefValueMap* prefs) {
162 if (DefaultSearchProviderIsDisabled(policies)) {
163 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false);
165 // If default search is disabled, the other fields are ignored.
166 prefs->SetString(prefs::kDefaultSearchProviderName, std::string());
167 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
168 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
169 prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
170 prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
171 prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
172 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
173 prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, std::string());
174 prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs,
175 new base::ListValue());
176 prefs->SetString(
177 prefs::kDefaultSearchProviderSearchTermsReplacementKey, std::string());
178 prefs->SetString(prefs::kDefaultSearchProviderImageURL, std::string());
179 prefs->SetString(
180 prefs::kDefaultSearchProviderSearchURLPostParams, std::string());
181 prefs->SetString(
182 prefs::kDefaultSearchProviderSuggestURLPostParams, std::string());
183 prefs->SetString(
184 prefs::kDefaultSearchProviderInstantURLPostParams, std::string());
185 prefs->SetString(
186 prefs::kDefaultSearchProviderImageURLPostParams, std::string());
187 } else {
188 // The search URL is required. The other entries are optional. Just make
189 // sure that they are all specified via policy, so that the regular prefs
190 // aren't used.
191 const base::Value* dummy;
192 std::string url;
193 if (DefaultSearchURLIsValid(policies, &dummy, &url)) {
195 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
196 handlers_.begin();
197 handler != handlers_.end(); ++handler) {
198 (*handler)->ApplyPolicySettings(policies, prefs);
201 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL);
202 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL);
203 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings);
204 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword);
205 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL);
206 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderNewTabURL);
207 EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs);
208 EnsureStringPrefExists(
209 prefs,
210 prefs::kDefaultSearchProviderSearchTermsReplacementKey);
211 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderImageURL);
212 EnsureStringPrefExists(
213 prefs,
214 prefs::kDefaultSearchProviderSearchURLPostParams);
215 EnsureStringPrefExists(
216 prefs,
217 prefs::kDefaultSearchProviderSuggestURLPostParams);
218 EnsureStringPrefExists(
219 prefs,
220 prefs::kDefaultSearchProviderInstantURLPostParams);
221 EnsureStringPrefExists(
222 prefs,
223 prefs::kDefaultSearchProviderImageURLPostParams);
225 // For the name and keyword, default to the host if not specified. If
226 // there is no host (file: URLs? Not sure), use "_" to guarantee that the
227 // keyword is non-empty.
228 std::string name, keyword;
229 std::string host(GURL(url).host());
230 if (host.empty())
231 host = "_";
232 if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) ||
233 name.empty()) {
234 prefs->SetString(prefs::kDefaultSearchProviderName, host);
236 if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) ||
237 keyword.empty()) {
238 prefs->SetString(prefs::kDefaultSearchProviderKeyword, host);
241 // And clear the IDs since these are not specified via policy.
242 prefs->SetString(prefs::kDefaultSearchProviderID, std::string());
243 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID,
244 std::string());
247 content::NotificationService::current()->Notify(
248 chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
249 content::NotificationService::AllSources(),
250 content::NotificationService::NoDetails());
253 bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
254 const PolicyMap& policies,
255 PolicyErrorMap* errors) {
256 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
257 handlers_.begin();
258 handler != handlers_.end(); ++handler) {
259 if (!(*handler)->CheckPolicySettings(policies, errors))
260 return false;
262 return true;
265 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
266 const PolicyMap& policies,
267 const char* policy_name) {
268 return policies.Get(policy_name) != NULL;
271 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
272 const PolicyMap& policies) {
273 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
274 handlers_.begin();
275 handler != handlers_.end(); ++handler) {
276 if (policies.Get((*handler)->policy_name()))
277 return true;
279 return false;
282 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
283 const PolicyMap& policies) {
284 const base::Value* provider_enabled =
285 policies.GetValue(key::kDefaultSearchProviderEnabled);
286 bool enabled = true;
287 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) &&
288 !enabled;
291 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
292 const PolicyMap& policies,
293 const base::Value** url_value,
294 std::string* url_string) {
295 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL);
296 if (!*url_value || !(*url_value)->GetAsString(url_string) ||
297 url_string->empty())
298 return false;
299 TemplateURLData data;
300 data.SetURL(*url_string);
301 SearchTermsData search_terms_data;
302 return TemplateURL(NULL, data).SupportsReplacementUsingTermsData(
303 search_terms_data);
306 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
307 PrefValueMap* prefs,
308 const std::string& path) {
309 std::string value;
310 if (!prefs->GetString(path, &value))
311 prefs->SetString(path, value);
314 void DefaultSearchPolicyHandler::EnsureListPrefExists(
315 PrefValueMap* prefs,
316 const std::string& path) {
317 base::Value* value;
318 base::ListValue* list_value;
319 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
320 prefs->SetValue(path, new base::ListValue());
323 } // namespace policy