OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/search_engines/util.h" | 5 #include "chrome/browser/search_engines/util.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 // Delete the others from the service and from memory. | 91 // Delete the others from the service and from memory. |
92 while (!unchecked_urls.empty()) { | 92 while (!unchecked_urls.empty()) { |
93 // Find the best URL. | 93 // Find the best URL. |
94 int prepopulate_id = unchecked_urls.begin()->first; | 94 int prepopulate_id = unchecked_urls.begin()->first; |
95 PrepopulatedURLMap::const_iterator prepopulated_url = | 95 PrepopulatedURLMap::const_iterator prepopulated_url = |
96 prepopulated_url_map.find(prepopulate_id); | 96 prepopulated_url_map.find(prepopulate_id); |
97 UncheckedURLMap::iterator end = unchecked_urls.upper_bound(prepopulate_id); | 97 UncheckedURLMap::iterator end = unchecked_urls.upper_bound(prepopulate_id); |
98 UncheckedURLMap::iterator best = unchecked_urls.begin(); | 98 UncheckedURLMap::iterator best = unchecked_urls.begin(); |
99 bool matched_keyword = false; | 99 bool matched_keyword = false; |
100 for (UncheckedURLMap::iterator i = unchecked_urls.begin(); i != end; ++i) { | 100 for (UncheckedURLMap::iterator i = unchecked_urls.begin(); i != end; ++i) { |
101 // A URL is automatically the best if it's the default search engine. | 101 // If the user-selected DSE is a prepopulated engine its properties will |
102 if (i->second == default_search_provider) { | 102 // either come from the prepopulation origin or from the user preferences |
| 103 // file (see DefaultSearchManager). Those properties will end up |
| 104 // overwriting whatever we load now anyway. If we are eliminating |
| 105 // duplicates, then, we err on the side of keeping the thing that looks |
| 106 // more like the value we will end up with in the end. |
| 107 if (default_search_provider && |
| 108 (default_search_provider->prepopulate_id() == |
| 109 i->second->prepopulate_id()) && |
| 110 default_search_provider->HasSameKeywordAs(i->second->data())) { |
103 best = i; | 111 best = i; |
104 break; | 112 break; |
105 } | 113 } |
106 | 114 |
107 // Otherwise, a URL is best if it matches the prepopulated data's keyword; | 115 // Otherwise, a URL is best if it matches the prepopulated data's keyword; |
108 // if none match, just fall back to using the one with the lowest ID. | 116 // if none match, just fall back to using the one with the lowest ID. |
109 if (matched_keyword) | 117 if (matched_keyword) |
110 continue; | 118 continue; |
111 if ((prepopulated_url != prepopulated_url_map.end()) && | 119 if ((prepopulated_url != prepopulated_url_map.end()) && |
112 i->second->HasSameKeywordAs(*prepopulated_url->second)) { | 120 i->second->HasSameKeywordAs(*prepopulated_url->second)) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 // This is invoked when the version of the prepopulate data changes. | 192 // This is invoked when the version of the prepopulate data changes. |
185 // If |removed_keyword_guids| is not NULL, the Sync GUID of each item removed | 193 // If |removed_keyword_guids| is not NULL, the Sync GUID of each item removed |
186 // from the DB will be added to it. Note that this function will take | 194 // from the DB will be added to it. Note that this function will take |
187 // ownership of |prepopulated_urls| and will clear the vector. | 195 // ownership of |prepopulated_urls| and will clear the vector. |
188 void MergeEnginesFromPrepopulateData( | 196 void MergeEnginesFromPrepopulateData( |
189 Profile* profile, | 197 Profile* profile, |
190 WebDataService* service, | 198 WebDataService* service, |
191 ScopedVector<TemplateURLData>* prepopulated_urls, | 199 ScopedVector<TemplateURLData>* prepopulated_urls, |
192 size_t default_search_index, | 200 size_t default_search_index, |
193 TemplateURLService::TemplateURLVector* template_urls, | 201 TemplateURLService::TemplateURLVector* template_urls, |
194 TemplateURL** default_search_provider, | 202 TemplateURL* default_search_provider, |
195 std::set<std::string>* removed_keyword_guids) { | 203 std::set<std::string>* removed_keyword_guids) { |
196 DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI)); | 204 DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI)); |
197 DCHECK(prepopulated_urls); | 205 DCHECK(prepopulated_urls); |
198 DCHECK(template_urls); | 206 DCHECK(template_urls); |
199 DCHECK(default_search_provider); | |
200 | 207 |
201 int default_prepopulated_id = | |
202 (*prepopulated_urls)[default_search_index]->prepopulate_id; | |
203 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( | 208 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( |
204 prepopulated_urls, *template_urls, *default_search_provider)); | 209 prepopulated_urls, *template_urls, default_search_provider)); |
205 | 210 |
206 // Remove items. | 211 // Remove items. |
207 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); | 212 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); |
208 i < actions.removed_engines.end(); ++i) { | 213 i < actions.removed_engines.end(); ++i) { |
209 scoped_ptr<TemplateURL> template_url(*i); | 214 scoped_ptr<TemplateURL> template_url(*i); |
210 TemplateURLService::TemplateURLVector::iterator j = | 215 TemplateURLService::TemplateURLVector::iterator j = |
211 std::find(template_urls->begin(), template_urls->end(), template_url); | 216 std::find(template_urls->begin(), template_urls->end(), template_url); |
212 DCHECK(j != template_urls->end()); | 217 DCHECK(j != template_urls->end()); |
213 DCHECK(*j != *default_search_provider); | 218 DCHECK(!default_search_provider || |
| 219 (*j)->prepopulate_id() != default_search_provider->prepopulate_id()); |
214 template_urls->erase(j); | 220 template_urls->erase(j); |
215 if (service) { | 221 if (service) { |
216 service->RemoveKeyword(template_url->id()); | 222 service->RemoveKeyword(template_url->id()); |
217 if (removed_keyword_guids) | 223 if (removed_keyword_guids) |
218 removed_keyword_guids->insert(template_url->sync_guid()); | 224 removed_keyword_guids->insert(template_url->sync_guid()); |
219 } | 225 } |
220 } | 226 } |
221 | 227 |
222 // Edit items. | 228 // Edit items. |
223 for (EditedEngines::iterator i(actions.edited_engines.begin()); | 229 for (EditedEngines::iterator i(actions.edited_engines.begin()); |
224 i < actions.edited_engines.end(); ++i) { | 230 i < actions.edited_engines.end(); ++i) { |
225 TemplateURLData& data = i->second; | 231 TemplateURLData& data = i->second; |
226 scoped_ptr<TemplateURL> existing_url(i->first); | 232 scoped_ptr<TemplateURL> existing_url(i->first); |
227 if (service) | 233 if (service) |
228 service->UpdateKeyword(data); | 234 service->UpdateKeyword(data); |
229 | 235 |
230 // Replace the entry in |template_urls| with the updated one. | 236 // Replace the entry in |template_urls| with the updated one. |
231 TemplateURLService::TemplateURLVector::iterator j = std::find( | 237 TemplateURLService::TemplateURLVector::iterator j = std::find( |
232 template_urls->begin(), template_urls->end(), existing_url.get()); | 238 template_urls->begin(), template_urls->end(), existing_url.get()); |
233 *j = new TemplateURL(profile, data); | 239 *j = new TemplateURL(profile, data); |
234 if (*default_search_provider == existing_url.get()) | |
235 *default_search_provider = *j; | |
236 } | 240 } |
237 | 241 |
238 // Add items. | 242 // Add items. |
239 for (std::vector<TemplateURLData>::const_iterator it = | 243 for (std::vector<TemplateURLData>::const_iterator it = |
240 actions.added_engines.begin(); | 244 actions.added_engines.begin(); |
241 it != actions.added_engines.end(); | 245 it != actions.added_engines.end(); |
242 ++it) { | 246 ++it) { |
243 template_urls->push_back(new TemplateURL(profile, *it)); | 247 template_urls->push_back(new TemplateURL(profile, *it)); |
244 } | 248 } |
245 | |
246 if (!*default_search_provider) { | |
247 // The user had no existing default search provider, so set the | |
248 // default to the default prepopulated engine. | |
249 *default_search_provider = FindURLByPrepopulateID(*template_urls, | |
250 default_prepopulated_id); | |
251 } | |
252 } | 249 } |
253 | 250 |
254 ActionsFromPrepopulateData CreateActionsFromCurrentPrepopulateData( | 251 ActionsFromPrepopulateData CreateActionsFromCurrentPrepopulateData( |
255 ScopedVector<TemplateURLData>* prepopulated_urls, | 252 ScopedVector<TemplateURLData>* prepopulated_urls, |
256 const TemplateURLService::TemplateURLVector& existing_urls, | 253 const TemplateURLService::TemplateURLVector& existing_urls, |
257 const TemplateURL* default_search_provider) { | 254 const TemplateURL* default_search_provider) { |
258 // Create a map to hold all provided |template_urls| that originally came from | 255 // Create a map to hold all provided |template_urls| that originally came from |
259 // prepopulate data (i.e. have a non-zero prepopulate_id()). | 256 // prepopulate data (i.e. have a non-zero prepopulate_id()). |
260 typedef std::map<int, TemplateURL*> IDMap; | 257 typedef std::map<int, TemplateURL*> IDMap; |
261 IDMap id_to_turl; | 258 IDMap id_to_turl; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 } | 292 } |
296 } | 293 } |
297 // The above loop takes ownership of all the contents of prepopulated_urls. | 294 // The above loop takes ownership of all the contents of prepopulated_urls. |
298 // Clear the pointers. | 295 // Clear the pointers. |
299 prepopulated_urls->weak_erase(prepopulated_urls->begin(), | 296 prepopulated_urls->weak_erase(prepopulated_urls->begin(), |
300 prepopulated_urls->end()); | 297 prepopulated_urls->end()); |
301 | 298 |
302 // The block above removed all the URLs from the |id_to_turl| map that were | 299 // The block above removed all the URLs from the |id_to_turl| map that were |
303 // found in the prepopulate data. Any remaining URLs that haven't been | 300 // found in the prepopulate data. Any remaining URLs that haven't been |
304 // user-edited or made default can be removed from the data store. | 301 // user-edited or made default can be removed from the data store. |
| 302 // We assume that this entry is equivalent to the DSE if its prepopulate ID |
| 303 // and keyword both match. If the prepopulate ID _does_ match all properties |
| 304 // will be replaced with those from |default_search_provider| anyway. |
305 for (IDMap::iterator i(id_to_turl.begin()); i != id_to_turl.end(); ++i) { | 305 for (IDMap::iterator i(id_to_turl.begin()); i != id_to_turl.end(); ++i) { |
306 TemplateURL* template_url = i->second; | 306 TemplateURL* template_url = i->second; |
307 if ((template_url->safe_for_autoreplace()) && | 307 if ((template_url->safe_for_autoreplace()) && |
308 (template_url != default_search_provider)) | 308 (!default_search_provider || |
| 309 (template_url->prepopulate_id() != |
| 310 default_search_provider->prepopulate_id()) || |
| 311 (template_url->keyword() != default_search_provider->keyword()))) |
309 actions.removed_engines.push_back(template_url); | 312 actions.removed_engines.push_back(template_url); |
310 } | 313 } |
311 | 314 |
312 return actions; | 315 return actions; |
313 } | 316 } |
314 | 317 |
315 void GetSearchProvidersUsingKeywordResult( | 318 void GetSearchProvidersUsingKeywordResult( |
316 const WDTypedResult& result, | 319 const WDTypedResult& result, |
317 WebDataService* service, | 320 WebDataService* service, |
318 Profile* profile, | 321 Profile* profile, |
319 TemplateURLService::TemplateURLVector* template_urls, | 322 TemplateURLService::TemplateURLVector* template_urls, |
320 TemplateURL** default_search_provider, | 323 TemplateURL* default_search_provider, |
321 int* new_resource_keyword_version, | 324 int* new_resource_keyword_version, |
322 std::set<std::string>* removed_keyword_guids) { | 325 std::set<std::string>* removed_keyword_guids) { |
323 DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI)); | 326 DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI)); |
324 DCHECK(template_urls); | 327 DCHECK(template_urls); |
325 DCHECK(template_urls->empty()); | 328 DCHECK(template_urls->empty()); |
326 DCHECK(default_search_provider); | |
327 DCHECK(*default_search_provider == NULL); | |
328 DCHECK_EQ(KEYWORDS_RESULT, result.GetType()); | 329 DCHECK_EQ(KEYWORDS_RESULT, result.GetType()); |
329 DCHECK(new_resource_keyword_version); | 330 DCHECK(new_resource_keyword_version); |
330 | 331 |
331 WDKeywordsResult keyword_result = reinterpret_cast< | 332 WDKeywordsResult keyword_result = reinterpret_cast< |
332 const WDResult<WDKeywordsResult>*>(&result)->GetValue(); | 333 const WDResult<WDKeywordsResult>*>(&result)->GetValue(); |
333 | 334 |
334 for (KeywordTable::Keywords::iterator i(keyword_result.keywords.begin()); | 335 for (KeywordTable::Keywords::iterator i(keyword_result.keywords.begin()); |
335 i != keyword_result.keywords.end(); ++i) { | 336 i != keyword_result.keywords.end(); ++i) { |
336 // Fix any duplicate encodings in the local database. Note that we don't | 337 // Fix any duplicate encodings in the local database. Note that we don't |
337 // adjust the last_modified time of this keyword; this way, we won't later | 338 // adjust the last_modified time of this keyword; this way, we won't later |
338 // overwrite any changes on the sync server that happened to this keyword | 339 // overwrite any changes on the sync server that happened to this keyword |
339 // since the last time we synced. Instead, we also run a de-duping pass on | 340 // since the last time we synced. Instead, we also run a de-duping pass on |
340 // the server-provided data in | 341 // the server-provided data in |
341 // TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData() and | 342 // TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData() and |
342 // update the server with the merged, de-duped results at that time. We | 343 // update the server with the merged, de-duped results at that time. We |
343 // still fix here, though, to correct problems in clients that have disabled | 344 // still fix here, though, to correct problems in clients that have disabled |
344 // search engine sync, since in that case that code will never be reached. | 345 // search engine sync, since in that case that code will never be reached. |
345 if (DeDupeEncodings(&i->input_encodings) && service) | 346 if (DeDupeEncodings(&i->input_encodings) && service) |
346 service->UpdateKeyword(*i); | 347 service->UpdateKeyword(*i); |
347 template_urls->push_back(new TemplateURL(profile, *i)); | 348 template_urls->push_back(new TemplateURL(profile, *i)); |
348 } | 349 } |
349 | 350 |
350 int64 default_search_provider_id = keyword_result.default_search_provider_id; | |
351 if (default_search_provider_id) { | |
352 *default_search_provider = | |
353 GetTemplateURLByID(*template_urls, default_search_provider_id); | |
354 } | |
355 | |
356 *new_resource_keyword_version = keyword_result.builtin_keyword_version; | 351 *new_resource_keyword_version = keyword_result.builtin_keyword_version; |
357 GetSearchProvidersUsingLoadedEngines(service, profile, template_urls, | 352 GetSearchProvidersUsingLoadedEngines(service, profile, template_urls, |
358 default_search_provider, | 353 default_search_provider, |
359 new_resource_keyword_version, | 354 new_resource_keyword_version, |
360 removed_keyword_guids); | 355 removed_keyword_guids); |
361 } | 356 } |
362 | 357 |
363 void GetSearchProvidersUsingLoadedEngines( | 358 void GetSearchProvidersUsingLoadedEngines( |
364 WebDataService* service, | 359 WebDataService* service, |
365 Profile* profile, | 360 Profile* profile, |
366 TemplateURLService::TemplateURLVector* template_urls, | 361 TemplateURLService::TemplateURLVector* template_urls, |
367 TemplateURL** default_search_provider, | 362 TemplateURL* default_search_provider, |
368 int* resource_keyword_version, | 363 int* resource_keyword_version, |
369 std::set<std::string>* removed_keyword_guids) { | 364 std::set<std::string>* removed_keyword_guids) { |
370 DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI)); | 365 DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI)); |
371 DCHECK(template_urls); | 366 DCHECK(template_urls); |
372 DCHECK(default_search_provider); | |
373 DCHECK(resource_keyword_version); | 367 DCHECK(resource_keyword_version); |
374 PrefService* prefs = profile ? profile->GetPrefs() : NULL; | 368 PrefService* prefs = profile ? profile->GetPrefs() : NULL; |
375 size_t default_search_index; | 369 size_t default_search_index; |
376 ScopedVector<TemplateURLData> prepopulated_urls = | 370 ScopedVector<TemplateURLData> prepopulated_urls = |
377 TemplateURLPrepopulateData::GetPrepopulatedEngines(prefs, | 371 TemplateURLPrepopulateData::GetPrepopulatedEngines(prefs, |
378 &default_search_index); | 372 &default_search_index); |
379 RemoveDuplicatePrepopulateIDs(service, prepopulated_urls, | 373 RemoveDuplicatePrepopulateIDs(service, prepopulated_urls, |
380 *default_search_provider, template_urls, | 374 default_search_provider, template_urls, |
381 removed_keyword_guids); | 375 removed_keyword_guids); |
382 | 376 |
383 const int prepopulate_resource_keyword_version = | 377 const int prepopulate_resource_keyword_version = |
384 TemplateURLPrepopulateData::GetDataVersion(prefs); | 378 TemplateURLPrepopulateData::GetDataVersion(prefs); |
385 if (*resource_keyword_version < prepopulate_resource_keyword_version) { | 379 if (*resource_keyword_version < prepopulate_resource_keyword_version) { |
386 MergeEnginesFromPrepopulateData(profile, service, &prepopulated_urls, | 380 MergeEnginesFromPrepopulateData(profile, service, &prepopulated_urls, |
387 default_search_index, template_urls, default_search_provider, | 381 default_search_index, template_urls, default_search_provider, |
388 removed_keyword_guids); | 382 removed_keyword_guids); |
389 *resource_keyword_version = prepopulate_resource_keyword_version; | 383 *resource_keyword_version = prepopulate_resource_keyword_version; |
390 } else { | 384 } else { |
391 *resource_keyword_version = 0; | 385 *resource_keyword_version = 0; |
392 } | 386 } |
393 } | 387 } |
394 | 388 |
395 bool DeDupeEncodings(std::vector<std::string>* encodings) { | 389 bool DeDupeEncodings(std::vector<std::string>* encodings) { |
396 std::vector<std::string> deduped_encodings; | 390 std::vector<std::string> deduped_encodings; |
397 std::set<std::string> encoding_set; | 391 std::set<std::string> encoding_set; |
398 for (std::vector<std::string>::const_iterator i(encodings->begin()); | 392 for (std::vector<std::string>::const_iterator i(encodings->begin()); |
399 i != encodings->end(); ++i) { | 393 i != encodings->end(); ++i) { |
400 if (encoding_set.insert(*i).second) | 394 if (encoding_set.insert(*i).second) |
401 deduped_encodings.push_back(*i); | 395 deduped_encodings.push_back(*i); |
402 } | 396 } |
403 encodings->swap(deduped_encodings); | 397 encodings->swap(deduped_encodings); |
404 return encodings->size() != deduped_encodings.size(); | 398 return encodings->size() != deduped_encodings.size(); |
405 } | 399 } |
OLD | NEW |