Merge tag 'android-13.0.0_r16' into staging/lineage-20.0_merge-android-13.0.0_r16

Android 13.0.0 Release 16 (TQ1A.221205.011)

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCY45r+QAKCRDorT+BmrEO
# eJ2eAKCPwwS819aZBSX7weztedjTRHiUHACfT26XIHeFojc9EQbZCL2C51uP6Zw=
# =Lsvh
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Dec  6 00:08:57 2022 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [marginal]
# gpg: initial-contribution@android.com: Verified 1444 signatures in the past
#      13 months.  Encrypted 4 messages in the past 10 months.
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 4340 D135 70EF 945E 8381  0964 E8AD 3F81 9AB1 0E78

# By Kelvin Zhang
# Via Automerger Merge Worker (14) and others
* tag 'android-13.0.0_r16':
  Cleanup DAP state before installing new OTA
  Fix partition mapping bug

Change-Id: I4a66db975e0505b939c7d75e7797287c5e0bd23b
diff --git a/Android.bp b/Android.bp
index cace5b6..858c575 100644
--- a/Android.bp
+++ b/Android.bp
@@ -194,7 +194,16 @@
         "libfec",
         "liblz4",
         "libziparchive",
+        "libprocessgroup",
+        "libselinux",
     ],
+    product_variables: {
+        debuggable: {
+            cflags: [
+                "-DRUN_BACKUPTOOL",
+            ],
+        },
+    },
 }
 
 cc_library_static {
diff --git a/aosp/binder_service_android.cc b/aosp/binder_service_android.cc
index 84b5b7a..c2231fb 100644
--- a/aosp/binder_service_android.cc
+++ b/aosp/binder_service_android.cc
@@ -258,4 +258,11 @@
   return Status::ok();
 }
 
+Status BinderUpdateEngineAndroidService::setPerformanceMode(bool enable) {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->SetPerformanceMode(enable, &error))
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
 }  // namespace chromeos_update_engine
diff --git a/aosp/binder_service_android.h b/aosp/binder_service_android.h
index f1ce6b5..6bd1ee3 100644
--- a/aosp/binder_service_android.h
+++ b/aosp/binder_service_android.h
@@ -79,6 +79,7 @@
       int64_t* return_value) override;
   android::binder::Status cleanupSuccessfulUpdate(
       const android::sp<android::os::IUpdateEngineCallback>& callback) override;
+  android::binder::Status setPerformanceMode(bool enable) override;
 
  private:
   // Remove the passed |callback| from the list of registered callbacks. Called
diff --git a/aosp/service_delegate_android_interface.h b/aosp/service_delegate_android_interface.h
index b3660ab..b50f0f9 100644
--- a/aosp/service_delegate_android_interface.h
+++ b/aosp/service_delegate_android_interface.h
@@ -129,6 +129,8 @@
       std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
       brillo::ErrorPtr* error) = 0;
 
+  virtual bool SetPerformanceMode(bool enable, brillo::ErrorPtr* error) = 0;
+
  protected:
   ServiceDelegateAndroidInterface() = default;
 };
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index 1d35b5e..b02e600 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -31,6 +31,7 @@
 #include <brillo/message_loops/message_loop.h>
 #include <brillo/strings/string_utils.h>
 #include <log/log_safetynet.h>
+#include <processgroup/processgroup.h>
 
 #include "update_engine/aosp/cleanup_previous_update_action.h"
 #include "update_engine/common/constants.h"
@@ -145,6 +146,7 @@
   metrics_reporter_ = metrics::CreateMetricsReporter(
       boot_control_->GetDynamicPartitionControl(), &install_plan_);
   network_selector_ = network::CreateNetworkSelector();
+  SetTaskProfiles(0, {"OtaProfiles"});
 }
 
 UpdateAttempterAndroid::~UpdateAttempterAndroid() {
@@ -560,6 +562,23 @@
   return true;
 }
 
