• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/profile_resetter/profile_resetter.h"
6 
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"
25 
ProfileResetter(Profile * profile)26 ProfileResetter::ProfileResetter(Profile* profile)
27     : profile_(profile),
28       template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
29       pending_reset_flags_(0),
30       cookies_remover_(NULL) {
31   DCHECK(CalledOnValidThread());
32   DCHECK(profile_);
33 }
34 
~ProfileResetter()35 ProfileResetter::~ProfileResetter() {
36   if (cookies_remover_)
37     cookies_remover_->RemoveObserver(this);
38 }
39 
Reset(ProfileResetter::ResettableFlags resettable_flags,scoped_ptr<BrandcodedDefaultSettings> master_settings,const base::Closure & callback)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);
46 
47   // We should never be called with unknown flags.
48   CHECK_EQ(static_cast<ResettableFlags>(0), resettable_flags & ~ALL);
49 
50   // We should never be called when a previous reset has not finished.
51   CHECK_EQ(static_cast<ResettableFlags>(0), pending_reset_flags_);
52 
53   if (!resettable_flags) {
54     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
55                                      callback);
56     return;
57   }
58 
59   master_settings_.swap(master_settings);
60   callback_ = callback;
61 
62   // These flags are set to false by the individual reset functions.
63   pending_reset_flags_ = resettable_flags;
64 
65   struct {
66     Resettable flag;
67     void (ProfileResetter::*method)();
68   } flagToMethod [] = {
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 },
76   };
77 
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)();
83     }
84   }
85 
86   DCHECK_EQ(resettable_flags, reset_triggered_for_flags);
87 }
88 
IsActive() const89 bool ProfileResetter::IsActive() const {
90   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
91   return pending_reset_flags_ != 0;
92 }
93 
MarkAsDone(Resettable resettable)94 void ProfileResetter::MarkAsDone(Resettable resettable) {
95   DCHECK(CalledOnValidThread());
96 
97   // Check that we are never called twice or unexpectedly.
98   CHECK(pending_reset_flags_ & resettable);
99 
100   pending_reset_flags_ &= ~resettable;
101 
102   if (!pending_reset_flags_) {
103     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
104                                      callback_);
105     callback_.Reset();
106     master_settings_.reset();
107     template_url_service_sub_.reset();
108   }
109 }
110 
ResetDefaultSearchEngine()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();
118     DCHECK(prefs);
119     TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(profile_);
120     scoped_ptr<ListValue> search_engines(
121         master_settings_->GetSearchProviderOverrides());
122     if (search_engines) {
123       // This Chrome distribution channel provides a custom search engine. We
124       // must reset to it.
125       ListPrefUpdate update(prefs, prefs::kSearchProviderOverrides);
126       update->Swap(search_engines.get());
127     }
128 
129     template_url_service_->RepairPrepopulatedSearchEngines();
130 
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);
138 
139     MarkAsDone(DEFAULT_SEARCH_ENGINE);
140   } else {
141     template_url_service_sub_ =
142         template_url_service_->RegisterOnLoadedCallback(
143             base::Bind(&ProfileResetter::OnTemplateURLServiceLoaded,
144                        base::Unretained(this)));
145     template_url_service_->Load();
146   }
147 }
148 
ResetHomepage()149 void ProfileResetter::ResetHomepage() {
150   DCHECK(CalledOnValidThread());
151   PrefService* prefs = profile_->GetPrefs();
152   DCHECK(prefs);
153   std::string homepage;
154   bool homepage_is_ntp, show_home_button;
155 
156   if (master_settings_->GetHomepage(&homepage))
157     prefs->SetString(prefs::kHomePage, homepage);
158 
159   if (master_settings_->GetHomepageIsNewTab(&homepage_is_ntp))
160     prefs->SetBoolean(prefs::kHomePageIsNewTabPage, homepage_is_ntp);
161   else
162     prefs->ClearPref(prefs::kHomePageIsNewTabPage);
163 
164   if (master_settings_->GetShowHomeButton(&show_home_button))
165     prefs->SetBoolean(prefs::kShowHomeButton, show_home_button);
166   else
167     prefs->ClearPref(prefs::kShowHomeButton);
168   MarkAsDone(HOMEPAGE);
169 }
170 
ResetContentSettings()171 void ProfileResetter::ResetContentSettings() {
172   DCHECK(CalledOnValidThread());
173   PrefService* prefs = profile_->GetPrefs();
174   HostContentSettingsMap* map = profile_->GetHostContentSettingsMap();
175 
176   for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
177     map->ClearSettingsForOneType(static_cast<ContentSettingsType>(type));
178     if (HostContentSettingsMap::IsSettingAllowedForType(
179             prefs,
180             CONTENT_SETTING_DEFAULT,
181             static_cast<ContentSettingsType>(type)))
182       map->SetDefaultContentSetting(static_cast<ContentSettingsType>(type),
183                                     CONTENT_SETTING_DEFAULT);
184   }
185   MarkAsDone(CONTENT_SETTINGS);
186 }
187 
ResetCookiesAndSiteData()188 void ProfileResetter::ResetCookiesAndSiteData() {
189   DCHECK(CalledOnValidThread());
190   DCHECK(!cookies_remover_);
191 
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();
197   DCHECK(prefs);
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);
202 }
203 
ResetExtensions()204 void ProfileResetter::ResetExtensions() {
205   DCHECK(CalledOnValidThread());
206 
207   std::vector<std::string> brandcode_extensions;
208   master_settings_->GetExtensions(&brandcode_extensions);
209 
210   ExtensionService* extension_service = profile_->GetExtensionService();
211   DCHECK(extension_service);
212   extension_service->DisableUserExtensions(brandcode_extensions);
213 
214   MarkAsDone(EXTENSIONS);
215 }
216 
ResetStartupPages()217 void ProfileResetter::ResetStartupPages() {
218   DCHECK(CalledOnValidThread());
219   PrefService* prefs = profile_->GetPrefs();
220   DCHECK(prefs);
221   scoped_ptr<ListValue> url_list(master_settings_->GetUrlsToRestoreOnStartup());
222   if (url_list)
223     ListPrefUpdate(prefs, prefs::kURLsToRestoreOnStartup)->Swap(url_list.get());
224 
225   int restore_on_startup;
226   if (master_settings_->GetRestoreOnStartup(&restore_on_startup))
227     prefs->SetInteger(prefs::kRestoreOnStartup, restore_on_startup);
228   else
229     prefs->ClearPref(prefs::kRestoreOnStartup);
230 
231   prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
232   MarkAsDone(STARTUP_PAGES);
233 }
234 
ResetPinnedTabs()235 void ProfileResetter::ResetPinnedTabs() {
236   // Unpin all the tabs.
237   for (chrome::BrowserIterator it; !it.done(); it.Next()) {
238     if (it->is_type_tabbed() && it->profile() == profile_) {
239       TabStripModel* tab_model = it->tab_strip_model();
240       // Here we assume that indexof(any mini tab) < indexof(any normal tab).
241       // If we unpin the tab, it can be moved to the right. Thus traversing in
242       // reverse direction is correct.
243       for (int i = tab_model->count() - 1; i >= 0; --i) {
244         if (tab_model->IsTabPinned(i) && !tab_model->IsAppTab(i))
245           tab_model->SetTabPinned(i, false);
246       }
247     }
248   }
249   MarkAsDone(PINNED_TABS);
250 }
251 
OnTemplateURLServiceLoaded()252 void ProfileResetter::OnTemplateURLServiceLoaded() {
253   // TemplateURLService has loaded. If we need to clean search engines, it's
254   // time to go on.
255   DCHECK(CalledOnValidThread());
256   template_url_service_sub_.reset();
257   if (pending_reset_flags_ & DEFAULT_SEARCH_ENGINE)
258     ResetDefaultSearchEngine();
259 }
260 
OnBrowsingDataRemoverDone()261 void ProfileResetter::OnBrowsingDataRemoverDone() {
262   cookies_remover_ = NULL;
263   MarkAsDone(COOKIES_AND_SITE_DATA);
264 }
265