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"
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"
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
) {
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
) {
49 for (size_t i
= 0; i
< url_list
->GetSize(); ++i
) {
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
);
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);
75 SessionStartupPref::Type
SessionStartupPref::GetDefaultStartupType() {
76 #if defined(OS_CHROMEOS)
77 return SessionStartupPref::LAST
;
79 return SessionStartupPref::DEFAULT
;
84 void SessionStartupPref::SetStartupPref(
86 const SessionStartupPref
& pref
) {
88 SetStartupPref(profile
->GetPrefs(), pref
);
92 void SessionStartupPref::SetStartupPref(PrefService
* prefs
,
93 const SessionStartupPref
& pref
) {
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()));
115 SessionStartupPref
SessionStartupPref::GetStartupPref(Profile
* profile
) {
117 return GetStartupPref(profile
->GetPrefs());
121 SessionStartupPref
SessionStartupPref::GetStartupPref(PrefService
* 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
);
139 void SessionStartupPref::MigrateIfNecessary(PrefService
* 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),
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",
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
))
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
))
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
);
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);
235 bool SessionStartupPref::TypeIsManaged(PrefService
* prefs
) {
237 const PrefService::Preference
* pref_restore
=
238 prefs
->FindPreference(prefs::kRestoreOnStartup
);
239 DCHECK(pref_restore
);
240 return pref_restore
->IsManaged();
244 bool SessionStartupPref::URLsAreManaged(PrefService
* prefs
) {
246 const PrefService::Preference
* pref_urls
=
247 prefs
->FindPreference(prefs::kURLsToRestoreOnStartup
);
249 return pref_urls
->IsManaged();
253 bool SessionStartupPref::TypeIsDefault(PrefService
* prefs
) {
255 const PrefService::Preference
* pref_restore
=
256 prefs
->FindPreference(prefs::kRestoreOnStartup
);
257 DCHECK(pref_restore
);
258 return pref_restore
->IsDefaultValue();
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() {}