+bool UpdateAttempterAndroid::SetPerformanceMode(bool enable,
+                                                brillo::ErrorPtr* error) {
+  LOG(INFO) << (enable ? "Enabling" : "Disabling") << " performance mode.";
+
+  if (performance_mode_ == enable)
+    return true;
+  bool ret;
+  if (enable)
+    ret = SetTaskProfiles(0, {"ProcessCapacityMax", "HighIoPriority", "MaxPerformance"});
+  else
+    ret = SetTaskProfiles(0, {"OtaProfiles"});
+  if (!ret)
+    return LogAndSetError(error, FROM_HERE, "Could not change profiles");
+  performance_mode_ = enable;
+  return true;
+}
+
 void UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor,
                                             ErrorCode code) {
   LOG(INFO) << "Processing Done.";
diff --git a/aosp/update_attempter_android.h b/aosp/update_attempter_android.h
index 5d832e0..4c5c70b 100644
--- a/aosp/update_attempter_android.h
+++ b/aosp/update_attempter_android.h
@@ -100,6 +100,8 @@
                                    brillo::ErrorPtr* error) override;
   bool resetShouldSwitchSlotOnReboot(brillo::ErrorPtr* error) override;
 
+  bool SetPerformanceMode(bool enable, brillo::ErrorPtr* error) override;
+
   // ActionProcessorDelegate methods:
   void ProcessingDone(const ActionProcessor* processor,
                       ErrorCode code) override;
@@ -282,6 +284,8 @@
   // The path to the zip file with X509 certificates.
   std::string update_certificates_path_{constants::kUpdateCertificatesPath};
 
+  bool performance_mode_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(UpdateAttempterAndroid);
 };
 
diff --git a/aosp/update_engine_client_android.cc b/aosp/update_engine_client_android.cc
index c00e9f5..a350409 100644
--- a/aosp/update_engine_client_android.cc
+++ b/aosp/update_engine_client_android.cc
@@ -169,6 +169,7 @@
               false,
               "Wait for previous update to merge. "
               "Only available after rebooting to new slot.");
+  DEFINE_bool(perf_mode, false, "Enable perf mode.");
   // Boilerplate init commands.
   base::CommandLine::Init(argc_, argv_);
   brillo::FlagHelper::Init(argc_, argv_, "Android Update Engine Client");
@@ -292,6 +293,10 @@
     keep_running = true;
   }
 
+  if (FLAGS_perf_mode) {
+    return ExitWhenIdle(service_->setPerformanceMode(true));
+  }
+
   if (FLAGS_update) {
     auto and_headers = ParseHeaders(FLAGS_headers);
     Status status = service_->applyPayload(
diff --git a/binder_bindings/android/os/IUpdateEngine.aidl b/binder_bindings/android/os/IUpdateEngine.aidl
index 4043b1a..061397c 100644
--- a/binder_bindings/android/os/IUpdateEngine.aidl
+++ b/binder_bindings/android/os/IUpdateEngine.aidl
@@ -76,4 +76,6 @@
    * but needs reboot). DEVICE_CORRUPTED for permanent errors.
    */
   void cleanupSuccessfulUpdate(IUpdateEngineCallback callback);
+  /** @hide */
+  void setPerformanceMode(in boolean enable);
 }
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index fc8858f..f9379b1 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -359,12 +359,15 @@
     if (perform_verification) {
       return MetadataParseResult::kError;
     }
-  } else {
+  }
+#ifndef __ANDROID_RECOVERY__
+  else {
     // We have the full metadata in |payload|. Verify its integrity
     // and authenticity based on the information we have in Omaha response.
     *error = payload_metadata_.ValidateMetadataSignature(
         payload, payload_->metadata_signature, *payload_verifier);
   }
