1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/profile_resetter/profile_resetter.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/browsing_data/browsing_data_helper.h"
9 #include "chrome/browser/content_settings/host_content_settings_map.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_system.h"
12 #include "chrome/browser/google/google_url_tracker.h"
13 #include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/search_engines/search_terms_data.h"
16 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
17 #include "chrome/browser/search_engines/template_url_service.h"
18 #include "chrome/browser/search_engines/template_url_service_factory.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_iterator.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/pref_names.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "extensions/browser/management_policy.h"
26 ProfileResetter::ProfileResetter(Profile
* profile
)
28 template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_
)),
29 pending_reset_flags_(0),
30 cookies_remover_(NULL
) {
31 DCHECK(CalledOnValidThread());
35 ProfileResetter::~ProfileResetter() {
37 cookies_remover_
->RemoveObserver(this);
40 void ProfileResetter::Reset(
41 ProfileResetter::ResettableFlags resettable_flags
,
42 scoped_ptr
<BrandcodedDefaultSettings
> master_settings
,
43 const base::Closure
& callback
) {
44 DCHECK(CalledOnValidThread());
45 DCHECK(master_settings
);
47 // We should never be called with unknown flags.
48 CHECK_EQ(static_cast<ResettableFlags
>(0), resettable_flags
& ~ALL
);
50 // We should never be called when a previous reset has not finished.
51 CHECK_EQ(static_cast<ResettableFlags
>(0), pending_reset_flags_
);
53 if (!resettable_flags
) {
54 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
59 master_settings_
.swap(master_settings
);
62 // These flags are set to false by the individual reset functions.
63 pending_reset_flags_
= resettable_flags
;
67 void (ProfileResetter::*method
)();
69 { DEFAULT_SEARCH_ENGINE
, &ProfileResetter::ResetDefaultSearchEngine
},
70 { HOMEPAGE
, &ProfileResetter::ResetHomepage
},
71 { CONTENT_SETTINGS
, &ProfileResetter::ResetContentSettings
},
72 { COOKIES_AND_SITE_DATA
, &ProfileResetter::ResetCookiesAndSiteData
},
73 { EXTENSIONS
, &ProfileResetter::ResetExtensions
},
74 { STARTUP_PAGES
, &ProfileResetter::ResetStartupPages
},
75 { PINNED_TABS
, &ProfileResetter::ResetPinnedTabs
},
78 ResettableFlags reset_triggered_for_flags
= 0;
79 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(flagToMethod
); ++i
) {
80 if (resettable_flags
& flagToMethod
[i
].flag
) {
81 reset_triggered_for_flags
|= flagToMethod
[i
].flag
;
82 (this->*flagToMethod
[i
].method
)();
86 DCHECK_EQ(resettable_flags
, reset_triggered_for_flags
);
89 bool ProfileResetter::IsActive() const {
90 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
91 return pending_reset_flags_
!= 0;
94 void ProfileResetter::MarkAsDone(Resettable resettable
) {
95 DCHECK(CalledOnValidThread());
97 // Check that we are never called twice or unexpectedly.
98 CHECK(pending_reset_flags_
& resettable
);
100 pending_reset_flags_
&= ~resettable
;
102 if (!pending_reset_flags_
) {
103 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
106 master_settings_
.reset();
107 template_url_service_sub_
.reset();
111 void ProfileResetter::ResetDefaultSearchEngine() {
112 DCHECK(CalledOnValidThread());
113 DCHECK(template_url_service_
);
114 // If TemplateURLServiceFactory is ready we can clean it right now.
115 // Otherwise, load it and continue from ProfileResetter::Observe.
116 if (template_url_service_
->loaded()) {
117 PrefService
* prefs
= profile_
->GetPrefs();
119 TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(profile_
);
120 scoped_ptr
<base::ListValue
> search_engines(
121 master_settings_
->GetSearchProviderOverrides());
122 if (search_engines
) {
123 // This Chrome distribution channel provides a custom search engine. We
125 ListPrefUpdate
update(prefs
, prefs::kSearchProviderOverrides
);
126 update
->Swap(search_engines
.get());
129 template_url_service_
->RepairPrepopulatedSearchEngines();
131 // Reset Google search URL.
132 prefs
->ClearPref(prefs::kLastPromptedGoogleURL
);
133 const TemplateURL
* default_search_provider
=
134 template_url_service_
->GetDefaultSearchProvider();
135 if (default_search_provider
&&
136 default_search_provider
->url_ref().HasGoogleBaseURLs())
137 GoogleURLTracker::RequestServerCheck(profile_
, true);
139 MarkAsDone(DEFAULT_SEARCH_ENGINE
);
141 template_url_service_sub_
=
142 template_url_service_
->RegisterOnLoadedCallback(
143 base::Bind(&ProfileResetter::OnTemplateURLServiceLoaded
,
144 base::Unretained(this)));
145 template_url_service_
->Load();
149 void ProfileResetter::ResetHomepage() {
150 DCHECK(CalledOnValidThread());
151 PrefService
* prefs
= profile_
->GetPrefs();
153 std::string homepage
;
154 bool homepage_is_ntp
, show_home_button
;
156 if (master_settings_
->GetHomepage(&homepage
))
157 prefs
->SetString(prefs::kHomePage
, homepage
);
159 if (master_settings_
->GetHomepageIsNewTab(&homepage_is_ntp
))
160 prefs
->SetBoolean(prefs::kHomePageIsNewTabPage
, homepage_is_ntp
);
162 prefs
->ClearPref(prefs::kHomePageIsNewTabPage
);
164 if (master_settings_
->GetShowHomeButton(&show_home_button
))
165 prefs
->SetBoolean(prefs::kShowHomeButton
, show_home_button
);
167 prefs
->ClearPref(prefs::kShowHomeButton
);
168 MarkAsDone(HOMEPAGE
);
171 void ProfileResetter::ResetContentSettings() {
172 DCHECK(CalledOnValidThread());
173 PrefService
* prefs
= profile_
->GetPrefs();
174 HostContentSettingsMap
* map
= profile_
->GetHostContentSettingsMap();
176 for (int type
= 0; type
< CONTENT_SETTINGS_NUM_TYPES
; ++type
) {
177 map
->ClearSettingsForOneType(static_cast<ContentSettingsType
>(type
));
178 if (HostContentSettingsMap::IsSettingAllowedForType(
180 CONTENT_SETTING_DEFAULT
,
181 static_cast<ContentSettingsType
>(type
)))
182 map
->SetDefaultContentSetting(static_cast<ContentSettingsType
>(type
),
183 CONTENT_SETTING_DEFAULT
);
185 MarkAsDone(CONTENT_SETTINGS
);
188 void ProfileResetter::ResetCookiesAndSiteData() {
189 DCHECK(CalledOnValidThread());
190 DCHECK(!cookies_remover_
);
192 cookies_remover_
= BrowsingDataRemover::CreateForUnboundedRange(profile_
);
193 cookies_remover_
->AddObserver(this);
194 int remove_mask
= BrowsingDataRemover::REMOVE_SITE_DATA
|
195 BrowsingDataRemover::REMOVE_CACHE
;
196 PrefService
* prefs
= profile_
->GetPrefs();
198 // Don't try to clear LSO data if it's not supported.
199 if (!prefs
->GetBoolean(prefs::kClearPluginLSODataEnabled
))
200 remove_mask
&= ~BrowsingDataRemover::REMOVE_PLUGIN_DATA
;
201 cookies_remover_
->Remove(remove_mask
, BrowsingDataHelper::UNPROTECTED_WEB
);
204 void ProfileResetter::ResetExtensions() {
205 DCHECK(CalledOnValidThread());
207 std::vector
<std::string
> brandcode_extensions
;
208 master_settings_
->GetExtensions(&brandcode_extensions
);
210 ExtensionService
* extension_service
= profile_
->GetExtensionService();
211 DCHECK(extension_service
);
212 extension_service
->DisableUserExtensions(brandcode_extensions
);
214 MarkAsDone(EXTENSIONS
);
217 void ProfileResetter::ResetStartupPages() {
218 DCHECK(CalledOnValidThread());
219 PrefService
* prefs
= profile_
->GetPrefs();
221 scoped_ptr
<base::ListValue
> url_list(
222 master_settings_
->GetUrlsToRestoreOnStartup());
224 ListPrefUpdate(prefs
, prefs::kURLsToRestoreOnStartup
)->Swap(url_list
.get());
226 int restore_on_startup
;
227 if (master_settings_
->GetRestoreOnStartup(&restore_on_startup
))
228 prefs
->SetInteger(prefs::kRestoreOnStartup
, restore_on_startup
);
230 prefs
->ClearPref(prefs::kRestoreOnStartup
);
232 prefs
->SetBoolean(prefs::kRestoreOnStartupMigrated
, true);
233 MarkAsDone(STARTUP_PAGES
);
236 void ProfileResetter::ResetPinnedTabs() {
237 // Unpin all the tabs.
238 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
239 if (it
->is_type_tabbed() && it
->profile() == profile_
) {
240 TabStripModel
* tab_model
= it
->tab_strip_model();
241 // Here we assume that indexof(any mini tab) < indexof(any normal tab).
242 // If we unpin the tab, it can be moved to the right. Thus traversing in
243 // reverse direction is correct.
244 for (int i
= tab_model
->count() - 1; i
>= 0; --i
) {
245 if (tab_model
->IsTabPinned(i
) && !tab_model
->IsAppTab(i
))
246 tab_model
->SetTabPinned(i
, false);
250 MarkAsDone(PINNED_TABS
);
253 void ProfileResetter::OnTemplateURLServiceLoaded() {
254 // TemplateURLService has loaded. If we need to clean search engines, it's
256 DCHECK(CalledOnValidThread());
257 template_url_service_sub_
.reset();
258 if (pending_reset_flags_
& DEFAULT_SEARCH_ENGINE
)
259 ResetDefaultSearchEngine();
262 void ProfileResetter::OnBrowsingDataRemoverDone() {
263 cookies_remover_
= NULL
;
264 MarkAsDone(COOKIES_AND_SITE_DATA
);