Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / profile_resetter / profile_resetter.cc
blobacdecdd30e3069ec084f45a7258cf486ad73af52
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/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"
34 #if defined(OS_WIN)
35 #include "base/base_paths.h"
36 #include "base/path_service.h"
37 #include "chrome/installer/util/shell_util.h"
39 namespace {
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))
46 return;
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),
53 dist,
54 ShellUtil::CURRENT_USER,
55 chrome_exe,
56 true,
57 NULL,
58 NULL);
62 } // namespace
63 #endif // defined(OS_WIN)
65 ProfileResetter::ProfileResetter(Profile* profile)
66 : 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());
72 DCHECK(profile_);
75 ProfileResetter::~ProfileResetter() {
76 if (cookies_remover_)
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,
96 callback);
97 return;
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;
106 struct {
107 Resettable flag;
108 void (ProfileResetter::*method)();
109 } flagToMethod[] = {
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,
146 callback_);
147 callback_.Reset();
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();
160 DCHECK(prefs);
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
167 // must reset to it.
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_);
182 if (tracker)
183 tracker->RequestServerCheck(true);
186 MarkAsDone(DEFAULT_SEARCH_ENGINE);
187 } else {
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();
199 DCHECK(prefs);
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);
208 else
209 prefs->ClearPref(prefs::kHomePageIsNewTabPage);
211 if (master_settings_->GetShowHomeButton(&show_home_button))
212 prefs->SetBoolean(prefs::kShowHomeButton, show_home_button);
213 else
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();
246 DCHECK(prefs);
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();
270 DCHECK(prefs);
271 scoped_ptr<base::ListValue> url_list(
272 master_settings_->GetUrlsToRestoreOnStartup());
273 if (url_list)
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);
279 else
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() {
304 #if defined(OS_WIN)
305 content::BrowserThread::PostTaskAndReply(
306 content::BrowserThread::FILE,
307 FROM_HERE,
308 base::Bind(&ResetShortcutsOnFileThread),
309 base::Bind(&ProfileResetter::MarkAsDone,
310 weak_ptr_factory_.GetWeakPtr(),
311 SHORTCUTS));
312 #else
313 MarkAsDone(SHORTCUTS);
314 #endif
317 void ProfileResetter::OnTemplateURLServiceLoaded() {
318 // TemplateURLService has loaded. If we need to clean search engines, it's
319 // time to go on.
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);
334 #if defined(OS_WIN)
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())
345 break;
346 ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
347 static_cast<ShellUtil::ShortcutLocation>(location),
348 dist,
349 ShellUtil::CURRENT_USER,
350 chrome_exe,
351 false,
352 cancel,
353 &shortcuts);
355 return shortcuts;
356 #else
357 return std::vector<ShortcutCommand>();
358 #endif