Merge "Allow update_engine to create executable files."
diff --git a/Android.mk b/Android.mk
index 70cbdce..ba7e392 100644
--- a/Android.mk
+++ b/Android.mk
@@ -155,6 +155,7 @@
     payload_constants.cc \
     payload_state.cc \
     payload_verifier.cc \
+    platform_constants_android.cc \
     postinstall_runner_action.cc \
     prefs.cc \
     proxy_resolver.cc \
@@ -208,6 +209,7 @@
     libchromeos-policy
 LOCAL_SRC_FILES := \
     main.cc
+LOCAL_INIT_RC := update_engine.rc
 $(eval $(update_engine_common))
 include $(BUILD_EXECUTABLE)
 
diff --git a/boot_control_android.cc b/boot_control_android.cc
index 4bb3b92..43a1c18 100644
--- a/boot_control_android.cc
+++ b/boot_control_android.cc
@@ -16,10 +16,12 @@
 
 #include "update_engine/boot_control_android.h"
 
-#include <base/logging.h>
+#include <base/bind.h>
 #include <base/files/file_util.h>
+#include <base/logging.h>
 #include <base/strings/string_util.h>
 #include <chromeos/make_unique_ptr.h>
+#include <chromeos/message_loops/message_loop.h>
 #include <cutils/properties.h>
 #include <fs_mgr.h>
 
@@ -174,4 +176,15 @@
   return ret == 0;
 }
 
+bool BootControlAndroid::MarkBootSuccessfulAsync(
+    base::Callback<void(bool)> callback) {
+  int ret = module_->markBootSuccessful(module_);
+  if (ret < 0) {
+    LOG(ERROR) << "Unable to mark boot successful: " << strerror(-ret);
+  }
+  return chromeos::MessageLoop::current()->PostTask(
+             FROM_HERE, base::Bind(callback, ret == 0)) !=
+         chromeos::MessageLoop::kTaskIdNull;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/boot_control_android.h b/boot_control_android.h
index 2e218a0..f429d9b 100644
--- a/boot_control_android.h
+++ b/boot_control_android.h
@@ -45,6 +45,7 @@
                           std::string* device) const override;
   bool IsSlotBootable(BootControlInterface::Slot slot) const override;
   bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
+  bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override;
 
  private:
   // NOTE: There is no way to release/unload HAL implementations so
diff --git a/boot_control_chromeos.cc b/boot_control_chromeos.cc
index 03e1c26..5f8f74e 100644
--- a/boot_control_chromeos.cc
+++ b/boot_control_chromeos.cc
@@ -18,6 +18,7 @@
 
 #include <string>
 
+#include <base/bind.h>
 #include <base/files/file_path.h>
 #include <base/files/file_util.h>
 #include <base/strings/string_util.h>
@@ -29,6 +30,7 @@
 }
 
 #include "update_engine/boot_control.h"
+#include "update_engine/subprocess.h"
 #include "update_engine/utils.h"
 
 using std::string;
@@ -57,6 +59,15 @@
   return boot_path;
 }
 
+// ExecCallback called when the execution of setgoodkernel finishes. Notifies
+// the caller of MarkBootSuccessfullAsync() by calling |callback| with the
+// result.
+void OnMarkBootSuccessfulDone(base::Callback<void(bool)> callback,
+                              int return_code,
+                              const string& output) {
+  callback.Run(return_code == 0);
+}
+
 }  // namespace
 
 namespace chromeos_update_engine {
@@ -194,6 +205,13 @@
   return true;
 }
 
+bool BootControlChromeOS::MarkBootSuccessfulAsync(
+    base::Callback<void(bool)> callback) {
+  return Subprocess::Get().Exec(
+             {"/usr/sbin/chromeos-setgoodkernel"},
+             base::Bind(&OnMarkBootSuccessfulDone, callback)) != 0;
+}
+
 // static
 string BootControlChromeOS::SysfsBlockDevice(const string& device) {
   base::FilePath device_path(device);
diff --git a/boot_control_chromeos.h b/boot_control_chromeos.h
index a7c269e..6f5497b 100644
--- a/boot_control_chromeos.h
+++ b/boot_control_chromeos.h
@@ -19,6 +19,7 @@
 
 #include <string>
 
+#include <base/callback.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include "update_engine/boot_control_interface.h"
@@ -47,6 +48,7 @@
                           std::string* device) const override;
   bool IsSlotBootable(BootControlInterface::Slot slot) const override;
   bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
+  bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override;
 
  private:
   friend class BootControlChromeOSTest;
diff --git a/boot_control_interface.h b/boot_control_interface.h
index 135d2eb..36f2caf 100644
--- a/boot_control_interface.h
+++ b/boot_control_interface.h
@@ -20,6 +20,7 @@
 #include <climits>
 #include <string>
 
