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
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 "url/gurl.h"
17
18 namespace {
19
20 // Converts the C-style string `str` to a base::StringPiece making sure to avoid
21 // dereferencing nullptrs.
ToStringPiece(const char * str)22 base::StringPiece ToStringPiece(const char* str) {
23 return str ? base::StringPiece(str) : base::StringPiece();
24 }
25
26 } // namespace
27
TemplateURLDataFromDictionary(const base::DictionaryValue & dict)28 std::unique_ptr<TemplateURLData> TemplateURLDataFromDictionary(
29 const base::DictionaryValue& dict) {
30 std::string search_url;
31 base::string16 keyword;
32 base::string16 short_name;
33 dict.GetString(DefaultSearchManager::kURL, &search_url);
34 dict.GetString(DefaultSearchManager::kKeyword, &keyword);
35 dict.GetString(DefaultSearchManager::kShortName, &short_name);
36 // Check required TemplateURLData fields first.
37 if (search_url.empty() || keyword.empty() || short_name.empty())
38 return std::unique_ptr<TemplateURLData>();
39
40 auto result = std::make_unique<TemplateURLData>();
41 result->SetKeyword(keyword);
42 result->SetURL(search_url);
43
44 std::string id;
45 dict.GetString(DefaultSearchManager::kID, &id);
46 base::StringToInt64(id, &result->id);
47
48 result->SetShortName(short_name);
49 dict.GetInteger(DefaultSearchManager::kPrepopulateID,
50 &result->prepopulate_id);
51 dict.GetString(DefaultSearchManager::kSyncGUID, &result->sync_guid);
52 dict.GetString(DefaultSearchManager::kSuggestionsURL,
53 &result->suggestions_url);
54
55 dict.GetString(DefaultSearchManager::kImageURL, &result->image_url);
56 dict.GetString(DefaultSearchManager::kNewTabURL, &result->new_tab_url);
57 dict.GetString(DefaultSearchManager::kContextualSearchURL,
58 &result->contextual_search_url);
59 std::string favicon_url;
60 std::string originating_url;
61 std::string logo_url;
62 std::string doodle_url;
63 dict.GetString(DefaultSearchManager::kFaviconURL, &favicon_url);
64 dict.GetString(DefaultSearchManager::kOriginatingURL, &originating_url);
65 dict.GetString(DefaultSearchManager::kLogoURL, &logo_url);
66 dict.GetString(DefaultSearchManager::kDoodleURL, &doodle_url);
67 result->favicon_url = GURL(favicon_url);
68 result->originating_url = GURL(originating_url);
69 result->logo_url = GURL(logo_url);
70 result->doodle_url = GURL(doodle_url);
71
72 dict.GetString(DefaultSearchManager::kSearchURLPostParams,
73 &result->search_url_post_params);
74 dict.GetString(DefaultSearchManager::kSuggestionsURLPostParams,
75 &result->suggestions_url_post_params);
76 dict.GetString(DefaultSearchManager::kImageURLPostParams,
77 &result->image_url_post_params);
78 dict.GetBoolean(DefaultSearchManager::kSafeForAutoReplace,
79 &result->safe_for_autoreplace);
80
81 std::string date_created_str;
82 std::string last_modified_str;
83 std::string last_visited_str;
84 dict.GetString(DefaultSearchManager::kDateCreated, &date_created_str);
85 dict.GetString(DefaultSearchManager::kLastModified, &last_modified_str);
86 dict.GetString(DefaultSearchManager::kLastVisited, &last_visited_str);
87
88 int64_t date_created = 0;
89 if (base::StringToInt64(date_created_str, &date_created))
90 result->date_created = base::Time::FromInternalValue(date_created);
91
92 int64_t last_modified = 0;
93 if (base::StringToInt64(last_modified_str, &last_modified))
94 result->last_modified = base::Time::FromInternalValue(last_modified);
95
96 int64_t last_visited = 0;
97 if (base::StringToInt64(last_visited_str, &last_visited))
98 result->last_visited = base::Time::FromInternalValue(last_visited);
99
100 dict.GetInteger(DefaultSearchManager::kUsageCount, &result->usage_count);
101
102 const base::ListValue* alternate_urls = nullptr;
103 if (dict.GetList(DefaultSearchManager::kAlternateURLs, &alternate_urls)) {
104 for (const auto& it : *alternate_urls) {
105 std::string alternate_url;
106 if (it.GetAsString(&alternate_url))
107 result->alternate_urls.push_back(std::move(alternate_url));
108 }
109 }
110
111 const base::ListValue* encodings = nullptr;
112 if (dict.GetList(DefaultSearchManager::kInputEncodings, &encodings)) {
113 for (const auto& it : *encodings) {
114 std::string encoding;
115 if (it.GetAsString(&encoding))
116 result->input_encodings.push_back(std::move(encoding));
117 }
118 }
119
120 dict.GetBoolean(DefaultSearchManager::kCreatedByPolicy,
121 &result->created_by_policy);
122 dict.GetBoolean(DefaultSearchManager::kCreatedFromPlayAPI,
123 &result->created_from_play_api);
124 return result;
125 }
126
TemplateURLDataToDictionary(const TemplateURLData & data)127 std::unique_ptr<base::DictionaryValue> TemplateURLDataToDictionary(
128 const TemplateURLData& data) {
129 auto url_dict = std::make_unique<base::DictionaryValue>();
130 url_dict->SetString(DefaultSearchManager::kID, base::NumberToString(data.id));
131 url_dict->SetString(DefaultSearchManager::kShortName, data.short_name());
132 url_dict->SetString(DefaultSearchManager::kKeyword, data.keyword());
133 url_dict->SetInteger(DefaultSearchManager::kPrepopulateID,
134 data.prepopulate_id);
135 url_dict->SetString(DefaultSearchManager::kSyncGUID, data.sync_guid);
136
137 url_dict->SetString(DefaultSearchManager::kURL, data.url());
138 url_dict->SetString(DefaultSearchManager::kSuggestionsURL,
139 data.suggestions_url);
140 url_dict->SetString(DefaultSearchManager::kImageURL, data.image_url);
141 url_dict->SetString(DefaultSearchManager::kNewTabURL, data.new_tab_url);
142 url_dict->SetString(DefaultSearchManager::kContextualSearchURL,
143 data.contextual_search_url);
144 url_dict->SetString(DefaultSearchManager::kFaviconURL,
145 data.favicon_url.spec());
146 url_dict->SetString(DefaultSearchManager::kOriginatingURL,
147 data.originating_url.spec());
148 url_dict->SetString(DefaultSearchManager::kLogoURL, data.logo_url.spec());
149 url_dict->SetString(DefaultSearchManager::kDoodleURL, data.doodle_url.spec());
150
151 url_dict->SetString(DefaultSearchManager::kSearchURLPostParams,
152 data.search_url_post_params);
153 url_dict->SetString(DefaultSearchManager::kSuggestionsURLPostParams,
154 data.suggestions_url_post_params);
155 url_dict->SetString(DefaultSearchManager::kImageURLPostParams,
156 data.image_url_post_params);
157
158 url_dict->SetBoolean(DefaultSearchManager::kSafeForAutoReplace,
159 data.safe_for_autoreplace);
160
161 url_dict->SetString(
162 DefaultSearchManager::kDateCreated,
163 base::NumberToString(data.date_created.ToInternalValue()));
164 url_dict->SetString(
165 DefaultSearchManager::kLastModified,
166 base::NumberToString(data.last_modified.ToInternalValue()));
167 url_dict->SetString(
168 DefaultSearchManager::kLastVisited,
169 base::NumberToString(data.last_visited.ToInternalValue()));
170 url_dict->SetInteger(DefaultSearchManager::kUsageCount, data.usage_count);
171
172 auto alternate_urls = std::make_unique<base::ListValue>();
173 for (const auto& alternate_url : data.alternate_urls)
174 alternate_urls->AppendString(alternate_url);
175
176 url_dict->Set(DefaultSearchManager::kAlternateURLs,
177 std::move(alternate_urls));
178
179 auto encodings = std::make_unique<base::ListValue>();
180 for (const auto& input_encoding : data.input_encodings)
181 encodings->AppendString(input_encoding);
182 url_dict->Set(DefaultSearchManager::kInputEncodings, std::move(encodings));
183
184 url_dict->SetBoolean(DefaultSearchManager::kCreatedByPolicy,
185 data.created_by_policy);
186 url_dict->SetBoolean(DefaultSearchManager::kCreatedFromPlayAPI,
187 data.created_from_play_api);
188 return url_dict;
189 }
190
TemplateURLDataFromPrepopulatedEngine(const TemplateURLPrepopulateData::PrepopulatedEngine & engine)191 std::unique_ptr<TemplateURLData> TemplateURLDataFromPrepopulatedEngine(
192 const TemplateURLPrepopulateData::PrepopulatedEngine& engine) {
193 base::ListValue alternate_urls;
194 if (engine.alternate_urls) {
195 for (size_t i = 0; i < engine.alternate_urls_size; ++i)
196 alternate_urls.AppendString(std::string(engine.alternate_urls[i]));
197 }
198
199 return std::make_unique<TemplateURLData>(
200 base::WideToUTF16(engine.name), base::WideToUTF16(engine.keyword),
201 ToStringPiece(engine.search_url), ToStringPiece(engine.suggest_url),
202 ToStringPiece(engine.image_url), ToStringPiece(engine.new_tab_url),
203 ToStringPiece(engine.contextual_search_url),
204 ToStringPiece(engine.logo_url), ToStringPiece(engine.doodle_url),
205 ToStringPiece(engine.search_url_post_params),
206 ToStringPiece(engine.suggest_url_post_params),
207 ToStringPiece(engine.image_url_post_params),
208 ToStringPiece(engine.favicon_url), ToStringPiece(engine.encoding),
209 alternate_urls, engine.id);
210 }
211
TemplateURLDataFromOverrideDictionary(const base::DictionaryValue & engine)212 std::unique_ptr<TemplateURLData> TemplateURLDataFromOverrideDictionary(
213 const base::DictionaryValue& engine) {
214 base::string16 name;
215 base::string16 keyword;
216 std::string search_url;
217 std::string favicon_url;
218 std::string encoding;
219 int id = -1;
220 // The following fields are required for each search engine configuration.
221 if (engine.GetString("name", &name) && !name.empty() &&
222 engine.GetString("keyword", &keyword) && !keyword.empty() &&
223 engine.GetString("search_url", &search_url) && !search_url.empty() &&
224 engine.GetString("favicon_url", &favicon_url) && !favicon_url.empty() &&
225 engine.GetString("encoding", &encoding) && !encoding.empty() &&
226 engine.GetInteger("id", &id)) {
227 // These fields are optional.
228 std::string suggest_url;
229 std::string image_url;
230 std::string new_tab_url;
231 std::string contextual_search_url;
232 std::string logo_url;
233 std::string doodle_url;
234 std::string search_url_post_params;
235 std::string suggest_url_post_params;
236 std::string image_url_post_params;
237 base::ListValue empty_list;
238 const base::ListValue* alternate_urls = &empty_list;
239 engine.GetString("suggest_url", &suggest_url);
240 engine.GetString("image_url", &image_url);
241 engine.GetString("new_tab_url", &new_tab_url);
242 engine.GetString("contextual_search_url", &contextual_search_url);
243 engine.GetString("logo_url", &logo_url);
244 engine.GetString("doodle_url", &doodle_url);
245 engine.GetString("search_url_post_params", &search_url_post_params);
246 engine.GetString("suggest_url_post_params", &suggest_url_post_params);
247 engine.GetString("image_url_post_params", &image_url_post_params);
248 engine.GetList("alternate_urls", &alternate_urls);
249 return std::make_unique<TemplateURLData>(
250 name, keyword, search_url, suggest_url, image_url, new_tab_url,
251 contextual_search_url, logo_url, doodle_url, search_url_post_params,
252 suggest_url_post_params, image_url_post_params, favicon_url, encoding,
253 *alternate_urls, id);
254 }
255 return std::unique_ptr<TemplateURLData>();
256 }
257