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/prefs/scoped_user_pref_update.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/common/net/url_fixer_upper.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 22 namespace { 23 24 // Converts a SessionStartupPref::Type to an integer written to prefs. 25 int 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 33 void 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 43 void 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 57 void 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 72 SessionStartupPref::Type SessionStartupPref::GetDefaultStartupType() { 73 #if defined(OS_CHROMEOS) 74 return SessionStartupPref::LAST; 75 #else 76 return SessionStartupPref::DEFAULT; 77 #endif 78 } 79 80 // static 81 void SessionStartupPref::SetStartupPref( 82 Profile* profile, 83 const SessionStartupPref& pref) { 84 DCHECK(profile); 85 SetStartupPref(profile->GetPrefs(), pref); 86 } 87 88 // static 89 void 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 112 SessionStartupPref SessionStartupPref::GetStartupPref(Profile* profile) { 113 DCHECK(profile); 114 return GetStartupPref(profile->GetPrefs()); 115 } 116 117 // static 118 SessionStartupPref 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 136 void 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 184 void 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 203 bool 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 212 bool 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 221 bool 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 230 SessionStartupPref::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 239 SessionStartupPref::SessionStartupPref(Type type) : type(type) {} 240 241 SessionStartupPref::~SessionStartupPref() {} 242