Implement trigger postinstall API

Test: adb shell update_engine_client --trigger_postinstall=system
Bug: 377557752
Change-Id: Ieb28e86bd979502c5b208cd8df917f3e49a50f0b
diff --git a/payload_consumer/filesystem_verifier_action.cc b/payload_consumer/filesystem_verifier_action.cc
index 8c21673..956f90b 100644
--- a/payload_consumer/filesystem_verifier_action.cc
+++ b/payload_consumer/filesystem_verifier_action.cc
@@ -16,7 +16,6 @@
 
 #include "update_engine/payload_consumer/filesystem_verifier_action.h"
 
-#include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -28,7 +27,6 @@
 #include <memory>
 #include <numeric>
 #include <string>
-#include <utility>
 
 #include <base/bind.h>
 #include <brillo/data_encoding.h>
diff --git a/payload_consumer/payload_metadata.cc b/payload_consumer/payload_metadata.cc
index d2e42f0..649d9be 100644
--- a/payload_consumer/payload_metadata.cc
+++ b/payload_consumer/payload_metadata.cc
@@ -154,7 +154,7 @@
 }
 
 ErrorCode PayloadMetadata::ValidateMetadataSignature(
-    const brillo::Blob& payload,
+    const std::string_view payload,
     const string& metadata_signature,
     const PayloadVerifier& payload_verifier) const {
   if (payload.size() < metadata_size_ + metadata_signature_size_)
diff --git a/payload_consumer/payload_metadata.h b/payload_consumer/payload_metadata.h
index 4d2d5b0..fd24f20 100644
--- a/payload_consumer/payload_metadata.h
+++ b/payload_consumer/payload_metadata.h
@@ -17,14 +17,12 @@
 #ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_METADATA_H_
 #define UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_METADATA_H_
 
-#include <inttypes.h>
-
 #include <string>
-#include <vector>
 
 #include <android-base/macros.h>
 #include <brillo/secure_blob.h>
 
+#include "update_engine/common/utils.h"
 #include "update_engine/common/error_code.h"
 #include "update_engine/payload_consumer/payload_verifier.h"
 #include "update_engine/update_metadata.pb.h"
@@ -55,6 +53,12 @@
   // the payload.
   MetadataParseResult ParsePayloadHeader(const brillo::Blob& payload,
                                          ErrorCode* error);
+  MetadataParseResult ParsePayloadHeader(std::string_view payload,
+                                         ErrorCode* error) {
+    return ParsePayloadHeader(reinterpret_cast<const uint8_t*>(payload.data()),
+                              payload.size(),
+                              error);
+  }
   MetadataParseResult ParsePayloadHeader(const unsigned char* payload,
                                          size_t size,
                                          ErrorCode* error);
@@ -69,9 +73,16 @@
   // to the payload server doesn't exploit any vulnerability in the code that
   // parses the protocol buffer.
   ErrorCode ValidateMetadataSignature(
-      const brillo::Blob& payload,
+      std::string_view payload,
       const std::string& metadata_signature,
       const PayloadVerifier& payload_verifier) const;
+  ErrorCode ValidateMetadataSignature(
+      const std::vector<uint8_t>& payload,
+      const std::string& metadata_signature,
+      const PayloadVerifier& payload_verifier) const {
+    return ValidateMetadataSignature(
+        ToStringView(payload), metadata_signature, payload_verifier);
+  }
 
   // Returns the major payload version. If the version was not yet parsed,
   // returns zero.
@@ -93,6 +104,12 @@
   bool GetManifest(const unsigned char* payload,
                    size_t size,
                    DeltaArchiveManifest* out_manifest) const;
+  bool GetManifest(std::string_view payload,
+                   DeltaArchiveManifest* out_manifest) const {
+    return GetManifest(reinterpret_cast<const uint8_t*>(payload.data()),
+                       payload.size(),
+                       out_manifest);
+  }
 
   // Parses a payload file |payload_path| and prepares the metadata properties,
   // manifest and metadata signatures. Can be used as an easy to use utility to
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index 5a6eeab..da9075a 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -35,7 +35,6 @@
 #include "update_engine/common/action_processor.h"
 #include "update_engine/common/boot_control_interface.h"
 #include "update_engine/common/error_code_utils.h"
-#include "update_engine/common/platform_constants.h"
 #include "update_engine/common/subprocess.h"
 #include "update_engine/common/utils.h"
 
@@ -280,14 +279,20 @@
   // Runs the postinstall script asynchronously to free up the main loop while
   // it's running.
   vector<string> command = {abs_path};
-#ifdef __ANDROID__
   // In Brillo and Android, we pass the slot number and status fd.
   command.push_back(std::to_string(install_plan_.target_slot));
   command.push_back(std::to_string(kPostinstallStatusFd));
-#else
-  // Chrome OS postinstall expects the target rootfs as the first parameter.
-  command.push_back(partition.target_path);
-#endif  // __ANDROID__
+  // If install plan only contains one partition, notify the script. Most likely
+  // we are scheduled by `triggerPostinstall` API. Certain scripts might want
+  // different behaviors when triggered by `triggerPostinstall` API. For
+  // example, call scheduler API to schedule a postinstall run during
+  // applyPayload(), and only run actual postinstall work if scheduled by
+  // external async scheduler.
+  if (install_plan_.partitions.size() == 1 &&
+      !install_plan_.switch_slot_on_reboot &&
+      install_plan_.download_url.starts_with(kPrefsManifestBytes)) {
+    command.push_back("1");
+  }
 
   current_command_ = Subprocess::Get().ExecFlags(
       command,