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/chromeos/login/startup_utils.h" 6 7#include "base/bind.h" 8#include "base/files/file_util.h" 9#include "base/path_service.h" 10#include "base/prefs/pref_registry_simple.h" 11#include "base/prefs/pref_service.h" 12#include "base/sys_info.h" 13#include "base/threading/thread_restrictions.h" 14#include "chrome/browser/browser_process.h" 15#include "chrome/common/chrome_paths.h" 16#include "chrome/common/pref_names.h" 17#include "content/public/browser/browser_thread.h" 18#include "ui/base/l10n/l10n_util.h" 19 20using content::BrowserThread; 21 22namespace { 23 24// Saves boolean "Local State" preference and forces its persistence to disk. 25void SaveBoolPreferenceForced(const char* pref_name, bool value) { 26 PrefService* prefs = g_browser_process->local_state(); 27 prefs->SetBoolean(pref_name, value); 28 prefs->CommitPendingWrite(); 29} 30 31// Saves integer "Local State" preference and forces its persistence to disk. 32void SaveIntegerPreferenceForced(const char* pref_name, int value) { 33 PrefService* prefs = g_browser_process->local_state(); 34 prefs->SetInteger(pref_name, value); 35 prefs->CommitPendingWrite(); 36} 37 38// Saves string "Local State" preference and forces its persistence to disk. 39void SaveStringPreferenceForced(const char* pref_name, 40 const std::string& value) { 41 PrefService* prefs = g_browser_process->local_state(); 42 prefs->SetString(pref_name, value); 43 prefs->CommitPendingWrite(); 44} 45 46} // namespace 47 48namespace chromeos { 49 50// static 51void StartupUtils::RegisterPrefs(PrefRegistrySimple* registry) { 52 registry->RegisterBooleanPref(prefs::kOobeComplete, false); 53 registry->RegisterStringPref(prefs::kOobeScreenPending, ""); 54 registry->RegisterIntegerPref(prefs::kDeviceRegistered, -1); 55 registry->RegisterBooleanPref(prefs::kEnrollmentRecoveryRequired, false); 56 registry->RegisterStringPref(prefs::kInitialLocale, "en-US"); 57} 58 59// static 60bool StartupUtils::IsEulaAccepted() { 61 return g_browser_process->local_state()->GetBoolean(prefs::kEulaAccepted); 62} 63 64// static 65bool StartupUtils::IsOobeCompleted() { 66 return g_browser_process->local_state()->GetBoolean(prefs::kOobeComplete); 67} 68 69// static 70void StartupUtils::MarkEulaAccepted() { 71 SaveBoolPreferenceForced(prefs::kEulaAccepted, true); 72} 73 74// static 75void StartupUtils::MarkOobeCompleted() { 76 // Forcing the second pref will force this one as well. Even if this one 77 // doesn't end up synced it is only going to eat up a couple of bytes with no 78 // side-effects. 79 g_browser_process->local_state()->ClearPref(prefs::kOobeScreenPending); 80 SaveBoolPreferenceForced(prefs::kOobeComplete, true); 81 82 // Successful enrollment implies that recovery is not required. 83 SaveBoolPreferenceForced(prefs::kEnrollmentRecoveryRequired, false); 84} 85 86void StartupUtils::SaveOobePendingScreen(const std::string& screen) { 87 SaveStringPreferenceForced(prefs::kOobeScreenPending, screen); 88} 89 90// Returns the path to flag file indicating that both parts of OOBE were 91// completed. 92// On chrome device, returns /home/chronos/.oobe_completed. 93// On Linux desktop, returns {DIR_USER_DATA}/.oobe_completed. 94static base::FilePath GetOobeCompleteFlagPath() { 95 // The constant is defined here so it won't be referenced directly. 96 const char kOobeCompleteFlagFilePath[] = "/home/chronos/.oobe_completed"; 97 98 if (base::SysInfo::IsRunningOnChromeOS()) { 99 return base::FilePath(kOobeCompleteFlagFilePath); 100 } else { 101 base::FilePath user_data_dir; 102 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 103 return user_data_dir.AppendASCII(".oobe_completed"); 104 } 105} 106 107static void CreateOobeCompleteFlagFile() { 108 // Create flag file for boot-time init scripts. 109 base::FilePath oobe_complete_path = GetOobeCompleteFlagPath(); 110 if (!base::PathExists(oobe_complete_path)) { 111 FILE* oobe_flag_file = base::OpenFile(oobe_complete_path, "w+b"); 112 if (oobe_flag_file == NULL) 113 DLOG(WARNING) << oobe_complete_path.value() << " doesn't exist."; 114 else 115 base::CloseFile(oobe_flag_file); 116 } 117} 118 119// static 120bool StartupUtils::IsDeviceRegistered() { 121 int value = 122 g_browser_process->local_state()->GetInteger(prefs::kDeviceRegistered); 123 if (value > 0) { 124 // Recreate flag file in case it was lost. 125 BrowserThread::PostTask( 126 BrowserThread::FILE, 127 FROM_HERE, 128 base::Bind(&CreateOobeCompleteFlagFile)); 129 return true; 130 } else if (value == 0) { 131 return false; 132 } else { 133 // Pref is not set. For compatibility check flag file. It causes blocking 134 // IO on UI thread. But it's required for update from old versions. 135 base::ThreadRestrictions::ScopedAllowIO allow_io; 136 base::FilePath oobe_complete_flag_file_path = GetOobeCompleteFlagPath(); 137 bool file_exists = base::PathExists(oobe_complete_flag_file_path); 138 SaveIntegerPreferenceForced(prefs::kDeviceRegistered, file_exists ? 1 : 0); 139 return file_exists; 140 } 141} 142 143// static 144void StartupUtils::MarkDeviceRegistered(const base::Closure& done_callback) { 145 SaveIntegerPreferenceForced(prefs::kDeviceRegistered, 1); 146 if (done_callback.is_null()) { 147 BrowserThread::PostTask( 148 BrowserThread::FILE, 149 FROM_HERE, 150 base::Bind(&CreateOobeCompleteFlagFile)); 151 } else { 152 BrowserThread::PostTaskAndReply( 153 BrowserThread::FILE, 154 FROM_HERE, 155 base::Bind(&CreateOobeCompleteFlagFile), 156 done_callback); 157 } 158} 159 160// static 161bool StartupUtils::IsEnrollmentRecoveryRequired() { 162 return g_browser_process->local_state() 163 ->GetBoolean(prefs::kEnrollmentRecoveryRequired); 164} 165 166// static 167void StartupUtils::MarkEnrollmentRecoveryRequired() { 168 SaveBoolPreferenceForced(prefs::kEnrollmentRecoveryRequired, true); 169} 170 171// static 172std::string StartupUtils::GetInitialLocale() { 173 std::string locale = 174 g_browser_process->local_state()->GetString(prefs::kInitialLocale); 175 if (!l10n_util::IsValidLocaleSyntax(locale)) 176 locale = "en-US"; 177 return locale; 178} 179 180// static 181void StartupUtils::SetInitialLocale(const std::string& locale) { 182 if (l10n_util::IsValidLocaleSyntax(locale)) 183 SaveStringPreferenceForced(prefs::kInitialLocale, locale); 184 else 185 NOTREACHED(); 186} 187 188} // namespace chromeos 189