template_url_data_util.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // Copyright 2016 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.
  4. #include "components/search_engines/template_url_data_util.h"
  5. #include <string>
  6. #include "base/strings/string_number_conversions.h"
  7. #include "base/strings/string_piece.h"
  8. #include "base/strings/utf_string_conversions.h"
  9. #include "base/values.h"
  10. #include "components/search_engines/default_search_manager.h"
  11. #include "components/search_engines/prepopulated_engines.h"
  12. #include "components/search_engines/template_url_data.h"
  13. #include "components/search_engines/template_url_starter_pack_data.h"
  14. #include "ui/base/l10n/l10n_util.h"
  15. #include "url/gurl.h"
  16. namespace {
  17. // Converts the C-style string `str` to a base::StringPiece making sure to avoid
  18. // dereferencing nullptrs.
  19. base::StringPiece ToStringPiece(const char* str) {
  20. return str ? base::StringPiece(str) : base::StringPiece();
  21. }
  22. } // namespace
  23. std::unique_ptr<TemplateURLData> TemplateURLDataFromDictionary(
  24. const base::Value::Dict& dict) {
  25. const std::string* search_url = dict.FindString(DefaultSearchManager::kURL);
  26. const std::string* keyword = dict.FindString(DefaultSearchManager::kKeyword);
  27. const std::string* short_name =
  28. dict.FindString(DefaultSearchManager::kShortName);
  29. // Check required TemplateURLData fields first.
  30. if (!search_url || !keyword || !short_name) {
  31. return nullptr;
  32. }
  33. auto result = std::make_unique<TemplateURLData>();
  34. result->SetKeyword(base::UTF8ToUTF16(*keyword));
  35. result->SetURL(*search_url);
  36. const std::string* id = dict.FindString(DefaultSearchManager::kID);
  37. if (id) {
  38. base::StringToInt64(*id, &result->id);
  39. }
  40. const std::string* string_value = nullptr;
  41. result->SetShortName(base::UTF8ToUTF16(*short_name));
  42. result->prepopulate_id = dict.FindInt(DefaultSearchManager::kPrepopulateID)
  43. .value_or(result->prepopulate_id);
  44. result->starter_pack_id = dict.FindInt(DefaultSearchManager::kStarterPackId)
  45. .value_or(result->starter_pack_id);
  46. string_value = dict.FindString(DefaultSearchManager::kSyncGUID);
  47. if (string_value) {
  48. result->sync_guid = *string_value;
  49. }
  50. string_value = dict.FindString(DefaultSearchManager::kSuggestionsURL);
  51. if (string_value) {
  52. result->suggestions_url = *string_value;
  53. }
  54. string_value = dict.FindString(DefaultSearchManager::kImageURL);
  55. if (string_value) {
  56. result->image_url = *string_value;
  57. }
  58. string_value = dict.FindString(DefaultSearchManager::kNewTabURL);
  59. if (string_value) {
  60. result->new_tab_url = *string_value;
  61. }
  62. string_value = dict.FindString(DefaultSearchManager::kContextualSearchURL);
  63. if (string_value) {
  64. result->contextual_search_url = *string_value;
  65. }
  66. string_value = dict.FindString(DefaultSearchManager::kFaviconURL);
  67. if (string_value) {
  68. result->favicon_url = GURL(*string_value);
  69. }
  70. string_value = dict.FindString(DefaultSearchManager::kOriginatingURL);
  71. if (string_value) {
  72. result->originating_url = GURL(*string_value);
  73. }
  74. string_value = dict.FindString(DefaultSearchManager::kLogoURL);
  75. if (string_value) {
  76. result->logo_url = GURL(*string_value);
  77. }
  78. string_value = dict.FindString(DefaultSearchManager::kDoodleURL);
  79. if (string_value) {
  80. result->doodle_url = GURL(*string_value);
  81. }
  82. const std::string* search_url_post_params =
  83. dict.FindString(DefaultSearchManager::kSearchURLPostParams);
  84. if (search_url_post_params) {
  85. result->search_url_post_params = *search_url_post_params;
  86. }
  87. const std::string* suggestions_url_post_params =
  88. dict.FindString(DefaultSearchManager::kSuggestionsURLPostParams);
  89. if (suggestions_url_post_params) {
  90. result->suggestions_url_post_params = *suggestions_url_post_params;
  91. }
  92. const std::string* image_url_post_params =
  93. dict.FindString(DefaultSearchManager::kImageURLPostParams);
  94. if (image_url_post_params) {
  95. result->image_url_post_params = *image_url_post_params;
  96. }
  97. const std::string* side_search_param =
  98. dict.FindString(DefaultSearchManager::kSideSearchParam);
  99. if (side_search_param) {
  100. result->side_search_param = *side_search_param;
  101. }
  102. absl::optional<bool> safe_for_autoreplace =
  103. dict.FindBool(DefaultSearchManager::kSafeForAutoReplace);
  104. if (safe_for_autoreplace) {
  105. result->safe_for_autoreplace = *safe_for_autoreplace;
  106. }
  107. std::string date_created_str;
  108. std::string last_modified_str;
  109. std::string last_visited_str;
  110. string_value = dict.FindString(DefaultSearchManager::kDateCreated);
  111. if (string_value) {
  112. date_created_str = *string_value;
  113. }
  114. string_value = dict.FindString(DefaultSearchManager::kLastModified);
  115. if (string_value) {
  116. last_modified_str = *string_value;
  117. }
  118. string_value = dict.FindString(DefaultSearchManager::kLastVisited);
  119. if (string_value) {
  120. last_visited_str = *string_value;
  121. }
  122. int64_t date_created = 0;
  123. if (base::StringToInt64(date_created_str, &date_created))
  124. result->date_created = base::Time::FromInternalValue(date_created);
  125. int64_t last_modified = 0;
  126. if (base::StringToInt64(last_modified_str, &last_modified))
  127. result->last_modified = base::Time::FromInternalValue(last_modified);
  128. int64_t last_visited = 0;
  129. if (base::StringToInt64(last_visited_str, &last_visited))
  130. result->last_visited = base::Time::FromInternalValue(last_visited);
  131. result->usage_count = dict.FindInt(DefaultSearchManager::kUsageCount)
  132. .value_or(result->usage_count);
  133. const base::Value::List* alternate_urls =
  134. dict.FindList(DefaultSearchManager::kAlternateURLs);
  135. if (alternate_urls) {
  136. for (const auto& it : *alternate_urls) {
  137. if (it.is_string())
  138. result->alternate_urls.push_back(it.GetString());
  139. }
  140. }
  141. const base::Value::List* encodings =
  142. dict.FindList(DefaultSearchManager::kInputEncodings);
  143. if (encodings) {
  144. for (const auto& it : *encodings) {
  145. std::string encoding;
  146. if (it.is_string())
  147. result->input_encodings.push_back(it.GetString());
  148. }
  149. }
  150. result->created_by_policy =
  151. dict.FindBool(DefaultSearchManager::kCreatedByPolicy)
  152. .value_or(result->created_by_policy);
  153. result->created_from_play_api =
  154. dict.FindBool(DefaultSearchManager::kCreatedFromPlayAPI)
  155. .value_or(result->created_from_play_api);
  156. result->preconnect_to_search_url =
  157. dict.FindBool(DefaultSearchManager::kPreconnectToSearchUrl)
  158. .value_or(result->preconnect_to_search_url);
  159. result->prefetch_likely_navigations =
  160. dict.FindBool(DefaultSearchManager::kPrefetchLikelyNavigations)
  161. .value_or(result->prefetch_likely_navigations);
  162. result->is_active = static_cast<TemplateURLData::ActiveStatus>(
  163. dict.FindInt(DefaultSearchManager::kIsActive)
  164. .value_or(static_cast<int>(result->is_active)));
  165. return result;
  166. }
  167. std::unique_ptr<base::DictionaryValue> TemplateURLDataToDictionary(
  168. const TemplateURLData& data) {
  169. auto url_dict = std::make_unique<base::DictionaryValue>();
  170. url_dict->SetStringKey(DefaultSearchManager::kID,
  171. base::NumberToString(data.id));
  172. url_dict->SetStringKey(DefaultSearchManager::kShortName, data.short_name());
  173. url_dict->SetStringKey(DefaultSearchManager::kKeyword, data.keyword());
  174. url_dict->SetIntKey(DefaultSearchManager::kPrepopulateID,
  175. data.prepopulate_id);
  176. url_dict->SetIntKey(DefaultSearchManager::kStarterPackId,
  177. data.starter_pack_id);
  178. url_dict->SetStringKey(DefaultSearchManager::kSyncGUID, data.sync_guid);
  179. url_dict->SetStringKey(DefaultSearchManager::kURL, data.url());
  180. url_dict->SetStringKey(DefaultSearchManager::kSuggestionsURL,
  181. data.suggestions_url);
  182. url_dict->SetStringKey(DefaultSearchManager::kImageURL, data.image_url);
  183. url_dict->SetStringKey(DefaultSearchManager::kNewTabURL, data.new_tab_url);
  184. url_dict->SetStringKey(DefaultSearchManager::kContextualSearchURL,
  185. data.contextual_search_url);
  186. url_dict->SetStringKey(DefaultSearchManager::kFaviconURL,
  187. data.favicon_url.spec());
  188. url_dict->SetStringKey(DefaultSearchManager::kOriginatingURL,
  189. data.originating_url.spec());
  190. url_dict->SetStringKey(DefaultSearchManager::kLogoURL, data.logo_url.spec());
  191. url_dict->SetStringKey(DefaultSearchManager::kDoodleURL,
  192. data.doodle_url.spec());
  193. url_dict->SetStringKey(DefaultSearchManager::kSearchURLPostParams,
  194. data.search_url_post_params);
  195. url_dict->SetStringKey(DefaultSearchManager::kSuggestionsURLPostParams,
  196. data.suggestions_url_post_params);
  197. url_dict->SetStringKey(DefaultSearchManager::kImageURLPostParams,
  198. data.image_url_post_params);
  199. url_dict->SetStringKey(DefaultSearchManager::kSideSearchParam,
  200. data.side_search_param);
  201. url_dict->SetBoolKey(DefaultSearchManager::kSafeForAutoReplace,
  202. data.safe_for_autoreplace);
  203. url_dict->SetStringKey(
  204. DefaultSearchManager::kDateCreated,
  205. base::NumberToString(data.date_created.ToInternalValue()));
  206. url_dict->SetStringKey(
  207. DefaultSearchManager::kLastModified,
  208. base::NumberToString(data.last_modified.ToInternalValue()));
  209. url_dict->SetStringKey(
  210. DefaultSearchManager::kLastVisited,
  211. base::NumberToString(data.last_visited.ToInternalValue()));
  212. url_dict->SetIntKey(DefaultSearchManager::kUsageCount, data.usage_count);
  213. base::ListValue alternate_urls;
  214. for (const auto& alternate_url : data.alternate_urls)
  215. alternate_urls.Append(alternate_url);
  216. url_dict->SetKey(DefaultSearchManager::kAlternateURLs,
  217. std::move(alternate_urls));
  218. base::ListValue encodings;
  219. for (const auto& input_encoding : data.input_encodings)
  220. encodings.Append(input_encoding);
  221. url_dict->SetKey(DefaultSearchManager::kInputEncodings, std::move(encodings));
  222. url_dict->SetBoolKey(DefaultSearchManager::kCreatedByPolicy,
  223. data.created_by_policy);
  224. url_dict->SetBoolKey(DefaultSearchManager::kCreatedFromPlayAPI,
  225. data.created_from_play_api);
  226. url_dict->SetBoolKey(DefaultSearchManager::kPreconnectToSearchUrl,
  227. data.preconnect_to_search_url);
  228. url_dict->SetBoolKey(DefaultSearchManager::kPrefetchLikelyNavigations,
  229. data.prefetch_likely_navigations);
  230. url_dict->SetIntKey(DefaultSearchManager::kIsActive,
  231. static_cast<int>(data.is_active));
  232. return url_dict;
  233. }
  234. std::unique_ptr<TemplateURLData> TemplateURLDataFromPrepopulatedEngine(
  235. const TemplateURLPrepopulateData::PrepopulatedEngine& engine) {
  236. base::ListValue alternate_urls;
  237. if (engine.alternate_urls) {
  238. for (size_t i = 0; i < engine.alternate_urls_size; ++i)
  239. alternate_urls.Append(std::string(engine.alternate_urls[i]));
  240. }
  241. return std::make_unique<TemplateURLData>(
  242. base::WideToUTF16(engine.name), base::WideToUTF16(engine.keyword),
  243. ToStringPiece(engine.search_url), ToStringPiece(engine.suggest_url),
  244. ToStringPiece(engine.image_url), ToStringPiece(engine.new_tab_url),
  245. ToStringPiece(engine.contextual_search_url),
  246. ToStringPiece(engine.logo_url), ToStringPiece(engine.doodle_url),
  247. ToStringPiece(engine.search_url_post_params),
  248. ToStringPiece(engine.suggest_url_post_params),
  249. ToStringPiece(engine.image_url_post_params),
  250. ToStringPiece(engine.side_search_param),
  251. ToStringPiece(engine.favicon_url), ToStringPiece(engine.encoding),
  252. alternate_urls,
  253. ToStringPiece(engine.preconnect_to_search_url) == "ALLOWED",
  254. ToStringPiece(engine.prefetch_likely_navigations) == "ALLOWED",
  255. engine.id);
  256. }
  257. std::unique_ptr<TemplateURLData> TemplateURLDataFromOverrideDictionary(
  258. const base::Value& engine) {
  259. const std::string* string_value = nullptr;
  260. std::u16string name;
  261. std::u16string keyword;
  262. std::string search_url;
  263. std::string favicon_url;
  264. std::string encoding;
  265. string_value = engine.FindStringKey("name");
  266. if (string_value) {
  267. name = base::UTF8ToUTF16(*string_value);
  268. }
  269. string_value = engine.FindStringKey("keyword");
  270. if (string_value) {
  271. keyword = base::UTF8ToUTF16(*string_value);
  272. }
  273. string_value = engine.FindStringKey("search_url");
  274. if (string_value) {
  275. search_url = *string_value;
  276. }
  277. string_value = engine.FindStringKey("favicon_url");
  278. if (string_value) {
  279. favicon_url = *string_value;
  280. }
  281. string_value = engine.FindStringKey("encoding");
  282. if (string_value) {
  283. encoding = *string_value;
  284. }
  285. absl::optional<int> id = engine.FindIntKey("id");
  286. // The following fields are required for each search engine configuration.
  287. if (!name.empty() && !keyword.empty() && !search_url.empty() &&
  288. !favicon_url.empty() && !encoding.empty() && id.has_value()) {
  289. // These fields are optional.
  290. base::Value empty_list;
  291. const base::Value* alternate_urls = engine.FindListKey("alternate_urls");
  292. if (!alternate_urls)
  293. alternate_urls = &empty_list;
  294. std::string suggest_url;
  295. std::string image_url;
  296. std::string new_tab_url;
  297. std::string contextual_search_url;
  298. std::string logo_url;
  299. std::string doodle_url;
  300. std::string search_url_post_params;
  301. std::string suggest_url_post_params;
  302. std::string image_url_post_params;
  303. std::string side_search_param;
  304. std::string preconnect_to_search_url;
  305. std::string prefetch_likely_navigations;
  306. string_value = engine.FindStringKey("suggest_url");
  307. if (string_value) {
  308. suggest_url = *string_value;
  309. }
  310. string_value = engine.FindStringKey("image_url");
  311. if (string_value) {
  312. image_url = *string_value;
  313. }
  314. string_value = engine.FindStringKey("new_tab_url");
  315. if (string_value) {
  316. new_tab_url = *string_value;
  317. }
  318. string_value = engine.FindStringKey("contextual_search_url");
  319. if (string_value) {
  320. contextual_search_url = *string_value;
  321. }
  322. string_value = engine.FindStringKey("logo_url");
  323. if (string_value) {
  324. logo_url = *string_value;
  325. }
  326. string_value = engine.FindStringKey("doodle_url");
  327. if (string_value) {
  328. doodle_url = *string_value;
  329. }
  330. string_value = engine.FindStringKey("search_url_post_params");
  331. if (string_value) {
  332. search_url_post_params = *string_value;
  333. }
  334. string_value = engine.FindStringKey("suggest_url_post_params");
  335. if (string_value) {
  336. suggest_url_post_params = *string_value;
  337. }
  338. string_value = engine.FindStringKey("image_url_post_params");
  339. if (string_value) {
  340. image_url_post_params = *string_value;
  341. }
  342. string_value = engine.FindStringKey("side_search_param");
  343. if (string_value) {
  344. side_search_param = *string_value;
  345. }
  346. string_value = engine.FindStringKey("preconnect_to_search_url");
  347. if (string_value) {
  348. preconnect_to_search_url = *string_value;
  349. }
  350. string_value = engine.FindStringKey("prefetch_likely_navigations");
  351. if (string_value) {
  352. prefetch_likely_navigations = *string_value;
  353. }
  354. return std::make_unique<TemplateURLData>(
  355. name, keyword, search_url, suggest_url, image_url, new_tab_url,
  356. contextual_search_url, logo_url, doodle_url, search_url_post_params,
  357. suggest_url_post_params, image_url_post_params, side_search_param,
  358. favicon_url, encoding, *alternate_urls,
  359. preconnect_to_search_url.compare("ALLOWED") == 0,
  360. prefetch_likely_navigations.compare("ALLOWED") == 0, *id);
  361. }
  362. return nullptr;
  363. }
  364. std::unique_ptr<TemplateURLData> TemplateURLDataFromStarterPackEngine(
  365. const TemplateURLStarterPackData::StarterPackEngine& engine) {
  366. auto turl = std::make_unique<TemplateURLData>();
  367. turl->SetShortName(l10n_util::GetStringUTF16(engine.name_message_id));
  368. turl->SetKeyword(u"@" + l10n_util::GetStringUTF16(engine.keyword_message_id));
  369. turl->SetURL(engine.search_url);
  370. turl->favicon_url = GURL(ToStringPiece(engine.favicon_url));
  371. turl->starter_pack_id = engine.id;
  372. turl->GenerateSyncGUID();
  373. turl->safe_for_autoreplace = true;
  374. turl->is_active = TemplateURLData::ActiveStatus::kTrue;
  375. return turl;
  376. }