1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_prepopulate_data.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::string16 GetDefaultSearchEngineName(TemplateURLService* service) { 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(service); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TemplateURL* const default_provider = 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service->GetDefaultSearchProvider(); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!default_provider) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(cpu): bug 1187517. It is possible to have no default provider. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returning an empty string is a stopgap measure for the crash 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://code.google.com/p/chromium/issues/detail?id=2573 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::string16(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_provider->short_name(); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGURL GetDefaultSearchURLForSearchTerms(TemplateURLService* service, 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& terms) { 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(service); 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const TemplateURL* default_provider = service->GetDefaultSearchProvider(); 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!default_provider) 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GURL(); 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const TemplateURLRef& search_url = default_provider->url_ref(); 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(search_url.SupportsReplacement(service->search_terms_data())); 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TemplateURLRef::SearchTermsArgs search_terms_args(terms); 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch search_terms_args.append_extra_query_params = true; 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GURL(search_url.ReplaceSearchTerms(search_terms_args, 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) service->search_terms_data())); 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveDuplicatePrepopulateIDs( 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeywordWebDataService* service, 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ScopedVector<TemplateURLData>& prepopulated_urls, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURL* default_search_provider, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLService::TemplateURLVector* template_urls, 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SearchTermsData& search_terms_data, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>* removed_keyword_guids) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(template_urls); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For convenience construct an ID->TemplateURL* map from |prepopulated_urls|. 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef std::map<int, TemplateURLData*> PrepopulatedURLMap; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepopulatedURLMap prepopulated_url_map; 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<TemplateURLData*>::const_iterator i( 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu prepopulated_urls.begin()); 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu i != prepopulated_urls.end(); 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++i) 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu prepopulated_url_map[(*i)->prepopulate_id] = *i; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Separate |template_urls| into prepopulated and non-prepopulated groups. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::multimap<int, TemplateURL*> UncheckedURLMap; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UncheckedURLMap unchecked_urls; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLService::TemplateURLVector checked_urls; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (TemplateURLService::TemplateURLVector::iterator i( 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template_urls->begin()); i != template_urls->end(); ++i) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURL* turl = *i; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prepopulate_id = turl->prepopulate_id(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prepopulate_id) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unchecked_urls.insert(std::make_pair(prepopulate_id, turl)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checked_urls.push_back(turl); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each group of prepopulated URLs with one ID, find the best URL to use 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and add it to the (initially all non-prepopulated) URLs we've already OKed. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the others from the service and from memory. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!unchecked_urls.empty()) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the best URL. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prepopulate_id = unchecked_urls.begin()->first; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepopulatedURLMap::const_iterator prepopulated_url = 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prepopulated_url_map.find(prepopulate_id); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UncheckedURLMap::iterator end = unchecked_urls.upper_bound(prepopulate_id); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UncheckedURLMap::iterator best = unchecked_urls.begin(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool matched_keyword = false; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UncheckedURLMap::iterator i = unchecked_urls.begin(); i != end; ++i) { 910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // If the user-selected DSE is a prepopulated engine its properties will 920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // either come from the prepopulation origin or from the user preferences 930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // file (see DefaultSearchManager). Those properties will end up 940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // overwriting whatever we load now anyway. If we are eliminating 950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // duplicates, then, we err on the side of keeping the thing that looks 960de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // more like the value we will end up with in the end. 970de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (default_search_provider && 980de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (default_search_provider->prepopulate_id() == 990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) i->second->prepopulate_id()) && 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default_search_provider->HasSameKeywordAs(i->second->data(), 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_terms_data)) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best = i; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, a URL is best if it matches the prepopulated data's keyword; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if none match, just fall back to using the one with the lowest ID. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (matched_keyword) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((prepopulated_url != prepopulated_url_map.end()) && 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) i->second->HasSameKeywordAs(*prepopulated_url->second, 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_terms_data)) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best = i; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched_keyword = true; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (i->second->id() < best->second->id()) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best = i; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the best URL to the checked group and delete the rest. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checked_urls.push_back(best->second); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UncheckedURLMap::iterator i = unchecked_urls.begin(); i != end; ++i) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == best) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->RemoveKeyword(i->second->id()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (removed_keyword_guids) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removed_keyword_guids->insert(i->second->sync_guid()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete i->second; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Done with this group. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unchecked_urls.erase(unchecked_urls.begin(), end); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the checked URLs. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template_urls->swap(checked_urls); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the TemplateURL with id specified from the list of TemplateURLs. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If not found, returns NULL. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TemplateURL* GetTemplateURLByID( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TemplateURLService::TemplateURLVector& template_urls, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 id) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (TemplateURLService::TemplateURLVector::const_iterator i( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template_urls.begin()); i != template_urls.end(); ++i) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->id() == id) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *i; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TemplateURL* FindURLByPrepopulateID( 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TemplateURLService::TemplateURLVector& template_urls, 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int prepopulate_id) { 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::vector<TemplateURL*>::const_iterator i = template_urls.begin(); 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i < template_urls.end(); ++i) { 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((*i)->prepopulate_id() == prepopulate_id) 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return *i; 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid MergeIntoPrepopulatedEngineData(const TemplateURL* original_turl, 1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu TemplateURLData* prepopulated_url) { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(original_turl->prepopulate_id(), prepopulated_url->prepopulate_id); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!original_turl->safe_for_autoreplace()) { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->safe_for_autoreplace = false; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->SetKeyword(original_turl->keyword()); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->short_name = original_turl->short_name(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->id = original_turl->id(); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->sync_guid = original_turl->sync_guid(); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->date_created = original_turl->date_created(); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepopulated_url->last_modified = original_turl->last_modified(); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ActionsFromPrepopulateData::ActionsFromPrepopulateData() {} 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ActionsFromPrepopulateData::~ActionsFromPrepopulateData() {} 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This is invoked when the version of the prepopulate data changes. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If |removed_keyword_guids| is not NULL, the Sync GUID of each item removed 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the DB will be added to it. Note that this function will take 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ownership of |prepopulated_urls| and will clear the vector. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MergeEnginesFromPrepopulateData( 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeywordWebDataService* service, 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedVector<TemplateURLData>* prepopulated_urls, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t default_search_index, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLService::TemplateURLVector* template_urls, 1930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) TemplateURL* default_search_provider, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>* removed_keyword_guids) { 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(prepopulated_urls); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(template_urls); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( 1990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) prepopulated_urls, *template_urls, default_search_provider)); 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Remove items. 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i < actions.removed_engines.end(); ++i) { 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TemplateURL> template_url(*i); 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TemplateURLService::TemplateURLVector::iterator j = 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::find(template_urls->begin(), template_urls->end(), template_url); 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(j != template_urls->end()); 2080de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK(!default_search_provider || 2090de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (*j)->prepopulate_id() != default_search_provider->prepopulate_id()); 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) template_urls->erase(j); 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (service) { 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) service->RemoveKeyword(template_url->id()); 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (removed_keyword_guids) 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) removed_keyword_guids->insert(template_url->sync_guid()); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Edit items. 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (EditedEngines::iterator i(actions.edited_engines.begin()); 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i < actions.edited_engines.end(); ++i) { 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TemplateURLData& data = i->second; 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TemplateURL> existing_url(i->first); 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (service) 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) service->UpdateKeyword(data); 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Replace the entry in |template_urls| with the updated one. 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TemplateURLService::TemplateURLVector::iterator j = std::find( 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) template_urls->begin(), template_urls->end(), existing_url.get()); 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *j = new TemplateURL(data); 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Add items. 2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<TemplateURLData>::const_iterator it = 2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu actions.added_engines.begin(); 2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != actions.added_engines.end(); 2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++it) { 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template_urls->push_back(new TemplateURL(*it)); 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ActionsFromPrepopulateData CreateActionsFromCurrentPrepopulateData( 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedVector<TemplateURLData>* prepopulated_urls, 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TemplateURLService::TemplateURLVector& existing_urls, 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TemplateURL* default_search_provider) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a map to hold all provided |template_urls| that originally came from 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prepopulate data (i.e. have a non-zero prepopulate_id()). 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int, TemplateURL*> IDMap; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDMap id_to_turl; 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (TemplateURLService::TemplateURLVector::const_iterator i( 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) existing_urls.begin()); i != existing_urls.end(); ++i) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prepopulate_id = (*i)->prepopulate_id(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prepopulate_id > 0) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_to_turl[prepopulate_id] = *i; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each current prepopulated URL, check whether |template_urls| contained 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a matching prepopulated URL. If so, update the passed-in URL to match the 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current data. (If the passed-in URL was user-edited, we persist the user's 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // name and keyword.) If not, add the prepopulated URL. 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ActionsFromPrepopulateData actions; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < prepopulated_urls->size(); ++i) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We take ownership of |prepopulated_urls[i]|. 2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<TemplateURLData> prepopulated_url((*prepopulated_urls)[i]); 2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const int prepopulated_id = prepopulated_url->prepopulate_id; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0, prepopulated_id); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDMap::iterator existing_url_iter(id_to_turl.find(prepopulated_id)); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_url_iter != id_to_turl.end()) { 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update the data store with the new prepopulated data. Preserve user 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // edits to the name and keyword. 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TemplateURL* existing_url(existing_url_iter->second); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_to_turl.erase(existing_url_iter); 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MergeIntoPrepopulatedEngineData(existing_url, prepopulated_url.get()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update last_modified to ensure that if this entry is later merged with 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entries from Sync, the conflict resolution logic knows that this was 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // updated and propagates the new values to the server. 2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu prepopulated_url->last_modified = base::Time::Now(); 2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu actions.edited_engines.push_back( 2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::make_pair(existing_url, *prepopulated_url)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu actions.added_engines.push_back(*prepopulated_url); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The above loop takes ownership of all the contents of prepopulated_urls. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the pointers. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prepopulated_urls->weak_erase(prepopulated_urls->begin(), 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prepopulated_urls->end()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The block above removed all the URLs from the |id_to_turl| map that were 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // found in the prepopulate data. Any remaining URLs that haven't been 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user-edited or made default can be removed from the data store. 2920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // We assume that this entry is equivalent to the DSE if its prepopulate ID 2930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // and keyword both match. If the prepopulate ID _does_ match all properties 2940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // will be replaced with those from |default_search_provider| anyway. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (IDMap::iterator i(id_to_turl.begin()); i != id_to_turl.end(); ++i) { 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TemplateURL* template_url = i->second; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((template_url->safe_for_autoreplace()) && 2980de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (!default_search_provider || 2990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (template_url->prepopulate_id() != 3000de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) default_search_provider->prepopulate_id()) || 3010de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (template_url->keyword() != default_search_provider->keyword()))) 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) actions.removed_engines.push_back(template_url); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return actions; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetSearchProvidersUsingKeywordResult( 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WDTypedResult& result, 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeywordWebDataService* service, 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PrefService* prefs, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLService::TemplateURLVector* template_urls, 3130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) TemplateURL* default_search_provider, 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SearchTermsData& search_terms_data, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* new_resource_keyword_version, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>* removed_keyword_guids) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(template_urls); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(template_urls->empty()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(KEYWORDS_RESULT, result.GetType()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_resource_keyword_version); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WDKeywordsResult keyword_result = reinterpret_cast< 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WDResult<WDKeywordsResult>*>(&result)->GetValue(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (KeywordTable::Keywords::iterator i(keyword_result.keywords.begin()); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != keyword_result.keywords.end(); ++i) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fix any duplicate encodings in the local database. Note that we don't 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // adjust the last_modified time of this keyword; this way, we won't later 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overwrite any changes on the sync server that happened to this keyword 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since the last time we synced. Instead, we also run a de-duping pass on 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the server-provided data in 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData() and 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update the server with the merged, de-duped results at that time. We 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still fix here, though, to correct problems in clients that have disabled 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // search engine sync, since in that case that code will never be reached. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DeDupeEncodings(&i->input_encodings) && service) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->UpdateKeyword(*i); 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template_urls->push_back(new TemplateURL(*i)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *new_resource_keyword_version = keyword_result.builtin_keyword_version; 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetSearchProvidersUsingLoadedEngines(service, prefs, template_urls, 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_search_provider, 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_terms_data, 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_resource_keyword_version, 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) removed_keyword_guids); 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GetSearchProvidersUsingLoadedEngines( 350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeywordWebDataService* service, 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PrefService* prefs, 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TemplateURLService::TemplateURLVector* template_urls, 3530de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) TemplateURL* default_search_provider, 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SearchTermsData& search_terms_data, 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int* resource_keyword_version, 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::set<std::string>* removed_keyword_guids) { 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(template_urls); 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(resource_keyword_version); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t default_search_index; 3605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedVector<TemplateURLData> prepopulated_urls = 3615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu TemplateURLPrepopulateData::GetPrepopulatedEngines(prefs, 3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &default_search_index); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveDuplicatePrepopulateIDs(service, prepopulated_urls, 3640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) default_search_provider, template_urls, 365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_terms_data, removed_keyword_guids); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int prepopulate_resource_keyword_version = 3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu TemplateURLPrepopulateData::GetDataVersion(prefs); 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (*resource_keyword_version < prepopulate_resource_keyword_version) { 370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MergeEnginesFromPrepopulateData( 371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service, &prepopulated_urls, default_search_index, template_urls, 372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch default_search_provider, removed_keyword_guids); 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *resource_keyword_version = prepopulate_resource_keyword_version; 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *resource_keyword_version = 0; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeDupeEncodings(std::vector<std::string>* encodings) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> deduped_encodings; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string> encoding_set; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<std::string>::const_iterator i(encodings->begin()); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != encodings->end(); ++i) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (encoding_set.insert(*i).second) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deduped_encodings.push_back(*i); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encodings->swap(deduped_encodings); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return encodings->size() != deduped_encodings.size(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 390