Home | History | Annotate | Download | only in login
      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