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"
22 // List of policy types to preference names, for policies affecting the default
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
))
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
) {
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());
117 handlers_
.push_back(new SimplePolicyHandler(
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
))
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
=
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
);
150 const base::Value
* url
;
152 if (DefaultSearchURLIsValid(policies
, &url
, &dummy
) ||
153 !AnyDefaultSearchPoliciesSpecified(policies
))
155 errors
->AddError(key::kDefaultSearchProviderSearchURL
, url
?
156 IDS_POLICY_INVALID_SEARCH_URL_ERROR
: IDS_POLICY_NOT_SPECIFIED_ERROR
);
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());
177 prefs::kDefaultSearchProviderSearchTermsReplacementKey
, std::string());
178 prefs
->SetString(prefs::kDefaultSearchProviderImageURL
, std::string());
180 prefs::kDefaultSearchProviderSearchURLPostParams
, std::string());
182 prefs::kDefaultSearchProviderSuggestURLPostParams
, std::string());
184 prefs::kDefaultSearchProviderInstantURLPostParams
, std::string());
186 prefs::kDefaultSearchProviderImageURLPostParams
, std::string());
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
191 const base::Value
* dummy
;
193 if (DefaultSearchURLIsValid(policies
, &dummy
, &url
)) {
195 for (std::vector
<TypeCheckingPolicyHandler
*>::const_iterator handler
=
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(
210 prefs::kDefaultSearchProviderSearchTermsReplacementKey
);
211 EnsureStringPrefExists(prefs
, prefs::kDefaultSearchProviderImageURL
);
212 EnsureStringPrefExists(
214 prefs::kDefaultSearchProviderSearchURLPostParams
);
215 EnsureStringPrefExists(
217 prefs::kDefaultSearchProviderSuggestURLPostParams
);
218 EnsureStringPrefExists(
220 prefs::kDefaultSearchProviderInstantURLPostParams
);
221 EnsureStringPrefExists(
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());
232 if (!prefs
->GetString(prefs::kDefaultSearchProviderName
, &name
) ||
234 prefs
->SetString(prefs::kDefaultSearchProviderName
, host
);
236 if (!prefs
->GetString(prefs::kDefaultSearchProviderKeyword
, &keyword
) ||
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
,
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
=
258 handler
!= handlers_
.end(); ++handler
) {
259 if (!(*handler
)->CheckPolicySettings(policies
, errors
))
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
=
275 handler
!= handlers_
.end(); ++handler
) {
276 if (policies
.Get((*handler
)->policy_name()))
282 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
283 const PolicyMap
& policies
) {
284 const base::Value
* provider_enabled
=
285 policies
.GetValue(key::kDefaultSearchProviderEnabled
);
287 return provider_enabled
&& provider_enabled
->GetAsBoolean(&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
) ||
299 TemplateURLData data
;
300 data
.SetURL(*url_string
);
301 SearchTermsData search_terms_data
;
302 return TemplateURL(NULL
, data
).SupportsReplacementUsingTermsData(
306 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
308 const std::string
& path
) {
310 if (!prefs
->GetString(path
, &value
))
311 prefs
->SetString(path
, value
);
314 void DefaultSearchPolicyHandler::EnsureListPrefExists(
316 const std::string
& path
) {
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