Add security patch level to update manifest

When installing a full OTA, the target build might have a newer
timestamp but older SPL. In these caess, update_engine will fail to
recognize the SPL downgrade and skip data wipe, causing /data decryption
to fail on next reboot. To fix this issue, add a SPL field to update
manifest. update_engine will check this field on OTA install and
schedule data wipe as needed.

Test: install OTA with newer timestamp but older SPL, make sure data wipe is scheduled
Bug: 242812845


Change-Id: I9d1dd73b46323939bbf990e29da5cc0ba79f86e2
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index fc8858f..47eb353 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -28,10 +28,12 @@
 #include <utility>
 #include <vector>
 
+#include <android-base/properties.h>
 #include <base/files/file_util.h>
 #include <base/format_macros.h>
 #include <base/metrics/histogram_macros.h>
 #include <base/strings/string_number_conversions.h>
+#include <base/strings/stringprintf.h>
 #include <base/time/time.h>
 #include <brillo/data_encoding.h>
 #include <bsdiff/bspatch.h>
@@ -44,24 +46,15 @@
 #include "update_engine/common/error_code_utils.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/prefs_interface.h"
-#include "update_engine/common/subprocess.h"
 #include "update_engine/common/terminator.h"
 #include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/bzip_extent_writer.h"
-#include "update_engine/payload_consumer/cached_file_descriptor.h"
-#include "update_engine/payload_consumer/certificate_parser_interface.h"
-#include "update_engine/payload_consumer/extent_reader.h"
-#include "update_engine/payload_consumer/extent_writer.h"
 #include "update_engine/payload_consumer/partition_update_generator_interface.h"
 #include "update_engine/payload_consumer/partition_writer.h"
 #if USE_FEC
 #include "update_engine/payload_consumer/fec_file_descriptor.h"
 #endif  // USE_FEC
-#include "update_engine/payload_consumer/file_descriptor_utils.h"
-#include "update_engine/payload_consumer/mount_history.h"
 #include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_consumer/payload_verifier.h"
-#include "update_engine/payload_consumer/xz_extent_writer.h"
 
 using google::protobuf::RepeatedPtrField;
 using std::min;
@@ -398,6 +391,23 @@
       base::TimeDelta::FromMinutes(5),                                      \
       20);
 
+void DeltaPerformer::CheckSPLDowngrade() {
+  const auto new_spl = manifest_.security_patch_level();
+  const auto current_spl =
+      android::base::GetProperty("ro.build.version.security_patch", "");
+  if (current_spl.empty()) {
+    LOG(ERROR) << "Failed to get ro.build.version.security_patch, unable to "
+                  "determine if this OTA is a SPL downgrade.";
+    return;
+  }
+  if (new_spl < current_spl) {
+    install_plan_->powerwash_required = true;
+    LOG(INFO) << "Target build SPL " << new_spl
+              << " is older than current build's SPL " << current_spl
+              << ", this OTA is an SPL downgrade. Data wipe will be required";
+  }
+}
+
 // Wrapper around write. Returns true if all requested bytes
 // were written, or false on any error, regardless of progress
 // and stores an action exit code in |error|.
@@ -444,6 +454,8 @@
 
     block_size_ = manifest_.block_size();
 
+    CheckSPLDowngrade();
+
     // This populates |partitions_| and the |install_plan.partitions| with the
     // list of partitions from the manifest.
     if (!ParseManifestPartitions(error))
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index dd71467..633c533 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -32,10 +32,9 @@
 
 #include "update_engine/common/hash_calculator.h"
 #include "update_engine/common/platform_constants.h"
-#include "update_engine/payload_consumer/file_descriptor.h"
 #include "update_engine/payload_consumer/file_writer.h"
 #include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/payload_consumer/partition_writer.h"
+#include "update_engine/payload_consumer/partition_writer_interface.h"
 #include "update_engine/payload_consumer/payload_metadata.h"
 #include "update_engine/payload_consumer/payload_verifier.h"
 #include "update_engine/update_metadata.pb.h"
@@ -88,7 +87,7 @@
   // FileWriter's Write implementation where caller doesn't care about
   // error codes.
   bool Write(const void* bytes, size_t count) override {
-    ErrorCode error;
+    ErrorCode error{};
     return Write(bytes, count, &error);
   }
 
@@ -315,6 +314,8 @@
   // Check if partition `part_name` is a dynamic partition.
   bool IsDynamicPartition(const std::string& part_name, uint32_t slot);
 
+  void CheckSPLDowngrade();
+
   // Update Engine preference store.
   PrefsInterface* prefs_;
 
diff --git a/payload_consumer/partition_writer_unittest.cc b/payload_consumer/partition_writer_unittest.cc
index 331a061..4910594 100644
--- a/payload_consumer/partition_writer_unittest.cc
+++ b/payload_consumer/partition_writer_unittest.cc
@@ -26,16 +26,15 @@
 #include "update_engine/common/hash_calculator.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/delta_performer.h"
-#include "update_engine/payload_consumer/extent_reader.h"
 #include "update_engine/payload_consumer/extent_writer.h"
 #include "update_engine/payload_consumer/fake_file_descriptor.h"
 #include "update_engine/payload_consumer/file_descriptor.h"
 #include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/payload_consumer/partition_writer.h"
+#include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_generator/annotated_operation.h"
 #include "update_engine/payload_generator/delta_diff_generator.h"
 #include "update_engine/payload_generator/extent_ranges.h"
-#include "update_engine/payload_generator/payload_file.h"
 #include "update_engine/payload_generator/payload_generation_config.h"
 #include "update_engine/update_metadata.pb.h"