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))