session_startup_pref.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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.
4
5#include "chrome/browser/prefs/session_startup_pref.h"
6
7#include <string>
8
9#include "base/prefs/pref_service.h"
10#include "base/values.h"
11#include "base/version.h"
12#include "chrome/browser/net/url_fixer_upper.h"
13#include "chrome/browser/prefs/scoped_user_pref_update.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/common/pref_names.h"
16#include "components/user_prefs/pref_registry_syncable.h"
17
18#if defined(OS_MACOSX)
19#include "chrome/browser/ui/cocoa/window_restore_utils.h"
20#endif
21
22namespace {
23
24// Converts a SessionStartupPref::Type to an integer written to prefs.
25int TypeToPrefValue(SessionStartupPref::Type type) {
26  switch (type) {
27    case SessionStartupPref::LAST: return SessionStartupPref::kPrefValueLast;
28    case SessionStartupPref::URLS: return SessionStartupPref::kPrefValueURLs;
29    default:                       return SessionStartupPref::kPrefValueNewTab;
30  }
31}
32
33void SetNewURLList(PrefService* prefs) {
34  if (prefs->IsUserModifiablePreference(prefs::kURLsToRestoreOnStartup)) {
35    base::ListValue new_url_pref_list;
36    base::StringValue* home_page =
37        new base::StringValue(prefs->GetString(prefs::kHomePage));
38    new_url_pref_list.Append(home_page);
39    prefs->Set(prefs::kURLsToRestoreOnStartup, new_url_pref_list);
40  }
41}
42
43void URLListToPref(const base::ListValue* url_list, SessionStartupPref* pref) {
44  pref->urls.clear();
45  for (size_t i = 0; i < url_list->GetSize(); ++i) {
46    std::string url_text;
47    if (url_list->GetString(i, &url_text)) {
48      GURL fixed_url = URLFixerUpper::FixupURL(url_text, std::string());
49      pref->urls.push_back(fixed_url);
50    }
51  }
52}
53
54}  // namespace
55
56// static
57void SessionStartupPref::RegisterProfilePrefs(
58    user_prefs::PrefRegistrySyncable* registry) {
59  registry->RegisterIntegerPref(
60      prefs::kRestoreOnStartup,
61      TypeToPrefValue(GetDefaultStartupType()),
62      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
63  registry->RegisterListPref(prefs::kURLsToRestoreOnStartup,
64                             user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
65  registry->RegisterBooleanPref(
66      prefs::kRestoreOnStartupMigrated,
67      false,
68      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
69}
70
71// static
72SessionStartupPref::Type SessionStartupPref::GetDefaultStartupType() {
73#if defined(OS_CHROMEOS)
74  return SessionStartupPref::LAST;
75#else
76  return SessionStartupPref::DEFAULT;
77#endif
78}
79
80// static
81void SessionStartupPref::SetStartupPref(
82    Profile* profile,
83    const SessionStartupPref& pref) {
84  DCHECK(profile);
85  SetStartupPref(profile->GetPrefs(), pref);
86}
87
88// static
89void SessionStartupPref::SetStartupPref(PrefService* prefs,
90                                        const SessionStartupPref& pref) {
91  DCHECK(prefs);
92
93  if (!SessionStartupPref::TypeIsManaged(prefs))
94    prefs->SetInteger(prefs::kRestoreOnStartup, TypeToPrefValue(pref.type));
95
96  if (!SessionStartupPref::URLsAreManaged(prefs)) {
97    // Always save the URLs, that way the UI can remain consistent even if the
98    // user changes the startup type pref.
99    // Ownership of the ListValue retains with the pref service.
100    ListPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
101    ListValue* url_pref_list = update.Get();
102    DCHECK(url_pref_list);
103    url_pref_list->Clear();
104    for (size_t i = 0; i < pref.urls.size(); ++i) {
105      url_pref_list->Set(static_cast<int>(i),
106                         new StringValue(pref.urls[i].spec()));
107    }
108  }
109}
110
111// static
112SessionStartupPref SessionStartupPref::GetStartupPref(Profile* profile) {
113  DCHECK(profile);
114  return GetStartupPref(profile->GetPrefs());
115}
116
117// static
118SessionStartupPref SessionStartupPref::GetStartupPref(PrefService* prefs) {
119  DCHECK(prefs);
120
121  MigrateIfNecessary(prefs);
122  MigrateMacDefaultPrefIfNecessary(prefs);
123
124  SessionStartupPref pref(
125      PrefValueToType(prefs->GetInteger(prefs::kRestoreOnStartup)));
126
127  // Always load the urls, even if the pref type isn't URLS. This way the
128  // preferences panels can show the user their last choice.
129  const ListValue* url_list = prefs->GetList(prefs::kURLsToRestoreOnStartup);
130  URLListToPref(url_list, &pref);
131
132  return pref;
133}
134
135// static
136void SessionStartupPref::MigrateIfNecessary(PrefService* prefs) {
137  DCHECK(prefs);
138
139  if (!prefs->GetBoolean(prefs::kRestoreOnStartupMigrated)) {
140    // Read existing values
141    const base::Value* homepage_is_new_tab_page_value =
142        prefs->GetUserPrefValue(prefs::kHomePageIsNewTabPage);
143    bool homepage_is_new_tab_page = true;
144    if (homepage_is_new_tab_page_value) {
145      if (!homepage_is_new_tab_page_value->GetAsBoolean(
146              &homepage_is_new_tab_page))
147        NOTREACHED();
148    }
149
150    const base::Value* restore_on_startup_value =
151        prefs->GetUserPrefValue(prefs::kRestoreOnStartup);
152    int restore_on_startup = -1;
153    if (restore_on_startup_value) {
154      if (!restore_on_startup_value->GetAsInteger(&restore_on_startup))
155        NOTREACHED();
156    }
157
158    // If restore_on_startup has the deprecated value kPrefValueHomePage,
159    // migrate it to open the homepage on startup. If 'homepage is NTP' is set,
160    // that means just opening the NTP. If not, it means opening a one-item URL
161    // list containing the homepage.
162    if (restore_on_startup == kPrefValueHomePage) {
163      if (homepage_is_new_tab_page) {
164        prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueNewTab);
165      } else {
166        prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueURLs);
167        SetNewURLList(prefs);
168      }
169    } else if (!restore_on_startup_value && !homepage_is_new_tab_page &&
170               GetDefaultStartupType() == DEFAULT) {
171      // kRestoreOnStartup was never set by the user, but the homepage was set.
172      // Migrate to the list of URLs. (If restore_on_startup was never set,
173      // and homepage_is_new_tab_page is true, no action is needed. The new
174      // default value is "open the new tab page" which is what we want.)
175      prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueURLs);
176      SetNewURLList(prefs);
177    }
178
179    prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
180  }
181}
182
183// static
184void SessionStartupPref::MigrateMacDefaultPrefIfNecessary(PrefService* prefs) {
185#if defined(OS_MACOSX)
186  DCHECK(prefs);
187  if (!restore_utils::IsWindowRestoreEnabled())
188    return;
189  // The default startup pref used to be LAST, now it is DEFAULT. Don't change
190  // the setting for existing profiles (even if the user has never changed it),
191  // but make new profiles default to DEFAULT.
192  bool old_profile_version =
193      !prefs->FindPreference(
194          prefs::kProfileCreatedByVersion)->IsDefaultValue() &&
195      Version(prefs->GetString(prefs::kProfileCreatedByVersion)).IsOlderThan(
196          "21.0.1180.0");
197  if (old_profile_version && TypeIsDefault(prefs))
198    prefs->SetInteger(prefs::kRestoreOnStartup, kPrefValueLast);
199#endif
200}
201
202// static
203bool SessionStartupPref::TypeIsManaged(PrefService* prefs) {
204  DCHECK(prefs);
205  const PrefService::Preference* pref_restore =
206      prefs->FindPreference(prefs::kRestoreOnStartup);
207  DCHECK(pref_restore);
208  return pref_restore->IsManaged();
209}
210
211// static
212bool SessionStartupPref::URLsAreManaged(PrefService* prefs) {
213  DCHECK(prefs);
214  const PrefService::Preference* pref_urls =
215      prefs->FindPreference(prefs::kURLsToRestoreOnStartup);
216  DCHECK(pref_urls);
217  return pref_urls->IsManaged();
218}
219
220// static
221bool SessionStartupPref::TypeIsDefault(PrefService* prefs) {
222  DCHECK(prefs);
223  const PrefService::Preference* pref_restore =
224      prefs->FindPreference(prefs::kRestoreOnStartup);
225  DCHECK(pref_restore);
226  return pref_restore->IsDefaultValue();
227}
228
229// static
230SessionStartupPref::Type SessionStartupPref::PrefValueToType(int pref_value) {
231  switch (pref_value) {
232    case kPrefValueLast:     return SessionStartupPref::LAST;
233    case kPrefValueURLs:     return SessionStartupPref::URLS;
234    case kPrefValueHomePage: return SessionStartupPref::HOMEPAGE;
235    default:                 return SessionStartupPref::DEFAULT;
236  }
237}
238
239SessionStartupPref::SessionStartupPref(Type type) : type(type) {}
240
241SessionStartupPref::~SessionStartupPref() {}
242