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