Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / profile_resetter / profile_resetter.cc
blobee0573fcebe534f9bfed0153691800eb05b42b5b
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 <string>
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/google/core/browser/google_url_tracker.h"
25 #include "components/search_engines/search_engines_pref_names.h"
26 #include "components/search_engines/template_url_prepopulate_data.h"
27 #include "components/search_engines/template_url_service.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "extensions/browser/extension_system.h"
30 #include "extensions/browser/management_policy.h"
32 #if defined(OS_WIN)
33 #include "base/base_paths.h"
34 #include "base/path_service.h"
35 #include "chrome/installer/util/shell_util.h"
37 namespace {
39 void ResetShortcutsOnFileThread() {
40 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
41 // Get full path of chrome.
42 base::FilePath chrome_exe;
43 if (!PathService::Get(base::FILE_EXE, &chrome_exe))
44 return;
45 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
46 BrowserDistribution::CHROME_BROWSER);
47 for (int location = ShellUtil::SHORTCUT_LOCATION_FIRST;
48 location < ShellUtil::NUM_SHORTCUT_LOCATIONS; ++location) {
49 ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
50 static_cast<ShellUtil::ShortcutLocation>(location),
51 dist,
52 ShellUtil::CURRENT_USER,
53 chrome_exe,
54 true,
55 NULL,
56 NULL);
60 } // namespace
61 #endif // defined(OS_WIN)
63 ProfileResetter::ProfileResetter(Profile* profile)
64 : profile_(profile),
65 template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
66 pending_reset_flags_(0),
67 cookies_remover_(NULL),
68 weak_ptr_factory_(this) {
69 DCHECK(CalledOnValidThread());
70 DCHECK(profile_);
73 ProfileResetter::~ProfileResetter() {
74 if (cookies_remover_)
75 cookies_remover_->RemoveObserver(this);
78 void ProfileResetter::Reset(
79 ProfileResetter::ResettableFlags resettable_flags,
80 scoped_ptr<BrandcodedDefaultSettings> master_settings,
81 bool accepted_send_feedback,
82 const base::Closure& callback) {
83 DCHECK(CalledOnValidThread());
84 DCHECK(master_settings);
86 // We should never be called with unknown flags.
87 CHECK_EQ(static_cast<ResettableFlags>(0), resettable_flags & ~ALL);
89 // We should never be called when a previous reset has not finished.
90 CHECK_EQ(static_cast<ResettableFlags>(0), pending_reset_flags_);
92 if (!resettable_flags) {
93 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
94 callback);
95 return;
98 master_settings_.swap(master_settings);
99 callback_ = callback;
101 // These flags are set to false by the individual reset functions.
102 pending_reset_flags_ = resettable_flags;
104 struct {
105 Resettable flag;
106 void (ProfileResetter::*method)();
107 } flagToMethod[] = {
108 {DEFAULT_SEARCH_ENGINE, &ProfileResetter::ResetDefaultSearchEngine},
109 {HOMEPAGE, &ProfileResetter::ResetHomepage},
110 {CONTENT_SETTINGS, &ProfileResetter::ResetContentSettings},
111 {COOKIES_AND_SITE_DATA, &ProfileResetter::ResetCookiesAndSiteData},
112 {EXTENSIONS, &ProfileResetter::ResetExtensions},
113 {STARTUP_PAGES, &ProfileResetter::ResetStartupPages},
114 {PINNED_TABS, &ProfileResetter::ResetPinnedTabs},
115 {SHORTCUTS, &ProfileResetter::ResetShortcuts},
118 ResettableFlags reset_triggered_for_flags = 0;
119 for (size_t i = 0; i < arraysize(flagToMethod); ++i) {
120 if (resettable_flags & flagToMethod[i].flag) {
121 reset_triggered_for_flags |= flagToMethod[i].flag;
122 (this->*flagToMethod[i].method)();
126 DCHECK_EQ(resettable_flags, reset_triggered_for_flags);
129 bool ProfileResetter::IsActive() const {
130 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
131 return pending_reset_flags_ != 0;
134 void ProfileResetter::MarkAsDone(Resettable resettable) {
135 DCHECK(CalledOnValidThread());
137 // Check that we are never called twice or unexpectedly.
138 CHECK(pending_reset_flags_ & resettable);
140 pending_reset_flags_ &= ~resettable;
142 if (!pending_reset_flags_) {
143 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
144 callback_);
145 callback_.Reset();
146 master_settings_.reset();
147 template_url_service_sub_.reset();
151 void ProfileResetter::ResetDefaultSearchEngine() {
152 DCHECK(CalledOnValidThread());
153 DCHECK(template_url_service_);
154 // If TemplateURLServiceFactory is ready we can clean it right now.
155 // Otherwise, load it and continue from ProfileResetter::Observe.
156 if (template_url_service_->loaded()) {
157 PrefService* prefs = profile_->GetPrefs();
158 DCHECK(prefs);
159 TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(
160 profile_->GetPrefs());
161 scoped_ptr<base::ListValue> search_engines(
162 master_settings_->GetSearchProviderOverrides());
163 if (search_engines) {
164 // This Chrome distribution channel provides a custom search engine. We
165 // must reset to it.
166 ListPrefUpdate update(prefs, prefs::kSearchProviderOverrides);
167 update->Swap(search_engines.get());
170 template_url_service_->RepairPrepopulatedSearchEngines();
172 // Reset Google search URL.
173 const TemplateURL* default_search_provider =
174 template_url_service_->GetDefaultSearchProvider();
175 if (default_search_provider &&
176 default_search_provider->HasGoogleBaseURLs(
177 template_url_service_->search_terms_data())) {
178 GoogleURLTracker* tracker =
179 GoogleURLTrackerFactory::GetForProfile(profile_);
180 if (tracker)
181 tracker->RequestServerCheck(true);
184 MarkAsDone(DEFAULT_SEARCH_ENGINE);
185 } else {
186 template_url_service_sub_ =
187 template_url_service_->RegisterOnLoadedCallback(
188 base::Bind(&ProfileResetter::OnTemplateURLServiceLoaded,
189 weak_ptr_factory_.GetWeakPtr()));
190 template_url_service_->Load();
194 void ProfileResetter::ResetHomepage() {
195 DCHECK(CalledOnValidThread());
196 PrefService* prefs = profile_->GetPrefs();
197 DCHECK(prefs);
198 std::string homepage;
199 bool homepage_is_ntp, show_home_button;
201 if (master_settings_->GetHomepage(&homepage))
202 prefs->SetString(prefs::kHomePage, homepage);
204 if (master_settings_->GetHomepageIsNewTab(&homepage_is_ntp))
205 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, homepage_is_ntp);
206 else
207 prefs->ClearPref(prefs::kHomePageIsNewTabPage);
209 if (master_settings_->GetShowHomeButton(&show_home_button))
210 prefs->SetBoolean(prefs::kShowHomeButton, show_home_button);
211 else
212 prefs->ClearPref(prefs::kShowHomeButton);
213 MarkAsDone(HOMEPAGE);
216 void ProfileResetter::ResetContentSettings() {
217 DCHECK(CalledOnValidThread());
218 PrefService* prefs = profile_->GetPrefs();
219 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap();
221 for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
222 map->ClearSettingsForOneType(static_cast<ContentSettingsType>(type));
223 if (HostContentSettingsMap::IsSettingAllowedForType(
224 prefs,
225 CONTENT_SETTING_DEFAULT,
226 static_cast<ContentSettingsType>(type)))
227 map->SetDefaultContentSetting(static_cast<ContentSettingsType>(type),
228 CONTENT_SETTING_DEFAULT);
230 MarkAsDone(CONTENT_SETTINGS);
233 void ProfileResetter::ResetCookiesAndSiteData() {
234 DCHECK(CalledOnValidThread());
235 DCHECK(!cookies_remover_);
237 cookies_remover_ = BrowsingDataRemover::CreateForUnboundedRange(profile_);
238 cookies_remover_->AddObserver(this);
239 int remove_mask = BrowsingDataRemover::REMOVE_SITE_DATA |
240 BrowsingDataRemover::REMOVE_CACHE;
241 PrefService* prefs = profile_->GetPrefs();
242 DCHECK(prefs);
243 // Don't try to clear LSO data if it's not supported.
244 if (!prefs->GetBoolean(prefs::kClearPluginLSODataEnabled))
245 remove_mask &= ~BrowsingDataRemover::REMOVE_PLUGIN_DATA;
246 cookies_remover_->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
249 void ProfileResetter::ResetExtensions() {
250 DCHECK(CalledOnValidThread());
252 std::vector<std::string> brandcode_extensions;
253 master_settings_->GetExtensions(&brandcode_extensions);
255 ExtensionService* extension_service =
256 extensions::ExtensionSystem::Get(profile_)->extension_service();
257 DCHECK(extension_service);
258 extension_service->DisableUserExtensions(brandcode_extensions);
260 MarkAsDone(EXTENSIONS);
263 void ProfileResetter::ResetStartupPages() {
264 DCHECK(CalledOnValidThread());
265 PrefService* prefs = profile_->GetPrefs();
266 DCHECK(prefs);
267 scoped_ptr<base::ListValue> url_list(
268 master_settings_->GetUrlsToRestoreOnStartup());
269 if (url_list)
270 ListPrefUpdate(prefs, prefs::kURLsToRestoreOnStartup)->Swap(url_list.get());
272 int restore_on_startup;
273 if (master_settings_->GetRestoreOnStartup(&restore_on_startup))
274 prefs->SetInteger(prefs::kRestoreOnStartup, restore_on_startup);
275 else
276 prefs->ClearPref(prefs::kRestoreOnStartup);
278 prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
279 MarkAsDone(STARTUP_PAGES);
282 void ProfileResetter::ResetPinnedTabs() {
283 // Unpin all the tabs.
284 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
285 if (it->is_type_tabbed() && it->profile() == profile_) {
286 TabStripModel* tab_model = it->tab_strip_model();
287 // Here we assume that indexof(any mini tab) < indexof(any normal tab).
288 // If we unpin the tab, it can be moved to the right. Thus traversing in
289 // reverse direction is correct.
290 for (int i = tab_model->count() - 1; i >= 0; --i) {
291 if (tab_model->IsTabPinned(i))
292 tab_model->SetTabPinned(i, false);
296 MarkAsDone(PINNED_TABS);
299 void ProfileResetter::ResetShortcuts() {
300 #if defined(OS_WIN)
301 content::BrowserThread::PostTaskAndReply(
302 content::BrowserThread::FILE,
303 FROM_HERE,
304 base::Bind(&ResetShortcutsOnFileThread),
305 base::Bind(&ProfileResetter::MarkAsDone,
306 weak_ptr_factory_.GetWeakPtr(),
307 SHORTCUTS));
308 #else
309 MarkAsDone(SHORTCUTS);
310 #endif
313 void ProfileResetter::OnTemplateURLServiceLoaded() {
314 // TemplateURLService has loaded. If we need to clean search engines, it's
315 // time to go on.
316 DCHECK(CalledOnValidThread());
317 template_url_service_sub_.reset();
318 if (pending_reset_flags_ & DEFAULT_SEARCH_ENGINE)
319 ResetDefaultSearchEngine();
322 void ProfileResetter::OnBrowsingDataRemoverDone() {
323 cookies_remover_ = NULL;
324 MarkAsDone(COOKIES_AND_SITE_DATA);
327 std::vector<ShortcutCommand> GetChromeLaunchShortcuts(
328 const scoped_refptr<SharedCancellationFlag>& cancel) {
329 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
330 #if defined(OS_WIN)
331 // Get full path of chrome.
332 base::FilePath chrome_exe;
333 if (!PathService::Get(base::FILE_EXE, &chrome_exe))
334 return std::vector<ShortcutCommand>();
335 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
336 BrowserDistribution::CHROME_BROWSER);
337 std::vector<ShortcutCommand> shortcuts;
338 for (int location = ShellUtil::SHORTCUT_LOCATION_FIRST;
339 location < ShellUtil::NUM_SHORTCUT_LOCATIONS; ++location) {
340 if (cancel.get() && cancel->data.IsSet())
341 break;
342 ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
343 static_cast<ShellUtil::ShortcutLocation>(location),
344 dist,
345 ShellUtil::CURRENT_USER,
346 chrome_exe,
347 false,
348 cancel,
349 &shortcuts);
351 return shortcuts;
352 #else
353 return std::vector<ShortcutCommand>();
354 #endif