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