Make non-volatile directory platform-specific.

update_engine daemon needs to persist files (such as the progress of
the update) in a non-volatile storage and also used to store a
marker file on a volatile storage to detect when update_engine is
restarted, likelly due to a crash.

This patch moves the non-volatile directory configuration to the
Hardware interface, making it platform-specific. It also replaces the
system rebooted detection using the boot_id provided by the kernel
instead of storing a file under /tmp. This implementation works both
on Chrome OS and Android.

Bug: 24074252
Test: FEATURES=test emerge-link update_engine; `mma`; deployed and tested manually on brillo.

Change-Id: I921d767982adebfd04eb12e08d8a157d9102d1e3
diff --git a/real_system_state.cc b/real_system_state.cc
index 03cbe2e..34ac5ed 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -53,21 +53,44 @@
     return false;
   }
 
-  if (!prefs_.Init(base::FilePath(kPrefsDirectory))) {
+  // Initialize standard and powerwash-safe prefs.
+  base::FilePath non_volatile_path;
+  // TODO(deymo): Fall back to in-memory prefs if there's no physical directory
+  // available.
+  if (!hardware_->GetNonVolatileDirectory(&non_volatile_path)) {
+    LOG(ERROR) << "Failed to get a non-volatile directory.";
+    return false;
+  }
+  Prefs* prefs;
+  prefs_.reset(prefs = new Prefs());
+  if (!prefs->Init(non_volatile_path.Append(kPrefsSubDirectory))) {
     LOG(ERROR) << "Failed to initialize preferences.";
     return false;
   }
 
-  if (!powerwash_safe_prefs_.Init(base::FilePath(kPowerwashSafePrefsDir))) {
+  base::FilePath powerwash_safe_path;
+  if (!hardware_->GetPowerwashSafeDirectory(&powerwash_safe_path)) {
+    // TODO(deymo): Fall-back to in-memory prefs if there's no powerwash-safe
+    // directory, or disable powerwash feature.
+    powerwash_safe_path = non_volatile_path.Append("powerwash-safe");
+    LOG(WARNING) << "No powerwash-safe directory, using non-volatile one.";
+  }
+  powerwash_safe_prefs_.reset(prefs = new Prefs());
+  if (!prefs->Init(
+          powerwash_safe_path.Append(kPowerwashSafePrefsSubDirectory))) {
     LOG(ERROR) << "Failed to initialize powerwash preferences.";
     return false;
   }
 
-  if (!utils::FileExists(kSystemRebootedMarkerFile)) {
-    if (!utils::WriteFile(kSystemRebootedMarkerFile, "", 0)) {
-      LOG(ERROR) << "Could not create reboot marker file";
-      return false;
-    }
+  // Check the system rebooted marker file.
+  std::string boot_id;
+  if (utils::GetBootId(&boot_id)) {
+    std::string prev_boot_id;
+    system_rebooted_ = (!prefs_->GetString(kPrefsBootId, &prev_boot_id) ||
+                        prev_boot_id != boot_id);
+    prefs_->SetString(kPrefsBootId, boot_id);
+  } else {
+    LOG(WARNING) << "Couldn't detect the bootid, assuming system was rebooted.";
     system_rebooted_ = true;
   }