Lazily build the app list model.
[chromium-blink-merge.git] / components / search_engines / default_search_policy_handler.cc
blobd88b7155b183dcc3f1b24631ccf58d8e10ab4304
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::ApplyPolicySettings(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 bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
301 const PolicyMap& policies,
302 PolicyErrorMap* errors) {
303 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
304 handlers_.begin();
305 handler != handlers_.end(); ++handler) {
306 if (!(*handler)->CheckPolicySettings(policies, errors))
307 return false;
309 return true;
312 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
313 const PolicyMap& policies,
314 const char* policy_name) {
315 return policies.Get(policy_name) != NULL;
318 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
319 const PolicyMap& policies) {
320 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
321 handlers_.begin();
322 handler != handlers_.end(); ++handler) {
323 if (policies.Get((*handler)->policy_name()))
324 return true;
326 return false;
329 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
330 const PolicyMap& policies) {
331 const base::Value* provider_enabled =
332 policies.GetValue(key::kDefaultSearchProviderEnabled);
333 bool enabled = true;
334 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) &&
335 !enabled;
338 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
339 const PolicyMap& policies,
340 const base::Value** url_value,
341 std::string* url_string) {
342 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL);
343 if (!*url_value || !(*url_value)->GetAsString(url_string) ||
344 url_string->empty())
345 return false;
346 TemplateURLData data;
347 data.SetURL(*url_string);
348 SearchTermsData search_terms_data;
349 return TemplateURL(data).SupportsReplacement(search_terms_data);
352 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
353 PrefValueMap* prefs,
354 const std::string& path) {
355 std::string value;
356 if (!prefs->GetString(path, &value))
357 prefs->SetString(path, value);
360 void DefaultSearchPolicyHandler::EnsureListPrefExists(
361 PrefValueMap* prefs,
362 const std::string& path) {
363 base::Value* value;
364 base::ListValue* list_value;
365 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
366 prefs->SetValue(path, new base::ListValue());
369 } // namespace policy