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