+#include <base/callback.h>
 #include <base/macros.h>
 
 namespace chromeos_update_engine {
@@ -64,6 +65,12 @@
   // Returns true on success.
   virtual bool MarkSlotUnbootable(Slot slot) = 0;
 
+  // Mark the current slot as successfully booted asynchronously. No other slot
+  // flags are modified. Returns false if it was not able to schedule the
+  // operation, otherwise, returns true and calls the |callback| with the result
+  // of the operation.
+  virtual bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) = 0;
+
   // Return a human-readable slot name used for logging.
   static std::string SlotName(Slot slot) {
     if (slot == kInvalidSlot)
diff --git a/constants.cc b/constants.cc
index 35ff835..d724564 100644
--- a/constants.cc
+++ b/constants.cc
@@ -23,18 +23,16 @@
 
 const char kPowerwashCommand[] = "safe fast keepimg reason=update_engine\n";
 
-const char kPowerwashSafePrefsDir[] =
-    "/mnt/stateful_partition/unencrypted/preserve/update_engine/prefs";
+const char kPowerwashSafePrefsSubDirectory[] = "update_engine/prefs";
 
-const char kPrefsDirectory[] = "/var/lib/update_engine/prefs";
+const char kPrefsSubDirectory[] = "prefs";
 
 const char kStatefulPartition[] = "/mnt/stateful_partition";
 
-const char kSystemRebootedMarkerFile[] = "/tmp/update_engine_update_recorded";
-
 // Constants defining keys for the persisted state of update engine.
 const char kPrefsAttemptInProgress[] = "attempt-in-progress";
 const char kPrefsBackoffExpiryTime[] = "backoff-expiry-time";
+const char kPrefsBootId[] = "boot-id";
 const char kPrefsCertificateReportToSendDownload[] =
     "certificate-report-to-send-download";
 const char kPrefsCertificateReportToSendUpdate[] =
diff --git a/constants.h b/constants.h
index c07ff48..211dc96 100644
--- a/constants.h
+++ b/constants.h
@@ -23,17 +23,14 @@
 // completes successfully so that the device is powerwashed on next reboot.
 extern const char kPowerwashMarkerFile[];
 
-// Path to the marker file we use to indicate we've recorded a system reboot.
-extern const char kSystemRebootedMarkerFile[];
-
 // The contents of the powerwash marker file.
 extern const char kPowerwashCommand[];
 
 // Directory for AU prefs that are preserved across powerwash.
-extern const char kPowerwashSafePrefsDir[];
+extern const char kPowerwashSafePrefsSubDirectory[];
 
 // The location where we store the AU preferences (state etc).
-extern const char kPrefsDirectory[];
+extern const char kPrefsSubDirectory[];
 
 // Path to the stateful partition on the root filesystem.
 extern const char kStatefulPartition[];
@@ -41,6 +38,7 @@
 // Constants related to preferences.
 extern const char kPrefsAttemptInProgress[];
 extern const char kPrefsBackoffExpiryTime[];
+extern const char kPrefsBootId[];
 extern const char kPrefsCertificateReportToSendDownload[];
 extern const char kPrefsCertificateReportToSendUpdate[];
 extern const char kPrefsCurrentBytesDownloaded[];
diff --git a/fake_boot_control.h b/fake_boot_control.h
index 508f578f..9d1b54b 100644
--- a/fake_boot_control.h
+++ b/fake_boot_control.h
@@ -65,6 +65,13 @@
     return true;
   }
 
