Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / prefs / session_startup_pref.cc
blob3af7469fbdc2037b28fa38d89b62169a4191051e
1 // Copyright (c) 2012 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/prefs/session_startup_pref.h"
7 #include <string>
9 #include "base/metrics/histogram.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/time/time.h"
13 #include "base/values.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/pref_registry/pref_registry_syncable.h"
17 #include "components/url_formatter/url_fixer.h"
19 namespace {
21 enum StartupURLsMigrationMetrics {
22 STARTUP_URLS_MIGRATION_METRICS_PERFORMED,
23 STARTUP_URLS_MIGRATION_METRICS_NOT_PRESENT,
24 STARTUP_URLS_MIGRATION_METRICS_RESET,
25 STARTUP_URLS_MIGRATION_METRICS_MAX,
28 // Converts a SessionStartupPref::Type to an integer written to prefs.
29 int TypeToPrefValue(SessionStartupPref::Type type) {
30 switch (type) {
31 case SessionStartupPref::LAST: return SessionStartupPref::kPrefValueLast;
32 case SessionStartupPref::URLS: return SessionStartupPref::kPrefValueURLs;
33 default: return SessionStartupPref::kPrefValueNewTab;
37 void SetNewURLList(PrefService* prefs) {
38 if (prefs->IsUserModifiablePreference(prefs::kURLsToRestoreOnStartup)) {
39 base::ListValue new_url_pref_list;
40 base::StringValue* home_page =
41 new base::StringValue(prefs->GetString(prefs::kHomePage));
42 new_url_pref_list.Append(home_page);
43 prefs->Set(prefs::kURLsToRestoreOnStartup, new_url_pref_list);
47 void URLListToPref(const base::ListValue* url_list, SessionStartupPref* pref) {
48 pref->urls.clear();
49 for (size_t i = 0; i < url_list->GetSize(); ++i) {
50 std::string url_text;
51 if (url_list->GetString(i, &url_text)) {
52 GURL fixed_url = url_formatter::FixupURL(url_text, std::string());
53 pref->urls.push_back(fixed_url);
58 } // namespace
60 // static
61 void SessionStartupPref::RegisterProfilePrefs(
62 user_prefs::PrefRegistrySyncable* registry) {
63 registry->RegisterIntegerPref(
64 prefs::kRestoreOnStartup,
65 TypeToPrefValue(GetDefaultStartupType()),
66 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
67 registry->RegisterListPref(prefs::kURLsToRestoreOnStartup,
68 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
69 registry->RegisterListPref(prefs::kURLsToRestoreOnStartupOld);
70 registry->RegisterBooleanPref(prefs::kRestoreOnStartupMigrated, false);
71 registry->RegisterInt64Pref(prefs::kRestoreStartupURLsMigrationTime, false);
74 // static
75 SessionStartupPref::Type SessionStartupPref::GetDefaultStartupType() {
76 #if defined(OS_CHROMEOS)
77 return SessionStartupPref::LAST;
78 #else
79 return SessionStartupPref::DEFAULT;
80 #endif
83 // static
84 void SessionStartupPref::SetStartupPref(
85 Profile* profile,
86 const SessionStartupPref& pref) {
87 DCHECK(profile);
88 SetStartupPref(profile->GetPrefs(), pref);
91 // static
92 void SessionStartupPref::SetStartupPref(PrefService* prefs,
93 const SessionStartupPref& pref) {
94 DCHECK(prefs);
96 if (!SessionStartupPref::TypeIsManaged(prefs))
97 prefs->SetInteger(prefs::kRestoreOnStartup, TypeToPrefValue(pref.type));
99 if (!SessionStartupPref::URLsAreManaged(prefs)) {
100 // Always save the URLs, that way the UI can remain consistent even if the
101 // user changes the startup type pref.
102 // Ownership of the ListValue retains with the pref service.
103 ListPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
104 base::ListValue* url_pref_list = update.Get();
105 DCHECK(url_pref_list);
106 url_pref_list->Clear();
107 for (size_t i = 0; i < pref.urls.size(); ++i) {
108 url_pref_list->Set(static_cast<int>(i),
109 new base::StringValue(pref.urls[i].spec()));
114 // static
115 SessionStartupPref SessionStartupPref::GetStartupPref(Profile* profile) {
116 DCHECK(profile);
117 return GetStartupPref(profile->GetPrefs());
120 // static
121 SessionStartupPref SessionStartupPref::GetStartupPref(PrefService* prefs) {
122 DCHECK(prefs);
124 MigrateIfNecessary(prefs);
126 SessionStartupPref pref(
127 PrefValueToType(prefs->GetInteger(prefs::kRestoreOnStartup)));
129 // Always load the urls, even if the pref type isn't URLS. This way the
130 // preferences panels can show the user their last choice.
131 const base::ListValue* url_list =
132 prefs->GetList(prefs::kURLsToRestoreOnStartup);
133 URLListToPref(url_list, &pref);
135 return pref;
138 // static
139 void SessionStartupPref::MigrateIfNecessary(PrefService* prefs) {
140 DCHECK(prefs);
142 // Check if we need to migrate the old version of the startup URLs preference
143 // to the new name, and also send metrics about the migration.
144 StartupURLsMigrationMetrics metrics_result =
145 STARTUP_URLS_MIGRATION_METRICS_MAX;
146 const base::ListValue* old_startup_urls =
147 prefs->GetList(prefs::kURLsToRestoreOnStartupOld);
148 if (!prefs->GetUserPrefValue(prefs::kRestoreStartupURLsMigrationTime)) {
149 // Record the absence of the migration timestamp, this will get overwritten
150 // below if migration occurs now.
151 metrics_result = STARTUP_URLS_MIGRATION_METRICS_NOT_PRESENT;
153 // Seems like we never migrated, do it if necessary.
154 if (!prefs->GetUserPrefValue(prefs::kURLsToRestoreOnStartup)) {
155 if (old_startup_urls && !old_startup_urls->empty()) {
156 prefs->Set(prefs::kURLsToRestoreOnStartup, *old_startup_urls);
157 prefs->ClearPref(prefs::kURLsToRestoreOnStartupOld);
159 metrics_result = STARTUP_URLS_MIGRATION_METRICS_PERFORMED;
162 prefs->SetInt64(prefs::kRestoreStartupURLsMigrationTime,
163 base::Time::Now().ToInternalValue());
164 } else if (old_startup_urls && !old_startup_urls->empty()) {
165 // Migration needs to be reset.
166 prefs->ClearPref(prefs::kURLsToRestoreOnStartupOld);
167 base::Time last_migration_time = base::Time::FromInternalValue(
168 prefs->GetInt64(prefs::kRestoreStartupURLsMigrationTime));
169 base::Time now = base::Time::Now();
170 prefs->SetInt64(prefs::kRestoreStartupURLsMigrationTime,
171 now.ToInternalValue());
172 if (now < last_migration_time)
173 last_migration_time = now;
174 UMA_HISTOGRAM_CUSTOM_TIMES("Settings.StartupURLsResetTime",
175 now - last_migration_time,
176 base::TimeDelta::FromDays(0),
177 base::TimeDelta::FromDays(7),
178 50);
179 metrics_result = STARTUP_URLS_MIGRATION_METRICS_RESET;
182 // Record a metric migration event if something interesting happened.
183 if (metrics_result != STARTUP_URLS_MIGRATION_METRICS_MAX) {
184 UMA_HISTOGRAM_ENUMERATION(
185 "Settings.StartupURLsMigration",
186 metrics_result,
187 STARTUP_URLS_MIGRATION_METRICS_MAX);
190 if (!prefs->GetBoolean(prefs::kRestoreOnStartupMigrated)) {
191 // Read existing values.
192 const base::Value* homepage_is_new_tab_page_value =
193 prefs->GetUserPrefValue(prefs::kHomePageIsNewTabPage);
194 bool homepage_is_new_tab_page = true;
195 if (homepage_is_new_tab_page_value) {
196 if (!homepage_is_new_tab_page_value->GetAsBoolean(
197 &homepage_is_new_tab_page))
198 NOTREACHED();
201 const base::Value* restore_on_startup_value =
202 prefs->GetUserPrefValue(prefs::kRestoreOnStartup);
203 int restore_on_startup = -1;
204 if (restore_on_startup_value) {
205 if (!restore_on_startup_value->GetAsInteger(&restore_on_startup))
206 NOTREACHED();
209 // If restore_on_startup has the deprecated value kPrefValueHomePage,
210 // migrate it to open the homepage on startup. If 'homepage is NTP' is set,
211 // that means just opening the NTP. If not, it means opening a one-item URL
212 // list containing the homepage.
213 if (restore_on_startup == kPrefValueHomePage) {
214 if (homepage_is_new_tab_page) {
215 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueNewTab);
216 } else {
217 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueURLs);
218 SetNewURLList(prefs);
220 } else if (!restore_on_startup_value && !homepage_is_new_tab_page &&
221 GetDefaultStartupType() == DEFAULT) {
222 // kRestoreOnStartup was never set by the user, but the homepage was set.
223 // Migrate to the list of URLs. (If restore_on_startup was never set,
224 // and homepage_is_new_tab_page is true, no action is needed. The new
225 // default value is "open the new tab page" which is what we want.)
226 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueURLs);
227 SetNewURLList(prefs);
230 prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
234 // static
235 bool SessionStartupPref::TypeIsManaged(PrefService* prefs) {
236 DCHECK(prefs);
237 const PrefService::Preference* pref_restore =
238 prefs->FindPreference(prefs::kRestoreOnStartup);
239 DCHECK(pref_restore);
240 return pref_restore->IsManaged();
243 // static
244 bool SessionStartupPref::URLsAreManaged(PrefService* prefs) {
245 DCHECK(prefs);
246 const PrefService::Preference* pref_urls =
247 prefs->FindPreference(prefs::kURLsToRestoreOnStartup);
248 DCHECK(pref_urls);
249 return pref_urls->IsManaged();
252 // static
253 bool SessionStartupPref::TypeIsDefault(PrefService* prefs) {
254 DCHECK(prefs);
255 const PrefService::Preference* pref_restore =
256 prefs->FindPreference(prefs::kRestoreOnStartup);
257 DCHECK(pref_restore);
258 return pref_restore->IsDefaultValue();
261 // static
262 SessionStartupPref::Type SessionStartupPref::PrefValueToType(int pref_value) {
263 switch (pref_value) {
264 case kPrefValueLast: return SessionStartupPref::LAST;
265 case kPrefValueURLs: return SessionStartupPref::URLS;
266 case kPrefValueHomePage: return SessionStartupPref::HOMEPAGE;
267 default: return SessionStartupPref::DEFAULT;
271 SessionStartupPref::SessionStartupPref(Type type) : type(type) {}
273 SessionStartupPref::~SessionStartupPref() {}