summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvasilii@chromium.org <vasilii@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-03 22:59:43 +0000
committervasilii@chromium.org <vasilii@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-03 22:59:43 +0000
commite937a970746f956283743e4df549369f0df64809 (patch)
tree05f8e6d132e5902d633bc8ff82a2b87daf32d8e7
parent7192c12637f571a7f2e2e65cb60d6deb92759ff6 (diff)
downloadchromium_src-e937a970746f956283743e4df549369f0df64809.zip
chromium_src-e937a970746f956283743e4df549369f0df64809.tar.gz
chromium_src-e937a970746f956283743e4df549369f0df64809.tar.bz2
Profile Reset: support "soft reset" of search engines, homepage and startup pages. The soft reset doesn't clear user-defined search engines, homepage URL and startup URLs.
BUG=235037 Review URL: https://codereview.chromium.org/23496004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226880 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/profile_resetter/profile_resetter.cc26
-rw-r--r--chrome/browser/profile_resetter/profile_resetter_unittest.cc106
-rw-r--r--chrome/browser/profile_resetter/resettable_settings_snapshot.cc34
-rw-r--r--chrome/browser/profile_resetter/resettable_settings_snapshot.h16
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data.cc30
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data.h9
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc34
-rw-r--r--chrome/browser/search_engines/template_url_service.cc80
-rw-r--r--chrome/browser/search_engines/template_url_service.h16
-rw-r--r--chrome/browser/search_engines/template_url_service_sync_unittest.cc6
-rw-r--r--chrome/browser/search_engines/template_url_service_unittest.cc175
-rw-r--r--chrome/browser/search_engines/util.cc127
-rw-r--r--chrome/browser/search_engines/util.h44
13 files changed, 357 insertions, 346 deletions
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index 3c797a7..0777632 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/search_terms_data.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
@@ -47,14 +48,19 @@ void ProfileResetter::Reset(
DCHECK(CalledOnValidThread());
DCHECK(master_settings);
- master_settings_.swap(master_settings);
-
// We should never be called with unknown flags.
CHECK_EQ(static_cast<ResettableFlags>(0), resettable_flags & ~ALL);
// We should never be called when a previous reset has not finished.
CHECK_EQ(static_cast<ResettableFlags>(0), pending_reset_flags_);
+ if (!resettable_flags) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ callback);
+ return;
+ }
+
+ master_settings_.swap(master_settings);
callback_ = callback;
// These flags are set to false by the individual reset functions.
@@ -63,7 +69,7 @@ void ProfileResetter::Reset(
struct {
Resettable flag;
void (ProfileResetter::*method)();
- } flag2Method [] = {
+ } flagToMethod [] = {
{ DEFAULT_SEARCH_ENGINE, &ProfileResetter::ResetDefaultSearchEngine },
{ HOMEPAGE, &ProfileResetter::ResetHomepage },
{ CONTENT_SETTINGS, &ProfileResetter::ResetContentSettings },
@@ -74,10 +80,10 @@ void ProfileResetter::Reset(
};
ResettableFlags reset_triggered_for_flags = 0;
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flag2Method); ++i) {
- if (resettable_flags & flag2Method[i].flag) {
- reset_triggered_for_flags |= flag2Method[i].flag;
- (this->*flag2Method[i].method)();
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flagToMethod); ++i) {
+ if (resettable_flags & flagToMethod[i].flag) {
+ reset_triggered_for_flags |= flagToMethod[i].flag;
+ (this->*flagToMethod[i].method)();
}
}
@@ -124,7 +130,7 @@ void ProfileResetter::ResetDefaultSearchEngine() {
update->Swap(search_engines.get());
}
- template_url_service_->ResetURLs();
+ template_url_service_->RepairPrepopulatedSearchEngines();
// Reset Google search URL.
prefs->ClearPref(prefs::kLastPromptedGoogleURL);
@@ -149,8 +155,6 @@ void ProfileResetter::ResetHomepage() {
if (master_settings_->GetHomepage(&homepage))
prefs->SetString(prefs::kHomePage, homepage);
- else
- prefs->ClearPref(prefs::kHomePage);
if (master_settings_->GetHomepageIsNewTab(&homepage_is_ntp))
prefs->SetBoolean(prefs::kHomePageIsNewTabPage, homepage_is_ntp);
@@ -217,8 +221,6 @@ void ProfileResetter::ResetStartupPages() {
scoped_ptr<ListValue> url_list(master_settings_->GetUrlsToRestoreOnStartup());
if (url_list)
ListPrefUpdate(prefs, prefs::kURLsToRestoreOnStartup)->Swap(url_list.get());
- else
- prefs->ClearPref(prefs::kURLsToRestoreOnStartup);
int restore_on_startup;
if (master_settings_->GetRestoreOnStartup(&restore_on_startup))
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index 3bac3e8..a1aaf6b 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -276,32 +276,9 @@ void ReplaceString(std::string* str,
/********************* Tests *********************/
-TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) {
- // Search engine's logic is tested by
- // TemplateURLServiceTest.ResetURLs.
- PrefService* prefs = profile()->GetPrefs();
- DCHECK(prefs);
- prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
-
- scoped_refptr<Extension> extension = CreateExtension(
- ASCIIToUTF16("xxx"),
- base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
- Manifest::COMPONENT,
- extensions::Manifest::TYPE_EXTENSION,
- false);
- service_->AddExtension(extension.get());
-
- ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE);
-
- // TemplateURLService should reset extension search engines.
- TemplateURLService* model =
- TemplateURLServiceFactory::GetForProfile(profile());
- TemplateURL* ext_url = model->GetTemplateURLForKeyword(ASCIIToUTF16("xxx"));
- ASSERT_TRUE(ext_url);
- EXPECT_TRUE(ext_url->IsExtensionKeyword());
- EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->keyword());
- EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->short_name());
- EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
+TEST_F(ProfileResetterTest, ResetNothing) {
+ // The callback should be called even if there is nothing to reset.
+ ResetAndWait(0);
}
TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
@@ -313,7 +290,6 @@ TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
TemplateURLService* model =
TemplateURLServiceFactory::GetForProfile(profile());
- EXPECT_EQ(1u, model->GetTemplateURLs().size());
TemplateURL* default_engine = model->GetDefaultSearchProvider();
ASSERT_NE(static_cast<TemplateURL*>(NULL), default_engine);
EXPECT_EQ(ASCIIToUTF16("first"), default_engine->short_name());
@@ -323,18 +299,25 @@ TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
}
-TEST_F(ProfileResetterTest, ResetHomepage) {
+TEST_F(ProfileResetterTest, ResetDefaultSearchEnginePartially) {
+ // Search engine's logic is tested by
+ // TemplateURLServiceTest.RepairPrepopulatedSearchEngines.
PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
- prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
- prefs->SetString(prefs::kHomePage, "http://google.com");
- prefs->SetBoolean(prefs::kShowHomeButton, true);
+ prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
- ResetAndWait(ProfileResetter::HOMEPAGE);
+ // Make sure TemplateURLService has loaded.
+ ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE);
- EXPECT_TRUE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
- EXPECT_EQ(std::string(), prefs->GetString(prefs::kHomePage));
- EXPECT_FALSE(prefs->GetBoolean(prefs::kShowHomeButton));
+ TemplateURLService* model =
+ TemplateURLServiceFactory::GetForProfile(profile());
+ TemplateURLService::TemplateURLVector urls = model->GetTemplateURLs();
+
+ // The second call should produce no effect.
+ ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE);
+
+ EXPECT_EQ(urls, model->GetTemplateURLs());
+ EXPECT_EQ(std::string(), prefs->GetString(prefs::kLastPromptedGoogleURL));
}
TEST_F(ProfileResetterTest, ResetHomepageNonOrganic) {
@@ -351,6 +334,20 @@ TEST_F(ProfileResetterTest, ResetHomepageNonOrganic) {
EXPECT_TRUE(prefs->GetBoolean(prefs::kShowHomeButton));
}
+TEST_F(ProfileResetterTest, ResetHomepagePartially) {
+ PrefService* prefs = profile()->GetPrefs();
+ DCHECK(prefs);
+ prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
+ prefs->SetString(prefs::kHomePage, "http://www.foo.com");
+ prefs->SetBoolean(prefs::kShowHomeButton, true);
+
+ ResetAndWait(ProfileResetter::HOMEPAGE);
+
+ EXPECT_TRUE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
+ EXPECT_EQ("http://www.foo.com", prefs->GetString(prefs::kHomePage));
+ EXPECT_FALSE(prefs->GetBoolean(prefs::kShowHomeButton));
+}
+
TEST_F(ProfileResetterTest, ResetContentSettings) {
HostContentSettingsMap* host_content_settings_map =
profile()->GetHostContentSettingsMap();
@@ -572,34 +569,35 @@ TEST_F(ProfileResetterTest, ResetExtensionsAndDefaultApps) {
EXPECT_TRUE(theme_service->UsingDefaultTheme());
}
-TEST_F(ProfileResetterTest, ResetStartPage) {
+TEST_F(ProfileResetterTest, ResetStartPageNonOrganic) {
PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
- SessionStartupPref startup_pref(SessionStartupPref::URLS);
- startup_pref.urls.push_back(GURL("http://foo"));
- startup_pref.urls.push_back(GURL("http://bar"));
+ SessionStartupPref startup_pref(SessionStartupPref::LAST);
SessionStartupPref::SetStartupPref(prefs, startup_pref);
- ResetAndWait(ProfileResetter::STARTUP_PAGES);
+ ResetAndWait(ProfileResetter::STARTUP_PAGES, kDistributionConfig);
startup_pref = SessionStartupPref::GetStartupPref(prefs);
- EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref.type);
- EXPECT_EQ(std::vector<GURL>(), startup_pref.urls);
+ EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type);
+ const GURL urls[] = {GURL("http://goo.gl"), GURL("http://foo.de")};
+ EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), startup_pref.urls);
}
-TEST_F(ProfileResetterTest, ResetStartPageNonOrganic) {
+
+TEST_F(ProfileResetterTest, ResetStartPagePartially) {
PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
- SessionStartupPref startup_pref(SessionStartupPref::LAST);
+ const GURL urls[] = {GURL("http://foo"), GURL("http://bar")};
+ SessionStartupPref startup_pref(SessionStartupPref::URLS);
+ startup_pref.urls.assign(urls, urls + arraysize(urls));
SessionStartupPref::SetStartupPref(prefs, startup_pref);
- ResetAndWait(ProfileResetter::STARTUP_PAGES, kDistributionConfig);
+ ResetAndWait(ProfileResetter::STARTUP_PAGES, std::string());
startup_pref = SessionStartupPref::GetStartupPref(prefs);
- EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type);
- const GURL urls[] = {GURL("http://goo.gl"), GURL("http://foo.de")};
+ EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref.type);
EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), startup_pref.urls);
}
@@ -715,7 +713,8 @@ TEST_F(ProfileResetterTest, CheckSnapshots) {
// Reset to non organic defaults.
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
ProfileResetter::HOMEPAGE |
- ProfileResetter::STARTUP_PAGES, master_prefs);
+ ProfileResetter::STARTUP_PAGES,
+ master_prefs);
ResettableSettingsSnapshot nonorganic_snap(profile());
EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS,
@@ -756,7 +755,8 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
// Reset to non organic defaults.
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
ProfileResetter::HOMEPAGE |
- ProfileResetter::STARTUP_PAGES, kDistributionConfig);
+ ProfileResetter::STARTUP_PAGES,
+ kDistributionConfig);
scoped_refptr<Extension> ext = CreateExtension(
ASCIIToUTF16("example"),
@@ -769,7 +769,7 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
const ResettableSettingsSnapshot nonorganic_snap(profile());
- COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
+ COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 15,
expand_this_test);
for (int field_mask = 0; field_mask <= ResettableSettingsSnapshot::ALL_FIELDS;
++field_mask) {
@@ -792,13 +792,13 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
ListValue* extensions;
int initiator = 0;
- EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_URLS),
+ EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_MODE),
dict->GetList("startup_urls", &startup_urls));
- EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_TYPE),
+ EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_MODE),
dict->GetInteger("startup_type", &startup_type));
EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE),
dict->GetString("homepage", &homepage));
- EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP),
+ EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE),
dict->GetBoolean("homepage_is_ntp", &homepage_is_ntp));
EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::DSE_URL),
dict->GetString("default_search_engine", &default_search_engine));
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
index 095efcf..a5b8101 100644
--- a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
+++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
@@ -79,10 +79,6 @@ ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {}
void ResettableSettingsSnapshot::Subtract(
const ResettableSettingsSnapshot& snapshot) {
- std::vector<GURL> urls = base::STLSetDifference<std::vector<GURL> >(
- startup_.urls, snapshot.startup_.urls);
- startup_.urls.swap(urls);
-
ExtensionList extensions = base::STLSetDifference<ExtensionList>(
enabled_extensions_, snapshot.enabled_extensions_);
enabled_extensions_.swap(extensions);
@@ -92,26 +88,21 @@ int ResettableSettingsSnapshot::FindDifferentFields(
const ResettableSettingsSnapshot& snapshot) const {
int bit_mask = 0;
- if (startup_.urls != snapshot.startup_.urls) {
- bit_mask |= STARTUP_URLS;
- }
-
- if (startup_.type != snapshot.startup_.type)
- bit_mask |= STARTUP_TYPE;
+ if (startup_.type != snapshot.startup_.type ||
+ startup_.urls != snapshot.startup_.urls)
+ bit_mask |= STARTUP_MODE;
- if (homepage_ != snapshot.homepage_)
+ if (homepage_is_ntp_ != snapshot.homepage_is_ntp_ ||
+ homepage_ != snapshot.homepage_)
bit_mask |= HOMEPAGE;
- if (homepage_is_ntp_ != snapshot.homepage_is_ntp_)
- bit_mask |= HOMEPAGE_IS_NTP;
-
if (dse_url_ != snapshot.dse_url_)
bit_mask |= DSE_URL;
if (enabled_extensions_ != snapshot.enabled_extensions_)
bit_mask |= EXTENSIONS;
- COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
+ COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 15,
add_new_field_here);
return bit_mask;
@@ -122,23 +113,20 @@ std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
SnapshotCaller source) {
DictionaryValue dict;
- if (field_mask & ResettableSettingsSnapshot::STARTUP_URLS) {
+ if (field_mask & ResettableSettingsSnapshot::STARTUP_MODE) {
ListValue* list = new ListValue;
const std::vector<GURL>& urls = snapshot.startup_urls();
for (std::vector<GURL>::const_iterator i = urls.begin();
i != urls.end(); ++i)
list->AppendString(i->spec());
dict.Set(kStartupURLPath, list);
- }
-
- if (field_mask & ResettableSettingsSnapshot::STARTUP_TYPE)
dict.SetInteger(kStartupTypePath, snapshot.startup_type());
+ }
- if (field_mask & ResettableSettingsSnapshot::HOMEPAGE)
+ if (field_mask & ResettableSettingsSnapshot::HOMEPAGE) {
dict.SetString(kHomepagePath, snapshot.homepage());
-
- if (field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP)
dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp());
+ }
if (field_mask & ResettableSettingsSnapshot::DSE_URL)
dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url());
@@ -157,7 +145,7 @@ std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
dict.Set(kEnabledExtensions, list);
}
- COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
+ COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 15,
serialize_new_field_here);
dict.SetInteger(kFeedbackCaller, source);
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.h b/chrome/browser/profile_resetter/resettable_settings_snapshot.h
index 5abac6f..d3062a3 100644
--- a/chrome/browser/profile_resetter/resettable_settings_snapshot.h
+++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.h
@@ -21,15 +21,12 @@ class ResettableSettingsSnapshot {
typedef std::vector<std::pair<std::string, std::string> > ExtensionList;
// All types of settings handled by this class.
enum Field {
- STARTUP_URLS = 1 << 0,
- STARTUP_TYPE = 1 << 1,
- HOMEPAGE = 1 << 2,
- HOMEPAGE_IS_NTP = 1 << 3,
- DSE_URL = 1 << 4,
- EXTENSIONS = 1 << 5,
-
- ALL_FIELDS = STARTUP_URLS | STARTUP_TYPE | HOMEPAGE |
- HOMEPAGE_IS_NTP | DSE_URL | EXTENSIONS,
+ STARTUP_MODE = 1 << 0,
+ HOMEPAGE = 1 << 1,
+ DSE_URL = 1 << 2,
+ EXTENSIONS = 1 << 3,
+
+ ALL_FIELDS = STARTUP_MODE | HOMEPAGE | DSE_URL | EXTENSIONS,
};
explicit ResettableSettingsSnapshot(Profile* profile);
@@ -50,7 +47,6 @@ class ResettableSettingsSnapshot {
return enabled_extensions_;
}
- // Substitutes |startup_.urls| with |startup_.urls|\|snapshot.startup_.urls|.
// Substitutes |enabled_extensions_| with
// |enabled_extensions_|\|snapshot.enabled_extensions_|.
void Subtract(const ResettableSettingsSnapshot& snapshot);
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc
index 652ecf58..ba234ff 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc
@@ -10,7 +10,6 @@
#include "base/command_line.h"
#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
#include "base/prefs/pref_service.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
@@ -1118,15 +1117,15 @@ TemplateURL* MakePrepopulatedTemplateURL(
return new TemplateURL(profile, data);
}
-void GetPrepopulatedTemplateFromPrefs(Profile* profile,
- std::vector<TemplateURL*>* t_urls) {
+ScopedVector<TemplateURL> GetPrepopulatedTemplateFromPrefs(Profile* profile) {
+ ScopedVector<TemplateURL> t_urls;
if (!profile)
- return;
+ return t_urls.Pass();
const ListValue* list =
profile->GetPrefs()->GetList(prefs::kSearchProviderOverrides);
if (!list)
- return;
+ return t_urls.Pass();
size_t num_engines = list->GetSize();
for (size_t i = 0; i != num_engines; ++i) {
@@ -1169,7 +1168,7 @@ void GetPrepopulatedTemplateFromPrefs(Profile* profile,
engine->GetList("alternate_urls", &alternate_urls);
engine->GetString("search_terms_replacement_key",
&search_terms_replacement_key);
- t_urls->push_back(MakePrepopulatedTemplateURL(profile, name, keyword,
+ t_urls.push_back(MakePrepopulatedTemplateURL(profile, name, keyword,
search_url, suggest_url, instant_url, image_url, new_tab_url,
search_url_post_params, suggest_url_post_params,
instant_url_post_params, image_url_post_params,
@@ -1177,6 +1176,7 @@ void GetPrepopulatedTemplateFromPrefs(Profile* profile,
id));
}
}
+ return t_urls.Pass();
}
// The caller owns the returned TemplateURL.
@@ -1248,24 +1248,24 @@ int GetDataVersion(PrefService* prefs) {
kCurrentDataVersion;
}
-void GetPrepopulatedEngines(Profile* profile,
- std::vector<TemplateURL*>* t_urls,
- size_t* default_search_provider_index) {
+ScopedVector<TemplateURL> GetPrepopulatedEngines(
+ Profile* profile, size_t* default_search_provider_index) {
// If there is a set of search engines in the preferences file, it overrides
// the built-in set.
*default_search_provider_index = 0;
- GetPrepopulatedTemplateFromPrefs(profile, t_urls);
- if (!t_urls->empty())
- return;
+ ScopedVector<TemplateURL> t_urls = GetPrepopulatedTemplateFromPrefs(profile);
+ if (!t_urls.empty())
+ return t_urls.Pass();
const PrepopulatedEngine** engines;
size_t num_engines;
GetPrepopulationSetFromCountryID(profile ? profile->GetPrefs() : NULL,
&engines, &num_engines);
for (size_t i = 0; i != num_engines; ++i) {
- t_urls->push_back(
+ t_urls.push_back(
MakePrepopulatedTemplateURLFromPrepopulateEngine(profile, *engines[i]));
}
+ return t_urls.Pass();
}
void ClearPrepopulatedEnginesInPrefs(Profile* profile) {
@@ -1280,11 +1280,11 @@ void ClearPrepopulatedEnginesInPrefs(Profile* profile) {
TemplateURL* GetPrepopulatedDefaultSearch(Profile* profile) {
TemplateURL* default_search_provider = NULL;
- ScopedVector<TemplateURL> loaded_urls;
size_t default_search_index;
// This could be more efficient. We are loading all the URLs to only keep
// the first one.
- GetPrepopulatedEngines(profile, &loaded_urls.get(), &default_search_index);
+ ScopedVector<TemplateURL> loaded_urls = GetPrepopulatedEngines(
+ profile, &default_search_index);
if (default_search_index < loaded_urls.size()) {
default_search_provider = loaded_urls[default_search_index];
loaded_urls.weak_erase(loaded_urls.begin() + default_search_index);
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.h b/chrome/browser/search_engines/template_url_prepopulate_data.h
index 40f6cd7..2d644982 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.h
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/memory/scoped_vector.h"
#include "base/strings/string16.h"
#include "chrome/browser/search_engines/search_engine_type.h"
@@ -44,13 +45,11 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// file then it returns the version specified there.
int GetDataVersion(PrefService* prefs);
-// Loads the set of TemplateURLs from the prepopulate data. Ownership of the
-// TemplateURLs is passed to the caller. On return,
+// Loads the set of TemplateURLs from the prepopulate data. On return,
// |default_search_provider_index| is set to the index of the default search
// provider.
-void GetPrepopulatedEngines(Profile* profile,
- std::vector<TemplateURL*>* t_urls,
- size_t* default_search_provider_index);
+ScopedVector<TemplateURL> GetPrepopulatedEngines(
+ Profile* profile, size_t* default_search_provider_index);
// Removes prepopulated engines and their version stored in user prefs.
void ClearPrepopulatedEnginesInPrefs(Profile* profile);
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc b/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
index d2e4db4..4e33b43 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
@@ -86,10 +86,10 @@ TEST(TemplateURLPrepopulateDataTest, UniqueIDs) {
TestingProfile profile;
for (size_t i = 0; i < arraysize(kCountryIds); ++i) {
profile.GetPrefs()->SetInteger(prefs::kCountryIDAtInstall, kCountryIds[i]);
- ScopedVector<TemplateURL> urls;
size_t default_index;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &urls.get(),
- &default_index);
+ ScopedVector<TemplateURL> urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
+ &default_index);
std::set<int> unique_ids;
for (size_t turl_i = 0; turl_i < urls.size(); ++turl_i) {
ASSERT_TRUE(unique_ids.find(urls[turl_i]->prepopulate_id()) ==
@@ -121,10 +121,10 @@ TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
int version = TemplateURLPrepopulateData::GetDataVersion(prefs);
EXPECT_EQ(1, version);
- ScopedVector<TemplateURL> t_urls;
size_t default_index;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &t_urls.get(),
- &default_index);
+ ScopedVector<TemplateURL> t_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
+ &default_index);
ASSERT_EQ(1u, t_urls.size());
EXPECT_EQ(ASCIIToUTF16("foo"), t_urls[0]->short_name());
@@ -149,9 +149,8 @@ TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
overrides->Append(entry->DeepCopy());
prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
- t_urls.clear();
- TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &t_urls.get(),
- &default_index);
+ t_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
+ &default_index);
ASSERT_EQ(1u, t_urls.size());
EXPECT_EQ(ASCIIToUTF16("foo"), t_urls[0]->short_name());
EXPECT_EQ(ASCIIToUTF16("fook"), t_urls[0]->keyword());
@@ -184,9 +183,8 @@ TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
overrides->Append(entry->DeepCopy());
prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
- t_urls.clear();
- TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &t_urls.get(),
- &default_index);
+ t_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
+ &default_index);
EXPECT_EQ(2u, t_urls.size());
}
@@ -216,10 +214,10 @@ TEST(TemplateURLPrepopulateDataTest, ClearProvidersFromPrefs) {
version = TemplateURLPrepopulateData::GetDataVersion(prefs);
EXPECT_EQ(TemplateURLPrepopulateData::kCurrentDataVersion, version);
- ScopedVector<TemplateURL> t_urls;
size_t default_index;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &t_urls.get(),
- &default_index);
+ ScopedVector<TemplateURL> t_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
+ &default_index);
ASSERT_FALSE(t_urls.empty());
for (size_t i = 0; i < t_urls.size(); ++i) {
EXPECT_NE(ASCIIToUTF16("foo"), t_urls[i]->short_name());
@@ -245,10 +243,10 @@ TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrepopulated) {
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kCountry, "US");
TestingProfile profile;
- ScopedVector<TemplateURL> t_urls;
size_t default_index;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &t_urls.get(),
- &default_index);
+ ScopedVector<TemplateURL> t_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
+ &default_index);
// Ensure all the URLs have the required fields populated.
ASSERT_FALSE(t_urls.empty());
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index 02f1551..cca1a36 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -708,53 +708,47 @@ TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
return FirstPotentialDefaultEngine(template_urls_);
}
-void TemplateURLService::ResetURLs() {
+void TemplateURLService::RepairPrepopulatedSearchEngines() {
// Can't clean DB if it hasn't been loaded.
DCHECK(loaded());
- DCHECK(service_);
- ClearDefaultProviderFromPrefs();
-
- TemplateURLVector entries_to_process = template_urls_;
- // Clear default provider to be able to delete it.
- default_search_provider_ = NULL;
- for (TemplateURLVector::const_iterator i = entries_to_process.begin();
- i != entries_to_process.end(); ++i)
- RemoveNoNotify(*i);
- entries_to_process.clear();
- provider_map_.reset(new SearchHostToURLsMap);
- UIThreadSearchTermsData search_terms_data(profile_);
- provider_map_->Init(TemplateURLVector(), search_terms_data);
+ size_t default_search_provider_index = 0;
+ ScopedVector<TemplateURL> prepopulated_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(
+ profile_, &default_search_provider_index);
+ DCHECK(!prepopulated_urls.empty());
+ int default_search_engine_id =
+ prepopulated_urls[default_search_provider_index]->prepopulate_id();
+ TemplateURL* current_dse = default_search_provider_;
+ ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
+ &prepopulated_urls, template_urls_, current_dse));
+ // Remove items.
+ for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin();
+ i < actions.removed_engines.end(); ++i)
+ RemoveNoNotify(*i);
- TemplateURL* default_search_provider = NULL;
- // Force GetSearchProvidersUsingLoadedEngines() to include the prepopulated
- // engines in the list by claiming we are currently on version 0, ensuring
- // that the prepopulate data version will be newer.
- int new_resource_keyword_version = 0;
- GetSearchProvidersUsingLoadedEngines(service_.get(), profile_,
- &entries_to_process,
- &default_search_provider,
- &new_resource_keyword_version,
- &pre_sync_deletes_);
- // Setup search engines and a default one.
- base::AutoReset<DefaultSearchChangeOrigin> change_origin(
- &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
- AddTemplateURLsAndSetupDefaultEngine(&entries_to_process,
- default_search_provider);
-
- // Repopulate extension keywords.
- std::vector<ExtensionKeyword> extension_keywords =
- GetExtensionKeywords(profile());
- for (size_t i = 0; i < extension_keywords.size(); ++i) {
- TemplateURL* extension_url =
- CreateTemplateURLForExtension(extension_keywords[i]);
- AddNoNotify(extension_url, true);
+ // Edit items.
+ for (EditedEngines::iterator i(actions.edited_engines.begin());
+ i < actions.edited_engines.end(); ++i) {
+ UIThreadSearchTermsData search_terms_data(profile());
+ TemplateURL new_values(profile(), i->second);
+ UpdateNoNotify(i->first, new_values, search_terms_data);
}
- if (new_resource_keyword_version)
- service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
+ // Add items.
+ for (std::vector<TemplateURL*>::iterator i = actions.added_engines.begin();
+ i < actions.added_engines.end(); ++i)
+ AddNoNotify(*i, true);
- EnsureDefaultSearchProviderExists();
+ // Change the DSE.
+ TemplateURL* new_dse = FindURLByPrepopulateID(template_urls_,
+ default_search_engine_id);
+ DCHECK(new_dse);
+ if (CanMakeDefault(new_dse)) {
+ base::AutoReset<DefaultSearchChangeOrigin> change_origin(
+ &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
+ SetDefaultSearchProviderNoNotify(new_dse);
+ }
NotifyObservers();
}
@@ -1880,10 +1874,10 @@ void TemplateURLService::UpdateTemplateURLIfPrepopulated(
if (template_url->prepopulate_id() == 0)
return;
- ScopedVector<TemplateURL> prepopulated_urls;
size_t default_search_index;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(profile,
- &prepopulated_urls.get(), &default_search_index);
+ ScopedVector<TemplateURL> prepopulated_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(profile,
+ &default_search_index);
for (size_t i = 0; i < prepopulated_urls.size(); ++i) {
if (prepopulated_urls[i]->prepopulate_id() == prepopulate_id) {
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index 019552f6..c47c85e 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -241,12 +241,16 @@ class TemplateURLService : public WebDataServiceConsumer,
// destroyed at any time so should be used right after the call.
TemplateURL* FindNewDefaultSearchProvider();
- // Resets the search providers to the prepopulated engines plus any keywords
- // from currently-installed extensions. The user will lose all auto-added
- // keywords from webpages, all edits to both normal and extension keywords,
- // and any keywords belonging to no-longer-installed extensions.
- // Modifications will be synced later.
- void ResetURLs();
+ // Performs the same actions that happen when the prepopulate data version is
+ // revved: all existing prepopulated entries are checked against the current
+ // prepopulate data, any now-extraneous safe_for_autoreplace() entries are
+ // removed, any existing engines are reset to the provided data (except for
+ // user-edited names or keywords), and any new prepopulated anegines are
+ // added.
+ //
+ // After this, the default search engine is reset to the default entry in the
+ // prepopulate data.
+ void RepairPrepopulatedSearchEngines();
// Observers used to listen for changes to the model.
// TemplateURLService does NOT delete the observers when deleted.
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index e41aeda..c4c9cfd 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -1885,10 +1885,10 @@ TEST_F(TemplateURLServiceSyncTest, PreSyncDeletes) {
TEST_F(TemplateURLServiceSyncTest, PreSyncUpdates) {
const char* kNewKeyword = "somethingnew";
// Fetch the prepopulate search engines so we know what they are.
- ScopedVector<TemplateURL> prepop_turls;
size_t default_search_provider_index = 0;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(
- profile_a(), &prepop_turls.get(), &default_search_provider_index);
+ ScopedVector<TemplateURL> prepop_turls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(
+ profile_a(), &default_search_provider_index);
// We have to prematurely exit this test if for some reason this machine does
// not have any prepopulate TemplateURLs.
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index 41c117e..252c58e 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -138,54 +138,6 @@ void ExpectSimilar(const TemplateURL* expected, const TemplateURL* actual) {
} // namespace
-// TemplateURLServiceExtensionTest --------------------------------------------
-
-class TemplateURLServiceExtensionTest : public ExtensionServiceTestBase,
- public TemplateURLServiceTestUtilBase {
- public:
- TemplateURLServiceExtensionTest();
- virtual ~TemplateURLServiceExtensionTest();
-
- // ExtensionServiceTestBase:
- virtual void SetUp() OVERRIDE;
-
- // TemplateURLServiceTestUtilBase:
- virtual TestingProfile* profile() const OVERRIDE;
-
- void CheckExtensionKeyword(const string16& keyword, const string16& name);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceExtensionTest);
-};
-
-TemplateURLServiceExtensionTest::TemplateURLServiceExtensionTest() {}
-
-TemplateURLServiceExtensionTest::~TemplateURLServiceExtensionTest() {}
-
-void TemplateURLServiceExtensionTest::SetUp() {
- ExtensionServiceTestBase::SetUp();
- ExtensionServiceInitParams params;
- InitializeExtensionService(params);
- TemplateURLServiceTestUtilBase::CreateTemplateUrlService();
-}
-
-
-TestingProfile* TemplateURLServiceExtensionTest::profile() const {
- return profile_.get();
-}
-
-void TemplateURLServiceExtensionTest::CheckExtensionKeyword(
- const string16& keyword, const string16& name) {
-#if !defined(OS_ANDROID)
- TemplateURL* ext_url =
- model()->GetTemplateURLForKeyword(keyword);
- ASSERT_TRUE(ext_url);
- EXPECT_EQ(keyword, ext_url->keyword());
- EXPECT_EQ(name, ext_url->short_name());
-#endif
-}
-
-
// TemplateURLServiceTest -----------------------------------------------------
class TemplateURLServiceTest : public testing::Test {
@@ -338,10 +290,10 @@ TemplateURL* TemplateURLServiceTest::CreateReplaceablePreloadedTemplateURL(
bool safe_for_autoreplace,
size_t index_offset_from_default,
string16* prepopulated_display_url) {
- ScopedVector<TemplateURL> prepopulated_urls;
size_t default_search_provider_index = 0;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(test_util_.profile(),
- &prepopulated_urls.get(), &default_search_provider_index);
+ ScopedVector<TemplateURL> prepopulated_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(
+ test_util_.profile(), &default_search_provider_index);
EXPECT_LT(index_offset_from_default, prepopulated_urls.size());
size_t prepopulated_index = (default_search_provider_index +
index_offset_from_default) % prepopulated_urls.size();
@@ -932,68 +884,57 @@ TEST_F(TemplateURLServiceTest, DefaultSearchProviderLoadedFromPrefs) {
AssertEquals(*cloned_url, *model()->GetDefaultSearchProvider());
}
-TEST_F(TemplateURLServiceExtensionTest, ResetURLs) {
- VerifyLoad();
+TEST_F(TemplateURLServiceTest, RepairPrepopulatedSearchEngines) {
+ test_util_.VerifyLoad();
- TemplateURL* new_provider = AddKeywordWithDate(
- model(), "short_name", "keyword", "http://test.com/search?t={searchTerms}",
+ // Edit Google search engine.
+ TemplateURL* google = model()->GetTemplateURLForKeyword(
+ ASCIIToUTF16("google.com"));
+ ASSERT_TRUE(google);
+ model()->ResetTemplateURL(google, ASCIIToUTF16("trash"), ASCIIToUTF16("xxx"),
+ "http://www.foo.com/s?q={searchTerms}");
+ EXPECT_EQ(ASCIIToUTF16("trash"), google->short_name());
+ EXPECT_EQ(ASCIIToUTF16("xxx"), google->keyword());
+
+ // Add third-party default search engine.
+ TemplateURL* user_dse = AddKeywordWithDate(
+ "malware", "google.com", "http://www.goo.com/s?q={searchTerms}",
std::string(), std::string(), std::string(),
true, "UTF-8", Time(), Time());
- model()->SetDefaultSearchProvider(new_provider);
- AddKeywordWithDate(
- model(), "extension1", "ext_keyword",
- std::string(extensions::kExtensionScheme) + "://test1", std::string(),
- std::string(), std::string(), false, "UTF-8", Time(), Time());
- AddKeywordWithDate(
- model(), "extension2", "ext_keyword2",
- std::string(extensions::kExtensionScheme) + "://test2", std::string(),
- std::string(), std::string(), false, "UTF-8", Time(), Time());
- TemplateURL* default_provider = model()->GetDefaultSearchProvider();
- EXPECT_NE(SEARCH_ENGINE_GOOGLE,
- TemplateURLPrepopulateData::GetEngineType(*default_provider));
-
- DictionaryValue manifest;
- manifest.SetString(extensions::manifest_keys::kVersion, "1.0.0.0");
- manifest.SetString(extensions::manifest_keys::kName, "ext1");
- manifest.SetString("app.launch.web_url", "http://www.google.com");
- manifest.SetString(extensions::manifest_keys::kOmniboxKeyword, "ext_keyword");
- std::string error;
- scoped_refptr<extensions::Extension> extension =
- extensions::Extension::Create(
- base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
- extensions::Manifest::COMPONENT,
- manifest,
- extensions::Extension::NO_FLAGS,
- &error);
- EXPECT_TRUE(extension.get() != NULL) << error;
- ExtensionService* extension_service = profile()->GetExtensionService();
- ASSERT_TRUE(extension_service);
- extension_service->AddExtension(extension.get());
- // All URLs except |extension_keywords| should go away. Default search engine
- // is Google again.
- model()->ResetURLs();
-
- default_provider = model()->GetDefaultSearchProvider();
- ASSERT_TRUE(default_provider);
- EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
- TemplateURLPrepopulateData::GetEngineType(*default_provider));
- CheckExtensionKeyword(ASCIIToUTF16("ext_keyword"), ASCIIToUTF16("ext1"));
- EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword2")));
- EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
-
- // Reload URLs. Result should be the same, as extension keywords are now
- // persisted.
- ResetModel(true);
- default_provider = model()->GetDefaultSearchProvider();
- ASSERT_TRUE(default_provider);
- EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
- TemplateURLPrepopulateData::GetEngineType(*default_provider));
- CheckExtensionKeyword(ASCIIToUTF16("ext_keyword"), ASCIIToUTF16("ext1"));
- EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword2")));
- EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
+ model()->SetDefaultSearchProvider(user_dse);
+ EXPECT_EQ(user_dse, model()->GetDefaultSearchProvider());
+
+ // Remove bing.
+ TemplateURL* bing = model()->GetTemplateURLForKeyword(
+ ASCIIToUTF16("bing.com"));
+ ASSERT_TRUE(bing);
+ model()->Remove(bing);
+ EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("bing.com")));
+
+ // Register an extension with bing keyword.
+ model()->RegisterExtensionKeyword("abcdefg", "extension_name", "bing.com");
+ EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("bing.com")));
+
+ model()->RepairPrepopulatedSearchEngines();
+
+ // Google is default.
+ ASSERT_EQ(google, model()->GetDefaultSearchProvider());
+ // The keyword wasn't reverted.
+ EXPECT_EQ(ASCIIToUTF16("trash"), google->short_name());
+ EXPECT_EQ("www.google.com",
+ TemplateURLService::GenerateSearchURL(google).host());
+
+ // Bing was repaired.
+ bing = model()->GetTemplateURLForKeyword(ASCIIToUTF16("bing.com"));
+ ASSERT_TRUE(bing);
+ EXPECT_FALSE(bing->IsExtensionKeyword());
+
+ // User search engine is preserved.
+ EXPECT_EQ(user_dse, model()->GetTemplateURLForHost("www.goo.com"));
+ EXPECT_EQ(ASCIIToUTF16("google.com"), user_dse->keyword());
}
-TEST_F(TemplateURLServiceExtensionTest, ResetURLsWithManagedDefault) {
+TEST_F(TemplateURLServiceTest, RepairSearchEnginesWithManagedDefault) {
// Set a managed preference that establishes a default search provider.
const char kName[] = "test1";
const char kKeyword[] = "test.com";
@@ -1002,12 +943,12 @@ TEST_F(TemplateURLServiceExtensionTest, ResetURLsWithManagedDefault) {
const char kEncodings[] = "UTF-16;UTF-32";
const char kAlternateURL[] = "http://test.com/search#t={searchTerms}";
const char kSearchTermsReplacementKey[] = "espv";
- SetManagedDefaultSearchPreferences(true, kName, kKeyword,
- kSearchURL, std::string(),
- kIconURL, kEncodings,
- kAlternateURL,
- kSearchTermsReplacementKey);
- VerifyLoad();
+ test_util_.SetManagedDefaultSearchPreferences(true, kName, kKeyword,
+ kSearchURL, std::string(),
+ kIconURL, kEncodings,
+ kAlternateURL,
+ kSearchTermsReplacementKey);
+ test_util_.VerifyLoad();
// Verify that the default manager we are getting is the managed one.
TemplateURLData data;
data.short_name = ASCIIToUTF16(kName);
@@ -1018,15 +959,15 @@ TEST_F(TemplateURLServiceExtensionTest, ResetURLsWithManagedDefault) {
base::SplitString(kEncodings, ';', &data.input_encodings);
data.alternate_urls.push_back(kAlternateURL);
data.search_terms_replacement_key = kSearchTermsReplacementKey;
- scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(profile(),
- data));
+ scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(
+ test_util_.profile(), data));
EXPECT_TRUE(model()->is_default_search_managed());
const TemplateURL* actual_managed_default =
model()->GetDefaultSearchProvider();
ExpectSimilar(expected_managed_default.get(), actual_managed_default);
// The following call has no effect on the managed search engine.
- model()->ResetURLs();
+ model()->RepairPrepopulatedSearchEngines();
EXPECT_TRUE(model()->is_default_search_managed());
actual_managed_default = model()->GetDefaultSearchProvider();
diff --git a/chrome/browser/search_engines/util.cc b/chrome/browser/search_engines/util.cc
index 6aa478e..0ccf57f 100644
--- a/chrome/browser/search_engines/util.cc
+++ b/chrome/browser/search_engines/util.cc
@@ -150,6 +150,17 @@ TemplateURL* GetTemplateURLByID(
return NULL;
}
+TemplateURL* FindURLByPrepopulateID(
+ const TemplateURLService::TemplateURLVector& template_urls,
+ int prepopulate_id) {
+ for (std::vector<TemplateURL*>::const_iterator i = template_urls.begin();
+ i < template_urls.end(); ++i) {
+ if ((*i)->prepopulate_id() == prepopulate_id)
+ return *i;
+ }
+ return NULL;
+}
+
void MergeIntoPrepopulatedEngineData(TemplateURLData* prepopulated_url,
const TemplateURL* original_turl) {
DCHECK_EQ(original_turl->prepopulate_id(), prepopulated_url->prepopulate_id);
@@ -164,7 +175,10 @@ void MergeIntoPrepopulatedEngineData(TemplateURLData* prepopulated_url,
prepopulated_url->last_modified = original_turl->last_modified();
}
-// Merges the provided prepopulated engines with the provided existing engines.
+ActionsFromPrepopulateData::ActionsFromPrepopulateData() {}
+
+ActionsFromPrepopulateData::~ActionsFromPrepopulateData() {}
+
// This is invoked when the version of the prepopulate data changes.
// If |removed_keyword_guids| is not NULL, the Sync GUID of each item removed
// from the DB will be added to it. Note that this function will take
@@ -178,15 +192,69 @@ void MergeEnginesFromPrepopulateData(
TemplateURL** default_search_provider,
std::set<std::string>* removed_keyword_guids) {
DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(prepopulated_urls);
DCHECK(template_urls);
DCHECK(default_search_provider);
+ int default_prepopulated_id =
+ (*prepopulated_urls)[default_search_index]->prepopulate_id();
+ ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
+ prepopulated_urls, *template_urls, *default_search_provider));
+
+ // Remove items.
+ for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin();
+ i < actions.removed_engines.end(); ++i) {
+ scoped_ptr<TemplateURL> template_url(*i);
+ TemplateURLService::TemplateURLVector::iterator j =
+ std::find(template_urls->begin(), template_urls->end(), template_url);
+ DCHECK(j != template_urls->end());
+ DCHECK(*j != *default_search_provider);
+ template_urls->erase(j);
+ if (service) {
+ service->RemoveKeyword(template_url->id());
+ if (removed_keyword_guids)
+ removed_keyword_guids->insert(template_url->sync_guid());
+ }
+ }
+
+ // Edit items.
+ for (EditedEngines::iterator i(actions.edited_engines.begin());
+ i < actions.edited_engines.end(); ++i) {
+ TemplateURLData& data = i->second;
+ scoped_ptr<TemplateURL> existing_url(i->first);
+ if (service)
+ service->UpdateKeyword(data);
+
+ // Replace the entry in |template_urls| with the updated one.
+ TemplateURLService::TemplateURLVector::iterator j = std::find(
+ template_urls->begin(), template_urls->end(), existing_url.get());
+ *j = new TemplateURL(profile, data);
+ if (*default_search_provider == existing_url.get())
+ *default_search_provider = *j;
+ }
+
+ // Add items.
+ template_urls->insert(template_urls->end(), actions.added_engines.begin(),
+ actions.added_engines.end());
+
+ if (!*default_search_provider) {
+ // The user had no existing default search provider, so set the
+ // default to the default prepopulated engine.
+ *default_search_provider = FindURLByPrepopulateID(*template_urls,
+ default_prepopulated_id);
+ }
+}
+
+ActionsFromPrepopulateData CreateActionsFromCurrentPrepopulateData(
+ ScopedVector<TemplateURL>* prepopulated_urls,
+ const TemplateURLService::TemplateURLVector& existing_urls,
+ const TemplateURL* default_search_provider) {
// Create a map to hold all provided |template_urls| that originally came from
// prepopulate data (i.e. have a non-zero prepopulate_id()).
typedef std::map<int, TemplateURL*> IDMap;
IDMap id_to_turl;
- for (TemplateURLService::TemplateURLVector::iterator i(
- template_urls->begin()); i != template_urls->end(); ++i) {
+ for (TemplateURLService::TemplateURLVector::const_iterator i(
+ existing_urls.begin()); i != existing_urls.end(); ++i) {
int prepopulate_id = (*i)->prepopulate_id();
if (prepopulate_id > 0)
id_to_turl[prepopulate_id] = *i;
@@ -195,45 +263,30 @@ void MergeEnginesFromPrepopulateData(
// For each current prepopulated URL, check whether |template_urls| contained
// a matching prepopulated URL. If so, update the passed-in URL to match the
// current data. (If the passed-in URL was user-edited, we persist the user's
- // name and keyword.) If not, add the prepopulated URL to |template_urls|.
- // Along the way, point |default_search_provider| at the default prepopulated
- // URL, if the user hasn't already set another URL as default.
+ // name and keyword.) If not, add the prepopulated URL.
+ ActionsFromPrepopulateData actions;
for (size_t i = 0; i < prepopulated_urls->size(); ++i) {
// We take ownership of |prepopulated_urls[i]|.
scoped_ptr<TemplateURL> prepopulated_url((*prepopulated_urls)[i]);
const int prepopulated_id = prepopulated_url->prepopulate_id();
DCHECK_NE(0, prepopulated_id);
- TemplateURL* url_in_vector = NULL;
IDMap::iterator existing_url_iter(id_to_turl.find(prepopulated_id));
if (existing_url_iter != id_to_turl.end()) {
- // Update the data store with the new prepopulated data. Preserve user
+ // Update the data store with the new prepopulated data. Preserve user
// edits to the name and keyword.
TemplateURLData data(prepopulated_url->data());
- scoped_ptr<TemplateURL> existing_url(existing_url_iter->second);
+ TemplateURL* existing_url(existing_url_iter->second);
id_to_turl.erase(existing_url_iter);
- MergeIntoPrepopulatedEngineData(&data, existing_url.get());
+ MergeIntoPrepopulatedEngineData(&data, existing_url);
// Update last_modified to ensure that if this entry is later merged with
// entries from Sync, the conflict resolution logic knows that this was
// updated and propagates the new values to the server.
data.last_modified = base::Time::Now();
- if (service)
- service->UpdateKeyword(data);
-
- // Replace the entry in |template_urls| with the updated one.
- TemplateURLService::TemplateURLVector::iterator j = std::find(
- template_urls->begin(), template_urls->end(), existing_url.get());
- *j = new TemplateURL(profile, data);
- url_in_vector = *j;
- if (*default_search_provider == existing_url.get())
- *default_search_provider = url_in_vector;
+ actions.edited_engines.push_back(std::make_pair(existing_url, data));
} else {
- template_urls->push_back(prepopulated_url.release());
- url_in_vector = template_urls->back();
+ actions.added_engines.push_back(prepopulated_url.release());
}
- DCHECK(url_in_vector);
- if (i == default_search_index && !*default_search_provider)
- *default_search_provider = url_in_vector;
}
// The above loop takes ownership of all the contents of prepopulated_urls.
// Clear the pointers.
@@ -244,21 +297,13 @@ void MergeEnginesFromPrepopulateData(
// found in the prepopulate data. Any remaining URLs that haven't been
// user-edited or made default can be removed from the data store.
for (IDMap::iterator i(id_to_turl.begin()); i != id_to_turl.end(); ++i) {
- const TemplateURL* template_url = i->second;
+ TemplateURL* template_url = i->second;
if ((template_url->safe_for_autoreplace()) &&
- (template_url != *default_search_provider)) {
- TemplateURLService::TemplateURLVector::iterator j =
- std::find(template_urls->begin(), template_urls->end(), template_url);
- DCHECK(j != template_urls->end());
- template_urls->erase(j);
- if (service) {
- service->RemoveKeyword(template_url->id());
- if (removed_keyword_guids)
- removed_keyword_guids->insert(template_url->sync_guid());
- }
- delete template_url;
- }
+ (template_url != default_search_provider))
+ actions.removed_engines.push_back(template_url);
}
+
+ return actions;
}
void GetSearchProvidersUsingKeywordResult(
@@ -321,10 +366,10 @@ void GetSearchProvidersUsingLoadedEngines(
DCHECK(default_search_provider);
DCHECK(resource_keyword_version);
- ScopedVector<TemplateURL> prepopulated_urls;
size_t default_search_index;
- TemplateURLPrepopulateData::GetPrepopulatedEngines(profile,
- &prepopulated_urls.get(), &default_search_index);
+ ScopedVector<TemplateURL> prepopulated_urls =
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(profile,
+ &default_search_index);
RemoveDuplicatePrepopulateIDs(service, prepopulated_urls,
*default_search_provider, template_urls,
removed_keyword_guids);
diff --git a/chrome/browser/search_engines/util.h b/chrome/browser/search_engines/util.h
index b496e2a..56553de 100644
--- a/chrome/browser/search_engines/util.h
+++ b/chrome/browser/search_engines/util.h
@@ -27,11 +27,55 @@ string16 GetDefaultSearchEngineName(Profile* profile);
// |profile|.
GURL GetDefaultSearchURLForSearchTerms(Profile* profile, const string16& terms);
+// Returns matching URL from |template_urls| or NULL.
+TemplateURL* FindURLByPrepopulateID(
+ const TemplateURLService::TemplateURLVector& template_urls,
+ int prepopulate_id);
+
// Modifies |prepopulated_url| so that it contains user-modified fields from
// |original_turl|. Both URLs must have the same prepopulate_id.
void MergeIntoPrepopulatedEngineData(TemplateURLData* prepopulated_url,
const TemplateURL* original_turl);
+// CreateActionsFromCurrentPrepopulateData() (see below) takes in the current
+// prepopulated URLs as well as the user's current URLs, and returns an instance
+// of the following struct representing the changes necessary to bring the
+// user's URLs in line with the prepopulated URLs.
+//
+// There are three types of changes:
+// (1) Previous prepopulated engines that no longer exist in the current set of
+// prepopulated engines and thus should be removed from the user's current
+// URLs.
+// (2) Previous prepopulated engines whose data has changed. The existing
+// entries for these engines should be updated to reflect the new data,
+// except for any user-set names and keywords, which can be preserved.
+// (3) New prepopulated engines not in the user's engine list, which should be
+// added.
+
+// The pair of current search engine and its new value.
+typedef std::pair<TemplateURL*, TemplateURLData> EditedSearchEngine;
+typedef std::vector<EditedSearchEngine> EditedEngines;
+
+struct ActionsFromPrepopulateData {
+ ActionsFromPrepopulateData();
+ ~ActionsFromPrepopulateData();
+
+ TemplateURLService::TemplateURLVector removed_engines;
+ EditedEngines edited_engines;
+ TemplateURLService::TemplateURLVector added_engines;
+};
+
+// Given the user's current URLs and the current set of prepopulated URLs,
+// produces the set of actions (see above) required to make the user's URLs
+// reflect the prepopulate data. |default_search_provider| is used to avoid
+// placing the current default provider on the "to be removed" list.
+//
+// NOTE: Takes ownership of, and clears, |prepopulated_urls|.
+ActionsFromPrepopulateData CreateActionsFromCurrentPrepopulateData(
+ ScopedVector<TemplateURL>* prepopulated_urls,
+ const TemplateURLService::TemplateURLVector& existing_urls,
+ const TemplateURL* default_search_provider);
+
// Processes the results of WebDataService::GetKeywords, combining it with
// prepopulated search providers to result in:
// * a set of template_urls (search providers). The caller owns the