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"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/synchronization/cancellation_flag.h"
12 #include "chrome/browser/browsing_data/browsing_data_helper.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/google/google_url_tracker_factory.h"
15 #include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/search_engines/template_url_service_factory.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_iterator.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/installer/util/browser_distribution.h"
23 #include "components/content_settings/core/browser/host_content_settings_map.h"
24 #include "components/content_settings/core/browser/website_settings_info.h"
25 #include "components/content_settings/core/browser/website_settings_registry.h"
26 #include "components/google/core/browser/google_url_tracker.h"
27 #include "components/search_engines/search_engines_pref_names.h"
28 #include "components/search_engines/template_url_prepopulate_data.h"
29 #include "components/search_engines/template_url_service.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "extensions/browser/extension_system.h"
32 #include "extensions/browser/management_policy.h"
35 #include "base/base_paths.h"
36 #include "base/path_service.h"
37 #include "chrome/installer/util/shell_util.h"
41 void ResetShortcutsOnFileThread() {
42 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
43 // Get full path of chrome.
44 base::FilePath chrome_exe
;
45 if (!PathService::Get(base::FILE_EXE
, &chrome_exe
))
47 BrowserDistribution
* dist
= BrowserDistribution::GetSpecificDistribution(
48 BrowserDistribution::CHROME_BROWSER
);
49 for (int location
= ShellUtil::SHORTCUT_LOCATION_FIRST
;
50 location
< ShellUtil::NUM_SHORTCUT_LOCATIONS
; ++location
) {
51 ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
52 static_cast<ShellUtil::ShortcutLocation
>(location
),
54 ShellUtil::CURRENT_USER
,
63 #endif // defined(OS_WIN)
65 ProfileResetter::ProfileResetter(Profile
* profile
)
67 template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_
)),
68 pending_reset_flags_(0),
69 cookies_remover_(NULL
),
70 weak_ptr_factory_(this) {
71 DCHECK(CalledOnValidThread());
75 ProfileResetter::~ProfileResetter() {
77 cookies_remover_
->RemoveObserver(this);
80 void ProfileResetter::Reset(
81 ProfileResetter::ResettableFlags resettable_flags
,
82 scoped_ptr
<BrandcodedDefaultSettings
> master_settings
,
83 bool accepted_send_feedback
,
84 const base::Closure
& callback
) {
85 DCHECK(CalledOnValidThread());
86 DCHECK(master_settings
);
88 // We should never be called with unknown flags.
89 CHECK_EQ(static_cast<ResettableFlags
>(0), resettable_flags
& ~ALL
);
91 // We should never be called when a previous reset has not finished.
92 CHECK_EQ(static_cast<ResettableFlags
>(0), pending_reset_flags_
);
94 if (!resettable_flags
) {
95 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
100 master_settings_
.swap(master_settings
);
101 callback_
= callback
;
103 // These flags are set to false by the individual reset functions.
104 pending_reset_flags_
= resettable_flags
;
108 void (ProfileResetter::*method
)();
110 {DEFAULT_SEARCH_ENGINE
, &ProfileResetter::ResetDefaultSearchEngine
},
111 {HOMEPAGE
, &ProfileResetter::ResetHomepage
},
112 {CONTENT_SETTINGS
, &ProfileResetter::ResetContentSettings
},
113 {COOKIES_AND_SITE_DATA
, &ProfileResetter::ResetCookiesAndSiteData
},
114 {EXTENSIONS
, &ProfileResetter::ResetExtensions
},
115 {STARTUP_PAGES
, &ProfileResetter::ResetStartupPages
},
116 {PINNED_TABS
, &ProfileResetter::ResetPinnedTabs
},
117 {SHORTCUTS
, &ProfileResetter::ResetShortcuts
},
120 ResettableFlags reset_triggered_for_flags
= 0;
121 for (size_t i
= 0; i
< arraysize(flagToMethod
); ++i
) {
122 if (resettable_flags
& flagToMethod
[i
].flag
) {
123 reset_triggered_for_flags
|= flagToMethod
[i
].flag
;
124 (this->*flagToMethod
[i
].method
)();
128 DCHECK_EQ(resettable_flags
, reset_triggered_for_flags
);
131 bool ProfileResetter::IsActive() const {
132 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
133 return pending_reset_flags_
!= 0;
136 void ProfileResetter::MarkAsDone(Resettable resettable
) {
137 DCHECK(CalledOnValidThread());
139 // Check that we are never called twice or unexpectedly.
140 CHECK(pending_reset_flags_
& resettable
);
142 pending_reset_flags_
&= ~resettable
;
144 if (!pending_reset_flags_
) {
145 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
148 master_settings_
.reset();
149 template_url_service_sub_
.reset();
153 void ProfileResetter::ResetDefaultSearchEngine() {
154 DCHECK(CalledOnValidThread());
155 DCHECK(template_url_service_
);
156 // If TemplateURLServiceFactory is ready we can clean it right now.
157 // Otherwise, load it and continue from ProfileResetter::Observe.
158 if (template_url_service_
->loaded()) {
159 PrefService
* prefs
= profile_
->GetPrefs();
161 TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(
162 profile_
->GetPrefs());
163 scoped_ptr
<base::ListValue
> search_engines(
164 master_settings_
->GetSearchProviderOverrides());
165 if (search_engines
) {
166 // This Chrome distribution channel provides a custom search engine. We
168 ListPrefUpdate
update(prefs
, prefs::kSearchProviderOverrides
);
169 update
->Swap(search_engines
.get());
172 template_url_service_
->RepairPrepopulatedSearchEngines();
174 // Reset Google search URL.
175 const TemplateURL
* default_search_provider
=
176 template_url_service_
->GetDefaultSearchProvider();
177 if (default_search_provider
&&
178 default_search_provider
->HasGoogleBaseURLs(
179 template_url_service_
->search_terms_data())) {
180 GoogleURLTracker
* tracker
=
181 GoogleURLTrackerFactory::GetForProfile(profile_
);
183 tracker
->RequestServerCheck(true);
186 MarkAsDone(DEFAULT_SEARCH_ENGINE
);
188 template_url_service_sub_
=
189 template_url_service_
->RegisterOnLoadedCallback(
190 base::Bind(&ProfileResetter::OnTemplateURLServiceLoaded
,
191 weak_ptr_factory_
.GetWeakPtr()));
192 template_url_service_
->Load();
196 void ProfileResetter::ResetHomepage() {
197 DCHECK(CalledOnValidThread());
198 PrefService
* prefs
= profile_
->GetPrefs();
200 std::string homepage
;
201 bool homepage_is_ntp
, show_home_button
;
203 if (master_settings_
->GetHomepage(&homepage
))
204 prefs
->SetString(prefs::kHomePage
, homepage
);
206 if (master_settings_
->GetHomepageIsNewTab(&homepage_is_ntp
))
207 prefs
->SetBoolean(prefs::kHomePageIsNewTabPage
, homepage_is_ntp
);
209 prefs
->ClearPref(prefs::kHomePageIsNewTabPage
);
211 if (master_settings_
->GetShowHomeButton(&show_home_button
))
212 prefs
->SetBoolean(prefs::kShowHomeButton
, show_home_button
);
214 prefs
->ClearPref(prefs::kShowHomeButton
);
215 MarkAsDone(HOMEPAGE
);
218 void ProfileResetter::ResetContentSettings() {
219 DCHECK(CalledOnValidThread());
220 PrefService
* prefs
= profile_
->GetPrefs();
221 HostContentSettingsMap
* map
= profile_
->GetHostContentSettingsMap();
223 content_settings::WebsiteSettingsRegistry
* registry
=
224 content_settings::WebsiteSettingsRegistry::GetInstance();
225 for (const content_settings::WebsiteSettingsInfo
* info
: *registry
) {
226 map
->ClearSettingsForOneType(info
->type());
227 if (HostContentSettingsMap::IsSettingAllowedForType(
228 prefs
, CONTENT_SETTING_DEFAULT
, info
->type())) {
229 // TODO(raymes): Why don't we just set this to
230 // info->intial_default_value().
231 map
->SetDefaultContentSetting(info
->type(), CONTENT_SETTING_DEFAULT
);
234 MarkAsDone(CONTENT_SETTINGS
);
237 void ProfileResetter::ResetCookiesAndSiteData() {
238 DCHECK(CalledOnValidThread());
239 DCHECK(!cookies_remover_
);
241 cookies_remover_
= BrowsingDataRemover::CreateForUnboundedRange(profile_
);
242 cookies_remover_
->AddObserver(this);
243 int remove_mask
= BrowsingDataRemover::REMOVE_SITE_DATA
|
244 BrowsingDataRemover::REMOVE_CACHE
;
245 PrefService
* prefs
= profile_
->GetPrefs();
247 // Don't try to clear LSO data if it's not supported.
248 if (!prefs
->GetBoolean(prefs::kClearPluginLSODataEnabled
))
249 remove_mask
&= ~BrowsingDataRemover::REMOVE_PLUGIN_DATA
;
250 cookies_remover_
->Remove(remove_mask
, BrowsingDataHelper::UNPROTECTED_WEB
);
253 void ProfileResetter::ResetExtensions() {
254 DCHECK(CalledOnValidThread());
256 std::vector
<std::string
> brandcode_extensions
;
257 master_settings_
->GetExtensions(&brandcode_extensions
);
259 ExtensionService
* extension_service
=
260 extensions::ExtensionSystem::Get(profile_
)->extension_service();
261 DCHECK(extension_service
);
262 extension_service
->DisableUserExtensions(brandcode_extensions
);
264 MarkAsDone(EXTENSIONS
);
267 void ProfileResetter::ResetStartupPages() {
268 DCHECK(CalledOnValidThread());
269 PrefService
* prefs
= profile_
->GetPrefs();
271 scoped_ptr
<base::ListValue
> url_list(
272 master_settings_
->GetUrlsToRestoreOnStartup());
274 ListPrefUpdate(prefs
, prefs::kURLsToRestoreOnStartup
)->Swap(url_list
.get());
276 int restore_on_startup
;
277 if (master_settings_
->GetRestoreOnStartup(&restore_on_startup
))
278 prefs
->SetInteger(prefs::kRestoreOnStartup
, restore_on_startup
);
280 prefs
->ClearPref(prefs::kRestoreOnStartup
);
282 prefs
->SetBoolean(prefs::kRestoreOnStartupMigrated
, true);
283 MarkAsDone(STARTUP_PAGES
);
286 void ProfileResetter::ResetPinnedTabs() {
287 // Unpin all the tabs.
288 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
289 if (it
->is_type_tabbed() && it
->profile() == profile_
) {
290 TabStripModel
* tab_model
= it
->tab_strip_model();
291 // Here we assume that indexof(any mini tab) < indexof(any normal tab).
292 // If we unpin the tab, it can be moved to the right. Thus traversing in
293 // reverse direction is correct.
294 for (int i
= tab_model
->count() - 1; i
>= 0; --i
) {
295 if (tab_model
->IsTabPinned(i
))
296 tab_model
->SetTabPinned(i
, false);
300 MarkAsDone(PINNED_TABS
);
303 void ProfileResetter::ResetShortcuts() {
305 content::BrowserThread::PostTaskAndReply(
306 content::BrowserThread::FILE,
308 base::Bind(&ResetShortcutsOnFileThread
),
309 base::Bind(&ProfileResetter::MarkAsDone
,
310 weak_ptr_factory_
.GetWeakPtr(),
313 MarkAsDone(SHORTCUTS
);
317 void ProfileResetter::OnTemplateURLServiceLoaded() {
318 // TemplateURLService has loaded. If we need to clean search engines, it's
320 DCHECK(CalledOnValidThread());
321 template_url_service_sub_
.reset();
322 if (pending_reset_flags_
& DEFAULT_SEARCH_ENGINE
)
323 ResetDefaultSearchEngine();
326 void ProfileResetter::OnBrowsingDataRemoverDone() {
327 cookies_remover_
= NULL
;
328 MarkAsDone(COOKIES_AND_SITE_DATA
);
331 std::vector
<ShortcutCommand
> GetChromeLaunchShortcuts(
332 const scoped_refptr
<SharedCancellationFlag
>& cancel
) {
333 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
335 // Get full path of chrome.
336 base::FilePath chrome_exe
;
337 if (!PathService::Get(base::FILE_EXE
, &chrome_exe
))
338 return std::vector
<ShortcutCommand
>();
339 BrowserDistribution
* dist
= BrowserDistribution::GetSpecificDistribution(
340 BrowserDistribution::CHROME_BROWSER
);
341 std::vector
<ShortcutCommand
> shortcuts
;
342 for (int location
= ShellUtil::SHORTCUT_LOCATION_FIRST
;
343 location
< ShellUtil::NUM_SHORTCUT_LOCATIONS
; ++location
) {
344 if (cancel
.get() && cancel
->data
.IsSet())
346 ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
347 static_cast<ShellUtil::ShortcutLocation
>(location
),
349 ShellUtil::CURRENT_USER
,
357 return std::vector
<ShortcutCommand
>();