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/chromeos/chromeos_version.h" 9 #include "base/file_util.h" 10 #include "base/prefs/pref_registry_simple.h" 11 #include "base/prefs/pref_service.h" 12 #include "base/threading/thread_restrictions.h" 13 #include "chrome/browser/browser_process.h" 14 #include "chrome/common/pref_names.h" 15 #include "content/public/browser/browser_thread.h" 16 #include "ui/base/l10n/l10n_util.h" 17 18 using content::BrowserThread; 19 20 namespace { 21 22 // A string pref with initial locale set in VPD or manifest. 23 const char kInitialLocale[] = "intl.initial_locale"; 24 25 // A boolean pref of the OOBE complete flag (first OOBE part before login). 26 const char kOobeComplete[] = "OobeComplete"; 27 28 // A boolean pref of the device registered flag (second part after first login). 29 const char kDeviceRegistered[] = "DeviceRegistered"; 30 31 // Time in seconds that we wait for the device to reboot. 32 // If reboot didn't happen, ask user to reboot device manually. 33 const int kWaitForRebootTimeSec = 3; 34 35 // Saves boolean "Local State" preference and forces its persistence to disk. 36 void SaveBoolPreferenceForced(const char* pref_name, bool value) { 37 PrefService* prefs = g_browser_process->local_state(); 38 prefs->SetBoolean(pref_name, value); 39 prefs->CommitPendingWrite(); 40 } 41 42 // Saves integer "Local State" preference and forces its persistence to disk. 43 void SaveIntegerPreferenceForced(const char* pref_name, int value) { 44 PrefService* prefs = g_browser_process->local_state(); 45 prefs->SetInteger(pref_name, value); 46 prefs->CommitPendingWrite(); 47 } 48 49 // Saves string "Local State" preference and forces its persistence to disk. 50 void SaveStringPreferenceForced(const char* pref_name, 51 const std::string& value) { 52 PrefService* prefs = g_browser_process->local_state(); 53 prefs->SetString(pref_name, value); 54 prefs->CommitPendingWrite(); 55 } 56 57 } // namespace 58 59 namespace chromeos { 60 61 // static 62 void StartupUtils::RegisterPrefs(PrefRegistrySimple* registry) { 63 registry->RegisterBooleanPref(kOobeComplete, false); 64 registry->RegisterIntegerPref(kDeviceRegistered, -1); 65 registry->RegisterStringPref(kInitialLocale, "en-US"); 66 } 67 68 // static 69 bool StartupUtils::IsEulaAccepted() { 70 return g_browser_process->local_state()->GetBoolean(prefs::kEulaAccepted); 71 } 72 73 // static 74 bool StartupUtils::IsOobeCompleted() { 75 return g_browser_process->local_state()->GetBoolean(kOobeComplete); 76 } 77 78 // static 79 void StartupUtils::MarkEulaAccepted() { 80 SaveBoolPreferenceForced(prefs::kEulaAccepted, true); 81 } 82 83 // static 84 void StartupUtils::MarkOobeCompleted() { 85 SaveBoolPreferenceForced(kOobeComplete, true); 86 } 87 88 // Returns the path to flag file indicating that both parts of OOBE were 89 // completed. 90 // On chrome device, returns /home/chronos/.oobe_completed. 91 // On Linux desktop, returns $HOME/.oobe_completed. 92 static base::FilePath GetOobeCompleteFlagPath() { 93 // The constant is defined here so it won't be referenced directly. 94 const char kOobeCompleteFlagFilePath[] = "/home/chronos/.oobe_completed"; 95 96 if (base::chromeos::IsRunningOnChromeOS()) { 97 return base::FilePath(kOobeCompleteFlagFilePath); 98 } else { 99 const char* home = getenv("HOME"); 100 // Unlikely but if HOME is not defined, use the current directory. 101 if (!home) 102 home = ""; 103 return base::FilePath(home).AppendASCII(".oobe_completed"); 104 } 105 } 106 107 static 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 = file_util::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 file_util::CloseFile(oobe_flag_file); 116 } 117 } 118 119 // static 120 bool StartupUtils::IsDeviceRegistered() { 121 int value = g_browser_process->local_state()->GetInteger(kDeviceRegistered); 122 if (value > 0) { 123 // Recreate flag file in case it was lost. 124 BrowserThread::PostTask( 125 BrowserThread::FILE, 126 FROM_HERE, 127 base::Bind(&CreateOobeCompleteFlagFile)); 128 return true; 129 } else if (value == 0) { 130 return false; 131 } else { 132 // Pref is not set. For compatibility check flag file. It causes blocking 133 // IO on UI thread. But it's required for update from old versions. 134 base::ThreadRestrictions::ScopedAllowIO allow_io; 135 base::FilePath oobe_complete_flag_file_path = GetOobeCompleteFlagPath(); 136 bool file_exists = base::PathExists(oobe_complete_flag_file_path); 137 SaveIntegerPreferenceForced(kDeviceRegistered, file_exists ? 1 : 0); 138 return file_exists; 139 } 140 } 141 142 // static 143 void StartupUtils::MarkDeviceRegistered() { 144 SaveIntegerPreferenceForced(kDeviceRegistered, 1); 145 BrowserThread::PostTask( 146 BrowserThread::FILE, 147 FROM_HERE, 148 base::Bind(&CreateOobeCompleteFlagFile)); 149 } 150 151 // static 152 std::string StartupUtils::GetInitialLocale() { 153 std::string locale = 154 g_browser_process->local_state()->GetString(kInitialLocale); 155 if (!l10n_util::IsValidLocaleSyntax(locale)) 156 locale = "en-US"; 157 return locale; 158 } 159 160 // static 161 void StartupUtils::SetInitialLocale(const std::string& locale) { 162 if (l10n_util::IsValidLocaleSyntax(locale)) 163 SaveStringPreferenceForced(kInitialLocale, locale); 164 else 165 NOTREACHED(); 166 } 167 168 } // namespace chromeos 169