Commit 4a40facd authored by vasilii@chromium.org's avatar vasilii@chromium.org

New methods allow to

- delete prepopulated search engines from user prefs
- delete the default search engine from user prefs
- reset unmanaged and non-extension URLs to prepopulated list. 

New unit tests:
- TemplateURLPrepopulateDataTest.ClearProvidersFromPrefs
- TemplateURLServiceTest.ResetNonExtensionURLs
- TemplateURLServiceTest.ResetURLsWithManagedDefault

BUG=235037,244291

Review URL: https://chromiumcodereview.appspot.com/15572002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202869 0039d316-1c4b-4281-b951-d872f2087c98
parent 6e206fad
......@@ -5,14 +5,24 @@
#include "chrome/browser/profile_resetter/profile_resetter.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/profiles/profile.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"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
ProfileResetter::ProfileResetter(Profile* profile)
: profile_(profile),
template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
pending_reset_flags_(0) {
DCHECK(CalledOnValidThread());
DCHECK(profile_);
DCHECK(template_url_service_);
registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
content::Source<TemplateURLService>(template_url_service_));
}
ProfileResetter::~ProfileResetter() {}
......@@ -81,16 +91,32 @@ void ProfileResetter::MarkAsDone(Resettable resettable) {
pending_reset_flags_ &= ~resettable;
if (!pending_reset_flags_)
if (!pending_reset_flags_) {
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
callback_);
callback_.Reset();
}
}
void ProfileResetter::ResetDefaultSearchEngine() {
DCHECK(CalledOnValidThread());
NOTIMPLEMENTED();
// TODO(battre/vabr): Implement
MarkAsDone(DEFAULT_SEARCH_ENGINE);
// If TemplateURLServiceFactory is ready we can clean it right now.
// Otherwise, load it and continue from ProfileResetter::Observe.
if (template_url_service_->loaded()) {
// Reset Google search URL.
PrefService* prefs = profile_->GetPrefs();
DCHECK(prefs);
prefs->ClearPref(prefs::kLastPromptedGoogleURL);
GoogleURLTracker::RequestServerCheck(profile_);
TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(profile_);
template_url_service_->ResetNonExtensionURLs();
MarkAsDone(DEFAULT_SEARCH_ENGINE);
} else {
template_url_service_->Load();
}
}
void ProfileResetter::ResetHomepage() {
......@@ -133,3 +159,13 @@ void ProfileResetter::ResetStartPage() {
prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
MarkAsDone(STARTUP_PAGE);
}
void ProfileResetter::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(CalledOnValidThread());
// TemplateURLService has loaded. If we need to clean search engines, it's
// time to go on.
if (pending_reset_flags_ & DEFAULT_SEARCH_ENGINE)
ResetDefaultSearchEngine();
}
......@@ -8,13 +8,17 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/threading/non_thread_safe.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
class Profile;
class TemplateURLService;
// This class allows resetting certain aspects of a profile to default values.
// It is used in case the profile has been damaged due to malware or bad user
// settings.
class ProfileResetter : public base::NonThreadSafe {
class ProfileResetter : public base::NonThreadSafe,
public content::NotificationObserver {
public:
// Flags indicating what aspects of a profile shall be reset.
enum Resettable {
......@@ -43,7 +47,7 @@ class ProfileResetter : public base::NonThreadSafe {
type_ResettableFlags_doesnt_match_Resettable);
explicit ProfileResetter(Profile* profile);
~ProfileResetter();
virtual ~ProfileResetter();
// Resets |resettable_flags| and calls |callback| on the UI thread on
// completion. If |resettable_flags| contains EXTENSIONS, these are handled
......@@ -66,7 +70,13 @@ class ProfileResetter : public base::NonThreadSafe {
void ResetExtensions(ExtensionHandling extension_handling);
void ResetStartPage();
// content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
Profile* profile_;
TemplateURLService* template_url_service_;
// Flags of a Resetable indicating which reset operations we are still waiting
// for.
......@@ -75,6 +85,8 @@ class ProfileResetter : public base::NonThreadSafe {
// Called on UI thread when reset has been completed.
base::Closure callback_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(ProfileResetter);
};
......
......@@ -39,6 +39,7 @@ class ProfileResetterTest : public testing::Test {
protected:
ProfileResetterTest();
~ProfileResetterTest();
// testing::Test:
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
......@@ -64,7 +65,6 @@ void ProfileResetterTest::TearDown() {
}
TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) {
test_util_.VerifyLoad();
resetter_->Reset(
ProfileResetter::DEFAULT_SEARCH_ENGINE,
ProfileResetter::DISABLE_EXTENSIONS,
......@@ -144,7 +144,6 @@ TEST_F(ProfileResetterTest, ResetStartPage) {
TEST_F(ProfileResetterTest, ResetExtensionsAll) {
// mock_object_ is a StrictMock, so we verify that it is called only once.
test_util_.VerifyLoad();
resetter_->Reset(
ProfileResetter::ALL,
ProfileResetter::UNINSTALL_EXTENSIONS,
......
......@@ -1197,6 +1197,16 @@ void GetPrepopulatedTemplateFromPrefs(Profile* profile,
}
}
void ClearPrepopulatedEnginesInPrefs(Profile* profile) {
if (!profile)
return;
PrefService* prefs = profile->GetPrefs();
DCHECK(prefs);
prefs->ClearPref(prefs::kSearchProviderOverrides);
prefs->ClearPref(prefs::kSearchProviderOverridesVersion);
}
// The caller owns the returned TemplateURL.
TemplateURL* MakePrepopulatedTemplateURLFromPrepopulateEngine(
Profile* profile,
......
......@@ -54,6 +54,9 @@ void GetPrepopulatedEngines(Profile* profile,
std::vector<TemplateURL*>* t_urls,
size_t* default_search_provider_index);
// Removes prepopulated engines and their version stored in user prefs.
void ClearPrepopulatedEnginesInPrefs(Profile* profile);
// Returns the default search provider specified by the prepopulate data.
// The caller owns the returned value, which may be NULL.
// If |profile| is NULL, any search provider overrides from the preferences are
......
......@@ -6,6 +6,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_vector.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/search_engines/prepopulated_engines.h"
#include "chrome/browser/search_engines/search_terms_data.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
......@@ -181,6 +182,52 @@ TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
EXPECT_EQ(2u, t_urls.size());
}
TEST(TemplateURLPrepopulateDataTest, ClearProvidersFromPrefs) {
TestingProfile profile;
TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
prefs->SetUserPref(prefs::kSearchProviderOverridesVersion,
Value::CreateIntegerValue(1));
ListValue* overrides = new ListValue;
DictionaryValue* entry(new DictionaryValue);
// Set only the minimal required settings for a search provider configuration.
entry->SetString("name", "foo");
entry->SetString("keyword", "fook");
entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
entry->SetString("favicon_url", "http://foi.com/favicon.ico");
entry->SetString("encoding", "UTF-8");
entry->SetInteger("id", 1001);
overrides->Append(entry);
prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
int version = TemplateURLPrepopulateData::GetDataVersion(prefs);
EXPECT_EQ(1, version);
// This call removes the above search engine.
TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(&profile);
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);
ASSERT_FALSE(t_urls.empty());
for (size_t i = 0; i < t_urls.size(); ++i) {
EXPECT_NE(ASCIIToUTF16("foo"), t_urls[i]->short_name());
EXPECT_NE(ASCIIToUTF16("fook"), t_urls[i]->keyword());
EXPECT_NE("foi.com", t_urls[i]->favicon_url().host());
EXPECT_NE("foo.com", t_urls[i]->url_ref().GetHost());
EXPECT_NE(1001, t_urls[i]->prepopulate_id());
}
// Ensures the default URL is Google and has the optional fields filled.
EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
EXPECT_FALSE(t_urls[default_index]->suggestions_url().empty());
EXPECT_FALSE(t_urls[default_index]->instant_url().empty());
EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
TemplateURLPrepopulateData::GetEngineType(t_urls[default_index]->url()));
}
// Verifies that built-in search providers are processed correctly.
TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrepopulated) {
// Use United States.
......
......@@ -225,6 +225,11 @@ 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
// extension-supplied engines. Also resets the default search engine unless
// it's managed.
void ResetNonExtensionURLs();
// Observers used to listen for changes to the model.
// TemplateURLService does NOT delete the observers when deleted.
void AddObserver(TemplateURLServiceObserver* observer);
......@@ -421,6 +426,9 @@ class TemplateURLService : public WebDataServiceConsumer,
scoped_ptr<TemplateURL>* default_provider,
bool* is_managed);
// Clears user preferences describing the default search engine.
void ClearDefaultProviderFromPrefs();
// Returns true if there is no TemplateURL that has a search url with the
// specified host, or the only TemplateURLs matching the specified host can
// be replaced.
......@@ -582,6 +590,17 @@ class TemplateURLService : public WebDataServiceConsumer,
void OnSyncedDefaultSearchProviderGUIDChanged();
// Adds |template_urls| to |template_urls_| and sets up the default search
// provider. If |default_search_provider| is non-NULL, it must refer to one
// of the |template_urls|, and will be used as the new default.
void AddTemplateURLsAndSetupDefaultEngine(
TemplateURLVector* template_urls,
TemplateURL* default_search_provider);
// If there is no current default search provider, sets the default to the
// result of calling FindNewDefaultSearchProvider().
void EnsureDefaultSearchProviderExists();
content::NotificationRegistrar notification_registrar_;
PrefChangeRegistrar pref_change_registrar_;
......
......@@ -922,6 +922,83 @@ TEST_F(TemplateURLServiceTest, DefaultSearchProviderLoadedFromPrefs) {
AssertEquals(*cloned_url, *model()->GetDefaultSearchProvider());
}
TEST_F(TemplateURLServiceTest, ResetNonExtensionURLs) {
test_util_.VerifyLoad();
TemplateURL* new_provider = AddKeywordWithDate(
"short_name", "keyword", "http://test.com/search?t={searchTerms}",
std::string(), std::string(), std::string(),
true, "UTF-8", Time(), Time());
model()->SetDefaultSearchProvider(new_provider);
AddKeywordWithDate(
"extension1", "ext_keyword",
std::string(extensions::kExtensionScheme) + "://test1", 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->url()));
// Non-extension URLs should go away. Default search engine is Google again.
model()->ResetNonExtensionURLs();
default_provider = model()->GetDefaultSearchProvider();
ASSERT_TRUE(default_provider);
EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword")));
EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
// Reload URLs. Result should be the same except that extension keywords
// aren't persisted.
test_util_.ResetModel(true);
default_provider = model()->GetDefaultSearchProvider();
ASSERT_TRUE(default_provider);
EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword")));
EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
}
TEST_F(TemplateURLServiceTest, ResetURLsWithManagedDefault) {
// Set a managed preference that establishes a default search provider.
const char kName[] = "test1";
const char kKeyword[] = "test.com";
const char kSearchURL[] = "http://test.com/search?t={searchTerms}";
const char kIconURL[] = "http://test.com/icon.jpg";
const char kEncodings[] = "UTF-16;UTF-32";
const char kAlternateURL[] = "http://test.com/search#t={searchTerms}";
const char kSearchTermsReplacementKey[] = "espv";
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);
data.SetKeyword(ASCIIToUTF16(kKeyword));
data.SetURL(kSearchURL);
data.favicon_url = GURL(kIconURL);
data.show_in_default_list = true;
base::SplitString(kEncodings, ';', &data.input_encodings);
data.alternate_urls.push_back(kAlternateURL);
data.search_terms_replacement_key = kSearchTermsReplacementKey;
Profile* profile = test_util_.profile();
scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(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()->ResetNonExtensionURLs();
EXPECT_TRUE(model()->is_default_search_managed());
actual_managed_default = model()->GetDefaultSearchProvider();
ExpectSimilar(expected_managed_default.get(), actual_managed_default);
}
TEST_F(TemplateURLServiceTest, UpdateKeywordSearchTermsForURL) {
struct TestData {
const std::string url;
......
......@@ -149,8 +149,8 @@ void MergeIntoPrepopulatedEngineData(TemplateURLData* prepopulated_url,
prepopulated_url->last_modified = original_turl->last_modified();
}
// Loads engines from prepopulate data and merges them in with the existing
// engines. This is invoked when the version of the prepopulate data changes.
// Merges the provided prepopulated engines with the provided existing engines.
// 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
// ownership of |prepopulated_urls| and will clear the vector.
......@@ -262,7 +262,6 @@ void GetSearchProvidersUsingKeywordResult(
DCHECK_EQ(KEYWORDS_RESULT, result.GetType());
DCHECK(new_resource_keyword_version);
*new_resource_keyword_version = 0;
WDKeywordsResult keyword_result = reinterpret_cast<
const WDResult<WDKeywordsResult>*>(&result)->GetValue();
......@@ -288,6 +287,25 @@ void GetSearchProvidersUsingKeywordResult(
GetTemplateURLByID(*template_urls, default_search_provider_id);
}
*new_resource_keyword_version = keyword_result.builtin_keyword_version;
GetSearchProvidersUsingLoadedEngines(service, profile, template_urls,
default_search_provider,
new_resource_keyword_version,
removed_keyword_guids);
}
void GetSearchProvidersUsingLoadedEngines(
WebDataService* service,
Profile* profile,
TemplateURLService::TemplateURLVector* template_urls,
TemplateURL** default_search_provider,
int* resource_keyword_version,
std::set<std::string>* removed_keyword_guids) {
DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(template_urls);
DCHECK(default_search_provider);
DCHECK(resource_keyword_version);
ScopedVector<TemplateURL> prepopulated_urls;
size_t default_search_index;
TemplateURLPrepopulateData::GetPrepopulatedEngines(profile,
......@@ -296,14 +314,16 @@ void GetSearchProvidersUsingKeywordResult(
*default_search_provider, template_urls,
removed_keyword_guids);
const int resource_keyword_version =
const int prepopulate_resource_keyword_version =
TemplateURLPrepopulateData::GetDataVersion(
profile ? profile->GetPrefs() : NULL);
if (keyword_result.builtin_keyword_version != resource_keyword_version) {
if (*resource_keyword_version < prepopulate_resource_keyword_version) {
MergeEnginesFromPrepopulateData(profile, service, &prepopulated_urls,
default_search_index, template_urls, default_search_provider,
removed_keyword_guids);
*new_resource_keyword_version = resource_keyword_version;
*resource_keyword_version = prepopulate_resource_keyword_version;
} else {
*resource_keyword_version = 0;
}
}
......
......@@ -50,6 +50,21 @@ void GetSearchProvidersUsingKeywordResult(
int* new_resource_keyword_version,
std::set<std::string>* removed_keyword_guids);
// Like GetSearchProvidersUsingKeywordResult(), but allows the caller to pass in
// engines in |template_urls| instead of getting them via processing a web data
// service request.
// |resource_keyword_version| should contain the version number of the current
// keyword data, i.e. the version number of the most recent prepopulate data
// that has been merged into the current keyword data. On exit, this will be
// set as in GetSearchProvidersUsingKeywordResult().
void GetSearchProvidersUsingLoadedEngines(
WebDataService* service,
Profile* profile,
TemplateURLService::TemplateURLVector* template_urls,
TemplateURL** default_search_provider,
int* resource_keyword_version,
std::set<std::string>* removed_keyword_guids);
// Due to a bug, the |input_encodings| field of TemplateURLData could have
// contained duplicate entries. This removes those entries and returns whether
// any were found.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment