Merge "Move partition info to PartitionUpdate in payload verison 2."
diff --git a/hardware_android.cc b/hardware_android.cc
index 6df5cd9..34f8c41 100644
--- a/hardware_android.cc
+++ b/hardware_android.cc
@@ -18,6 +18,7 @@
 
 #include <base/files/file_util.h>
 #include <chromeos/make_unique_ptr.h>
+#include <cutils/properties.h>
 
 #include "update_engine/hardware.h"
 
@@ -41,18 +42,36 @@
 
 }  // namespace hardware
 
+// In Android there are normally three kinds of builds: eng, userdebug and user.
+// These builds target respectively a developer build, a debuggable version of
+// the final product and the pristine final product the end user will run.
+// Apart from the ro.build.type property name, they differ in the following
+// properties that characterize the builds:
+// * eng builds: ro.secure=0 and ro.debuggable=1
+// * userdebug builds: ro.secure=1 and ro.debuggable=1
+// * user builds: ro.secure=1 and ro.debuggable=0
+//
+// See IsOfficialBuild() and IsNormalMode() for the meaning of these options in
+// Android.
+
 bool HardwareAndroid::IsOfficialBuild() const {
-  // TODO(deymo): Read the kind of build we are running from the metadata
-  // partition.
-  LOG(WARNING) << "STUB: Assuming we are not an official build.";
-  return false;
+  // We run an official build iff ro.secure == 1, because we expect the build to
+  // behave like the end user product and check for updates. Note that while
+  // developers are able to build "official builds" by just running "make user",
+  // that will only result in a more restrictive environment. The important part
+  // is that we don't produce and push "non-official" builds to the end user.
+  //
+  // In case of a non-bool value, we take the most restrictive option and
+  // assume we are in an official-build.
+  return property_get_bool("ro.secure", 1) != 0;
 }
 
 bool HardwareAndroid::IsNormalBootMode() const {
-  // TODO(deymo): Read the kind of build we are running from the metadata
-  // partition.
-  LOG(WARNING) << "STUB: Assuming we are in dev-mode.";
-  return false;
+  // We are running in "dev-mode" iff ro.debuggable == 1. In dev-mode the
+  // update_engine will allow extra developers options, such as providing a
+  // different update URL. In case of error, we assume the build is in
+  // normal-mode.
+  return property_get_bool("ro.debuggable", 0) != 1;
 }
 
 bool HardwareAndroid::IsOOBEComplete(base::Time* out_time_of_oobe) const {
diff --git a/hardware_chromeos.cc b/hardware_chromeos.cc
index d8c659a..2bd0de8 100644
--- a/hardware_chromeos.cc
+++ b/hardware_chromeos.cc
@@ -72,7 +72,6 @@
 
 bool HardwareChromeOS::IsNormalBootMode() const {
   bool dev_mode = VbGetSystemPropertyInt("devsw_boot") != 0;
-  LOG_IF(INFO, dev_mode) << "Booted in dev mode.";
   return !dev_mode;
 }
 
diff --git a/hardware_interface.h b/hardware_interface.h
index df8f227..46dd058 100644
--- a/hardware_interface.h
+++ b/hardware_interface.h
@@ -33,12 +33,15 @@
  public:
   virtual ~HardwareInterface() {}
 
-  // Returns true if this is an official Chrome OS build, false otherwise.
+  // Returns whether this is an official build. Official build means that the
+  // server maintains and updates the build, so update_engine should run and
+  // periodically check for updates.
   virtual bool IsOfficialBuild() const = 0;
 
   // Returns true if the boot mode is normal or if it's unable to
   // determine the boot mode. Returns false if the boot mode is
-  // developer.
+  // developer. A dev-mode boot will allow the user to access developer-only
+  // features.
   virtual bool IsNormalBootMode() const = 0;
 
   // Returns true if the OOBE process has been completed and EULA accepted,
diff --git a/real_system_state.cc b/real_system_state.cc
index 34ac5ed..1d11090 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -48,6 +48,9 @@
     return false;
   }
 
+  LOG_IF(INFO, !hardware_->IsNormalBootMode()) << "Booted in dev mode.";
+  LOG_IF(INFO, !hardware_->IsOfficialBuild()) << "Booted non-official build.";
+
   if (!shill_proxy_.Init()) {
     LOG(ERROR) << "Failed to initialize shill proxy.";
     return false;
diff --git a/update_metadata.proto b/update_metadata.proto
index be97c26..c856405 100644
--- a/update_metadata.proto
+++ b/update_metadata.proto
@@ -202,23 +202,36 @@
   // example, in Chrome OS this could be "ROOT" or "KERNEL".
   required string partition_name = 1;
 
-  // Whether this partition carries a filesystem with a "/postinstall" script
-  // that must be run to finalize the update process.
+  // Whether this partition carries a filesystem with post-install program that
+  // must be run to finalize the update process. See also |postinstall_path| and
+  // |filesystem_type|.
   optional bool run_postinstall = 2;
 
+  // The path of the executable program to run during the post-install step,
+  // relative to the root of this filesystem. If not set, the default "postinst"
+  // will be used. This setting is only used when |run_postinstall| is set and
+  // true.
+  optional string postinstall_path = 3;
+
+  // The filesystem type as passed to the mount(2) syscall when mounting the new
+  // filesystem to run the post-install program. If not set, a fixed list of
+  // filesystems will be attempted. This setting is only used if
+  // |run_postinstall| is set and true.
+  optional string filesystem_type = 4;
+
   // If present, a list of signatures of the new_partition_info.hash signed with
   // different keys. If the update_engine daemon requires vendor-signed images
   // and has its public key installed, one of the signatures should be valid
   // for /postinstall to run.
-  repeated Signatures.Signature new_partition_signature = 3;
+  repeated Signatures.Signature new_partition_signature = 5;
 
-  optional PartitionInfo old_partition_info = 4;
-  optional PartitionInfo new_partition_info = 5;
+  optional PartitionInfo old_partition_info = 6;
+  optional PartitionInfo new_partition_info = 7;
 
   // The list of operations to be performed to apply this PartitionUpdate. The
   // associated operation blobs (in operations[i].data_offset, data_length)
   // should be stored contiguously and in the same order.
-  repeated InstallOperation operations = 6;
+  repeated InstallOperation operations = 8;
 }
 
 message DeltaArchiveManifest {