Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / prefs / session_startup_pref.cc
blob996adc846a2ccee6481fb50a8a40fb66070b2adc
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 "base/version.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "components/url_fixer/url_fixer.h"
20 #if defined(OS_MACOSX)
21 #include "chrome/browser/ui/cocoa/window_restore_utils.h"
22 #endif
24 namespace {
26 enum StartupURLsMigrationMetrics {
27 STARTUP_URLS_MIGRATION_METRICS_PERFORMED,
28 STARTUP_URLS_MIGRATION_METRICS_NOT_PRESENT,
29 STARTUP_URLS_MIGRATION_METRICS_RESET,
30 STARTUP_URLS_MIGRATION_METRICS_MAX,
33 // Converts a SessionStartupPref::Type to an integer written to prefs.
34 int TypeToPrefValue(SessionStartupPref::Type type) {
35 switch (type) {
36 case SessionStartupPref::LAST: return SessionStartupPref::kPrefValueLast;
37 case SessionStartupPref::URLS: return SessionStartupPref::kPrefValueURLs;
38 default: return SessionStartupPref::kPrefValueNewTab;
42 void SetNewURLList(PrefService* prefs) {
43 if (prefs->IsUserModifiablePreference(prefs::kURLsToRestoreOnStartup)) {
44 base::ListValue new_url_pref_list;
45 base::StringValue* home_page =
46 new base::StringValue(prefs->GetString(prefs::kHomePage));
47 new_url_pref_list.Append(home_page);
48 prefs->Set(prefs::kURLsToRestoreOnStartup, new_url_pref_list);
52 void URLListToPref(const base::ListValue* url_list, SessionStartupPref* pref) {
53 pref->urls.clear();
54 for (size_t i = 0; i < url_list->GetSize(); ++i) {
55 std::string url_text;
56 if (url_list->GetString(i, &url_text)) {
57 GURL fixed_url = url_fixer::FixupURL(url_text, std::string());
58 pref->urls.push_back(fixed_url);
63 } // namespace
65 // static
66 void SessionStartupPref::RegisterProfilePrefs(
67 user_prefs::PrefRegistrySyncable* registry) {
68 registry->RegisterIntegerPref(
69 prefs::kRestoreOnStartup,
70 TypeToPrefValue(GetDefaultStartupType()),
71 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
72 registry->RegisterListPref(prefs::kURLsToRestoreOnStartup,
73 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
74 registry->RegisterListPref(prefs::kURLsToRestoreOnStartupOld);
75 registry->RegisterBooleanPref(prefs::kRestoreOnStartupMigrated, false);
76 registry->RegisterInt64Pref(prefs::kRestoreStartupURLsMigrationTime, false);
79 // static
80 SessionStartupPref::Type SessionStartupPref::GetDefaultStartupType() {
81 #if defined(OS_CHROMEOS)
82 return SessionStartupPref::LAST;
83 #else
84 return SessionStartupPref::DEFAULT;
85 #endif
88 // static
89 void SessionStartupPref::SetStartupPref(
90 Profile* profile,
91 const SessionStartupPref& pref) {
92 DCHECK(profile);
93 SetStartupPref(profile->GetPrefs(), pref);
96 // static
97 void SessionStartupPref::SetStartupPref(PrefService* prefs,
98 const SessionStartupPref& pref) {
99 DCHECK(prefs);
101 if (!SessionStartupPref::TypeIsManaged(prefs))
102 prefs->SetInteger(prefs::kRestoreOnStartup, TypeToPrefValue(pref.type));
104 if (!SessionStartupPref::URLsAreManaged(prefs)) {
105 // Always save the URLs, that way the UI can remain consistent even if the
106 // user changes the startup type pref.
107 // Ownership of the ListValue retains with the pref service.
108 ListPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
109 base::ListValue* url_pref_list = update.Get();
110 DCHECK(url_pref_list);
111 url_pref_list->Clear();
112 for (size_t i = 0; i < pref.urls.size(); ++i) {
113 url_pref_list->Set(static_cast<int>(i),
114 new base::StringValue(pref.urls[i].spec()));
119 // static
120 SessionStartupPref SessionStartupPref::GetStartupPref(Profile* profile) {
121 DCHECK(profile);
122 return GetStartupPref(profile->GetPrefs());
125 // static
126 SessionStartupPref SessionStartupPref::GetStartupPref(PrefService* prefs) {
127 DCHECK(prefs);
129 MigrateIfNecessary(prefs);
130 MigrateMacDefaultPrefIfNecessary(prefs);
132 SessionStartupPref pref(
133 PrefValueToType(prefs->GetInteger(prefs::kRestoreOnStartup)));
135 // Always load the urls, even if the pref type isn't URLS. This way the
136 // preferences panels can show the user their last choice.
137 const base::ListValue* url_list =
138 prefs->GetList(prefs::kURLsToRestoreOnStartup);
139 URLListToPref(url_list, &pref);
141 return pref;
144 // static
145 void SessionStartupPref::MigrateIfNecessary(PrefService* prefs) {
146 DCHECK(prefs);
148 // Check if we need to migrate the old version of the startup URLs preference
149 // to the new name, and also send metrics about the migration.
150 StartupURLsMigrationMetrics metrics_result =
151 STARTUP_URLS_MIGRATION_METRICS_MAX;
152 const base::ListValue* old_startup_urls =
153 prefs->GetList(prefs::kURLsToRestoreOnStartupOld);
154 if (!prefs->GetUserPrefValue(prefs::kRestoreStartupURLsMigrationTime)) {
155 // Record the absence of the migration timestamp, this will get overwritten
156 // below if migration occurs now.
157 metrics_result = STARTUP_URLS_MIGRATION_METRICS_NOT_PRESENT;
159 // Seems like we never migrated, do it if necessary.
160 if (!prefs->GetUserPrefValue(prefs::kURLsToRestoreOnStartup)) {
161 if (old_startup_urls && !old_startup_urls->empty()) {
162 prefs->Set(prefs::kURLsToRestoreOnStartup, *old_startup_urls);
163 prefs->ClearPref(prefs::kURLsToRestoreOnStartupOld);
165 metrics_result = STARTUP_URLS_MIGRATION_METRICS_PERFORMED;
168 prefs->SetInt64(prefs::kRestoreStartupURLsMigrationTime,
169 base::Time::Now().ToInternalValue());
170 } else if (old_startup_urls && !old_startup_urls->empty()) {
171 // Migration needs to be reset.
172 prefs->ClearPref(prefs::kURLsToRestoreOnStartupOld);
173 base::Time last_migration_time = base::Time::FromInternalValue(
174 prefs->GetInt64(prefs::kRestoreStartupURLsMigrationTime));
175 base::Time now = base::Time::Now();
176 prefs->SetInt64(prefs::kRestoreStartupURLsMigrationTime,
177 now.ToInternalValue());
178 if (now < last_migration_time)
179 last_migration_time = now;
180 UMA_HISTOGRAM_CUSTOM_TIMES("Settings.StartupURLsResetTime",
181 now - last_migration_time,
182 base::TimeDelta::FromDays(0),
183 base::TimeDelta::FromDays(7),
184 50);
185 metrics_result = STARTUP_URLS_MIGRATION_METRICS_RESET;
188 // Record a metric migration event if something interesting happened.
189 if (metrics_result != STARTUP_URLS_MIGRATION_METRICS_MAX) {
190 UMA_HISTOGRAM_ENUMERATION(
191 "Settings.StartupURLsMigration",
192 metrics_result,
193 STARTUP_URLS_MIGRATION_METRICS_MAX);
196 if (!prefs->GetBoolean(prefs::kRestoreOnStartupMigrated)) {
197 // Read existing values.
198 const base::Value* homepage_is_new_tab_page_value =
199 prefs->GetUserPrefValue(prefs::kHomePageIsNewTabPage);
200 bool homepage_is_new_tab_page = true;
201 if (homepage_is_new_tab_page_value) {
202 if (!homepage_is_new_tab_page_value->GetAsBoolean(
203 &homepage_is_new_tab_page))
204 NOTREACHED();
207 const base::Value* restore_on_startup_value =
208 prefs->GetUserPrefValue(prefs::kRestoreOnStartup);
209 int restore_on_startup = -1;
210 if (restore_on_startup_value) {
211 if (!restore_on_startup_value->GetAsInteger(&restore_on_startup))
212 NOTREACHED();
215 // If restore_on_startup has the deprecated value kPrefValueHomePage,
216 // migrate it to open the homepage on startup. If 'homepage is NTP' is set,
217 // that means just opening the NTP. If not, it means opening a one-item URL
218 // list containing the homepage.
219 if (restore_on_startup == kPrefValueHomePage) {
220 if (homepage_is_new_tab_page) {
221 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueNewTab);
222 } else {
223 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueURLs);
224 SetNewURLList(prefs);
226 } else if (!restore_on_startup_value && !homepage_is_new_tab_page &&
227 GetDefaultStartupType() == DEFAULT) {
228 // kRestoreOnStartup was never set by the user, but the homepage was set.
229 // Migrate to the list of URLs. (If restore_on_startup was never set,
230 // and homepage_is_new_tab_page is true, no action is needed. The new
231 // default value is "open the new tab page" which is what we want.)
232 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueURLs);
233 SetNewURLList(prefs);
236 prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
240 // static
241 void SessionStartupPref::MigrateMacDefaultPrefIfNecessary(PrefService* prefs) {
242 #if defined(OS_MACOSX)
243 DCHECK(prefs);
244 if (!restore_utils::IsWindowRestoreEnabled())
245 return;
246 // The default startup pref used to be LAST, now it is DEFAULT. Don't change
247 // the setting for existing profiles (even if the user has never changed it),
248 // but make new profiles default to DEFAULT.
249 bool old_profile_version =
250 !prefs->FindPreference(
251 prefs::kProfileCreatedByVersion)->IsDefaultValue() &&
252 Version(prefs->GetString(prefs::kProfileCreatedByVersion)).IsOlderThan(
253 "21.0.1180.0");
254 if (old_profile_version && TypeIsDefault(prefs))
255 prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueLast);
256 #endif
259 // static
260 bool SessionStartupPref::TypeIsManaged(PrefService* prefs) {
261 DCHECK(prefs);
262 const PrefService::Preference* pref_restore =
263 prefs->FindPreference(prefs::kRestoreOnStartup);
264 DCHECK(pref_restore);
265 return pref_restore->IsManaged();
268 // static
269 bool SessionStartupPref::URLsAreManaged(PrefService* prefs) {
270 DCHECK(prefs);
271 const PrefService::Preference* pref_urls =
272 prefs->FindPreference(prefs::kURLsToRestoreOnStartup);
273 DCHECK(pref_urls);
274 return pref_urls->IsManaged();
277 // static
278 bool SessionStartupPref::TypeIsDefault(PrefService* prefs) {
279 DCHECK(prefs);
280 const PrefService::Preference* pref_restore =
281 prefs->FindPreference(prefs::kRestoreOnStartup);
282 DCHECK(pref_restore);
283 return pref_restore->IsDefaultValue();
286 // static
287 SessionStartupPref::Type SessionStartupPref::PrefValueToType(int pref_value) {
288 switch (pref_value) {
289 case kPrefValueLast: return SessionStartupPref::LAST;
290 case kPrefValueURLs: return SessionStartupPref::URLS;
291 case kPrefValueHomePage: return SessionStartupPref::HOMEPAGE;
292 default: return SessionStartupPref::DEFAULT;
296 SessionStartupPref::SessionStartupPref(Type type) : type(type) {}
298 SessionStartupPref::~SessionStartupPref() {}