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 <stddef.h>
8 
9 #include <string>
10 
11 #include "base/values.h"
12 #include "build/build_config.h"
13 #include "build/chromeos_buildflags.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/prefs/pref_service.h"
18 #include "components/prefs/scoped_user_pref_update.h"
19 #include "components/url_formatter/url_fixer.h"
20 
21 namespace {
22 
23 // Converts a SessionStartupPref::Type to an integer written to prefs.
TypeToPrefValue(SessionStartupPref::Type type)24 int TypeToPrefValue(SessionStartupPref::Type type) {
25   switch (type) {
26     case SessionStartupPref::LAST: return SessionStartupPref::kPrefValueLast;
27     case SessionStartupPref::URLS: return SessionStartupPref::kPrefValueURLs;
28     default:                       return SessionStartupPref::kPrefValueNewTab;
29   }
30 }
31 
URLListToPref(const base::ListValue * url_list,SessionStartupPref * pref)32 void URLListToPref(const base::ListValue* url_list, SessionStartupPref* pref) {
33   pref->urls.clear();
34   for (size_t i = 0; i < url_list->GetSize(); ++i) {
35     std::string url_text;
36     if (url_list->GetString(i, &url_text)) {
37       GURL fixed_url = url_formatter::FixupURL(url_text, std::string());
38       pref->urls.push_back(fixed_url);
39     }
40   }
41 }
42 
43 }  // namespace
44 
45 // static
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)46 void SessionStartupPref::RegisterProfilePrefs(
47     user_prefs::PrefRegistrySyncable* registry) {
48 #if defined(OS_ANDROID)
49   uint32_t flags = PrefRegistry::NO_REGISTRATION_FLAGS;
50 #else
51   uint32_t flags = user_prefs::PrefRegistrySyncable::SYNCABLE_PREF;
52 #endif
53   registry->RegisterIntegerPref(prefs::kRestoreOnStartup,
54                                 TypeToPrefValue(GetDefaultStartupType()),
55                                 flags);
56   registry->RegisterListPref(prefs::kURLsToRestoreOnStartup, flags);
57 }
58 
59 // static
GetDefaultStartupType()60 SessionStartupPref::Type SessionStartupPref::GetDefaultStartupType() {
61 #if defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS)
62   return SessionStartupPref::LAST;
63 #else
64   return SessionStartupPref::DEFAULT;
65 #endif
66 }
67 
68 // static
SetStartupPref(Profile * profile,const SessionStartupPref & pref)69 void SessionStartupPref::SetStartupPref(
70     Profile* profile,
71     const SessionStartupPref& pref) {
72   DCHECK(profile);
73   SetStartupPref(profile->GetPrefs(), pref);
74 }
75 
76 // static
SetStartupPref(PrefService * prefs,const SessionStartupPref & pref)77 void SessionStartupPref::SetStartupPref(PrefService* prefs,
78                                         const SessionStartupPref& pref) {
79   DCHECK(prefs);
80 
81   if (!SessionStartupPref::TypeIsManaged(prefs))
82     prefs->SetInteger(prefs::kRestoreOnStartup, TypeToPrefValue(pref.type));
83 
84   if (!SessionStartupPref::URLsAreManaged(prefs)) {
85     // Always save the URLs, that way the UI can remain consistent even if the
86     // user changes the startup type pref.
87     // Ownership of the ListValue retains with the pref service.
88     ListPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
89     base::ListValue* url_pref_list = update.Get();
90     DCHECK(url_pref_list);
91     url_pref_list->Clear();
92     for (size_t i = 0; i < pref.urls.size(); ++i) {
93       url_pref_list->Set(static_cast<int>(i),
94                          std::make_unique<base::Value>(pref.urls[i].spec()));
95     }
96   }
97 }
98 
99 // static
GetStartupPref(const Profile * profile)100 SessionStartupPref SessionStartupPref::GetStartupPref(const Profile* profile) {
101   DCHECK(profile);
102 
103   // Guest sessions should not store any state, therefore they should never
104   // trigger a restore during startup.
105   return (profile->IsGuestSession() || profile->IsEphemeralGuestProfile())
106              ? SessionStartupPref(SessionStartupPref::DEFAULT)
107              : GetStartupPref(profile->GetPrefs());
108 }
109 
110 // static
GetStartupPref(const PrefService * prefs)111 SessionStartupPref SessionStartupPref::GetStartupPref(
112     const PrefService* prefs) {
113   DCHECK(prefs);
114 
115   SessionStartupPref pref(
116       PrefValueToType(prefs->GetInteger(prefs::kRestoreOnStartup)));
117 
118   // Always load the urls, even if the pref type isn't URLS. This way the
119   // preferences panels can show the user their last choice.
120   const base::ListValue* url_list =
121       prefs->GetList(prefs::kURLsToRestoreOnStartup);
122   URLListToPref(url_list, &pref);
123 
124   return pref;
125 }
126 
127 // static
TypeIsManaged(PrefService * prefs)128 bool SessionStartupPref::TypeIsManaged(PrefService* prefs) {
129   DCHECK(prefs);
130   const PrefService::Preference* pref_restore =
131       prefs->FindPreference(prefs::kRestoreOnStartup);
132   DCHECK(pref_restore);
133   return pref_restore->IsManaged();
134 }
135 
136 // static
URLsAreManaged(PrefService * prefs)137 bool SessionStartupPref::URLsAreManaged(PrefService* prefs) {
138   DCHECK(prefs);
139   const PrefService::Preference* pref_urls =
140       prefs->FindPreference(prefs::kURLsToRestoreOnStartup);
141   DCHECK(pref_urls);
142   return pref_urls->IsManaged();
143 }
144 
145 // static
TypeHasRecommendedValue(PrefService * prefs)146 bool SessionStartupPref::TypeHasRecommendedValue(PrefService* prefs) {
147   DCHECK(prefs);
148   const PrefService::Preference* pref_restore =
149       prefs->FindPreference(prefs::kRestoreOnStartup);
150   DCHECK(pref_restore);
151   return pref_restore->GetRecommendedValue() != nullptr;
152 }
153 
154 // static
TypeIsDefault(const PrefService * prefs)155 bool SessionStartupPref::TypeIsDefault(const PrefService* prefs) {
156   DCHECK(prefs);
157   const PrefService::Preference* pref_restore =
158       prefs->FindPreference(prefs::kRestoreOnStartup);
159   DCHECK(pref_restore);
160   return pref_restore->IsDefaultValue();
161 }
162 
163 // static
PrefValueToType(int pref_value)164 SessionStartupPref::Type SessionStartupPref::PrefValueToType(int pref_value) {
165   switch (pref_value) {
166     case kPrefValueLast:     return SessionStartupPref::LAST;
167     case kPrefValueURLs:     return SessionStartupPref::URLS;
168     default:                 return SessionStartupPref::DEFAULT;
169   }
170 }
171 
SessionStartupPref(Type type)172 SessionStartupPref::SessionStartupPref(Type type) : type(type) {}
173 
174 SessionStartupPref::SessionStartupPref(const SessionStartupPref& other) =
175     default;
176 
~SessionStartupPref()177 SessionStartupPref::~SessionStartupPref() {}
178