diff --git a/installcommand.cpp b/installcommand.cpp
new file mode 100644
index 0000000..d6e95c8
--- /dev/null
+++ b/installcommand.cpp
@@ -0,0 +1,337 @@
+<<<<<<< HEAD   (fc79aa Encryption: don't try wrapped key if not needed)
+=======
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+#ifdef AB_OTA_UPDATER
+#include <inttypes.h>
+#include <map>
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#endif
+#include <cutils/properties.h>
+
+#include "common.h"
+#include "installcommand.h"
+#include "zipwrap.hpp"
+#ifndef USE_MINZIP
+#include <ziparchive/zip_archive.h>
+#include <vintf/VintfObjectRecovery.h>
+#endif
+#ifdef USE_OLD_VERIFIER
+#include "verifier24/verifier.h"
+#else
+#include "verifier.h"
+#endif
+
+#ifdef AB_OTA_UPDATER
+
+static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
+static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
+static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
+
+// This function parses and returns the build.version.incremental
+static int parse_build_number(std::string str) {
+    size_t pos = str.find("=");
+    if (pos != std::string::npos) {
+        std::string num_string = android::base::Trim(str.substr(pos+1));
+        int build_number;
+        if (android::base::ParseInt(num_string.c_str(), &build_number, 0)) {
+            return build_number;
+        }
+    }
+
+    printf("Failed to parse build number in %s.\n", str.c_str());
+    return -1;
+}
+
+bool read_metadata_from_package(ZipWrap* zip, std::string* meta_data) {
+    long size = zip->GetUncompressedSize(METADATA_PATH);
+    if (size <= 0)
+		return false;
+
+    meta_data->resize(size, '\0');
+    if (!zip->ExtractToBuffer(METADATA_PATH, reinterpret_cast<uint8_t*>(&(*meta_data)[0]))) {
+        printf("Failed to read metadata in update package.\n");
+        return false;
+    }
+    return true;
+}
+
+// Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
+void read_source_target_build(ZipWrap* zip/*, std::vector<std::string>& log_buffer*/) {
+    std::string meta_data;
+    if (!read_metadata_from_package(zip, &meta_data)) {
+        return;
+    }
+    // Examples of the pre-build and post-build strings in metadata:
+    // pre-build-incremental=2943039
+    // post-build-incremental=2951741
+    std::vector<std::string> lines = android::base::Split(meta_data, "\n");
+    for (const std::string& line : lines) {
+        std::string str = android::base::Trim(line);
+        if (android::base::StartsWith(str, "pre-build-incremental")){
+            int source_build = parse_build_number(str);
+            if (source_build != -1) {
+                printf("source_build: %d\n", source_build);
+                /*log_buffer.push_back(android::base::StringPrintf("source_build: %d",
+                        source_build));*/
+            }
+        } else if (android::base::StartsWith(str, "post-build-incremental")) {
+            int target_build = parse_build_number(str);
+            if (target_build != -1) {
+                printf("target_build: %d\n", target_build);
+                /*log_buffer.push_back(android::base::StringPrintf("target_build: %d",
+                        target_build));*/
+            }
+        }
+    }
+}
+
+// Parses the metadata of the OTA package in |zip| and checks whether we are
+// allowed to accept this A/B package. Downgrading is not allowed unless
+// explicitly enabled in the package and only for incremental packages.
+static int check_newer_ab_build(ZipWrap* zip)
+{
+    std::string metadata_str;
+    if (!read_metadata_from_package(zip, &metadata_str)) {
+        return INSTALL_CORRUPT;
+    }
+    std::map<std::string, std::string> metadata;
+    for (const std::string& line : android::base::Split(metadata_str, "\n")) {
+        size_t eq = line.find('=');
+        if (eq != std::string::npos) {
+            metadata[line.substr(0, eq)] = line.substr(eq + 1);
+        }
+    }
+    char value[PROPERTY_VALUE_MAX];
+    char propmodel[PROPERTY_VALUE_MAX];
+    char propname[PROPERTY_VALUE_MAX];
+
+    property_get("ro.product.device", value, "");
+    property_get("ro.product.model", propmodel, "");
+    property_get("ro.product.name", propname, "");
+    const std::string& pkg_device = metadata["pre-device"];
+
+    std::vector<std::string> assertResults = android::base::Split(pkg_device, ",");
+
+    bool deviceExists = false;
+
+    for(const std::string& deviceAssert : assertResults)
+    {
+        std::string assertName = android::base::Trim(deviceAssert);
+        if ((assertName == value || assertName == propmodel || assertName == propname ) && !assertName.empty()) {
+            deviceExists = true;
+            break;
+        }
+    }
+
+    if (!deviceExists) {
+        printf("Package is for product %s but expected %s\n",
+            pkg_device.c_str(), value);
+        return INSTALL_ERROR;
+    }
+
+    // We allow the package to not have any serialno, but if it has a non-empty
+    // value it should match.
+    property_get("ro.serialno", value, "");
+    const std::string& pkg_serial_no = metadata["serialno"];
+    if (!pkg_serial_no.empty() && pkg_serial_no != value) {
+        printf("Package is for serial %s\n", pkg_serial_no.c_str());
+        return INSTALL_ERROR;
+    }
+
+    if (metadata["ota-type"] != "AB") {
+        printf("Package is not A/B\n");
+        return INSTALL_ERROR;
+    }
+
+    // Incremental updates should match the current build.
+    property_get("ro.build.version.incremental", value, "");
+    const std::string& pkg_pre_build = metadata["pre-build-incremental"];
+    if (!pkg_pre_build.empty() && pkg_pre_build != value) {
+        printf("Package is for source build %s but expected %s\n",
+             pkg_pre_build.c_str(), value);
+        return INSTALL_ERROR;
+    }
+    property_get("ro.build.fingerprint", value, "");
+    const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
+    if (!pkg_pre_build_fingerprint.empty() &&
+        pkg_pre_build_fingerprint != value) {
+        printf("Package is for source build %s but expected %s\n",
+             pkg_pre_build_fingerprint.c_str(), value);
+        return INSTALL_ERROR;
+    }
+
+    return 0;
+}
+
+int
+abupdate_binary_command(const char* path, ZipWrap* zip, int retry_count __unused,
+                      int status_fd, std::vector<std::string>* cmd)
+{
+    read_source_target_build(zip);
+    int ret = check_newer_ab_build(zip);
+    if (ret) {
+        return ret;
+    }
+
+    // For A/B updates we extract the payload properties to a buffer and obtain
+    // the RAW payload offset in the zip file.
+    if (!zip->EntryExists(AB_OTA_PAYLOAD_PROPERTIES)) {
+        printf("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES);
+        return INSTALL_CORRUPT;
+    }
+    std::vector<unsigned char> payload_properties(
+            zip->GetUncompressedSize(AB_OTA_PAYLOAD_PROPERTIES));
+    if (!zip->ExtractToBuffer(AB_OTA_PAYLOAD_PROPERTIES, payload_properties.data())) {
+        printf("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES);
+        return INSTALL_CORRUPT;
+    }
+
+    if (!zip->EntryExists(AB_OTA_PAYLOAD)) {
+        printf("Can't find %s\n", AB_OTA_PAYLOAD);
+        return INSTALL_CORRUPT;
+    }
+    long payload_offset = zip->GetEntryOffset(AB_OTA_PAYLOAD);
+    *cmd = {
+        "/sbin/update_engine_sideload",
+        android::base::StringPrintf("--payload=file://%s", path),
+        android::base::StringPrintf("--offset=%ld", payload_offset),
+        "--headers=" + std::string(payload_properties.begin(),
+                                   payload_properties.end()),
+        android::base::StringPrintf("--status_fd=%d", status_fd),
+    };
+    return INSTALL_SUCCESS;
+}
+
+#else
+
+void read_source_target_build(ZipWrap* zip __unused /*, std::vector<std::string>& log_buffer*/) {return;}
+
+int
+abupdate_binary_command(__unused const char* path, __unused ZipWrap* zip, __unused int retry_count,
+                      __unused int status_fd, __unused std::vector<std::string>* cmd)
+{
+    printf("No support for AB OTA zips included\n");
+    return INSTALL_CORRUPT;
+}
+
+#endif
+
+int
+update_binary_command(const char* path, int retry_count,
+                      int status_fd, std::vector<std::string>* cmd)
+{
+    char charfd[16];
+    sprintf(charfd, "%i", status_fd);
+    cmd->push_back(TMP_UPDATER_BINARY_PATH);
+    cmd->push_back(EXPAND(RECOVERY_API_VERSION));
+    cmd->push_back(charfd);
+    cmd->push_back(path);
+    /**cmd = {
+        TMP_UPDATER_BINARY_PATH,
+        EXPAND(RECOVERY_API_VERSION),   // defined in Android.mk
+        charfd,
+        path,
+    };*/
+    if (retry_count > 0)
+        cmd->push_back("retry");
+    return 0;
+}
+
+#ifdef USE_MINZIP
+bool verify_package_compatibility(ZipWrap *package_zip) {
+  if (package_zip->EntryExists("compatibility.zip"))
+    printf("Cannot verify treble package compatibility, must build TWRP in Oreo tree or higher.\n");
+  return true;
+}
+#else
+// Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
+// entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
+// package.
+bool verify_package_compatibility(ZipWrap *zw) {
+  ZipArchiveHandle package_zip = zw->GetZipArchiveHandle();
+  printf("Verifying package compatibility...\n");
+
+  static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
+  ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
+  ZipEntry compatibility_entry;
+  if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) {
+    printf("Package doesn't contain %s entry\n", COMPATIBILITY_ZIP_ENTRY);
+    return true;
+  }
+
+  std::string zip_content(compatibility_entry.uncompressed_length, '\0');
+  int32_t ret;
+  if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
+                             reinterpret_cast<uint8_t*>(&zip_content[0]),
+                             compatibility_entry.uncompressed_length)) != 0) {
+    printf("Failed to read %s: %s\n", COMPATIBILITY_ZIP_ENTRY, ErrorCodeString(ret));
+    return false;
+  }
+
+  ZipArchiveHandle zip_handle;
+  ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
+                              zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
+  if (ret != 0) {
+    printf("Failed to OpenArchiveFromMemory: %s\n", ErrorCodeString(ret));
+    return false;
+  }
+
+  // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
+  void* cookie;
+  ret = StartIteration(zip_handle, &cookie, nullptr, nullptr);
+  if (ret != 0) {
+    printf("Failed to start iterating zip entries: %s\n", ErrorCodeString(ret));
+    CloseArchive(zip_handle);
+    return false;
+  }
+  std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
+
+  std::vector<std::string> compatibility_info;
+  ZipEntry info_entry;
+  ZipString info_name;
+  while (Next(cookie, &info_entry, &info_name) == 0) {
+    std::string content(info_entry.uncompressed_length, '\0');
+    int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
+                                  info_entry.uncompressed_length);
+    if (ret != 0) {
+      printf("Failed to read %s: %s\n", info_name.name, ErrorCodeString(ret));
+      CloseArchive(zip_handle);
+      return false;
+    }
+    compatibility_info.emplace_back(std::move(content));
+  }
+  CloseArchive(zip_handle);
+
+  // VintfObjectRecovery::CheckCompatibility returns zero on success. TODO THIS CAUSES A WEIRD COMPILE ERROR
+  std::string err;
+  int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
+  if (result == 0) {
+    return true;
+  }
+
+  printf("Failed to verify package compatibility (result %i): %s\n", result, err.c_str());
+  return false;
+}
+#endif
+>>>>>>> CHANGE (1913bf Make the twrp verify the pre-device among several props)
