Update {virtual,override,final} to follow C++11 style in chrome/browser/chromeos.
[chromium-blink-merge.git] / components / search_engines / default_search_policy_handler.cc
blob4041975aea502d50bfca61bc603800f71b8d23f3
1 // Copyright 2014 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 "components/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_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "components/policy/core/browser/policy_error_map.h"
12 #include "components/policy/core/common/policy_map.h"
13 #include "components/search_engines/default_search_manager.h"
14 #include "components/search_engines/search_engines_pref_names.h"
15 #include "components/search_engines/search_terms_data.h"
16 #include "components/search_engines/template_url.h"
17 #include "grit/components_strings.h"
18 #include "policy/policy_constants.h"
20 namespace policy {
22 namespace {
23 // Extracts a list from a policy value and adds it to a pref dictionary.
24 void SetListInPref(const PolicyMap& policies,
25 const char* policy_name,
26 const char* key,
27 base::DictionaryValue* dict) {
28 DCHECK(dict);
29 const base::Value* policy_value = policies.GetValue(policy_name);
30 const base::ListValue* policy_list = NULL;
31 if (policy_value) {
32 bool is_list = policy_value->GetAsList(&policy_list);
33 DCHECK(is_list);
35 dict->Set(key, policy_list ? policy_list->DeepCopy() : new base::ListValue());
38 // Extracts a string from a policy value and adds it to a pref dictionary.
39 void SetStringInPref(const PolicyMap& policies,
40 const char* policy_name,
41 const char* key,
42 base::DictionaryValue* dict) {
43 DCHECK(dict);
44 const base::Value* policy_value = policies.GetValue(policy_name);
45 std::string str;
46 if (policy_value) {
47 bool is_string = policy_value->GetAsString(&str);
48 DCHECK(is_string);
50 dict->SetString(key, str);
53 } // namespace
55 // List of policy types to preference names, for policies affecting the default
56 // search provider.
57 const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[] = {
58 { key::kDefaultSearchProviderEnabled,
59 prefs::kDefaultSearchProviderEnabled,
60 base::Value::TYPE_BOOLEAN },
61 { key::kDefaultSearchProviderName,
62 prefs::kDefaultSearchProviderName,
63 base::Value::TYPE_STRING },
64 { key::kDefaultSearchProviderKeyword,
65 prefs::kDefaultSearchProviderKeyword,
66 base::Value::TYPE_STRING },
67 { key::kDefaultSearchProviderSearchURL,
68 prefs::kDefaultSearchProviderSearchURL,
69 base::Value::TYPE_STRING },
70 { key::kDefaultSearchProviderSuggestURL,
71 prefs::kDefaultSearchProviderSuggestURL,
72 base::Value::TYPE_STRING },
73 { key::kDefaultSearchProviderInstantURL,
74 prefs::kDefaultSearchProviderInstantURL,
75 base::Value::TYPE_STRING },
76 { key::kDefaultSearchProviderIconURL,
77 prefs::kDefaultSearchProviderIconURL,
78 base::Value::TYPE_STRING },
79 { key::kDefaultSearchProviderEncodings,
80 prefs::kDefaultSearchProviderEncodings,
81 base::Value::TYPE_LIST },
82 { key::kDefaultSearchProviderAlternateURLs,
83 prefs::kDefaultSearchProviderAlternateURLs,
84 base::Value::TYPE_LIST },
85 { key::kDefaultSearchProviderSearchTermsReplacementKey,
86 prefs::kDefaultSearchProviderSearchTermsReplacementKey,
87 base::Value::TYPE_STRING },
88 { key::kDefaultSearchProviderImageURL,
89 prefs::kDefaultSearchProviderImageURL,
90 base::Value::TYPE_STRING },
91 { key::kDefaultSearchProviderNewTabURL,
92 prefs::kDefaultSearchProviderNewTabURL,
93 base::Value::TYPE_STRING },
94 { key::kDefaultSearchProviderSearchURLPostParams,
95 prefs::kDefaultSearchProviderSearchURLPostParams,
96 base::Value::TYPE_STRING },
97 { key::kDefaultSearchProviderSuggestURLPostParams,
98 prefs::kDefaultSearchProviderSuggestURLPostParams,
99 base::Value::TYPE_STRING },
100 { key::kDefaultSearchProviderInstantURLPostParams,
101 prefs::kDefaultSearchProviderInstantURLPostParams,
102 base::Value::TYPE_STRING },
103 { key::kDefaultSearchProviderImageURLPostParams,
104 prefs::kDefaultSearchProviderImageURLPostParams,
105 base::Value::TYPE_STRING },
108 // List of policy types to preference names, for policies affecting the default
109 // search provider.
110 const PolicyToPreferenceMapEntry kDefaultSearchPolicyDataMap[] = {
111 {key::kDefaultSearchProviderName, DefaultSearchManager::kShortName,
112 base::Value::TYPE_STRING},
113 {key::kDefaultSearchProviderKeyword, DefaultSearchManager::kKeyword,
114 base::Value::TYPE_STRING},
115 {key::kDefaultSearchProviderSearchURL, DefaultSearchManager::kURL,
116 base::Value::TYPE_STRING},
117 {key::kDefaultSearchProviderSuggestURL,
118 DefaultSearchManager::kSuggestionsURL, base::Value::TYPE_STRING},
119 {key::kDefaultSearchProviderInstantURL, DefaultSearchManager::kInstantURL,
120 base::Value::TYPE_STRING},
121 {key::kDefaultSearchProviderIconURL, DefaultSearchManager::kFaviconURL,
122 base::Value::TYPE_STRING},
123 {key::kDefaultSearchProviderEncodings,
124 DefaultSearchManager::kInputEncodings, base::Value::TYPE_LIST},
125 {key::kDefaultSearchProviderAlternateURLs,
126 DefaultSearchManager::kAlternateURLs, base::Value::TYPE_LIST},
127 {key::kDefaultSearchProviderSearchTermsReplacementKey,
128 DefaultSearchManager::kSearchTermsReplacementKey,
129 base::Value::TYPE_STRING},
130 {key::kDefaultSearchProviderImageURL, DefaultSearchManager::kImageURL,
131 base::Value::TYPE_STRING},
132 {key::kDefaultSearchProviderNewTabURL, DefaultSearchManager::kNewTabURL,
133 base::Value::TYPE_STRING},
134 {key::kDefaultSearchProviderSearchURLPostParams,
135 DefaultSearchManager::kSearchURLPostParams, base::Value::TYPE_STRING},
136 {key::kDefaultSearchProviderSuggestURLPostParams,
137 DefaultSearchManager::kSuggestionsURLPostParams, base::Value::TYPE_STRING},
138 {key::kDefaultSearchProviderInstantURLPostParams,
139 DefaultSearchManager::kInstantURLPostParams, base::Value::TYPE_STRING},
140 {key::kDefaultSearchProviderImageURLPostParams,
141 DefaultSearchManager::kImageURLPostParams, base::Value::TYPE_STRING},
144 // DefaultSearchEncodingsPolicyHandler implementation --------------------------
146 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler()
147 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings,
148 base::Value::TYPE_LIST) {}
150 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() {
153 void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings(
154 const PolicyMap& policies, PrefValueMap* prefs) {
155 // The DefaultSearchProviderEncodings policy has type list, but the related
156 // preference has type string. Convert one into the other here, using
157 // ';' as a separator.
158 const base::Value* value = policies.GetValue(policy_name());
159 const base::ListValue* list;
160 if (!value || !value->GetAsList(&list))
161 return;
163 base::ListValue::const_iterator iter(list->begin());
164 base::ListValue::const_iterator end(list->end());
165 std::vector<std::string> string_parts;
166 for (; iter != end; ++iter) {
167 std::string s;
168 if ((*iter)->GetAsString(&s)) {
169 string_parts.push_back(s);
172 std::string encodings = JoinString(string_parts, ';');
173 prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings);
177 // DefaultSearchPolicyHandler implementation -----------------------------------
179 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {
180 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
181 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
182 if (policy_name == key::kDefaultSearchProviderEncodings) {
183 handlers_.push_back(new DefaultSearchEncodingsPolicyHandler());
184 } else {
185 handlers_.push_back(new SimplePolicyHandler(
186 policy_name,
187 kDefaultSearchPolicyMap[i].preference_path,
188 kDefaultSearchPolicyMap[i].value_type));
193 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {
194 STLDeleteElements(&handlers_);
197 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
198 PolicyErrorMap* errors) {
199 if (!CheckIndividualPolicies(policies, errors))
200 return false;
202 if (DefaultSearchProviderIsDisabled(policies)) {
203 // Add an error for all specified default search policies except
204 // DefaultSearchProviderEnabled.
206 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
207 handlers_.begin();
208 handler != handlers_.end(); ++handler) {
209 const char* policy_name = (*handler)->policy_name();
210 if (policy_name != key::kDefaultSearchProviderEnabled &&
211 HasDefaultSearchPolicy(policies, policy_name)) {
212 errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED);
215 return true;
218 const base::Value* url;
219 std::string dummy;
220 if (DefaultSearchURLIsValid(policies, &url, &dummy) ||
221 !AnyDefaultSearchPoliciesSpecified(policies))
222 return true;
223 errors->AddError(key::kDefaultSearchProviderSearchURL, url ?
224 IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR);
225 return false;
228 void DefaultSearchPolicyHandler::HandleDictionaryPref(const PolicyMap& policies,
229 PrefValueMap* prefs) {
230 if (DefaultSearchProviderIsDisabled(policies)) {
231 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
232 dict->SetBoolean(DefaultSearchManager::kDisabledByPolicy, true);
233 DefaultSearchManager::AddPrefValueToMap(dict.release(), prefs);
234 return;
237 // The search URL is required. The other entries are optional. Just make
238 // sure that they are all specified via policy, so that the regular prefs
239 // aren't used.
240 const base::Value* dummy;
241 std::string url;
242 if (!DefaultSearchURLIsValid(policies, &dummy, &url))
243 return;
245 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
246 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyDataMap); ++i) {
247 const char* policy_name = kDefaultSearchPolicyDataMap[i].policy_name;
248 switch (kDefaultSearchPolicyDataMap[i].value_type) {
249 case base::Value::TYPE_STRING:
250 SetStringInPref(policies,
251 policy_name,
252 kDefaultSearchPolicyDataMap[i].preference_path,
253 dict.get());
254 break;
255 case base::Value::TYPE_LIST:
256 SetListInPref(policies,
257 policy_name,
258 kDefaultSearchPolicyDataMap[i].preference_path,
259 dict.get());
260 break;
261 default:
262 NOTREACHED();
263 break;
267 // Set the fields which are not specified by the policy to default values.
268 dict->SetString(DefaultSearchManager::kID,
269 base::Int64ToString(kInvalidTemplateURLID));
270 dict->SetInteger(DefaultSearchManager::kPrepopulateID, 0);
271 dict->SetString(DefaultSearchManager::kSyncGUID, std::string());
272 dict->SetString(DefaultSearchManager::kOriginatingURL, std::string());
273 dict->SetBoolean(DefaultSearchManager::kSafeForAutoReplace, true);
274 dict->SetDouble(DefaultSearchManager::kDateCreated,
275 base::Time::Now().ToInternalValue());
276 dict->SetDouble(DefaultSearchManager::kLastModified,
277 base::Time::Now().ToInternalValue());
278 dict->SetInteger(DefaultSearchManager::kUsageCount, 0);
279 dict->SetBoolean(DefaultSearchManager::kCreatedByPolicy, true);
281 // For the name and keyword, default to the host if not specified. If
282 // there is no host (as is the case with file URLs of the form:
283 // "file:///c:/..."), use "_" to guarantee that the keyword is non-empty.
284 std::string name, keyword;
285 dict->GetString(DefaultSearchManager::kKeyword, &keyword);
286 dict->GetString(DefaultSearchManager::kShortName, &name);
287 dict->GetString(DefaultSearchManager::kURL, &url);
289 std::string host(GURL(url).host());
290 if (host.empty())
291 host = "_";
292 if (name.empty())
293 dict->SetString(DefaultSearchManager::kShortName, host);
294 if (keyword.empty())
295 dict->SetString(DefaultSearchManager::kKeyword, host);
297 DefaultSearchManager::AddPrefValueToMap(dict.release(), prefs);
300 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
301 PrefValueMap* prefs) {
302 HandleDictionaryPref(policies, prefs);
304 if (DefaultSearchProviderIsDisabled(policies)) {
305 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false);
307 // If default search is disabled, the other fields are ignored.
308 prefs->SetString(prefs::kDefaultSearchProviderName, std::string());
309 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
310 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
311 prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
312 prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
313 prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
314 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
315 prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, std::string());
316 prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs,
317 new base::ListValue());
318 prefs->SetString(
319 prefs::kDefaultSearchProviderSearchTermsReplacementKey, std::string());
320 prefs->SetString(prefs::kDefaultSearchProviderImageURL, std::string());
321 prefs->SetString(
322 prefs::kDefaultSearchProviderSearchURLPostParams, std::string());
323 prefs->SetString(
324 prefs::kDefaultSearchProviderSuggestURLPostParams, std::string());
325 prefs->SetString(
326 prefs::kDefaultSearchProviderInstantURLPostParams, std::string());
327 prefs->SetString(
328 prefs::kDefaultSearchProviderImageURLPostParams, std::string());
329 } else {
330 // The search URL is required. The other entries are optional. Just make
331 // sure that they are all specified via policy, so that the regular prefs
332 // aren't used.
333 const base::Value* dummy;
334 std::string url;
335 if (DefaultSearchURLIsValid(policies, &dummy, &url)) {
337 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
338 handlers_.begin();
339 handler != handlers_.end(); ++handler) {
340 (*handler)->ApplyPolicySettings(policies, prefs);
343 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL);
344 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL);
345 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings);
346 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword);
347 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL);
348 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderNewTabURL);
349 EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs);
350 EnsureStringPrefExists(
351 prefs,
352 prefs::kDefaultSearchProviderSearchTermsReplacementKey);
353 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderImageURL);
354 EnsureStringPrefExists(
355 prefs,
356 prefs::kDefaultSearchProviderSearchURLPostParams);
357 EnsureStringPrefExists(
358 prefs,
359 prefs::kDefaultSearchProviderSuggestURLPostParams);
360 EnsureStringPrefExists(
361 prefs,
362 prefs::kDefaultSearchProviderInstantURLPostParams);
363 EnsureStringPrefExists(
364 prefs,
365 prefs::kDefaultSearchProviderImageURLPostParams);
367 // For the name and keyword, default to the host if not specified. If
368 // there is no host (file: URLs? Not sure), use "_" to guarantee that the
369 // keyword is non-empty.
370 std::string name, keyword;
371 std::string host(GURL(url).host());
372 if (host.empty())
373 host = "_";
374 if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) ||
375 name.empty()) {
376 prefs->SetString(prefs::kDefaultSearchProviderName, host);
378 if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) ||
379 keyword.empty()) {
380 prefs->SetString(prefs::kDefaultSearchProviderKeyword, host);
383 // And clear the IDs since these are not specified via policy.
384 prefs->SetString(prefs::kDefaultSearchProviderID, std::string());
385 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID,
386 std::string());
391 bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
392 const PolicyMap& policies,
393 PolicyErrorMap* errors) {
394 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
395 handlers_.begin();
396 handler != handlers_.end(); ++handler) {
397 if (!(*handler)->CheckPolicySettings(policies, errors))
398 return false;
400 return true;
403 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
404 const PolicyMap& policies,
405 const char* policy_name) {
406 return policies.Get(policy_name) != NULL;
409 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
410 const PolicyMap& policies) {
411 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
412 handlers_.begin();
413 handler != handlers_.end(); ++handler) {
414 if (policies.Get((*handler)->policy_name()))
415 return true;
417 return false;
420 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
421 const PolicyMap& policies) {
422 const base::Value* provider_enabled =
423 policies.GetValue(key::kDefaultSearchProviderEnabled);
424 bool enabled = true;
425 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) &&
426 !enabled;
429 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
430 const PolicyMap& policies,
431 const base::Value** url_value,
432 std::string* url_string) {
433 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL);
434 if (!*url_value || !(*url_value)->GetAsString(url_string) ||
435 url_string->empty())
436 return false;
437 TemplateURLData data;
438 data.SetURL(*url_string);
439 SearchTermsData search_terms_data;
440 return TemplateURL(data).SupportsReplacement(search_terms_data);
443 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
444 PrefValueMap* prefs,
445 const std::string& path) {
446 std::string value;
447 if (!prefs->GetString(path, &value))
448 prefs->SetString(path, value);
451 void DefaultSearchPolicyHandler::EnsureListPrefExists(
452 PrefValueMap* prefs,
453 const std::string& path) {
454 base::Value* value;
455 base::ListValue* list_value;
456 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
457 prefs->SetValue(path, new base::ListValue());
460 } // namespace policy