Upload upstream chromium 114.0.5735.31
[platform/framework/web/chromium-efl.git] / components / search_engines / template_url_data_util.cc
1 // Copyright 2016 The Chromium Authors
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 "components/search_engines/template_url_data_util.h"
6
7 #include <string>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_piece.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "components/search_engines/default_search_manager.h"
14 #include "components/search_engines/prepopulated_engines.h"
15 #include "components/search_engines/template_url_data.h"
16 #include "components/search_engines/template_url_starter_pack_data.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "url/gurl.h"
19
20 namespace {
21
22 // Converts the C-style string `str` to a base::StringPiece making sure to avoid
23 // dereferencing nullptrs.
24 base::StringPiece ToStringPiece(const char* str) {
25   return str ? base::StringPiece(str) : base::StringPiece();
26 }
27
28 }  // namespace
29
30 std::unique_ptr<TemplateURLData> TemplateURLDataFromDictionary(
31     const base::Value::Dict& dict) {
32   const std::string* search_url = dict.FindString(DefaultSearchManager::kURL);
33   const std::string* keyword = dict.FindString(DefaultSearchManager::kKeyword);
34   const std::string* short_name =
35       dict.FindString(DefaultSearchManager::kShortName);
36   // Check required TemplateURLData fields first.
37   if (!search_url || !keyword || !short_name) {
38     return nullptr;
39   }
40
41   auto result = std::make_unique<TemplateURLData>();
42   result->SetKeyword(base::UTF8ToUTF16(*keyword));
43   result->SetURL(*search_url);
44
45   const std::string* id = dict.FindString(DefaultSearchManager::kID);
46   if (id) {
47     base::StringToInt64(*id, &result->id);
48   }
49
50   const std::string* string_value = nullptr;
51
52   result->SetShortName(base::UTF8ToUTF16(*short_name));
53   result->prepopulate_id = dict.FindInt(DefaultSearchManager::kPrepopulateID)
54                                .value_or(result->prepopulate_id);
55   result->starter_pack_id = dict.FindInt(DefaultSearchManager::kStarterPackId)
56                                 .value_or(result->starter_pack_id);
57   string_value = dict.FindString(DefaultSearchManager::kSyncGUID);
58   if (string_value) {
59     result->sync_guid = *string_value;
60   }
61   string_value = dict.FindString(DefaultSearchManager::kSuggestionsURL);
62   if (string_value) {
63     result->suggestions_url = *string_value;
64   }
65
66   string_value = dict.FindString(DefaultSearchManager::kImageURL);
67   if (string_value) {
68     result->image_url = *string_value;
69   }
70   string_value = dict.FindString(DefaultSearchManager::kImageTranslateURL);
71   if (string_value) {
72     result->image_translate_url = *string_value;
73   }
74   string_value = dict.FindString(DefaultSearchManager::kNewTabURL);
75   if (string_value) {
76     result->new_tab_url = *string_value;
77   }
78   string_value = dict.FindString(DefaultSearchManager::kContextualSearchURL);
79   if (string_value) {
80     result->contextual_search_url = *string_value;
81   }
82
83   string_value = dict.FindString(DefaultSearchManager::kFaviconURL);
84   if (string_value) {
85     result->favicon_url = GURL(*string_value);
86   }
87   string_value = dict.FindString(DefaultSearchManager::kOriginatingURL);
88   if (string_value) {
89     result->originating_url = GURL(*string_value);
90   }
91   string_value = dict.FindString(DefaultSearchManager::kLogoURL);
92   if (string_value) {
93     result->logo_url = GURL(*string_value);
94   }
95   string_value = dict.FindString(DefaultSearchManager::kDoodleURL);
96   if (string_value) {
97     result->doodle_url = GURL(*string_value);
98   }
99
100   const std::string* search_url_post_params =
101       dict.FindString(DefaultSearchManager::kSearchURLPostParams);
102   if (search_url_post_params) {
103     result->search_url_post_params = *search_url_post_params;
104   }
105   const std::string* suggestions_url_post_params =
106       dict.FindString(DefaultSearchManager::kSuggestionsURLPostParams);
107   if (suggestions_url_post_params) {
108     result->suggestions_url_post_params = *suggestions_url_post_params;
109   }
110   const std::string* image_url_post_params =
111       dict.FindString(DefaultSearchManager::kImageURLPostParams);
112   if (image_url_post_params) {
113     result->image_url_post_params = *image_url_post_params;
114   }
115   const std::string* side_search_param =
116       dict.FindString(DefaultSearchManager::kSideSearchParam);
117   if (side_search_param) {
118     result->side_search_param = *side_search_param;
119   }
120   const std::string* side_image_search_param =
121       dict.FindString(DefaultSearchManager::kSideImageSearchParam);
122   if (side_image_search_param) {
123     result->side_image_search_param = *side_image_search_param;
124   }
125   const std::string* image_translate_source_language_param_key =
126       dict.FindString(
127           DefaultSearchManager::kImageTranslateSourceLanguageParamKey);
128   if (image_translate_source_language_param_key) {
129     result->image_translate_source_language_param_key =
130         *image_translate_source_language_param_key;
131   }
132   const std::string* image_translate_target_language_param_key =
133       dict.FindString(
134           DefaultSearchManager::kImageTranslateTargetLanguageParamKey);
135   if (image_translate_target_language_param_key) {
136     result->image_translate_target_language_param_key =
137         *image_translate_target_language_param_key;
138   }
139   const std::string* image_search_branding_label =
140       dict.FindString(DefaultSearchManager::kImageSearchBrandingLabel);
141   if (image_search_branding_label) {
142     result->image_search_branding_label =
143         base::UTF8ToUTF16(*image_search_branding_label);
144   }
145   const base::Value::List* additional_params_list =
146       dict.FindList(DefaultSearchManager::kSearchIntentParams);
147   if (additional_params_list) {
148     for (const auto& additional_param_value : *additional_params_list) {
149       const auto* additional_param = additional_param_value.GetIfString();
150       DCHECK(additional_param && !additional_param->empty());
151       if (additional_param && !additional_param->empty()) {
152         result->search_intent_params.push_back(*additional_param);
153       }
154     }
155   }
156   absl::optional<bool> safe_for_autoreplace =
157       dict.FindBool(DefaultSearchManager::kSafeForAutoReplace);
158   if (safe_for_autoreplace) {
159     result->safe_for_autoreplace = *safe_for_autoreplace;
160   }
161
162   std::string date_created_str;
163   std::string last_modified_str;
164   std::string last_visited_str;
165
166   string_value = dict.FindString(DefaultSearchManager::kDateCreated);
167   if (string_value) {
168     date_created_str = *string_value;
169   }
170   string_value = dict.FindString(DefaultSearchManager::kLastModified);
171   if (string_value) {
172     last_modified_str = *string_value;
173   }
174   string_value = dict.FindString(DefaultSearchManager::kLastVisited);
175   if (string_value) {
176     last_visited_str = *string_value;
177   }
178
179   int64_t date_created = 0;
180   if (base::StringToInt64(date_created_str, &date_created))
181     result->date_created = base::Time::FromInternalValue(date_created);
182
183   int64_t last_modified = 0;
184   if (base::StringToInt64(last_modified_str, &last_modified))
185     result->last_modified = base::Time::FromInternalValue(last_modified);
186
187   int64_t last_visited = 0;
188   if (base::StringToInt64(last_visited_str, &last_visited))
189     result->last_visited = base::Time::FromInternalValue(last_visited);
190
191   result->usage_count = dict.FindInt(DefaultSearchManager::kUsageCount)
192                             .value_or(result->usage_count);
193
194   const base::Value::List* alternate_urls =
195       dict.FindList(DefaultSearchManager::kAlternateURLs);
196   if (alternate_urls) {
197     for (const auto& it : *alternate_urls) {
198       if (it.is_string())
199         result->alternate_urls.push_back(it.GetString());
200     }
201   }
202
203   const base::Value::List* encodings =
204       dict.FindList(DefaultSearchManager::kInputEncodings);
205   if (encodings) {
206     for (const auto& it : *encodings) {
207       std::string encoding;
208       if (it.is_string())
209         result->input_encodings.push_back(it.GetString());
210     }
211   }
212
213   result->created_by_policy =
214       dict.FindBool(DefaultSearchManager::kCreatedByPolicy)
215           .value_or(result->created_by_policy);
216   result->created_from_play_api =
217       dict.FindBool(DefaultSearchManager::kCreatedFromPlayAPI)
218           .value_or(result->created_from_play_api);
219   result->preconnect_to_search_url =
220       dict.FindBool(DefaultSearchManager::kPreconnectToSearchUrl)
221           .value_or(result->preconnect_to_search_url);
222   result->prefetch_likely_navigations =
223       dict.FindBool(DefaultSearchManager::kPrefetchLikelyNavigations)
224           .value_or(result->prefetch_likely_navigations);
225   result->is_active = static_cast<TemplateURLData::ActiveStatus>(
226       dict.FindInt(DefaultSearchManager::kIsActive)
227           .value_or(static_cast<int>(result->is_active)));
228   result->enforced_by_policy =
229       dict.FindBool(DefaultSearchManager::kEnforcedByPolicy)
230           .value_or(result->enforced_by_policy);
231   return result;
232 }
233
234 base::Value::Dict TemplateURLDataToDictionary(const TemplateURLData& data) {
235   base::Value::Dict url_dict;
236   url_dict.Set(DefaultSearchManager::kID, base::NumberToString(data.id));
237   url_dict.Set(DefaultSearchManager::kShortName, data.short_name());
238   url_dict.Set(DefaultSearchManager::kKeyword, data.keyword());
239   url_dict.Set(DefaultSearchManager::kPrepopulateID, data.prepopulate_id);
240   url_dict.Set(DefaultSearchManager::kStarterPackId, data.starter_pack_id);
241   url_dict.Set(DefaultSearchManager::kSyncGUID, data.sync_guid);
242
243   url_dict.Set(DefaultSearchManager::kURL, data.url());
244   url_dict.Set(DefaultSearchManager::kSuggestionsURL, data.suggestions_url);
245   url_dict.Set(DefaultSearchManager::kImageURL, data.image_url);
246   url_dict.Set(DefaultSearchManager::kImageTranslateURL,
247                data.image_translate_url);
248   url_dict.Set(DefaultSearchManager::kNewTabURL, data.new_tab_url);
249   url_dict.Set(DefaultSearchManager::kContextualSearchURL,
250                data.contextual_search_url);
251   url_dict.Set(DefaultSearchManager::kFaviconURL, data.favicon_url.spec());
252   url_dict.Set(DefaultSearchManager::kOriginatingURL,
253                data.originating_url.spec());
254   url_dict.Set(DefaultSearchManager::kLogoURL, data.logo_url.spec());
255   url_dict.Set(DefaultSearchManager::kDoodleURL, data.doodle_url.spec());
256
257   url_dict.Set(DefaultSearchManager::kSearchURLPostParams,
258                data.search_url_post_params);
259   url_dict.Set(DefaultSearchManager::kSuggestionsURLPostParams,
260                data.suggestions_url_post_params);
261   url_dict.Set(DefaultSearchManager::kImageURLPostParams,
262                data.image_url_post_params);
263   url_dict.Set(DefaultSearchManager::kSideSearchParam, data.side_search_param);
264   url_dict.Set(DefaultSearchManager::kSideImageSearchParam,
265                data.side_image_search_param);
266   url_dict.Set(DefaultSearchManager::kImageTranslateSourceLanguageParamKey,
267                data.image_translate_source_language_param_key);
268   url_dict.Set(DefaultSearchManager::kImageTranslateTargetLanguageParamKey,
269                data.image_translate_target_language_param_key);
270   url_dict.Set(DefaultSearchManager::kImageSearchBrandingLabel,
271                data.image_search_branding_label);
272
273   base::Value::List additional_params_list;
274   for (const auto& additional_param : data.search_intent_params) {
275     additional_params_list.Append(additional_param);
276   }
277   url_dict.Set(DefaultSearchManager::kSearchIntentParams,
278                std::move(additional_params_list));
279
280   url_dict.Set(DefaultSearchManager::kSafeForAutoReplace,
281                data.safe_for_autoreplace);
282
283   url_dict.Set(DefaultSearchManager::kDateCreated,
284                base::NumberToString(data.date_created.ToInternalValue()));
285   url_dict.Set(DefaultSearchManager::kLastModified,
286                base::NumberToString(data.last_modified.ToInternalValue()));
287   url_dict.Set(DefaultSearchManager::kLastVisited,
288                base::NumberToString(data.last_visited.ToInternalValue()));
289   url_dict.Set(DefaultSearchManager::kUsageCount, data.usage_count);
290
291   base::Value::List alternate_urls;
292   for (const auto& alternate_url : data.alternate_urls)
293     alternate_urls.Append(alternate_url);
294
295   url_dict.Set(DefaultSearchManager::kAlternateURLs, std::move(alternate_urls));
296
297   base::Value::List encodings;
298   for (const auto& input_encoding : data.input_encodings)
299     encodings.Append(input_encoding);
300   url_dict.Set(DefaultSearchManager::kInputEncodings, std::move(encodings));
301
302   url_dict.Set(DefaultSearchManager::kCreatedByPolicy, data.created_by_policy);
303   url_dict.Set(DefaultSearchManager::kCreatedFromPlayAPI,
304                data.created_from_play_api);
305   url_dict.Set(DefaultSearchManager::kPreconnectToSearchUrl,
306                data.preconnect_to_search_url);
307   url_dict.Set(DefaultSearchManager::kPrefetchLikelyNavigations,
308                data.prefetch_likely_navigations);
309   url_dict.Set(DefaultSearchManager::kIsActive,
310                static_cast<int>(data.is_active));
311   url_dict.Set(DefaultSearchManager::kEnforcedByPolicy,
312                data.enforced_by_policy);
313   return url_dict;
314 }
315
316 std::unique_ptr<TemplateURLData> TemplateURLDataFromPrepopulatedEngine(
317     const TemplateURLPrepopulateData::PrepopulatedEngine& engine) {
318   std::vector<std::string> search_intent_params;
319   if (engine.search_intent_params) {
320     for (size_t i = 0; i < engine.search_intent_params_size; ++i) {
321       search_intent_params.emplace_back(engine.search_intent_params[i]);
322     }
323   }
324
325   base::Value::List alternate_urls;
326   if (engine.alternate_urls) {
327     for (size_t i = 0; i < engine.alternate_urls_size; ++i)
328       alternate_urls.Append(std::string(engine.alternate_urls[i]));
329   }
330
331   std::u16string image_search_branding_label =
332       engine.image_search_branding_label
333           ? base::WideToUTF16(engine.image_search_branding_label)
334           : std::u16string();
335
336   return std::make_unique<TemplateURLData>(
337       base::WideToUTF16(engine.name), base::WideToUTF16(engine.keyword),
338       ToStringPiece(engine.search_url), ToStringPiece(engine.suggest_url),
339       ToStringPiece(engine.image_url),
340       ToStringPiece(engine.image_translate_url),
341       ToStringPiece(engine.new_tab_url),
342       ToStringPiece(engine.contextual_search_url),
343       ToStringPiece(engine.logo_url), ToStringPiece(engine.doodle_url),
344       ToStringPiece(engine.search_url_post_params),
345       ToStringPiece(engine.suggest_url_post_params),
346       ToStringPiece(engine.image_url_post_params),
347       ToStringPiece(engine.side_search_param),
348       ToStringPiece(engine.side_image_search_param),
349       ToStringPiece(engine.image_translate_source_language_param_key),
350       ToStringPiece(engine.image_translate_target_language_param_key),
351       std::move(search_intent_params), ToStringPiece(engine.favicon_url),
352       ToStringPiece(engine.encoding), image_search_branding_label,
353       alternate_urls,
354       ToStringPiece(engine.preconnect_to_search_url) == "ALLOWED",
355       ToStringPiece(engine.prefetch_likely_navigations) == "ALLOWED",
356       engine.id);
357 }
358
359 std::unique_ptr<TemplateURLData> TemplateURLDataFromOverrideDictionary(
360     const base::Value::Dict& engine_dict) {
361   const std::string* string_value = nullptr;
362
363   std::u16string name;
364   std::u16string keyword;
365   std::string search_url;
366   std::string favicon_url;
367   std::string encoding;
368
369   string_value = engine_dict.FindString("name");
370   if (string_value) {
371     name = base::UTF8ToUTF16(*string_value);
372   }
373   string_value = engine_dict.FindString("keyword");
374   if (string_value) {
375     keyword = base::UTF8ToUTF16(*string_value);
376   }
377   string_value = engine_dict.FindString("search_url");
378   if (string_value) {
379     search_url = *string_value;
380   }
381   string_value = engine_dict.FindString("favicon_url");
382   if (string_value) {
383     favicon_url = *string_value;
384   }
385   string_value = engine_dict.FindString("encoding");
386   if (string_value) {
387     encoding = *string_value;
388   }
389   absl::optional<int> id = engine_dict.FindInt("id");
390
391   // The following fields are required for each search engine configuration.
392   if (!name.empty() && !keyword.empty() && !search_url.empty() &&
393       !favicon_url.empty() && !encoding.empty() && id.has_value()) {
394     // These fields are optional.
395     base::Value::List empty_list;
396     const base::Value::List* alternate_urls =
397         engine_dict.FindList("alternate_urls");
398     if (!alternate_urls)
399       alternate_urls = &empty_list;
400
401     std::string suggest_url;
402     std::string image_url;
403     std::string image_translate_url;
404     std::string new_tab_url;
405     std::string contextual_search_url;
406     std::string logo_url;
407     std::string doodle_url;
408     std::string search_url_post_params;
409     std::string suggest_url_post_params;
410     std::string image_url_post_params;
411     std::string side_search_param;
412     std::string side_image_search_param;
413     std::string image_translate_source_language_param_key;
414     std::string image_translate_target_language_param_key;
415     std::u16string image_search_branding_label;
416     std::vector<std::string> search_intent_params;
417     std::string preconnect_to_search_url;
418     std::string prefetch_likely_navigations;
419
420     string_value = engine_dict.FindString("suggest_url");
421     if (string_value) {
422       suggest_url = *string_value;
423     }
424     string_value = engine_dict.FindString("image_url");
425     if (string_value) {
426       image_url = *string_value;
427     }
428     string_value = engine_dict.FindString("image_translate_url");
429     if (string_value) {
430       image_translate_url = *string_value;
431     }
432     string_value = engine_dict.FindString("new_tab_url");
433     if (string_value) {
434       new_tab_url = *string_value;
435     }
436     string_value = engine_dict.FindString("contextual_search_url");
437     if (string_value) {
438       contextual_search_url = *string_value;
439     }
440     string_value = engine_dict.FindString("logo_url");
441     if (string_value) {
442       logo_url = *string_value;
443     }
444     string_value = engine_dict.FindString("doodle_url");
445     if (string_value) {
446       doodle_url = *string_value;
447     }
448     string_value = engine_dict.FindString("search_url_post_params");
449     if (string_value) {
450       search_url_post_params = *string_value;
451     }
452     string_value = engine_dict.FindString("suggest_url_post_params");
453     if (string_value) {
454       suggest_url_post_params = *string_value;
455     }
456     string_value = engine_dict.FindString("image_url_post_params");
457     if (string_value) {
458       image_url_post_params = *string_value;
459     }
460     string_value = engine_dict.FindString("side_search_param");
461     if (string_value) {
462       side_search_param = *string_value;
463     }
464     string_value = engine_dict.FindString("side_image_search_param");
465     if (string_value) {
466       side_image_search_param = *string_value;
467     }
468     string_value =
469         engine_dict.FindString("image_translate_source_language_param_key");
470     if (string_value) {
471       image_translate_source_language_param_key = *string_value;
472     }
473     string_value =
474         engine_dict.FindString("image_translate_target_language_param_key");
475     if (string_value) {
476       image_translate_target_language_param_key = *string_value;
477     }
478     string_value = engine_dict.FindString("image_search_branding_label");
479     if (string_value) {
480       image_search_branding_label = base::UTF8ToUTF16(*string_value);
481     }
482     const base::Value::List* additional_params_list =
483         engine_dict.FindList(DefaultSearchManager::kSearchIntentParams);
484     if (additional_params_list) {
485       for (const auto& additional_param_value : *additional_params_list) {
486         const auto* additional_param = additional_param_value.GetIfString();
487         if (additional_param && !additional_param->empty()) {
488           search_intent_params.push_back(*additional_param);
489         }
490       }
491     }
492     string_value = engine_dict.FindString("preconnect_to_search_url");
493     if (string_value) {
494       preconnect_to_search_url = *string_value;
495     }
496     string_value = engine_dict.FindString("prefetch_likely_navigations");
497     if (string_value) {
498       prefetch_likely_navigations = *string_value;
499     }
500
501     return std::make_unique<TemplateURLData>(
502         name, keyword, search_url, suggest_url, image_url, image_translate_url,
503         new_tab_url, contextual_search_url, logo_url, doodle_url,
504         search_url_post_params, suggest_url_post_params, image_url_post_params,
505         side_search_param, side_image_search_param,
506         image_translate_source_language_param_key,
507         image_translate_target_language_param_key,
508         std::move(search_intent_params), favicon_url, encoding,
509         image_search_branding_label, *alternate_urls,
510         preconnect_to_search_url.compare("ALLOWED") == 0,
511         prefetch_likely_navigations.compare("ALLOWED") == 0, *id);
512   }
513   return nullptr;
514 }
515
516 std::unique_ptr<TemplateURLData> TemplateURLDataFromStarterPackEngine(
517     const TemplateURLStarterPackData::StarterPackEngine& engine) {
518   auto turl = std::make_unique<TemplateURLData>();
519   turl->SetShortName(l10n_util::GetStringUTF16(engine.name_message_id));
520   turl->SetKeyword(u"@" + l10n_util::GetStringUTF16(engine.keyword_message_id));
521   turl->SetURL(engine.search_url);
522   turl->favicon_url = GURL(ToStringPiece(engine.favicon_url));
523   turl->starter_pack_id = engine.id;
524   turl->GenerateSyncGUID();
525   turl->safe_for_autoreplace = true;
526   turl->is_active = TemplateURLData::ActiveStatus::kTrue;
527
528   return turl;
529 }