+#endif
   if (*error != ErrorCode::kSuccess) {
     if (install_plan_->hash_checks_mandatory) {
       // The autoupdate_CatchBadSignatures test checks for this string
@@ -1176,12 +1179,14 @@
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
                       hash_data.size() == kSHA256Size);
 
+#ifndef __ANDROID_RECOVERY__
   if (!payload_verifier->VerifySignature(signatures_message_data_, hash_data)) {
     // The autoupdate_CatchBadSignatures test checks for this string
     // in log-files. Keep in sync.
     LOG(ERROR) << "Public key verification failed, thus update failed.";
     return ErrorCode::kDownloadPayloadPubKeyVerificationError;
   }
+#endif
 
   LOG(INFO) << "Payload hash matches value in payload.";
   return ErrorCode::kSuccess;
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index a72462a..8f387ca 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -19,6 +19,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <selinux/selinux.h>
 #include <sys/mount.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -178,6 +179,75 @@
   EnsureUnmounted();
 
 #ifdef __ANDROID__
+#if !defined(__ANDROID_RECOVERY__) && defined(RUN_BACKUPTOOL)
+  // Check the currently installed /system partition to see if it's ever
+  // been mounted R/W. If it has, we'll run backuptool scripts for it
+  // since we can safely assume something on the partition has been
+  // changed and we won't be breaking verity (since it's already been
+  // broken). If it hasn't ever been mounted R/W, we can assume that
+  // the rom that the user is upgrading to will have everything they
+  // need and no addon.d scripts will need to be run to retain stuff
+  // after the upgrade.
+  //
+  // Use the following disk layout info to make the determination
+  // https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout
+  // Super block starts from block 0, offset 0x400
+  //   0x2C: len32 Mount time
+  //   0x30: len32 Write time
+  //   0x34: len16 Number of mounts since the last fsck
+  //   0x38: len16 Magic signature 0xEF53
+
+  string source_path;
+
+  if (install_plan_.source_slot != BootControlInterface::kInvalidSlot) {
+    boot_control_->GetPartitionDevice(partition.name, install_plan_.source_slot, &source_path);
+  }
+
+  uint16_t mount_count = 0;
+
+  if (!source_path.empty()) {
+    brillo::Blob chunk;
+
+    utils::ReadFileChunk(source_path, 0x400 + 0x34, sizeof(uint16_t), &chunk);
+    mount_count = *reinterpret_cast<uint16_t*>(chunk.data());
+  }
+
+  LOG(INFO) << source_path << " has been mounted R/W " << mount_count << " times.";
+
+  if (mount_count > 0) {
+    if (!utils::SetBlockDeviceReadOnly(mountable_device, false)) {
+      LOG(ERROR) << "Error marking the device " << mountable_device << " writeable.";
+      return false;
+    }
+    // Mount the target partition R/W
+    LOG(INFO) << "Running backuptool scripts";
+    utils::MountFilesystem(mountable_device, fs_mount_dir_, MS_NOATIME | MS_NODEV | MS_NODIRATIME,
+                           partition.filesystem_type, "seclabel");
+
+    // Switch to a permissive domain
+    if (setexeccon("u:r:backuptool:s0")) {
+      LOG(ERROR) << "Failed to set backuptool context";
+      return false;
+    }
+
+    // Run backuptool script
+    int ret = system("/postinstall/system/bin/backuptool_postinstall.sh");
+    if (ret == -1 || WEXITSTATUS(ret) != 0) {
+      LOG(ERROR) << "Backuptool postinstall step failed. ret=" << ret;
+    }
+
+    // Switch back to update_engine domain
+    if (setexeccon(nullptr)) {
+      LOG(ERROR) << "Failed to set update_engine context";
+      return false;
+    }
+  } else {
+    LOG(INFO) << "Skipping backuptool scripts";
+  }
+
+  utils::UnmountFilesystem(fs_mount_dir_);
+#endif  // !__ANDROID_RECOVERY__ && RUN_BACKUPTOOL
+
   // In Chromium OS, the postinstall step is allowed to write to the block
   // device on the target image, so we don't mark it as read-only and should
   // be read-write since we just wrote to it during the update.
diff --git a/update_engine.rc b/update_engine.rc
index bc6447b..76072d5 100644
--- a/update_engine.rc
+++ b/update_engine.rc
@@ -2,7 +2,6 @@
     class late_start
     user root
     group root system wakelock inet cache media_rw
-    task_profiles OtaProfiles
     disabled
 
 on property:ro.boot.slot_suffix=*