+  bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override {
+    // We run the callback directly from here to avoid having to setup a message
+    // loop in the test environment.
+    callback.Run(true);
+    return true;
+  }
+
   // Setters
   void SetNumSlots(unsigned int num_slots) {
     num_slots_ = num_slots;
diff --git a/fake_hardware.h b/fake_hardware.h
index 686c1cc..6036a40 100644
--- a/fake_hardware.h
+++ b/fake_hardware.h
@@ -62,6 +62,14 @@
 
   int GetPowerwashCount() const override { return powerwash_count_; }
 
+  bool GetNonVolatileDirectory(base::FilePath* path) const override {
+    return false;
+  }
+
+  bool GetPowerwashSafeDirectory(base::FilePath* path) const override {
+    return false;
+  }
+
   // Setters
   void SetIsOfficialBuild(bool is_official_build) {
     is_official_build_ = is_official_build;
diff --git a/hardware_android.cc b/hardware_android.cc
index 73fef99..6df5cd9 100644
--- a/hardware_android.cc
+++ b/hardware_android.cc
@@ -16,12 +16,20 @@
 
 #include "update_engine/hardware_android.h"
 
+#include <base/files/file_util.h>
 #include <chromeos/make_unique_ptr.h>
 
 #include "update_engine/hardware.h"
 
 using std::string;
 
+namespace {
+
+// The stateful directory used by update_engine.
+const char kNonVolatileDirectory[] = "/data/misc/update_engine";
+
+}  // namespace
+
 namespace chromeos_update_engine {
 
 namespace hardware {
@@ -74,4 +82,19 @@
   return 0;
 }
 
+bool HardwareAndroid::GetNonVolatileDirectory(base::FilePath* path) const {
+  base::FilePath local_path(kNonVolatileDirectory);
+  if (!base::PathExists(local_path)) {
+    LOG(ERROR) << "Non-volatile directory not found: " << local_path.value();
+    return false;
+  }
+  *path = local_path;
+  return true;
+}
+
+bool HardwareAndroid::GetPowerwashSafeDirectory(base::FilePath* path) const {
+  // On Android, we don't have a directory persisted across powerwash.
+  return false;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/hardware_android.h b/hardware_android.h
index 0a341c0..03bc9fc 100644
--- a/hardware_android.h
+++ b/hardware_android.h
@@ -41,6 +41,8 @@
   std::string GetFirmwareVersion() const override;
   std::string GetECVersion() const override;
   int GetPowerwashCount() const override;
+  bool GetNonVolatileDirectory(base::FilePath* path) const override;
+  bool GetPowerwashSafeDirectory(base::FilePath* path) const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(HardwareAndroid);
diff --git a/hardware_chromeos.cc b/hardware_chromeos.cc
index 888772d..d8c659a 100644
--- a/hardware_chromeos.cc
+++ b/hardware_chromeos.cc
@@ -37,13 +37,21 @@
 
 namespace {
 
-static const char kOOBECompletedMarker[] = "/home/chronos/.oobe_completed";
+const char kOOBECompletedMarker[] = "/home/chronos/.oobe_completed";
+
+// The stateful directory used by update_engine to store powerwash-safe files.
+// The files stored here must be whitelisted in the powerwash scripts.
+const char kPowerwashSafeDirectory[] =
+    "/mnt/stateful_partition/unencrypted/preserve";
 
 // The powerwash_count marker file contains the number of times the device was
 // powerwashed. This value is incremented by the clobber-state script when
 // a powerwash is performed.
-static const char kPowerwashCountMarker[] =
-    "/mnt/stateful_partition/unencrypted/preserve/powerwash_count";
+const char kPowerwashCountMarker[] = "powerwash_count";
+
+// The stateful directory used by update_engine. This directory is wiped during
+// powerwash.
+const char kNonVolatileDirectory[] = "/var/lib/update_engine";
 
 }  // namespace
 
@@ -125,8 +133,10 @@
 
 int HardwareChromeOS::GetPowerwashCount() const {
   int powerwash_count;
+  base::FilePath marker_path = base::FilePath(kPowerwashSafeDirectory).Append(
+      kPowerwashCountMarker);
   string contents;
-  if (!utils::ReadFile(kPowerwashCountMarker, &contents))
+  if (!utils::ReadFile(marker_path.value(), &contents))
     return -1;
   base::TrimWhitespaceASCII(contents, base::TRIM_TRAILING, &contents);
   if (!base::StringToInt(contents, &powerwash_count))
@@ -134,4 +144,14 @@
   return powerwash_count;
 }
 
+bool HardwareChromeOS::GetNonVolatileDirectory(base::FilePath* path) const {
+  *path = base::FilePath(kNonVolatileDirectory);
+  return true;
+}
+
+bool HardwareChromeOS::GetPowerwashSafeDirectory(base::FilePath* path) const {
+  *path = base::FilePath(kPowerwashSafeDirectory);
+  return true;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/hardware_chromeos.h b/hardware_chromeos.h
index 56f5ba8..e7fe486 100644
--- a/hardware_chromeos.h
+++ b/hardware_chromeos.h
@@ -42,6 +42,8 @@
   std::string GetFirmwareVersion() const override;
   std::string GetECVersion() const override;
   int GetPowerwashCount() const override;
+  bool GetNonVolatileDirectory(base::FilePath* path) const override;
+  bool GetPowerwashSafeDirectory(base::FilePath* path) const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(HardwareChromeOS);
diff --git a/hardware_interface.h b/hardware_interface.h
index 7dc4e53..df8f227 100644
--- a/hardware_interface.h
+++ b/hardware_interface.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 
+#include <base/files/file_path.h>
 #include <base/time/time.h>
 
 namespace chromeos_update_engine {
@@ -60,6 +61,16 @@
   // or is invalid, returns -1. Brand new machines out of the factory or after
   // recovery don't have this value set.
   virtual int GetPowerwashCount() const = 0;
+
+  // Store in |path| the path to a non-volatile directory (persisted across
+  // reboots) available for this daemon. In case of an error, such as no
+  // directory available, returns false.
+  virtual bool GetNonVolatileDirectory(base::FilePath* path) const = 0;
+
+  // Store in |path| the path to a non-volatile directory persisted across
+  // powerwash cycles. In case of an error, such as no directory available,
+  // returns false.
+  virtual bool GetPowerwashSafeDirectory(base::FilePath* path) const = 0;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/install_plan.cc b/install_plan.cc
index c378860..382eb4e 100644
--- a/install_plan.cc
+++ b/install_plan.cc
@@ -24,8 +24,8 @@
 
 namespace chromeos_update_engine {
 
-const char* kLegacyPartitionNameKernel = "KERNEL";
-const char* kLegacyPartitionNameRoot = "ROOT";
+const char* kLegacyPartitionNameKernel = "boot";
+const char* kLegacyPartitionNameRoot = "system";
 
 InstallPlan::InstallPlan(bool is_resume,
                          bool is_full_update,
diff --git a/install_plan.h b/install_plan.h
index 6e6f7ae..5e50626 100644
--- a/install_plan.h
+++ b/install_plan.h
@@ -31,6 +31,9 @@
 // parts of the update system about the install that should happen.
 namespace chromeos_update_engine {
 
+// The kernel and rootfs partition names used by the BootControlInterface when
+// handling update payloads with a major version 1. The names of the updated
+// partitions are include in the payload itself for major version 2.
 // TODO(deymo): Remove these constants from this interface once the InstallPlan
 // doesn't list the partitions explicitly.
 extern const char* kLegacyPartitionNameKernel;
diff --git a/mock_hardware.h b/mock_hardware.h
index e082a4f..ff387f4 100644
--- a/mock_hardware.h
+++ b/mock_hardware.h
@@ -51,6 +51,12 @@
     ON_CALL(*this, GetPowerwashCount())
       .WillByDefault(testing::Invoke(&fake_,
             &FakeHardware::GetPowerwashCount));
+    ON_CALL(*this, GetNonVolatileDirectory(testing::_))
+      .WillByDefault(testing::Invoke(&fake_,
+            &FakeHardware::GetNonVolatileDirectory));
+    ON_CALL(*this, GetPowerwashSafeDirectory(testing::_))
+      .WillByDefault(testing::Invoke(&fake_,
+            &FakeHardware::GetPowerwashSafeDirectory));
   }
 
   ~MockHardware() override = default;
@@ -63,6 +69,8 @@
   MOCK_CONST_METHOD0(GetFirmwareVersion, std::string());
   MOCK_CONST_METHOD0(GetECVersion, std::string());
   MOCK_CONST_METHOD0(GetPowerwashCount, int());
+  MOCK_CONST_METHOD1(GetNonVolatileDirectory, bool(base::FilePath*));
+  MOCK_CONST_METHOD1(GetPowerwashSafeDirectory, bool(base::FilePath*));
 
   // Returns a reference to the underlying FakeHardware.
   FakeHardware& fake() {
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 2be66af..05d950f 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -40,6 +40,7 @@
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/p2p_manager.h"
 #include "update_engine/payload_state_interface.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/prefs_interface.h"
 #include "update_engine/utils.h"
 
@@ -71,9 +72,9 @@
 static const char* kTagDisableP2PForSharing = "DisableP2PForSharing";
 static const char* kTagPublicKeyRsa = "PublicKeyRsa";
 
-namespace {
+static const char* kOmahaUpdaterVersion = "0.1.0.0";
 
-static const char* const kGupdateVersion = "ChromeOSUpdateEngine-0.1.0.0";
+namespace {
 
 // Returns an XML ping element attribute assignment with attribute
 // |name| and value |ping_days| if |ping_days| has a value that needs
@@ -289,12 +290,15 @@
   string install_source = base::StringPrintf("installsource=\"%s\" ",
       (params->interactive() ? "ondemandupdate" : "scheduler"));
 
+  string updater_version = XmlEncodeWithDefault(
+      base::StringPrintf("%s-%s",
+                         constants::kOmahaUpdaterID,
+                         kOmahaUpdaterVersion), "");
   string request_xml =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
       "<request protocol=\"3.0\" " + (
-          "version=\"" + XmlEncodeWithDefault(kGupdateVersion, "") + "\" "
-          "updaterversion=\"" + XmlEncodeWithDefault(kGupdateVersion,
-                                                     "") + "\" " +
+          "version=\"" + updater_version + "\" "
+          "updaterversion=\"" + updater_version + "\" " +
           install_source +
           "ismachine=\"1\">\n") +
       os_xml +
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index f22c137..55eb02f 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -40,6 +40,7 @@
 #include "update_engine/mock_payload_state.h"
 #include "update_engine/omaha_hash_calculator.h"
 #include "update_engine/omaha_request_params.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/prefs.h"
 #include "update_engine/test_utils.h"
 #include "update_engine/utils.h"
@@ -211,7 +212,7 @@
   // fake_system_state_.
   OmahaRequestParams request_params_ = OmahaRequestParams{
       &fake_system_state_,
-      OmahaRequestParams::kOsPlatform,
+      constants::kOmahaPlatformName,
       OmahaRequestParams::kOsVersion,
       "service_pack",
       "x86-generic",
@@ -1043,7 +1044,7 @@
 
   // Make sure XML Encode is being called on the params
   OmahaRequestParams params(&fake_system_state_,
-                            OmahaRequestParams::kOsPlatform,
+                            constants::kOmahaPlatformName,
                             OmahaRequestParams::kOsVersion,
                             "testtheservice_pack>",
                             "x86 generic<id",
@@ -1236,7 +1237,7 @@
     const char* delta_okay_str = delta_okay ? "true" : "false";
     chromeos::Blob post_data;
     OmahaRequestParams params(&fake_system_state_,
-                              OmahaRequestParams::kOsPlatform,
+                              constants::kOmahaPlatformName,
                               OmahaRequestParams::kOsVersion,
                               "service_pack",
                               "x86-generic",
@@ -1277,7 +1278,7 @@
     chromeos::Blob post_data;
     FakeSystemState fake_system_state;
     OmahaRequestParams params(&fake_system_state_,
-                              OmahaRequestParams::kOsPlatform,
+                              constants::kOmahaPlatformName,
                               OmahaRequestParams::kOsVersion,
                               "service_pack",
                               "x86-generic",
diff --git a/omaha_request_params.cc b/omaha_request_params.cc
index 6e8d636..4118a11 100644
--- a/omaha_request_params.cc
+++ b/omaha_request_params.cc
@@ -31,6 +31,7 @@
 
 #include "update_engine/constants.h"
 #include "update_engine/hardware_interface.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/system_state.h"
 #include "update_engine/utils.h"
 
@@ -42,14 +43,8 @@
 
 namespace chromeos_update_engine {
 
-const char kProductionOmahaUrl[] =
-    "https://tools.google.com/service/update2";
-const char kAUTestOmahaUrl[] =
-    "https://omaha.sandbox.google.com/service/update2";
-
 const char OmahaRequestParams::kAppId[] =
     "{87efface-864d-49a5-9bb3-4b050a7c227a}";
-const char OmahaRequestParams::kOsPlatform[] = "Chrome OS";
 const char OmahaRequestParams::kOsVersion[] = "Indy";
 const char OmahaRequestParams::kUpdateChannelKey[] = "CHROMEOS_RELEASE_TRACK";
 const char OmahaRequestParams::kIsPowerwashAllowedKey[] =
@@ -70,7 +65,7 @@
   LOG(INFO) << "Initializing parameters for this update attempt";
   InitFromLsbValue();
   bool stateful_override = !ShouldLockDown();
-  os_platform_ = OmahaRequestParams::kOsPlatform;
+  os_platform_ = constants::kOmahaPlatformName;
   os_version_ = OmahaRequestParams::kOsVersion;
   app_version_ = in_app_version.empty() ?
       GetLsbValue("CHROMEOS_RELEASE_VERSION", "", nullptr, stateful_override) :
@@ -117,7 +112,8 @@
   }
 
   if (in_update_url.empty())
-    update_url_ = GetLsbValue(kAutoUpdateServerKey, kProductionOmahaUrl,
+    update_url_ = GetLsbValue(kAutoUpdateServerKey,
+                              constants::kOmahaDefaultProductionURL,
                               nullptr, stateful_override);
   else
     update_url_ = in_update_url;
@@ -128,8 +124,9 @@
 }
 
 bool OmahaRequestParams::IsUpdateUrlOfficial() const {
-  return (update_url_ == kAUTestOmahaUrl ||
-          update_url_ == GetLsbValue(kAutoUpdateServerKey, kProductionOmahaUrl,
+  return (update_url_ == constants::kOmahaDefaultAUTestURL ||
+          update_url_ == GetLsbValue(kAutoUpdateServerKey,
+                                     constants::kOmahaDefaultProductionURL,
                                      nullptr, !ShouldLockDown()));
 }
 
diff --git a/omaha_request_params.h b/omaha_request_params.h
index 7109518..099c07c 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -25,17 +25,13 @@
 #include <base/time/time.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
+#include "update_engine/platform_constants.h"
+
 // This gathers local system information and prepares info used by the
 // Omaha request action.
 
 namespace chromeos_update_engine {
 
-// The default "official" Omaha update URL.
-extern const char kProductionOmahaUrl[];
-
-// The autoupdate test Omaha update URL.
-extern const char kAUTestOmahaUrl[];
-
 class SystemState;
 
 // This class encapsulates the data Omaha gets for the request, along with
@@ -48,7 +44,7 @@
  public:
   explicit OmahaRequestParams(SystemState* system_state)
       : system_state_(system_state),
-        os_platform_(kOsPlatform),
+        os_platform_(constants::kOmahaPlatformName),
         os_version_(kOsVersion),
         board_app_id_(kAppId),
         canary_app_id_(kAppId),
@@ -192,9 +188,7 @@
 
   // Suggested defaults
   static const char kAppId[];
-  static const char kOsPlatform[];
   static const char kOsVersion[];
-  static const char kUpdateUrl[];
   static const char kUpdateChannelKey[];
   static const char kIsPowerwashAllowedKey[];
   static const char kAutoUpdateServerKey[];
diff --git a/omaha_request_params_unittest.cc b/omaha_request_params_unittest.cc
index 90d8519..a4aeeec 100644
--- a/omaha_request_params_unittest.cc
+++ b/omaha_request_params_unittest.cc
@@ -26,6 +26,7 @@
 #include "update_engine/constants.h"
 #include "update_engine/fake_system_state.h"
 #include "update_engine/install_plan.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/test_utils.h"
 #include "update_engine/utils.h"
 
@@ -247,7 +248,7 @@
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_TRUE(out.delta_okay());
   EXPECT_EQ("dev-channel", out.target_channel());
-  EXPECT_EQ(kProductionOmahaUrl, out.update_url());
+  EXPECT_EQ(constants::kOmahaDefaultProductionURL, out.update_url());
 }
 
 TEST_F(OmahaRequestParamsTest, NoDeltasTest) {
diff --git a/omaha_response_handler_action_unittest.cc b/omaha_response_handler_action_unittest.cc
index 20d0166..5e14511 100644
--- a/omaha_response_handler_action_unittest.cc
+++ b/omaha_response_handler_action_unittest.cc
@@ -23,6 +23,7 @@
 #include "update_engine/constants.h"
 #include "update_engine/fake_system_state.h"
 #include "update_engine/mock_payload_state.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/test_utils.h"
 #include "update_engine/utils.h"
 
@@ -408,7 +409,7 @@
   // We're using a real OmahaRequestParams object here so we can't mock
   // IsUpdateUrlOfficial(), but setting the update URL to the AutoUpdate test
   // server will cause IsUpdateUrlOfficial() to return true.
-  params.set_update_url(kAUTestOmahaUrl);
+  params.set_update_url(constants::kOmahaDefaultAUTestURL);
   fake_system_state_.set_request_params(&params);
 
   EXPECT_CALL(*fake_system_state_.mock_payload_state(),
diff --git a/platform_constants.h b/platform_constants.h
new file mode 100644
index 0000000..9f8778e
--- /dev/null
+++ b/platform_constants.h
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_PLATFORM_CONSTANTS_H_
+#define UPDATE_ENGINE_PLATFORM_CONSTANTS_H_
+
+namespace chromeos_update_engine {
+namespace constants {
+
+// The default URL used by all products when running in normal mode. The AUTest
+// URL is used when testing normal images against the alternative AUTest server.
+// Note that the URL can be override in run-time in certain cases.
+extern const char kOmahaDefaultProductionURL[];
+extern const char kOmahaDefaultAUTestURL[];
+
+// Our product name used in Omaha. This value must match the one configured in
+// the server side and is sent on every request.
+extern const char kOmahaUpdaterID[];
+
+// The name of the platform as sent to Omaha.
+extern const char kOmahaPlatformName[];
+
+}  // namespace constants
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PLATFORM_CONSTANTS_H_
diff --git a/platform_constants_android.cc b/platform_constants_android.cc
new file mode 100644
index 0000000..55ec974
--- /dev/null
+++ b/platform_constants_android.cc
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/platform_constants.h"
+
+namespace chromeos_update_engine {
+namespace constants {
+
+const char kOmahaDefaultProductionURL[] =
+    "https://clients2.google.com/service/update2/brillo";
+const char kOmahaDefaultAUTestURL[] =
+    "https://clients2.google.com/service/update2/brillo";
+const char kOmahaUpdaterID[] = "Brillo";
+const char kOmahaPlatformName[] = "Brillo";
+
+}  // namespace constants
+}  // namespace chromeos_update_engine
diff --git a/platform_constants_chromeos.cc b/platform_constants_chromeos.cc
new file mode 100644
index 0000000..62c1720
--- /dev/null
+++ b/platform_constants_chromeos.cc
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/platform_constants.h"
+
+namespace chromeos_update_engine {
+namespace constants {
+
+const char kOmahaDefaultProductionURL[] =
+    "https://tools.google.com/service/update2";
+const char kOmahaDefaultAUTestURL[] =
+    "https://omaha.sandbox.google.com/service/update2";
+const char kOmahaUpdaterID[] = "ChromeOSUpdateEngine";
+const char kOmahaPlatformName[] = "Chrome OS";
+
+}  // namespace constants
+}  // namespace chromeos_update_engine
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;
   }
 
diff --git a/real_system_state.h b/real_system_state.h
index 5797d18..fd2a684 100644
--- a/real_system_state.h
+++ b/real_system_state.h
@@ -77,11 +77,11 @@
     return &metrics_lib_;
   }
 
-  inline PrefsInterface* prefs() override { return &prefs_; }
+  inline PrefsInterface* prefs() override { return prefs_.get(); }
 
   inline PrefsInterface* powerwash_safe_prefs() override {
-      return &powerwash_safe_prefs_;
-    }
+    return powerwash_safe_prefs_.get();
+  }
 
   inline PayloadStateInterface* payload_state() override {
     return &payload_state_;
@@ -136,10 +136,10 @@
   MetricsLibrary metrics_lib_;
 
   // Interface for persisted store.
-  Prefs prefs_;
+  std::unique_ptr<PrefsInterface> prefs_;
 
   // Interface for persisted store that persists across powerwashes.
-  Prefs powerwash_safe_prefs_;
+  std::unique_ptr<PrefsInterface> powerwash_safe_prefs_;
 
   // All state pertaining to payload state such as response, URL, backoff
   // states.
diff --git a/update_attempter.cc b/update_attempter.cc
index 6152992..c5320f7 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -41,6 +41,7 @@
 #include <power_manager/dbus-proxies.h>
 #include <update_engine/dbus-constants.h>
 
+#include "update_engine/boot_control_interface.h"
 #include "update_engine/certificate_checker.h"
 #include "update_engine/clock_interface.h"
 #include "update_engine/constants.h"
@@ -56,6 +57,7 @@
 #include "update_engine/omaha_response_handler_action.h"
 #include "update_engine/p2p_manager.h"
 #include "update_engine/payload_state_interface.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/postinstall_runner_action.h"
 #include "update_engine/prefs_interface.h"
 #include "update_engine/subprocess.h"
@@ -819,13 +821,13 @@
     forced_omaha_url_ = omaha_url;
   }
   if (omaha_url == kScheduledAUTestURLRequest) {
-    forced_omaha_url_ = chromeos_update_engine::kAUTestOmahaUrl;
+    forced_omaha_url_ = constants::kOmahaDefaultAUTestURL;
     // Pretend that it's not user-initiated even though it is,
     // so as to test scattering logic, etc. which get kicked off
     // only in scheduled update checks.
     interactive = false;
   } else if (omaha_url == kAUTestURLRequest) {
-    forced_omaha_url_ = chromeos_update_engine::kAUTestOmahaUrl;
+    forced_omaha_url_ = constants::kOmahaDefaultAUTestURL;
   }
 
   if (forced_update_pending_callback_.get()) {
@@ -1184,22 +1186,15 @@
   // the script asynchronously to avoid blocking the event loop regardless of
   // the script runtime.
   update_boot_flags_running_ = true;
-  LOG(INFO) << "Updating boot flags...";
-  vector<string> cmd{"/usr/sbin/chromeos-setgoodkernel"};
-  if (skip_set_good_kernel_) {
-    CompleteUpdateBootFlags(1, "Skipping the call to set");
-  } else {
-    if (!Subprocess::Get().Exec(cmd,
-                                Bind(&UpdateAttempter::CompleteUpdateBootFlags,
-                                     base::Unretained(this)))) {
-      CompleteUpdateBootFlags(
-          1, "Failed to launch process to mark kernel as good");
-    }
+  LOG(INFO) << "Marking booted slot as good.";
+  if (!system_state_->boot_control()->MarkBootSuccessfulAsync(Bind(
+          &UpdateAttempter::CompleteUpdateBootFlags, base::Unretained(this)))) {
+    LOG(ERROR) << "Failed to mark current boot as successful.";
+    CompleteUpdateBootFlags(false);
   }
 }
 
-void UpdateAttempter::CompleteUpdateBootFlags(int return_code,
-                                              const string& output) {
+void UpdateAttempter::CompleteUpdateBootFlags(bool successful) {
   update_boot_flags_running_ = false;
   updated_boot_flags_ = true;
   if (start_action_processor_) {
@@ -1232,8 +1227,10 @@
   if (!system_state_->hardware()->IsOfficialBuild())
     flags |= static_cast<uint32_t>(ErrorCode::kTestImageFlag);
 
-  if (omaha_request_params_->update_url() != kProductionOmahaUrl)
+  if (omaha_request_params_->update_url() !=
+      constants::kOmahaDefaultProductionURL) {
     flags |= static_cast<uint32_t>(ErrorCode::kTestOmahaUrlFlag);
+  }
 
   return flags;
 }
diff --git a/update_attempter.h b/update_attempter.h
index 12da537..06a3dac 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -124,8 +124,8 @@
   // attempt goes through this method.
   void UpdateBootFlags();
 
-  // Subprocess::Exec callback.
-  void CompleteUpdateBootFlags(int return_code, const std::string& output);
+  // Called when the boot flags have been updated.
+  void CompleteUpdateBootFlags(bool success);
 
   UpdateStatus status() const { return status_; }
 
@@ -473,10 +473,6 @@
   // True if UpdateBootFlags is running.
   bool update_boot_flags_running_ = false;
 
-  // Whether we should skip the async call to "setgoodkernel" command. Used in
-  // unittests.
-  bool skip_set_good_kernel_ = false;
-
   // True if the action processor needs to be started by the boot flag updater.
   bool start_action_processor_ = false;
 
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 4e48d0b..10ab843 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -47,6 +47,7 @@
 #include "update_engine/mock_p2p_manager.h"
 #include "update_engine/mock_payload_state.h"
 #include "update_engine/mock_prefs.h"
+#include "update_engine/platform_constants.h"
 #include "update_engine/postinstall_runner_action.h"
 #include "update_engine/prefs.h"
 #include "update_engine/test_utils.h"
@@ -124,8 +125,6 @@
 
     // Finish initializing the attempter.
     attempter_.Init();
-    // Don't run setgoodkernel command.
-    attempter_.skip_set_good_kernel_ = true;
   }
 
   void SetUp() override {
@@ -1009,16 +1008,14 @@
   fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
   fake_system_state_.fake_hardware()->SetIsNormalBootMode(true);
   attempter_.CheckForUpdate("", "autest", true);
-  EXPECT_EQ(chromeos_update_engine::kAUTestOmahaUrl,
-            attempter_.forced_omaha_url());
+  EXPECT_EQ(constants::kOmahaDefaultAUTestURL, attempter_.forced_omaha_url());
 }
 
 TEST_F(UpdateAttempterTest, CheckForUpdateScheduledAUTest) {
   fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
   fake_system_state_.fake_hardware()->SetIsNormalBootMode(true);
   attempter_.CheckForUpdate("", "autest-scheduled", true);
-  EXPECT_EQ(chromeos_update_engine::kAUTestOmahaUrl,
-            attempter_.forced_omaha_url());
+  EXPECT_EQ(constants::kOmahaDefaultAUTestURL, attempter_.forced_omaha_url());
 }
 
 }  // namespace chromeos_update_engine
diff --git a/update_engine.gyp b/update_engine.gyp
index e2a8de0..6138b87 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -189,6 +189,7 @@
         'payload_constants.cc',
         'payload_state.cc',
         'payload_verifier.cc',
+        'platform_constants_chromeos.cc',
         'postinstall_runner_action.cc',
         'prefs.cc',
         'proxy_resolver.cc',
diff --git a/update_engine.rc b/update_engine.rc
new file mode 100644
index 0000000..3d673a7
--- /dev/null
+++ b/update_engine.rc
@@ -0,0 +1,7 @@
+on boot
+    mkdir /data/misc/update_engine 0700 system system
+
+service update_engine /system/bin/update_engine --logtostderr --foreground
+    class late_start
+    user system
+    group system dbus inet
diff --git a/utils.cc b/utils.cc
index 2baa087..cf7913c 100644
--- a/utils.cc
+++ b/utils.cc
@@ -85,6 +85,9 @@
 // in GetFileFormat.
 const int kGetFileFormatMaxHeaderSize = 32;
 
+// The path to the kernel's boot_id.
+const char kBootIdPath[] = "/proc/sys/kernel/random/boot_id";
+
 // Return true if |disk_name| is an MTD or a UBI device. Note that this test is
 // simply based on the name of the device.
 bool IsMtdDeviceName(const string& disk_name) {
@@ -1609,6 +1612,13 @@
   return true;
 }
 
+bool GetBootId(string* boot_id) {
+  TEST_AND_RETURN_FALSE(
+      base::ReadFileToString(base::FilePath(kBootIdPath), boot_id));
+  base::TrimWhitespaceASCII(*boot_id, base::TRIM_TRAILING, boot_id);
+  return true;
+}
+
 }  // namespace utils
 
 }  // namespace chromeos_update_engine
diff --git a/utils.h b/utils.h
index 803a0d6..6668c39 100644
--- a/utils.h
+++ b/utils.h
@@ -416,6 +416,11 @@
                  chromeos::Blob* out_data, ssize_t out_data_size,
                  size_t block_size);
 
+// Read the current boot identifier and store it in |boot_id|. This identifier
+// is constants during the same boot of the kernel and is regenerated after
+// reboot. Returns whether it succeeded getting the boot_id.
+bool GetBootId(std::string* boot_id);
+
 }  // namespace utils