diff --git a/twrpinstall/Android.bp b/twrpinstall/Android.bp
new file mode 100755
index 0000000..66ae163
--- /dev/null
+++ b/twrpinstall/Android.bp
@@ -0,0 +1,92 @@
+// Copyright (C) 2019 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.
+
+cc_defaults {
+    name: "libtwrpinstall_defaults",
+
+    defaults: [
+        "recovery_defaults",
+    ],
+
+    header_libs: [
+        "libminadbd_headers",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libbootloader_message",
+        "libcrypto",
+        "libext4_utils",
+        "libfs_mgr",
+        "libfusesideload",
+        "libhidl-gen-utils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libselinux",
+        "libtinyxml2",
+        "libutils",
+        "libz",
+        "libziparchive",
+    ],
+
+    static_libs: [
+        "libotautil",
+
+        // external dependencies
+        "libvintf_recovery",
+        "libvintf",
+        "libfstab",
+    ],
+}
+
+cc_library_static {
+    name: "libtwrpinstall",
+    recovery_available: true,
+
+    defaults: [
+        "libtwrpinstall_defaults",
+    ],
+
+    cflags: [
+        "-DAB_OTA_UPDATER=1"
+    ],
+
+    include_dirs: [
+        "bootable/recovery",
+        "bootable/recovery/install/include",
+    ],
+
+    srcs: [
+        "adb_install.cpp",
+        "asn1_decoder.cpp",
+        "install.cpp",
+        "installcommand.cpp",
+        "package.cpp",
+        "tw_atomic.cpp",
+        "twinstall.cpp",
+        "verifier.cpp",
+    ],
+    shared_libs: [
+        "librecovery_ui",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "librecovery_ui",
+    ],
+}
diff --git a/twrpinstall/ZipUtil.cpp b/twrpinstall/ZipUtil.cpp
new file mode 100755
index 0000000..f8134bc
--- /dev/null
+++ b/twrpinstall/ZipUtil.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 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 "ZipUtil.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <utime.h>
+
+#include <string>
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <selinux/label.h>
+#include <selinux/selinux.h>
+#include <ziparchive/zip_archive.h>
+
+#include "otautil/dirutil.h"
+
+static constexpr mode_t UNZIP_DIRMODE = 0755;
+static constexpr mode_t UNZIP_FILEMODE = 0644;
+
+bool ExtractPackageRecursive(ZipArchiveHandle zip, const std::string& zip_path,
+                             const std::string& dest_path, const struct utimbuf* timestamp,
+                             struct selabel_handle* sehnd) {
+    if (!zip_path.empty() && zip_path[0] == '/') {
+        LOG(ERROR) << "ExtractPackageRecursive(): zip_path must be a relative path " << zip_path;
+        return false;
+    }
+    if (dest_path.empty() || dest_path[0] != '/') {
+        LOG(ERROR) << "ExtractPackageRecursive(): dest_path must be an absolute path " << dest_path;
+        return false;
+    }
+
+    void* cookie;
+    std::string target_dir(dest_path);
+    if (dest_path.back() != '/') {
+        target_dir += '/';
+    }
+    std::string prefix_path(zip_path);
+    if (!zip_path.empty() && zip_path.back() != '/') {
+        prefix_path += '/';
+    }
+    const ZipString zip_prefix(prefix_path.c_str());
+
+    int ret = StartIteration(zip, &cookie, &zip_prefix, nullptr);
+    if (ret != 0) {
+        LOG(ERROR) << "failed to start iterating zip entries.";
+        return false;
+    }
+
+    std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
+    ZipEntry entry;
+    ZipString name;
+    int extractCount = 0;
+    while (Next(cookie, &entry, &name) == 0) {
+        std::string entry_name(name.name, name.name + name.name_length);
+        CHECK_LE(prefix_path.size(), entry_name.size());
+        std::string path = target_dir + entry_name.substr(prefix_path.size());
+        // Skip dir.
+        if (path.back() == '/') {
+            continue;
+        }
+        //TODO(b/31917448) handle the symlink.
+
+        if (dirCreateHierarchy(path.c_str(), UNZIP_DIRMODE, timestamp, true, sehnd) != 0) {
+            LOG(ERROR) << "failed to create dir for " << path;
+            return false;
+        }
+
+        char *secontext = NULL;
+        if (sehnd) {
+            selabel_lookup(sehnd, &secontext, path.c_str(), UNZIP_FILEMODE);
+            setfscreatecon(secontext);
+        }
+        android::base::unique_fd fd(open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, UNZIP_FILEMODE));
+        if (fd == -1) {
+            PLOG(ERROR) << "Can't create target file \"" << path << "\"";
+            return false;
+        }
+        if (secontext) {
+            freecon(secontext);
+            setfscreatecon(NULL);
+        }
+
+        int err = ExtractEntryToFile(zip, &entry, fd);
+        if (err != 0) {
+            LOG(ERROR) << "Error extracting \"" << path << "\" : " << ErrorCodeString(err);
+            return false;
+        }
+
+        if (fsync(fd) != 0) {
+            PLOG(ERROR) << "Error syncing file descriptor when extracting \"" << path << "\"";
+            return false;
+        }
+
+        if (timestamp != nullptr && utime(path.c_str(), timestamp)) {
+            PLOG(ERROR) << "Error touching \"" << path << "\"";
+            return false;
+        }
+
+        LOG(INFO) << "Extracted file \"" << path << "\"";
+        ++extractCount;
+    }
+
+    LOG(INFO) << "Extracted " << extractCount << " file(s)";
+    return true;
+}
diff --git a/twrpinstall/ZipUtil.h b/twrpinstall/ZipUtil.h
new file mode 100644
index 0000000..cda405c
--- /dev/null
+++ b/twrpinstall/ZipUtil.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _OTAUTIL_ZIPUTIL_H
+#define _OTAUTIL_ZIPUTIL_H
+
+#include <utime.h>
+
+#include <string>
+
+#include <selinux/label.h>
+#include <ziparchive/zip_archive.h>
+
+/*
+ * Inflate all files under zip_path to the directory specified by
+ * dest_path, which must exist and be a writable directory. The zip_path
+ * is allowed to be an empty string, in which case the whole package
+ * will be extracted.
+ *
+ * Directory entries are not extracted.
+ *
+ * The immediate children of zip_path will become the immediate
+ * children of dest_path; e.g., if the archive contains the entries
+ *
+ *     a/b/c/one
+ *     a/b/c/two
+ *     a/b/c/d/three
+ *
+ * and ExtractPackageRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
+ * files will be
+ *
+ *     /tmp/one
+ *     /tmp/two
+ *     /tmp/d/three
+ *
+ * If timestamp is non-NULL, file timestamps will be set accordingly.
+ *
+ * Returns true on success, false on failure.
+ */
+bool ExtractPackageRecursive(ZipArchiveHandle zip, const std::string& zip_path,
+                             const std::string& dest_path, const struct utimbuf* timestamp,
+                             struct selabel_handle* sehnd);
+
+#endif // _OTAUTIL_ZIPUTIL_H
diff --git a/twrpinstall/adb_install.cpp b/twrpinstall/adb_install.cpp
new file mode 100755
index 0000000..5eb8c0b
--- /dev/null
+++ b/twrpinstall/adb_install.cpp
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2012 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 "twinstall/adb_install.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <atomic>
+#include <functional>
+#include <map>
+#include <utility>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/memory.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+
+#include "fuse_sideload.h"
+#include "twinstall/install.h"
+#include "twinstall/wipe_data.h"
+#include "minadbd_types.h"
+#include "otautil/sysutil.h"
+#include "recovery_ui/device.h"
+#include "recovery_ui/ui.h"
+
+// A CommandFunction returns a pair of (result, should_continue), which indicates the command
+// execution result and whether it should proceed to the next iteration. The execution result will
+// always be sent to the minadbd side.
+using CommandFunction = std::function<std::pair<bool, bool>()>;
+
+pid_t child;
+
+pid_t GetMiniAdbdPid() {
+  return child;
+}
+
+static bool SetUsbConfig(const std::string& state) {
+  android::base::SetProperty("sys.usb.config", state);
+  return android::base::WaitForProperty("sys.usb.state", state);
+}
+
+// Parses the minadbd command in |message|; returns MinadbdCommand::kError upon errors.
+static MinadbdCommand ParseMinadbdCommand(const std::string& message) {
+  if (!android::base::StartsWith(message, kMinadbdCommandPrefix)) {
+    LOG(ERROR) << "Failed to parse command in message " << message;
+    return MinadbdCommand::kError;
+  }
+
+  auto cmd_code_string = message.substr(strlen(kMinadbdCommandPrefix));
+  auto cmd_code = android::base::get_unaligned<uint32_t>(cmd_code_string.c_str());
+  if (cmd_code >= static_cast<uint32_t>(MinadbdCommand::kError)) {
+    LOG(ERROR) << "Unsupported command code: " << cmd_code;
+    return MinadbdCommand::kError;
+  }
+
+  return static_cast<MinadbdCommand>(cmd_code);
+}
+
+static bool WriteStatusToFd(MinadbdCommandStatus status, int fd) {
+  char message[kMinadbdMessageSize];
+  memcpy(message, kMinadbdStatusPrefix, strlen(kMinadbdStatusPrefix));
+  android::base::put_unaligned(message + strlen(kMinadbdStatusPrefix), status);
+
+  if (!android::base::WriteFully(fd, message, kMinadbdMessageSize)) {
+    PLOG(ERROR) << "Failed to write message " << message;
+    return false;
+  }
+  return true;
+}
+
+// Installs the package from FUSE. Returns the installation result and whether it should continue
+// waiting for new commands.
+static auto AdbInstallPackageHandler(int* result) {
+  // How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long
+  // because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME
+  // will start to exist once the host connects and starts serving a package. Poll for its
+  // appearance. (Note that inotify doesn't work with FUSE.)
+  constexpr int ADB_INSTALL_TIMEOUT = 15;
+  bool should_continue = true;
+  *result = INSTALL_ERROR;
+  for (int i = 0; i < ADB_INSTALL_TIMEOUT; ++i) {
+    PLOG(ERROR) << "i: " << i;
+    struct stat st;
+    if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &st) != 0) {
+      if (errno == ENOENT && i < ADB_INSTALL_TIMEOUT - 1) {
+        sleep(1);
+        continue;
+      } else {
+        should_continue = false;
+        break;
+      }
+    }
+    *result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0);
+    break;
+  }
+
+  // Calling stat() on this magic filename signals the FUSE to exit.
+  struct stat st;
+  stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st);
+  return std::make_pair(*result == INSTALL_SUCCESS, should_continue);
+}
+
+static auto AdbRebootHandler(MinadbdCommand command, int* result,
+                             Device::BuiltinAction* reboot_action) {
+  // Use Device::REBOOT_{FASTBOOT,RECOVERY,RESCUE}, instead of the ones with ENTER_. This allows
+  // rebooting back into fastboot/recovery/rescue mode through bootloader, which may use a newly
+  // installed bootloader/recovery image.
+  switch (command) {
+    case MinadbdCommand::kRebootBootloader:
+      *reboot_action = Device::REBOOT_BOOTLOADER;
+      break;
+    case MinadbdCommand::kRebootFastboot:
+      *reboot_action = Device::REBOOT_FASTBOOT;
+      break;
+    case MinadbdCommand::kRebootRecovery:
+      *reboot_action = Device::REBOOT_RECOVERY;
+      break;
+    case MinadbdCommand::kRebootRescue:
+      *reboot_action = Device::REBOOT_RESCUE;
+      break;
+    case MinadbdCommand::kRebootAndroid:
+    default:
+      *reboot_action = Device::REBOOT;
+      break;
+  }
+  *result = INSTALL_REBOOT;
+  return std::make_pair(true, false);
+}
+
+// Parses and executes the command from minadbd. Returns whether the caller should keep waiting for
+// next command.
+static bool HandleMessageFromMinadbd(int socket_fd,
+                                     const std::map<MinadbdCommand, CommandFunction>& command_map) {
+  char buffer[kMinadbdMessageSize];
+  if (!android::base::ReadFully(socket_fd, buffer, kMinadbdMessageSize)) {
+    PLOG(ERROR) << "Failed to read message from minadbd";
+    return false;
+  }
+
+  std::string message(buffer, buffer + kMinadbdMessageSize);
+  auto command_type = ParseMinadbdCommand(message);
+  if (command_type == MinadbdCommand::kError) {
+    return false;
+  }
+  if (command_map.find(command_type) == command_map.end()) {
+    LOG(ERROR) << "Unsupported command: "
+               << android::base::get_unaligned<unsigned int>(
+                      message.substr(strlen(kMinadbdCommandPrefix)).c_str());
+    return false;
+  }
+
+  // We have received a valid command, execute the corresponding function.
+  const auto& command_func = command_map.at(command_type);
+  const auto [result, should_continue] = command_func();
+  LOG(INFO) << "Command " << static_cast<uint32_t>(command_type) << " finished with " << result;
+  if (!WriteStatusToFd(result ? MinadbdCommandStatus::kSuccess : MinadbdCommandStatus::kFailure,
+                       socket_fd)) {
+    return false;
+  }
+  return should_continue;
+}
+
+// TODO(xunchang) add a wrapper function and kill the minadbd service there.
+static void ListenAndExecuteMinadbdCommands(
+    pid_t minadbd_pid, android::base::unique_fd&& socket_fd,
+    const std::map<MinadbdCommand, CommandFunction>& command_map) {
+  android::base::unique_fd epoll_fd(epoll_create1(O_CLOEXEC));
+  if (epoll_fd == -1) {
+    PLOG(ERROR) << "Failed to create epoll";
+    kill(minadbd_pid, SIGKILL);
+    return;
+  }
+
+  constexpr int EPOLL_MAX_EVENTS = 10;
+  struct epoll_event ev = {};
+  ev.events = EPOLLIN | EPOLLHUP;
+  ev.data.fd = socket_fd.get();
+  struct epoll_event events[EPOLL_MAX_EVENTS];
+  if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, socket_fd.get(), &ev) == -1) {
+    PLOG(ERROR) << "Failed to add socket fd to epoll";
+    kill(minadbd_pid, SIGKILL);
+    return;
+  }
+
+  // Set the timeout to be 300s when waiting for minadbd commands.
+  constexpr int TIMEOUT_MILLIS = 300 * 1000;
+  while (true) {
+    // Poll for the status change of the socket_fd, and handle the message if the fd is ready to
+    // read.
+    int event_count =
+        TEMP_FAILURE_RETRY(epoll_wait(epoll_fd.get(), events, EPOLL_MAX_EVENTS, TIMEOUT_MILLIS));
+    if (event_count == -1) {
+      PLOG(ERROR) << "Failed to wait for epoll events";
+      kill(minadbd_pid, SIGKILL);
+      return;
+    }
+    if (event_count == 0) {
+      LOG(ERROR) << "Timeout waiting for messages from minadbd";
+      kill(minadbd_pid, SIGKILL);
+      return;
+    }
+
+    for (int n = 0; n < event_count; n++) {
+      if (events[n].events & EPOLLHUP) {
+        LOG(INFO) << "Socket has been closed";
+        kill(minadbd_pid, SIGKILL);
+        return;
+      }
+      if (!HandleMessageFromMinadbd(socket_fd.get(), command_map)) {
+        kill(minadbd_pid, SIGKILL);
+        return;
+      }
+    }
+  }
+}
+
+// Recovery starts minadbd service as a child process, and spawns another thread to listen for the
+// message from minadbd through a socket pair. Here is an example to execute one command from adb
+// host.
+//  a. recovery                    b. listener thread               c. minadbd service
+//
+//  a1. create socket pair
+//  a2. fork minadbd service
+//                                                                c3. wait for the adb commands
+//                                                                    from host
+//                                                                c4. after receiving host commands:
+//                                                                  1) set up pre-condition (i.e.
+//                                                                     start fuse for adb sideload)
+//                                                                  2) issue command through
+//                                                                     socket.
+//                                                                  3) wait for result
+//  a5. start listener thread
+//                               b6. listen for message from
+//                                   minadbd in a loop.
+//                               b7. After receiving a minadbd
+//                                   command from socket
+//                                 1) execute the command function
+//                                 2) send the result back to
+//                                    minadbd
+//  ......
+//                                                                 c8. exit upon receiving the
+//                                                                     result
+// a9.  wait for listener thread
+//      to exit.
+//
+// a10. wait for minadbd to
+//      exit
+//                               b11. exit the listening loop
+//
+static void CreateMinadbdServiceAndExecuteCommands(
+    const std::map<MinadbdCommand, CommandFunction>& command_map,
+    bool rescue_mode __unused, std::string install_file __unused) {
+  signal(SIGPIPE, SIG_IGN);
+
+  android::base::unique_fd recovery_socket;
+  android::base::unique_fd minadbd_socket;
+  if (!android::base::Socketpair(AF_UNIX, SOCK_STREAM, 0, &recovery_socket, &minadbd_socket)) {
+    PLOG(ERROR) << "Failed to create socket";
+    return;
+  }
+
+  child = fork();
+  if (child == -1) {
+    PLOG(ERROR) << "Failed to fork child process";
+    return;
+  }
+  if (child == 0) {
+    recovery_socket.reset();
+    std::vector<std::string> minadbd_commands = {
+      "/system/bin/minadbd",
+      "--socket_fd",
+      std::to_string(minadbd_socket.release()),
+    };
+    // if (rescue_mode) {
+    //   minadbd_commands.push_back("--rescue");
+    // }
+    auto exec_args = StringVectorToNullTerminatedArray(minadbd_commands);
+    execv(exec_args[0], exec_args.data());
+    _exit(EXIT_FAILURE);
+  }
+
+  minadbd_socket.reset();
+
+  // We need to call SetUsbConfig() after forking minadbd service. Because the function waits for
+  // the usb state to be updated, which depends on sys.usb.ffs.ready=1 set in the adb daemon.
+  if (!SetUsbConfig("sideload")) {
+    LOG(ERROR) << "Failed to set usb config to sideload";
+    return;
+  }
+
+  std::thread listener_thread(ListenAndExecuteMinadbdCommands, child,
+                              std::move(recovery_socket), std::ref(command_map));
+  if (listener_thread.joinable()) {
+    listener_thread.join();
+  }
+
+  int status;
+  waitpid(child, &status, 0);
+  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+    if (WEXITSTATUS(status) == MinadbdErrorCode::kMinadbdAdbVersionError) {
+      LOG(ERROR) << "\nYou need adb 1.0.32 or newer to sideload\nto this device.\n";
+    } else if (!WIFSIGNALED(status)) {
+      LOG(ERROR) << "\n(adbd status " << WEXITSTATUS(status) << ")";
+    }
+  }
+
+  signal(SIGPIPE, SIG_DFL);
+}
+
+  int twrp_sideload(const char* install_file, Device::BuiltinAction* reboot_action) {
+
+  // Save the usb state to restore after the sideload operation.
+  std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
+  // Clean up state and stop adbd.
+  if (usb_state != "none" && !SetUsbConfig("none")) {
+    LOG(ERROR) << "Failed to clear USB config";
+    return INSTALL_ERROR;
+  }
+
+  int install_result = INSTALL_ERROR;
+  std::map<MinadbdCommand, CommandFunction> command_map{
+  { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, &install_result) },
+  { MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid,
+                                              &install_result, reboot_action) },
+  { MinadbdCommand::kRebootBootloader,
+    std::bind(&AdbRebootHandler, MinadbdCommand::kRebootBootloader, &install_result,
+              reboot_action) },
+  { MinadbdCommand::kRebootFastboot, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootFastboot,
+                                                &install_result, reboot_action) },
+  { MinadbdCommand::kRebootRecovery, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootRecovery,
+                                                &install_result, reboot_action) },
+  { MinadbdCommand::kRebootRescue,
+    std::bind(&AdbRebootHandler, MinadbdCommand::kRebootRescue, &install_result, reboot_action) },
+};
+
+  CreateMinadbdServiceAndExecuteCommands(command_map, false, install_file);
+
+  // Clean up before switching to the older state, for example setting the state
+  // to none sets sys/class/android_usb/android0/enable to 0.
+  if (!SetUsbConfig("none")) {
+    LOG(ERROR) << "Failed to clear USB config";
+  }
+
+  if (usb_state != "none") {
+    if (!SetUsbConfig(usb_state)) {
+      LOG(ERROR) << "Failed to set USB config to " << usb_state;
+    }
+  }
+
+  return install_result;
+}
diff --git a/twrpinstall/asn1_decoder.cpp b/twrpinstall/asn1_decoder.cpp
new file mode 100644
index 0000000..2d81a6e
--- /dev/null
+++ b/twrpinstall/asn1_decoder.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2013 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 "private/asn1_decoder.h"
+
+int asn1_context::peek_byte() const {
+  if (length_ == 0) {
+    return -1;
+  }
+  return *p_;
+}
+
+int asn1_context::get_byte() {
+  if (length_ == 0) {
+    return -1;
+  }
+
+  int byte = *p_;
+  p_++;
+  length_--;
+  return byte;
+}
+
+bool asn1_context::skip_bytes(size_t num_skip) {
+  if (length_ < num_skip) {
+    return false;
+  }
+  p_ += num_skip;
+  length_ -= num_skip;
+  return true;
+}
+
+bool asn1_context::decode_length(size_t* out_len) {
+  int num_octets = get_byte();
+  if (num_octets == -1) {
+    return false;
+  }
+  if ((num_octets & 0x80) == 0x00) {
+    *out_len = num_octets;
+    return true;
+  }
+  num_octets &= kMaskTag;
+  if (static_cast<size_t>(num_octets) >= sizeof(size_t)) {
+    return false;
+  }
+  size_t length = 0;
+  for (int i = 0; i < num_octets; ++i) {
+    int byte = get_byte();
+    if (byte == -1) {
+      return false;
+    }
+    length <<= 8;
+    length += byte;
+  }
+  *out_len = length;
+  return true;
+}
+
+/**
+ * Returns the constructed type and advances the pointer. E.g. A0 -> 0
+ */
+asn1_context* asn1_context::asn1_constructed_get() {
+  int type = get_byte();
+  if (type == -1 || (type & kMaskConstructed) != kTagConstructed) {
+    return nullptr;
+  }
+  size_t length;
+  if (!decode_length(&length) || length > length_) {
+    return nullptr;
+  }
+  asn1_context* app_ctx = new asn1_context(p_, length);
+  app_ctx->app_type_ = type & kMaskAppType;
+  return app_ctx;
+}
+
+bool asn1_context::asn1_constructed_skip_all() {
+  int byte = peek_byte();
+  while (byte != -1 && (byte & kMaskConstructed) == kTagConstructed) {
+    skip_bytes(1);
+    size_t length;
+    if (!decode_length(&length) || !skip_bytes(length)) {
+      return false;
+    }
+    byte = peek_byte();
+  }
+  return byte != -1;
+}
+
+int asn1_context::asn1_constructed_type() const {
+  return app_type_;
+}
+
+asn1_context* asn1_context::asn1_sequence_get() {
+  if ((get_byte() & kMaskTag) != kTagSequence) {
+    return nullptr;
+  }
+  size_t length;
+  if (!decode_length(&length) || length > length_) {
+    return nullptr;
+  }
+  return new asn1_context(p_, length);
+}
+
+asn1_context* asn1_context::asn1_set_get() {
+  if ((get_byte() & kMaskTag) != kTagSet) {
+    return nullptr;
+  }
+  size_t length;
+  if (!decode_length(&length) || length > length_) {
+    return nullptr;
+  }
+  return new asn1_context(p_, length);
+}
+
+bool asn1_context::asn1_sequence_next() {
+  size_t length;
+  if (get_byte() == -1 || !decode_length(&length) || !skip_bytes(length)) {
+    return false;
+  }
+  return true;
+}
+
+bool asn1_context::asn1_oid_get(const uint8_t** oid, size_t* length) {
+  if (get_byte() != kTagOid) {
+    return false;
+  }
+  if (!decode_length(length) || *length == 0 || *length > length_) {
+    return false;
+  }
+  *oid = p_;
+  return true;
+}
+
+bool asn1_context::asn1_octet_string_get(const uint8_t** octet_string, size_t* length) {
+  if (get_byte() != kTagOctetString) {
+    return false;
+  }
+  if (!decode_length(length) || *length == 0 || *length > length_) {
+    return false;
+  }
+  *octet_string = p_;
+  return true;
+}
diff --git a/twrpinstall/include/common.h b/twrpinstall/include/common.h
new file mode 100755
index 0000000..e82bec3
--- /dev/null
+++ b/twrpinstall/include/common.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#ifndef __cplusplus
+extern "C" {
+#endif
+
+#define LOGE(...) fprintf(stdout, "E:" __VA_ARGS__)
+#define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
+#define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
+
+#if 0
+#define LOGV(...) fprintf(stdout, "V:" __VA_ARGS__)
+#define LOGD(...) fprintf(stdout, "D:" __VA_ARGS__)
+#else
+#define LOGV(...) do {} while (0)
+#define LOGD(...) do {} while (0)
+#endif
+
+#define STRINGIFY(x) #x
+#define EXPAND(x) STRINGIFY(x)
+
+// Not using the command-line defined macro here because this header could be included by
+// device-specific recovery libraries. We static assert the value consistency in recovery.cpp.
+//static constexpr int kRecoveryApiVersion = 3;
+
+class RecoveryUI;
+struct selabel_handle;
+
+extern struct selabel_handle* sehandle;
+extern RecoveryUI* ui;
+extern bool has_cache;
+
+// The current stage, e.g. "1/2".
+extern std::string stage;
+
+// The reason argument provided in "--reason=".
+extern const char* reason;
+
+// static bool is_ro_debuggable();
diff --git a/twrpinstall/include/installcommand.h b/twrpinstall/include/installcommand.h
new file mode 100644
index 0000000..f265801
--- /dev/null
+++ b/twrpinstall/include/installcommand.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef RECOVERY_INSTALL_COMMAND_H_
+#define RECOVERY_INSTALL_COMMAND_H_
+
+#define TMP_UPDATER_BINARY_PATH "/tmp/updater"
+
+#include <string>
+#include <ziparchive/zip_archive.h>
+
+bool read_metadata_from_package(ZipArchiveHandle zip, std::string* meta_data);
+
+int
+abupdate_binary_command(const char* path, int retry_count,
+                      int status_fd, std::vector<std::string>* cmd);
+int
+update_binary_command(const char* path, int retry_count,
+                      int status_fd, std::vector<std::string>* cmd);
+
+bool verify_package_compatibility(ZipArchiveHandle package_zip);
+
+void read_source_target_build(ZipArchiveHandle zip/*, std::vector<std::string>& log_buffer*/);
+
+#endif  // RECOVERY_INSTALL_COMMAND_H_
diff --git a/twrpinstall/include/legacy_property_service.h b/twrpinstall/include/legacy_property_service.h
new file mode 100644
index 0000000..d20bdef
--- /dev/null
+++ b/twrpinstall/include/legacy_property_service.h
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#ifndef _LEGACY_PROPERTY_H
+#define _LEGACY_PROPERTY_H
+
+#include <stdbool.h>
+
+void legacy_get_property_workspace(int *fd, int *sz);
+int legacy_properties_init();
+
+#endif	/* _LEGACY_PROPERTY_H */
diff --git a/twrpinstall/include/private/asn1_decoder.h b/twrpinstall/include/private/asn1_decoder.h
new file mode 100644
index 0000000..e5337d9
--- /dev/null
+++ b/twrpinstall/include/private/asn1_decoder.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef ASN1_DECODER_H_
+#define ASN1_DECODER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+class asn1_context {
+ public:
+  asn1_context(const uint8_t* buffer, size_t length) : p_(buffer), length_(length), app_type_(0) {}
+  int asn1_constructed_type() const;
+  asn1_context* asn1_constructed_get();
+  bool asn1_constructed_skip_all();
+  asn1_context* asn1_sequence_get();
+  asn1_context* asn1_set_get();
+  bool asn1_sequence_next();
+  bool asn1_oid_get(const uint8_t** oid, size_t* length);
+  bool asn1_octet_string_get(const uint8_t** octet_string, size_t* length);
+
+ private:
+  static constexpr int kMaskConstructed = 0xE0;
+  static constexpr int kMaskTag = 0x7F;
+  static constexpr int kMaskAppType = 0x1F;
+
+  static constexpr int kTagOctetString = 0x04;
+  static constexpr int kTagOid = 0x06;
+  static constexpr int kTagSequence = 0x30;
+  static constexpr int kTagSet = 0x31;
+  static constexpr int kTagConstructed = 0xA0;
+
+  int peek_byte() const;
+  int get_byte();
+  bool skip_bytes(size_t num_skip);
+  bool decode_length(size_t* out_len);
+
+  const uint8_t* p_;
+  size_t length_;
+  int app_type_;
+};
+
+#endif /* ASN1_DECODER_H_ */
diff --git a/twrpinstall/include/private/setup_commands.h b/twrpinstall/include/private/setup_commands.h
new file mode 100644
index 0000000..7fdc741
--- /dev/null
+++ b/twrpinstall/include/private/setup_commands.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// Private headers exposed for testing purpose only.
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <ziparchive/zip_archive.h>
+
+// Sets up the commands for a non-A/B update. Extracts the updater binary from the open zip archive
+// |zip| located at |package|. Stores the command line that should be called into |cmd|. The
+// |status_fd| is the file descriptor the child process should use to report back the progress of
+// the update.
+int SetUpNonAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int retry_count,
+                             int status_fd, std::vector<std::string>* cmd);
+
+// Sets up the commands for an A/B update. Extracts the needed entries from the open zip archive
+// |zip| located at |package|. Stores the command line that should be called into |cmd|. The
+// |status_fd| is the file descriptor the child process should use to report back the progress of
+// the update. Note that since this applies to the sideloading flow only, it takes one less
+// parameter |retry_count| than the non-A/B version.
+int SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd,
+                          std::vector<std::string>* cmd);
diff --git a/twrpinstall/include/set_metadata.h b/twrpinstall/include/set_metadata.h
new file mode 100644
index 0000000..9a46be9
--- /dev/null
+++ b/twrpinstall/include/set_metadata.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Team Win Recovery 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.
+ */
+
+/*
+ * The purpose of these functions is to try to get and set the proper
+ * file permissions, SELinux contexts, owner, and group so that these
+ * files are accessible when we boot up to normal Android via MTP and to
+ * file manager apps. During early boot we try to read the contexts and
+ * owner / group info from /data/media or from /data/media/0 and store
+ * them in static variables. From there, we'll try to set the same
+ * contexts, owner, and group information on most files we create during
+ * operations like backups, copying the log, and MTP operations.
+ */
+
+#ifndef _RECOVERY_SET_CONTEXTS_H
+#define _RECOVERY_SET_CONTEXTS_H
+
+#include <sys/stat.h>
+#include "selinux/selinux.h"
+
+int tw_get_default_metadata(const char* filename);
+int tw_set_default_metadata(const char* filename);
+
+#endif //_RECOVERY_SET_CONTEXTS_H
diff --git a/twrpinstall/include/tw_atomic.hpp b/twrpinstall/include/tw_atomic.hpp
new file mode 100644
index 0000000..0f29f02
--- /dev/null
+++ b/twrpinstall/include/tw_atomic.hpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Team Win Recovery 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.
+ */
+
+#ifndef _TWATOMIC_HPP_HEADER
+#define _TWATOMIC_HPP_HEADER
+
+#include <pthread.h>
+
+class TWAtomicInt
+{
+public:
+	TWAtomicInt(int initial_value = 0);
+	~TWAtomicInt();
+	void set_value(int new_value);
+	int get_value();
+
+private:
+	int value;
+	bool use_mutex;
+	pthread_mutex_t mutex_lock;
+};
+
+#endif //_TWATOMIC_HPP_HEADER
diff --git a/twrpinstall/include/twinstall.h b/twrpinstall/include/twinstall.h
new file mode 100755
index 0000000..f60dd26
--- /dev/null
+++ b/twrpinstall/include/twinstall.h
@@ -0,0 +1,6 @@
+#ifndef RECOVERY_TWINSTALL_H_
+#define RECOVERY_TWINSTALL_H_
+
+int TWinstall_zip(const char* path, int* wipe_cache);
+
+#endif  // RECOVERY_TWINSTALL_H_
diff --git a/twrpinstall/include/twinstall/adb_install.h b/twrpinstall/include/twinstall/adb_install.h
new file mode 100755
index 0000000..42321d4
--- /dev/null
+++ b/twrpinstall/include/twinstall/adb_install.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#pragma once
+
+#include <recovery_ui/device.h>
+
+// Applies a package via `adb sideload` or `adb rescue`. Returns the install result (in `enum
+// InstallResult`). When a reboot has been requested, INSTALL_REBOOT will be the return value, with
+// the reboot target set in reboot_action.
+int twrp_sideload(const char* install_file, Device::BuiltinAction* reboot_action);
+pid_t GetMiniAdbdPid();
\ No newline at end of file
diff --git a/twrpinstall/include/twinstall/get_args.h b/twrpinstall/include/twinstall/get_args.h
new file mode 100755
index 0000000..edad642
--- /dev/null
+++ b/twrpinstall/include/twinstall/get_args.h
@@ -0,0 +1,17 @@
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+
+#include "otautil/roots.h"
+
+#include "bootloader_message/include/bootloader_message/bootloader_message.h"
+
+extern std::string stage;
+
+class args {
+    public:
+        static std::vector<std::string> get_args(const int *argc, char*** const argv);
+};
\ No newline at end of file
diff --git a/twrpinstall/include/twinstall/install.h b/twrpinstall/include/twinstall/install.h
new file mode 100755
index 0000000..29647ad
--- /dev/null
+++ b/twrpinstall/include/twinstall/install.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stddef.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <ziparchive/zip_archive.h>
+
+#include "package.h"
+
+enum InstallResult {
+  INSTALL_SUCCESS,
+  INSTALL_ERROR,
+  INSTALL_CORRUPT,
+  INSTALL_NONE,
+  INSTALL_SKIPPED,
+  INSTALL_RETRY,
+  INSTALL_KEY_INTERRUPTED,
+  INSTALL_REBOOT,
+};
+
+enum class OtaType {
+  AB,
+  BLOCK,
+  BRICK,
+};
+
+static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
+static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
+
+// Installs the given update package. This function should also wipe the cache partition after a
+// successful installation if |should_wipe_cache| is true or an updater command asks to wipe the
+// cache.
+int install_package(const std::string& package, bool should_wipe_cache, bool needs_mount,
+                    int retry_count);
+
+// Verifies the package by ota keys. Returns true if the package is verified successfully,
+// otherwise returns false.
+bool verify_package(Package* package);
+
+// Reads meta data file of the package; parses each line in the format "key=value"; and writes the
+// result to |metadata|. Return true if succeed, otherwise return false.
+bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::string>* metadata);
+
+// Reads the "recovery.wipe" entry in the zip archive returns a list of partitions to wipe.
+std::vector<std::string> GetWipePartitionList(Package* wipe_package);
+
+// Verifies the compatibility info in a Treble-compatible package. Returns true directly if the
+// entry doesn't exist.
+bool verify_package_compatibility(ZipArchiveHandle package_zip);
+
+// Checks if the the metadata in the OTA package has expected values. Returns 0 on success.
+// Mandatory checks: ota-type, pre-device and serial number(if presents)
+// AB OTA specific checks: pre-build version, fingerprint, timestamp.
+int CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type);
+bool HasUpdaterBinary(ZipArchiveHandle zip);
\ No newline at end of file
diff --git a/twrpinstall/include/twinstall/package.h b/twrpinstall/include/twinstall/package.h
new file mode 100755
index 0000000..50a4ffa
--- /dev/null
+++ b/twrpinstall/include/twinstall/package.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <ziparchive/zip_archive.h>
+
+#include "verifier.h"
+
+// This class serves as a wrapper for an OTA update package. It aims to provide the common
+// interface for both packages loaded in memory and packages read from fd.
+class Package : public VerifierInterface {
+ public:
+  static std::unique_ptr<Package> CreateMemoryPackage(
+      const std::string& path);
+  static std::unique_ptr<Package> CreateMemoryPackage(
+      std::vector<uint8_t> content);
+  static std::unique_ptr<Package> CreateFilePackage(const std::string& path,
+                                                    const std::function<void(float)>& set_progress);
+
+  virtual ~Package() = default;
+
+  // Opens the package as a zip file and returns the ZipArchiveHandle.
+  virtual ZipArchiveHandle GetZipArchiveHandle() = 0;
+
+  // Updates the progress in fraction during package verification.
+  void SetProgress(float progress) override;
+
+ protected:
+  // An optional function to update the progress.
+  std::function<void(float)> set_progress_;
+};
diff --git a/twrpinstall/include/twinstall/verifier.h b/twrpinstall/include/twinstall/verifier.h
new file mode 100644
index 0000000..5d66e85
--- /dev/null
+++ b/twrpinstall/include/twinstall/verifier.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <openssl/ec_key.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+
+constexpr size_t MiB = 1024 * 1024;
+
+using HasherUpdateCallback = std::function<void(const uint8_t* addr, uint64_t size)>;
+
+struct RSADeleter {
+  void operator()(RSA* rsa) const {
+    RSA_free(rsa);
+  }
+};
+
+struct ECKEYDeleter {
+  void operator()(EC_KEY* ec_key) const {
+    EC_KEY_free(ec_key);
+  }
+};
+
+struct Certificate {
+  typedef enum {
+    KEY_TYPE_RSA,
+    KEY_TYPE_EC,
+  } KeyType;
+
+  Certificate(int hash_len_, KeyType key_type_, std::unique_ptr<RSA, RSADeleter>&& rsa_,
+              std::unique_ptr<EC_KEY, ECKEYDeleter>&& ec_)
+      : hash_len(hash_len_), key_type(key_type_), rsa(std::move(rsa_)), ec(std::move(ec_)) {}
+
+  // SHA_DIGEST_LENGTH (SHA-1) or SHA256_DIGEST_LENGTH (SHA-256)
+  int hash_len;
+  KeyType key_type;
+  std::unique_ptr<RSA, RSADeleter> rsa;
+  std::unique_ptr<EC_KEY, ECKEYDeleter> ec;
+};
+
+class VerifierInterface {
+ public:
+  virtual ~VerifierInterface() = default;
+
+  // Returns the package size in bytes.
+  virtual uint64_t GetPackageSize() const = 0;
+
+  // Reads |byte_count| data starting from |offset|, and puts the result in |buffer|.
+  virtual bool ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) = 0;
+
+  // Updates the hash contexts for |length| bytes data starting from |start|.
+  virtual bool UpdateHashAtOffset(const std::vector<HasherUpdateCallback>& hashers, uint64_t start,
+                                  uint64_t length) = 0;
+
+  // Updates the progress in fraction during package verification.
+  virtual void SetProgress(float progress) = 0;
+};
+
+//  Looks for an RSA signature embedded in the .ZIP file comment given the path to the zip.
+//  Verifies that it matches one of the given public keys. Returns VERIFY_SUCCESS or
+//  VERIFY_FAILURE (if any error is encountered or no key matches the signature).
+int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys,
+                const std::function<void(float)>& set_progress = nullptr);
+
+// Checks that the RSA key has a modulus of 2048 or 4096 bits long, and public exponent is 3 or
+// 65537.
+bool CheckRSAKey(const std::unique_ptr<RSA, RSADeleter>& rsa);
+
+// Checks that the field size of the curve for the EC key is 256 bits.
+bool CheckECKey(const std::unique_ptr<EC_KEY, ECKEYDeleter>& ec_key);
+
+// Parses a PEM-encoded x509 certificate from the given buffer and saves it into |cert|. Returns
+// false if there is a parsing failure or the signature's encryption algorithm is not supported.
+bool LoadCertificateFromBuffer(const std::vector<uint8_t>& pem_content, Certificate* cert);
+
+// Iterates over the zip entries with the suffix "x509.pem" and returns a list of recognized
+// certificates. Returns an empty list if we fail to parse any of the entries.
+std::vector<Certificate> LoadKeysFromZipfile(const std::string& zip_name);
+
+#define VERIFY_SUCCESS 0
+#define VERIFY_FAILURE 1
diff --git a/twrpinstall/include/twinstall/wipe_data.h b/twrpinstall/include/twinstall/wipe_data.h
new file mode 100755
index 0000000..07b1e40
--- /dev/null
+++ b/twrpinstall/include/twinstall/wipe_data.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <functional>
+
+struct selabel_handle;
+
+// Returns true on success.
+bool WipeCache(const std::function<bool()>& confirm);
+
+// Returns true on success.
+bool WipeData(bool convert_fbe);
diff --git a/twrpinstall/install.cpp b/twrpinstall/install.cpp
new file mode 100755
index 0000000..f3c7769
--- /dev/null
+++ b/twrpinstall/install.cpp
@@ -0,0 +1,753 @@
+/*
+ * 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 "twinstall/install.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <functional>
+#include <limits>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
+#include <android-base/parseint.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <vintf/VintfObjectRecovery.h>
+
+#include "twinstall/package.h"
+#include "twinstall/verifier.h"
+#include "twinstall/wipe_data.h"
+#include "otautil/error_code.h"
+#include "otautil/paths.h"
+#include "otautil/roots.h"
+#include "otautil/sysutil.h"
+#include "otautil/thermalutil.h"
+#include "private/setup_commands.h"
+
+using namespace std::chrono_literals;
+
+static constexpr int kRecoveryApiVersion = 3;
+// Assert the version defined in code and in Android.mk are consistent.
+static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions.");
+
+// Default allocation of progress bar segments to operations
+// static constexpr int VERIFICATION_PROGRESS_TIME = 60;
+// static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
+
+static std::condition_variable finish_log_temperature;
+
+bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::string>* metadata) {
+  CHECK(metadata != nullptr);
+
+  static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
+  ZipString path(METADATA_PATH);
+  ZipEntry entry;
+  if (FindEntry(zip, path, &entry) != 0) {
+    LOG(ERROR) << "Failed to find " << METADATA_PATH;
+    return false;
+  }
+
+  uint32_t length = entry.uncompressed_length;
+  std::string metadata_string(length, '\0');
+  int32_t err =
+      ExtractToMemory(zip, &entry, reinterpret_cast<uint8_t*>(&metadata_string[0]), length);
+  if (err != 0) {
+    LOG(ERROR) << "Failed to extract " << METADATA_PATH << ": " << ErrorCodeString(err);
+    return false;
+  }
+
+  for (const std::string& line : android::base::Split(metadata_string, "\n")) {
+    size_t eq = line.find('=');
+    if (eq != std::string::npos) {
+      metadata->emplace(android::base::Trim(line.substr(0, eq)),
+                        android::base::Trim(line.substr(eq + 1)));
+    }
+  }
+
+  return true;
+}
+
+// Gets the value for the given key in |metadata|. Returns an emtpy string if the key isn't
+// present.
+static std::string get_value(const std::map<std::string, std::string>& metadata,
+                             const std::string& key) {
+  const auto& it = metadata.find(key);
+  return (it == metadata.end()) ? "" : it->second;
+}
+
+static std::string OtaTypeToString(OtaType type) {
+  switch (type) {
+    case OtaType::AB:
+      return "AB";
+    case OtaType::BLOCK:
+      return "BLOCK";
+    case OtaType::BRICK:
+      return "BRICK";
+  }
+}
+
+// Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
+static void ReadSourceTargetBuild(const std::map<std::string, std::string>& metadata,
+                                  std::vector<std::string>* log_buffer) {
+  // Examples of the pre-build and post-build strings in metadata:
+  //   pre-build-incremental=2943039
+  //   post-build-incremental=2951741
+  auto source_build = get_value(metadata, "pre-build-incremental");
+  if (!source_build.empty()) {
+    log_buffer->push_back("source_build: " + source_build);
+  }
+
+  auto target_build = get_value(metadata, "post-build-incremental");
+  if (!target_build.empty()) {
+    log_buffer->push_back("target_build: " + target_build);
+  }
+}
+
+// Checks the build version, fingerprint and timestamp in the metadata of the A/B package.
+// Downgrading is not allowed unless explicitly enabled in the package and only for
+// incremental packages.
+static int CheckAbSpecificMetadata(const std::map<std::string, std::string>& metadata) {
+  // Incremental updates should match the current build.
+  auto device_pre_build = android::base::GetProperty("ro.build.version.incremental", "");
+  auto pkg_pre_build = get_value(metadata, "pre-build-incremental");
+  if (!pkg_pre_build.empty() && pkg_pre_build != device_pre_build) {
+    LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected "
+               << device_pre_build;
+    return INSTALL_ERROR;
+  }
+
+  auto device_fingerprint = android::base::GetProperty("ro.build.fingerprint", "");
+  auto pkg_pre_build_fingerprint = get_value(metadata, "pre-build");
+  if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != device_fingerprint) {
+    LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected "
+               << device_fingerprint;
+    return INSTALL_ERROR;
+  }
+
+  // Check for downgrade version.
+  // int64_t build_timestamp =
+      // android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
+  // int64_t pkg_post_timestamp = 0;
+  // We allow to full update to the same version we are running, in case there
+  // is a problem with the current copy of that version.
+  auto pkg_post_timestamp_string = get_value(metadata, "post-timestamp");
+  // if (pkg_post_timestamp_string.empty() ||
+  //     !android::base::ParseInt(pkg_post_timestamp_string, &pkg_post_timestamp) ||
+  //     pkg_post_timestamp < build_timestamp) {
+  //   if (get_value(metadata, "ota-downgrade") != "yes") {
+  //     LOG(ERROR) << "Update package is older than the current build, expected a build "
+  //                   "newer than timestamp "
+  //                << build_timestamp << " but package has timestamp " << pkg_post_timestamp
+  //                << " and downgrade not allowed.";
+  //     return INSTALL_ERROR;
+  //   }
+  //   if (pkg_pre_build_fingerprint.empty()) {
+  //     LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
+  //     return INSTALL_ERROR;
+  //   }
+  // }
+
+  return 0;
+}
+
+int CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type) {
+  auto package_ota_type = get_value(metadata, "ota-type");
+  auto expected_ota_type = OtaTypeToString(ota_type);
+  if (ota_type != OtaType::AB && ota_type != OtaType::BRICK) {
+    LOG(INFO) << "Skip package metadata check for ota type " << expected_ota_type;
+    return 0;
+  }
+
+  if (package_ota_type != expected_ota_type) {
+    LOG(ERROR) << "Unexpected ota package type, expects " << expected_ota_type << ", actual "
+               << package_ota_type;
+    return INSTALL_ERROR;
+  }
+
+  auto device = android::base::GetProperty("ro.product.device", "");
+  auto pkg_device = get_value(metadata, "pre-device");
+  if (pkg_device != device || pkg_device.empty()) {
+    LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << device;
+    return INSTALL_ERROR;
+  }
+
+  // We allow the package to not have any serialno; and we also allow it to carry multiple serial
+  // numbers split by "|"; e.g. serialno=serialno1|serialno2|serialno3 ... We will fail the
+  // verification if the device's serialno doesn't match any of these carried numbers.
+  auto pkg_serial_no = get_value(metadata, "serialno");
+  if (!pkg_serial_no.empty()) {
+    auto device_serial_no = android::base::GetProperty("ro.serialno", "");
+    bool serial_number_match = false;
+    for (const auto& number : android::base::Split(pkg_serial_no, "|")) {
+      if (device_serial_no == android::base::Trim(number)) {
+        serial_number_match = true;
+      }
+    }
+    if (!serial_number_match) {
+      LOG(ERROR) << "Package is for serial " << pkg_serial_no;
+      return INSTALL_ERROR;
+    }
+  }
+
+  if (ota_type == OtaType::AB) {
+    return CheckAbSpecificMetadata(metadata);
+  }
+
+  return 0;
+}
+
+int SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd,
+                          std::vector<std::string>* cmd) {
+  CHECK(cmd != nullptr);
+
+  // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
+  // in the zip file.
+  static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
+  ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES);
+  ZipEntry properties_entry;
+  if (FindEntry(zip, property_name, &properties_entry) != 0) {
+    LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
+    return INSTALL_CORRUPT;
+  }
+  uint32_t properties_entry_length = properties_entry.uncompressed_length;
+  std::vector<uint8_t> payload_properties(properties_entry_length);
+  int32_t err =
+      ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length);
+  if (err != 0) {
+    LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
+    return INSTALL_CORRUPT;
+  }
+
+  static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
+  ZipString payload_name(AB_OTA_PAYLOAD);
+  ZipEntry payload_entry;
+  if (FindEntry(zip, payload_name, &payload_entry) != 0) {
+    LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD;
+    return INSTALL_CORRUPT;
+  }
+  long payload_offset = payload_entry.offset;
+  *cmd = {
+    "/system/bin/update_engine_sideload",
+    "--payload=file://" + package,
+    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 0;
+}
+
+int SetUpNonAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int retry_count,
+                             int status_fd, std::vector<std::string>* cmd) {
+  CHECK(cmd != nullptr);
+
+  // In non-A/B updates we extract the update binary from the package.
+  ZipString binary_name(UPDATE_BINARY_NAME);
+  ZipEntry binary_entry;
+  if (FindEntry(zip, binary_name, &binary_entry) != 0) {
+    LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
+    return INSTALL_CORRUPT;
+  }
+
+  LOG(ERROR) << "SetupNonAbUpdateCommands::here1";
+  const std::string binary_path = Paths::Get().temporary_update_binary();
+  unlink(binary_path.c_str());
+  LOG(ERROR) << "SetupNonAbUpdateCommands::here2";
+  android::base::unique_fd fd(
+      open(binary_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755));
+  if (fd == -1) {
+    PLOG(ERROR) << "Failed to create " << binary_path;
+    return INSTALL_ERROR;
+  }
+  LOG(ERROR) << "SetupNonAbUpdateCommands::here3";
+
+  int32_t error = ExtractEntryToFile(zip, &binary_entry, fd);
+  if (error != 0) {
+    LOG(ERROR) << "Failed to extract " << UPDATE_BINARY_NAME << ": " << ErrorCodeString(error);
+    return INSTALL_ERROR;
+  }
+  LOG(ERROR) << "SetupNonAbUpdateCommands::here4";
+
+  // When executing the update binary contained in the package, the arguments passed are:
+  //   - the version number for this interface
+  //   - an FD to which the program can write in order to update the progress bar.
+  //   - the name of the package zip file.
+  //   - an optional argument "retry" if this update is a retry of a failed update attempt.
+  *cmd = {
+    binary_path,
+    std::to_string(kRecoveryApiVersion),
+    std::to_string(status_fd),
+    package,
+  };
+  if (retry_count > 0) {
+    cmd->push_back("retry");
+  }
+  return 0;
+}
+
+static void log_max_temperature(int* max_temperature, const std::atomic<bool>& logger_finished) {
+  CHECK(max_temperature != nullptr);
+  std::mutex mtx;
+  std::unique_lock<std::mutex> lck(mtx);
+  while (!logger_finished.load() &&
+         finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
+    *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
+  }
+}
+
+// If the package contains an update binary, extract it and run it.
+static int try_update_binary(const std::string& package, ZipArchiveHandle zip, bool* wipe_cache,
+                             std::vector<std::string>* log_buffer, int retry_count,
+                             int* max_temperature) {
+  std::map<std::string, std::string> metadata;
+
+  if (!ReadMetadataFromPackage(zip, &metadata)) {
+    LOG(ERROR) << "Failed to parse metadata in the zip file";
+    // return INSTALL_CORRUPT;
+  }
+
+  bool is_ab = android::base::GetBoolProperty("ro.build.ab_update", false);
+  // Verifies against the metadata in the package first.
+  // if (int check_status = is_ab ? CheckPackageMetadata(metadata, OtaType::AB) : 0;
+  //     check_status != 0) {
+  //   log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
+    // return check_status;
+  // }
+
+  ReadSourceTargetBuild(metadata, log_buffer);
+  LOG(ERROR) << "try_update_binary::here1";
+  // The updater in child process writes to the pipe to communicate with recovery.
+  android::base::unique_fd pipe_read, pipe_write;
+  // Explicitly disable O_CLOEXEC using 0 as the flags (last) parameter to Pipe
+  // so that the child updater process will recieve a non-closed fd.
+  if (!android::base::Pipe(&pipe_read, &pipe_write, 0)) {
+    PLOG(ERROR) << "Failed to create pipe for updater-recovery communication";
+    return INSTALL_CORRUPT;
+  }
+
+  // The updater-recovery communication protocol.
+  //
+  //   progress <frac> <secs>
+  //       fill up the next <frac> part of of the progress bar over <secs> seconds. If <secs> is
+  //       zero, use `set_progress` commands to manually control the progress of this segment of the
+  //       bar.
+  //
+  //   set_progress <frac>
+  //       <frac> should be between 0.0 and 1.0; sets the progress bar within the segment defined by
+  //       the most recent progress command.
+  //
+  //   ui_print <string>
+  //       display <string> on the screen.
+  //
+  //   wipe_cache
+  //       a wipe of cache will be performed following a successful installation.
+  //
+  //   clear_display
+  //       turn off the text display.
+  //
+  //   enable_reboot
+  //       packages can explicitly request that they want the user to be able to reboot during
+  //       installation (useful for debugging packages that don't exit).
+  //
+  //   retry_update
+  //       updater encounters some issue during the update. It requests a reboot to retry the same
+  //       package automatically.
+  //
+  //   log <string>
+  //       updater requests logging the string (e.g. cause of the failure).
+  //
+
+  std::vector<std::string> args;
+
+  is_ab = false;
+  ZipString binary_name(UPDATE_BINARY_NAME);
+  ZipEntry binary_entry;
+  if (FindEntry(zip, binary_name, &binary_entry) != 0) {
+    LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
+    is_ab = true;
+  }
+
+  if (int update_status =
+          is_ab ? SetUpAbUpdateCommands(package, zip, pipe_write.get(), &args)
+                : SetUpNonAbUpdateCommands(package, zip, retry_count, pipe_write.get(), &args);
+      update_status != 0) {
+    log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
+    // return update_status;
+  }
+
+  pid_t pid = fork();
+  if (pid == -1) {
+    PLOG(ERROR) << "Failed to fork update binary";
+    log_buffer->push_back(android::base::StringPrintf("error: %d", kForkUpdateBinaryFailure));
+    return INSTALL_ERROR;
+  }
+
+  if (pid == 0) {
+    umask(022);
+    pipe_read.reset();
+
+    // Convert the std::string vector to a NULL-terminated char* vector suitable for execv.
+    auto chr_args = StringVectorToNullTerminatedArray(args);
+    execv(chr_args[0], chr_args.data());
+    // We shouldn't use LOG/PLOG in the forked process, since they may cause the child process to
+    // hang. This deadlock results from an improperly copied mutex in the ui functions.
+    // (Bug: 34769056)
+    fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
+    _exit(EXIT_FAILURE);
+  }
+  pipe_write.reset();
+
+  std::atomic<bool> logger_finished(false);
+  std::thread temperature_logger(log_max_temperature, max_temperature, std::ref(logger_finished));
+
+  *wipe_cache = false;
+  bool retry_update = false;
+
+  char buffer[1024];
+  FILE* from_child = android::base::Fdopen(std::move(pipe_read), "r");
+  while (fgets(buffer, sizeof(buffer), from_child) != nullptr) {
+    std::string line(buffer);
+    size_t space = line.find_first_of(" \n");
+    std::string command(line.substr(0, space));
+    if (command.empty()) continue;
+
+    // Get rid of the leading and trailing space and/or newline.
+    std::string args = space == std::string::npos ? "" : android::base::Trim(line.substr(space));
+
+    if (command == "progress") {
+      std::vector<std::string> tokens = android::base::Split(args, " ");
+      double fraction;
+      int seconds;
+      if (tokens.size() == 2 && android::base::ParseDouble(tokens[0].c_str(), &fraction) &&
+          android::base::ParseInt(tokens[1], &seconds)) {
+        // ui->ShowProgress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
+      } else {
+        LOG(ERROR) << "invalid \"progress\" parameters: " << line;
+      }
+    } else if (command == "set_progress") {
+      std::vector<std::string> tokens = android::base::Split(args, " ");
+      double fraction;
+      if (tokens.size() == 1 && android::base::ParseDouble(tokens[0].c_str(), &fraction)) {
+        // ui->SetProgress(fraction);
+      } else {
+        LOG(ERROR) << "invalid \"set_progress\" parameters: " << line;
+      }
+    } else if (command == "ui_print") {
+      // ui->PrintOnScreenOnly("%s\n", args.c_str());
+      fflush(stdout);
+    } else if (command == "wipe_cache") {
+      *wipe_cache = true;
+    } else if (command == "clear_display") {
+      // ui->SetBackground(RecoveryUI::NONE);
+    } else if (command == "enable_reboot") {
+      // packages can explicitly request that they want the user
+      // to be able to reboot during installation (useful for
+      // debugging packages that don't exit).
+      // ui->SetEnableReboot(true);
+    } else if (command == "retry_update") {
+      retry_update = true;
+    } else if (command == "log") {
+      if (!args.empty()) {
+        // Save the logging request from updater and write to last_install later.
+        log_buffer->push_back(args);
+      } else {
+        LOG(ERROR) << "invalid \"log\" parameters: " << line;
+      }
+    } else {
+      LOG(ERROR) << "unknown command [" << command << "]";
+    }
+  }
+  fclose(from_child);
+
+  int status;
+  waitpid(pid, &status, 0);
+
+  logger_finished.store(true);
+  finish_log_temperature.notify_one();
+  temperature_logger.join();
+
+  if (retry_update) {
+    return INSTALL_RETRY;
+  }
+  if (WIFEXITED(status)) {
+    if (WEXITSTATUS(status) != EXIT_SUCCESS) {
+      LOG(ERROR) << "Error in " << package << " (status " << WEXITSTATUS(status) << ")";
+      return INSTALL_ERROR;
+    }
+  } else if (WIFSIGNALED(status)) {
+    LOG(ERROR) << "Error in " << package << " (killed by signal " << WTERMSIG(status) << ")";
+    return INSTALL_ERROR;
+  } else {
+    LOG(FATAL) << "Invalid status code " << status;
+  }
+
+  return INSTALL_SUCCESS;
+}
+
+// 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(ZipArchiveHandle package_zip __unused) {
+//   LOG(INFO) << "Verifying package compatibility...";
+
+//   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) {
+//     LOG(INFO) << "Package doesn't contain " << COMPATIBILITY_ZIP_ENTRY << " 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) {
+//     LOG(ERROR) << "Failed to read " << 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) {
+//     LOG(ERROR) << "Failed to OpenArchiveFromMemory: " << 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) {
+//     LOG(ERROR) << "Failed to start iterating zip entries: " << 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) {
+//       LOG(ERROR) << "Failed to read " << 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.
+//   std::string err;
+//   int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
+//   if (result == 0) {
+//     return true;
+//   }
+
+//   LOG(ERROR) << "Failed to verify package compatibility (result " << result << "): " << err;
+//   return false;
+// }
+
+static int really_install_package(const std::string& path, bool* wipe_cache __unused, bool needs_mount __unused,
+                                  std::vector<std::string>* log_buffer __unused, int retry_count __unused,
+                                  int* max_temperature __unused) {
+  // ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
+  // ui->Print("Finding update package...\n");
+  // Give verification half the progress bar...
+  // ui->SetProgressType(RecoveryUI::DETERMINATE);
+  // ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
+  LOG(INFO) << "Update location: " << path;
+
+  // Map the update package into memory.
+  // ui->Print("Opening update package...\n");
+  if (needs_mount) {
+    if (path[0] == '@') {
+      ensure_path_mounted(path.substr(1));
+    } else {
+      ensure_path_mounted(path);
+    }
+  }
+
+  auto package = Package::CreateMemoryPackage(
+      path);
+  if (!package) {
+    log_buffer->push_back(android::base::StringPrintf("error: %d", kMapFileFailure));
+    return INSTALL_CORRUPT;
+  }
+
+  // Verify package.
+  if (!verify_package(package.get())) {
+    log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
+    return INSTALL_CORRUPT;
+  }
+
+  // Try to open the package.
+  ZipArchiveHandle zip = package->GetZipArchiveHandle();
+  if (!zip) {
+    log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
+    return INSTALL_CORRUPT;
+  }
+  LOG(ERROR) << "really_install_package::here1";
+
+  // Additionally verify the compatibility of the package if it's a fresh install.
+  if (retry_count == 0 && !verify_package_compatibility(zip)) {
+    log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
+    return INSTALL_CORRUPT;
+  }
+
+  // Verify and install the contents of the package.
+  // ui->Print("Installing update...\n");
+  // if (retry_count > 0) {
+    // ui->Print("Retry attempt: %d\n", retry_count);
+  // }
+  // ui->SetEnableReboot(false);
+  LOG(ERROR) << "really_install_package::here2";
+  int result =
+      try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);
+  // ui->SetEnableReboot(true);
+  // ui->Print("\n");
+  return result;
+}
+
+int install_package(const std::string& path, bool should_wipe_cache, bool needs_mount,
+                    int retry_count) {
+  CHECK(!path.empty());
+
+  auto start = std::chrono::system_clock::now();
+
+  int start_temperature = GetMaxValueFromThermalZone();
+  int max_temperature = start_temperature;
+
+  int result;
+  std::vector<std::string> log_buffer;
+  // if (setup_install_mounts() != 0) {
+  //   LOG(ERROR) << "failed to set up expected mounts for install; aborting";
+  //   result = INSTALL_ERROR;
+  // } else {
+    bool updater_wipe_cache = false;
+    result = really_install_package(path, &updater_wipe_cache, needs_mount, &log_buffer,
+                                    retry_count, &max_temperature);
+    should_wipe_cache = should_wipe_cache || updater_wipe_cache;
+  // }
+
+  // Measure the time spent to apply OTA update in seconds.
+  std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
+  int time_total = static_cast<int>(duration.count());
+
+  bool has_cache = volume_for_mount_point("/cache") != nullptr;
+  // Skip logging the uncrypt_status on devices without /cache.
+  if (has_cache) {
+    static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
+    if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
+      LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
+    } else {
+      std::string uncrypt_status;
+      if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
+        PLOG(WARNING) << "failed to read uncrypt status";
+      } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
+        LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
+      } else {
+        log_buffer.push_back(android::base::Trim(uncrypt_status));
+      }
+    }
+  }
+
+  // The first two lines need to be the package name and install result.
+  std::vector<std::string> log_header = {
+    path,
+    result == INSTALL_SUCCESS ? "1" : "0",
+    "time_total: " + std::to_string(time_total),
+    "retry: " + std::to_string(retry_count),
+  };
+
+  int end_temperature = GetMaxValueFromThermalZone();
+  max_temperature = std::max(end_temperature, max_temperature);
+  if (start_temperature > 0) {
+    log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
+  }
+  if (end_temperature > 0) {
+    log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
+  }
+  if (max_temperature > 0) {
+    log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
+  }
+
+  std::string log_content =
+      android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n") + "\n";
+  const std::string& install_file = Paths::Get().temporary_install_file();
+  if (!android::base::WriteStringToFile(log_content, install_file)) {
+    PLOG(ERROR) << "failed to write " << install_file;
+  }
+
+  // Write a copy into last_log.
+  LOG(INFO) << log_content;
+
+  if (result == INSTALL_SUCCESS && should_wipe_cache) {
+    if (!WipeCache(nullptr)) {
+      result = INSTALL_ERROR;
+    }
+  }
+
+  return result;
+}
+
+bool verify_package(Package* package) {
+  static constexpr const char* CERTIFICATE_ZIP_FILE = "/system/etc/security/otacerts.zip";
+  std::vector<Certificate> loaded_keys = LoadKeysFromZipfile(CERTIFICATE_ZIP_FILE);
+  if (loaded_keys.empty()) {
+    LOG(ERROR) << "Failed to load keys";
+    return false;
+  }
+  LOG(INFO) << loaded_keys.size() << " key(s) loaded from " << CERTIFICATE_ZIP_FILE;
+
+  // Verify package.
+  // ui->Print("Verifying update package...\n");
+  // auto t0 = std::chrono::system_clock::now();
+  int err = verify_file(package, loaded_keys);
+  // if(err != VERIFY_SUCCESS) {
+
+  // }
+  // std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
+  // ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
+  if (err != VERIFY_SUCCESS) {
+    LOG(ERROR) << "Signature verification failed";
+    LOG(ERROR) << "error: " << kZipVerificationFailure;
+  //   return false;
+  }
+  return true;
+}
diff --git a/twrpinstall/installcommand.cpp b/twrpinstall/installcommand.cpp
new file mode 100755
index 0000000..a03cb01
--- /dev/null
+++ b/twrpinstall/installcommand.cpp
@@ -0,0 +1,341 @@
+/*
+ * 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 <ziparchive/zip_archive.h>
+#include <vintf/VintfObjectRecovery.h>
+#include "twinstall/install.h"
+
+#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(ZipArchiveHandle zip, std::string* meta_data) {
+    ZipString binary_name(METADATA_PATH);
+    ZipEntry binary_entry;
+    if (FindEntry(zip, binary_name, &binary_entry) == 0) {
+        long size = binary_entry.uncompressed_length;
+        if (size <= 0)
+            return false;
+
+        meta_data->resize(size, '\0');
+        int32_t ret = ExtractToMemory(zip, &binary_entry, reinterpret_cast<uint8_t*>(&(*meta_data)[0]),
+                                  size);
+        if (ret != 0) {
+            printf("Failed to read metadata in update package.\n");
+            CloseArchive(zip);
+            return false;
+        }
+        return true;
+      }
+      return false;
+}
+
+// Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
+void read_source_target_build(ZipArchiveHandle 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(ZipArchiveHandle 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, int retry_count __unused,
+                      int status_fd, std::vector<std::string>* cmd)
+{
+    auto package = Package::CreateMemoryPackage(path);
+	if (!package) {
+		return INSTALL_CORRUPT;
+	}
+
+	ZipArchiveHandle Zip = package->GetZipArchiveHandle();
+    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)) {
+	ZipString binary_name(AB_OTA_PAYLOAD_PROPERTIES);
+    ZipEntry binary_entry;
+    if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
+        printf("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES);
+        return INSTALL_CORRUPT;
+    }
+    std::vector<unsigned char> payload_properties(
+            binary_entry.uncompressed_length);
+    int32_t extract_ret = ExtractToMemory(Zip, &binary_entry, reinterpret_cast<uint8_t*>(payload_properties.data()),
+                                  binary_entry.uncompressed_length);
+    if (extract_ret != 0) {
+        printf("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES);
+        CloseArchive(Zip);
+        return false;
+    }
+
+    ZipString ab_ota_payload(AB_OTA_PAYLOAD);
+    ZipEntry ab_ota_payload_entry;
+    if (FindEntry(Zip, ab_ota_payload, &ab_ota_payload_entry) != 0) {
+        printf("Can't find %s\n", AB_OTA_PAYLOAD);
+        return INSTALL_CORRUPT;
+    }
+    // long payload_offset = Zip->GetEntryOffset(AB_OTA_PAYLOAD);
+    long payload_offset = ab_ota_payload_entry.offset;
+    *cmd = {
+        "/system/bin/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(ZipArchiveHandle zip __unused /*, std::vector<std::string>& log_buffer*/) {return;}
+
+int
+abupdate_binary_command(__unused const char* path, __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;
+}
+
+// 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(ZipArchiveHandle zw) {
+  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(zw, 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(zw, &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;
+}
diff --git a/twrpinstall/legacy_property_service.cpp b/twrpinstall/legacy_property_service.cpp
new file mode 100644
index 0000000..c3990f7
--- /dev/null
+++ b/twrpinstall/legacy_property_service.cpp
@@ -0,0 +1,217 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "../../bionic/libc/private/bionic_futex.h"
+
+#include <cutils/properties.h>
+
+#include "legacy_properties.h"
+
+#include <sys/mman.h>
+// Not available in 5.0
+//#include <sys/atomics.h>
+#include "legacy_property_service.h"
+
+#ifndef INT32_MAX
+#define INT32_MAX	(2147483647)
+#endif
+
+static int property_area_inited = 0;
+
+typedef struct {
+    void *data;
+    size_t size;
+    int fd;
+} workspace;
+
+static int init_workspace(workspace *w, size_t size)
+{
+    void *data;
+    int fd;
+
+        /* dev is a tmpfs that we can use to carve a shared workspace
+         * out of, so let's do that...
+         */
+    fd = open("/dev/__legacy_properties__", O_RDWR | O_CREAT, 0600);
+    if (fd < 0)
+        return -1;
+
+    if (ftruncate(fd, size) < 0)
+        goto out;
+
+    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    if(data == MAP_FAILED)
+        goto out;
+
+    close(fd);
+
+    fd = open("/dev/__legacy_properties__", O_RDONLY);
+    if (fd < 0)
+        return -1;
+
+    unlink("/dev/__legacy_properties__");
+
+    w->data = data;
+    w->size = size;
+    w->fd = fd;
+    return 0;
+
+out:
+    close(fd);
+    return -1;
+}
+
+/* (8 header words + 247 toc words) = 1020 bytes */
+/* 1024 bytes header and toc + 247 prop_infos @ 128 bytes = 32640 bytes */
+
+#define PA_COUNT_MAX  247
+#define PA_INFO_START 1024
+#define PA_SIZE       32768
+
+static workspace pa_workspace;
+static prop_info *pa_info_array;
+
+prop_area *__legacy_property_area__;
+
+static int init_property_area(void)
+{
+    prop_area *pa;
+
+    if(pa_info_array)
+        return -1;
+
+    if(init_workspace(&pa_workspace, PA_SIZE))
+        return -1;
+
+    fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC);
+
+    pa_info_array = (prop_info*) (((char*) pa_workspace.data) + PA_INFO_START);
+
+    pa = (prop_area*)(pa_workspace.data);
+    memset(pa, 0, PA_SIZE);
+    pa->magic = PROP_AREA_MAGIC;
+    pa->version = PROP_AREA_VERSION;
+
+    /* plug into the lib property services */
+    __legacy_property_area__ = pa;
+    property_area_inited = 1;
+    return 0;
+}
+
+static void update_prop_info(prop_info *pi, const char *value, unsigned len)
+{
+    pi->serial = pi->serial | 1;
+    memcpy(pi->value, value, len + 1);
+    pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff);
+    __futex_wake(&pi->serial, INT32_MAX);
+}
+
+static const prop_info *__legacy_property_find(const char *name)
+{
+    prop_area *pa = __legacy_property_area__;
+    unsigned count = pa->count;
+    unsigned *toc = pa->toc;
+    unsigned len = strlen(name);
+    prop_info *pi;
+
+    while(count--) {
+        unsigned entry = *toc++;
+        if(TOC_NAME_LEN(entry) != len) continue;
+
+        pi = TOC_TO_INFO(pa, entry);
+        if(memcmp(name, pi->name, len)) continue;
+
+        return pi;
+    }
+
+    return 0;
+}
+
+static int legacy_property_set(const char *name, const char *value)
+{
+    prop_area *pa;
+    prop_info *pi;
+
+    int namelen = strlen(name);
+    int valuelen = strlen(value);
+
+    if(namelen >= PROP_NAME_MAX) return -1;
+    if(valuelen >= PROP_VALUE_MAX) return -1;
+    if(namelen < 1) return -1;
+
+    pi = (prop_info*) __legacy_property_find(name);
+
+
+    if(pi != 0) {
+        /* ro.* properties may NEVER be modified once set */
+        if(!strncmp(name, "ro.", 3)) return -1;
+
+        pa = __legacy_property_area__;
+        update_prop_info(pi, value, valuelen);
+        pa->serial++;
+        __futex_wake(&pa->serial, INT32_MAX);
+    } else {
+        pa = __legacy_property_area__;
+        if(pa->count == PA_COUNT_MAX) return -1;
+
+        pi = pa_info_array + pa->count;
+        pi->serial = (valuelen << 24);
+        memcpy(pi->name, name, namelen + 1);
+        memcpy(pi->value, value, valuelen + 1);
+
+        pa->toc[pa->count] =
+            (namelen << 24) | (((unsigned long) pi) - ((unsigned long) pa));
+
+        pa->count++;
+        pa->serial++;
+        __futex_wake(&pa->serial, INT32_MAX);
+    }
+
+    return 0;
+}
+
+void legacy_get_property_workspace(int *fd, int *sz)
+{
+    *fd = pa_workspace.fd;
+    *sz = pa_workspace.size;
+}
+
+static void copy_property_to_legacy(const char *key, const char *value, void *cookie __unused)
+{
+    legacy_property_set(key, value);
+}
+
+int legacy_properties_init()
+{
+    if(init_property_area() != 0)
+        return -1;
+
+    if(property_list(copy_property_to_legacy, 0) != 0)
+        return -1;
+
+    return 0;
+}
diff --git a/twrpinstall/package.cpp b/twrpinstall/package.cpp
new file mode 100755
index 0000000..ba1d5df
--- /dev/null
+++ b/twrpinstall/package.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2019 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 "twinstall/package.h"
+
+#include <string.h>
+#include <unistd.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+
+#include "otautil/error_code.h"
+#include "otautil/sysutil.h"
+
+// This class wraps the package in memory, i.e. a memory mapped package, or a package loaded
+// to a string/vector.
+class MemoryPackage : public Package {
+ public:
+  // Constructs the class from a file. We will memory maps the file later.
+  MemoryPackage(const std::string& path, std::unique_ptr<MemMapping> map);
+
+  // Constructs the class from the package bytes in |content|.
+  MemoryPackage(std::vector<uint8_t> content);
+
+  ~MemoryPackage() override;
+
+  // Memory maps the package file if necessary. Initializes the start address and size of the
+  // package.
+  uint64_t GetPackageSize() const override {
+    return package_size_;
+  }
+
+  bool ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) override;
+
+  ZipArchiveHandle GetZipArchiveHandle() override;
+
+  bool UpdateHashAtOffset(const std::vector<HasherUpdateCallback>& hashers, uint64_t start,
+                          uint64_t length) override;
+
+ private:
+  const uint8_t* addr_;    // Start address of the package in memory.
+  uint64_t package_size_;  // Package size in bytes.
+
+  // The memory mapped package.
+  std::unique_ptr<MemMapping> map_;
+  // A copy of the package content, valid only if we create the class with the exact bytes of
+  // the package.
+  std::vector<uint8_t> package_content_;
+  // The physical path to the package, empty if we create the class with the package content.
+  std::string path_;
+
+  // The ZipArchiveHandle of the package.
+  ZipArchiveHandle zip_handle_;
+};
+
+void Package::SetProgress(float progress) {
+  if (set_progress_) {
+    set_progress_(progress);
+  }
+}
+
+class FilePackage : public Package {
+ public:
+  FilePackage(android::base::unique_fd&& fd, uint64_t file_size, const std::string& path,
+              const std::function<void(float)>& set_progress);
+
+  ~FilePackage() override;
+
+  uint64_t GetPackageSize() const override {
+    return package_size_;
+  }
+
+  bool ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) override;
+
+  ZipArchiveHandle GetZipArchiveHandle() override;
+
+  bool UpdateHashAtOffset(const std::vector<HasherUpdateCallback>& hashers, uint64_t start,
+                          uint64_t length) override;
+
+ private:
+  android::base::unique_fd fd_;  // The underlying fd to the open package.
+  uint64_t package_size_;
+  std::string path_;  // The physical path to the package.
+
+  ZipArchiveHandle zip_handle_;
+};
+
+std::unique_ptr<Package> Package::CreateMemoryPackage(
+    const std::string& path) {
+  std::unique_ptr<MemMapping> mmap = std::make_unique<MemMapping>();
+  if (!mmap->MapFile(path)) {
+    LOG(ERROR) << "failed to map file";
+    return nullptr;
+  }
+
+  return std::make_unique<MemoryPackage>(path, std::move(mmap));
+}
+
+std::unique_ptr<Package> Package::CreateFilePackage(
+    const std::string& path, const std::function<void(float)>& set_progress) {
+  android::base::unique_fd fd(open(path.c_str(), O_RDONLY));
+  if (fd == -1) {
+    PLOG(ERROR) << "Failed to open " << path;
+    return nullptr;
+  }
+
+  off64_t file_size = lseek64(fd.get(), 0, SEEK_END);
+  if (file_size == -1) {
+    PLOG(ERROR) << "Failed to get the package size";
+    return nullptr;
+  }
+
+  return std::make_unique<FilePackage>(std::move(fd), file_size, path, set_progress);
+}
+
+std::unique_ptr<Package> Package::CreateMemoryPackage(
+    std::vector<uint8_t> content) {
+  return std::make_unique<MemoryPackage>(std::move(content));
+}
+
+MemoryPackage::MemoryPackage(const std::string& path, std::unique_ptr<MemMapping> map)
+    : map_(std::move(map)), path_(path), zip_handle_(nullptr) {
+  addr_ = map_->addr;
+  package_size_ = map_->length;
+}
+
+MemoryPackage::MemoryPackage(std::vector<uint8_t> content)
+    : package_content_(std::move(content)), zip_handle_(nullptr) {
+  CHECK(!package_content_.empty());
+  addr_ = package_content_.data();
+  package_size_ = package_content_.size();
+}
+
+MemoryPackage::~MemoryPackage() {
+  if (zip_handle_) {
+    CloseArchive(zip_handle_);
+  }
+}
+
+bool MemoryPackage::ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) {
+  if (byte_count > package_size_ || offset > package_size_ - byte_count) {
+    LOG(ERROR) << "Out of bound read, offset: " << offset << ", size: " << byte_count
+               << ", total package_size: " << package_size_;
+    return false;
+  }
+  memcpy(buffer, addr_ + offset, byte_count);
+  return true;
+}
+
+bool MemoryPackage::UpdateHashAtOffset(const std::vector<HasherUpdateCallback>& hashers,
+                                       uint64_t start, uint64_t length) {
+  if (length > package_size_ || start > package_size_ - length) {
+    LOG(ERROR) << "Out of bound read, offset: " << start << ", size: " << length
+               << ", total package_size: " << package_size_;
+    return false;
+  }
+
+  for (const auto& hasher : hashers) {
+    hasher(addr_ + start, length);
+  }
+  return true;
+}
+
+ZipArchiveHandle MemoryPackage::GetZipArchiveHandle() {
+  if (zip_handle_) {
+    return zip_handle_;
+  }
+
+  if (auto err = OpenArchiveFromMemory(const_cast<uint8_t*>(addr_), package_size_, path_.c_str(),
+                                       &zip_handle_);
+      err != 0) {
+    LOG(ERROR) << "Can't open package" << path_ << " : " << ErrorCodeString(err);
+    return nullptr;
+  }
+
+  return zip_handle_;
+}
+
+FilePackage::FilePackage(android::base::unique_fd&& fd, uint64_t file_size, const std::string& path,
+                         const std::function<void(float)>& set_progress)
+    : fd_(std::move(fd)), package_size_(file_size), path_(path), zip_handle_(nullptr) {
+  set_progress_ = set_progress;
+}
+
+FilePackage::~FilePackage() {
+  if (zip_handle_) {
+    CloseArchive(zip_handle_);
+  }
+}
+
+bool FilePackage::ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) {
+  if (byte_count > package_size_ || offset > package_size_ - byte_count) {
+    LOG(ERROR) << "Out of bound read, offset: " << offset << ", size: " << byte_count
+               << ", total package_size: " << package_size_;
+    return false;
+  }
+
+  if (!android::base::ReadFullyAtOffset(fd_.get(), buffer, byte_count, offset)) {
+    PLOG(ERROR) << "Failed to read " << byte_count << " bytes data at offset " << offset;
+    return false;
+  }
+
+  return true;
+}
+
+bool FilePackage::UpdateHashAtOffset(const std::vector<HasherUpdateCallback>& hashers,
+                                     uint64_t start, uint64_t length) {
+  if (length > package_size_ || start > package_size_ - length) {
+    LOG(ERROR) << "Out of bound read, offset: " << start << ", size: " << length
+               << ", total package_size: " << package_size_;
+    return false;
+  }
+
+  uint64_t so_far = 0;
+  while (so_far < length) {
+    uint64_t read_size = std::min<uint64_t>(length - so_far, 16 * MiB);
+    std::vector<uint8_t> buffer(read_size);
+    if (!ReadFullyAtOffset(buffer.data(), read_size, start + so_far)) {
+      return false;
+    }
+
+    for (const auto& hasher : hashers) {
+      hasher(buffer.data(), read_size);
+    }
+    so_far += read_size;
+  }
+
+  return true;
+}
+
+ZipArchiveHandle FilePackage::GetZipArchiveHandle() {
+  if (zip_handle_) {
+    return zip_handle_;
+  }
+
+  if (auto err = OpenArchiveFd(fd_.get(), path_.c_str(), &zip_handle_); err != 0) {
+    LOG(ERROR) << "Can't open package" << path_ << " : " << ErrorCodeString(err);
+    return nullptr;
+  }
+
+  return zip_handle_;
+}
diff --git a/twrpinstall/set_metadata.cpp b/twrpinstall/set_metadata.cpp
new file mode 100644
index 0000000..2e1d769
--- /dev/null
+++ b/twrpinstall/set_metadata.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 The Team Win Recovery 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.
+ */
+
+/*
+ * The purpose of these functions is to try to get and set the proper
+ * file permissions, SELinux contexts, owner, and group so that these
+ * files are accessible when we boot up to normal Android via MTP and to
+ * file manager apps. During early boot we try to read the contexts and
+ * owner / group info from /data/media or from /data/media/0 and store
+ * them in static variables. From there, we'll try to set the same
+ * contexts, owner, and group information on most files we create during
+ * operations like backups, copying the log, and MTP operations.
+ */
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "selinux/selinux.h"
+
+static security_context_t selinux_context;
+struct stat s;
+static int has_stat = 0;
+
+int tw_get_context(const char* filename) {
+	if (lgetfilecon(filename, &selinux_context) >= 0) {
+		printf("tw_get_context got selinux context: %s\n", selinux_context);
+		return 0;
+	} else {
+		printf("tw_get_context failed to get selinux context\n");
+		selinux_context = NULL;
+	}
+	return -1;
+}
+
+int tw_get_stat(const char* filename) {
+	if (lstat(filename, &s) == 0) {
+		has_stat = 1;
+		return 0;
+	}
+	printf("tw_get_stat failed to lstat '%s'\n", filename);
+	return -1;
+}
+
+int tw_get_default_metadata(const char* filename) {
+	if (tw_get_context(filename) == 0 && tw_get_stat(filename) == 0)
+		return 0;
+	return -1;
+}
+
+// Most of this logging is disabled to prevent log spam if we are trying
+// to set contexts and permissions on file systems that do not support
+// these types of things (e.g. vfat / FAT / FAT32).
+int tw_set_default_metadata(const char* filename) {
+	int ret = 0;
+	struct stat st;
+
+	if (selinux_context == NULL) {
+		//printf("selinux_context was null, '%s'\n", filename);
+		ret = -1;
+	} else if (lsetfilecon(filename, selinux_context) < 0) {
+		//printf("Failed to set default contexts on '%s'.\n", filename);
+		ret = -1;
+	}
+
+	if (lstat(filename, &st) == 0 && st.st_mode & S_IFREG && chmod(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) < 0) {
+		//printf("Failed to chmod '%s'\n", filename);
+		ret = -1;
+	}
+
+	if (has_stat && chown(filename, s.st_uid, s.st_gid) < 0) {
+		//printf("Failed to lchown '%s'.\n", filename);
+		ret = -1;
+	}
+	//printf("Done trying to set defaults on '%s'\n");
+	return ret;
+}
diff --git a/twrpinstall/tw_atomic.cpp b/twrpinstall/tw_atomic.cpp
new file mode 100644
index 0000000..31cdd85
--- /dev/null
+++ b/twrpinstall/tw_atomic.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Team Win Recovery 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 <pthread.h>
+#include <stdio.h>
+#include "tw_atomic.hpp"
+
+/*
+ * According to this documentation:
+ * https://developer.android.com/training/articles/smp.html
+ * it is recommended to use mutexes instead of atomics. This class
+ * provides us with a wrapper to make "atomic" variables easy to use.
+ */
+
+TWAtomicInt::TWAtomicInt(int initial_value /* = 0 */) {
+	if (pthread_mutex_init(&mutex_lock, NULL) != 0) {
+		// This should hopefully never happen. If it does, the
+		// operations will not be atomic, but we will allow things to
+		// continue anyway after logging the issue and just hope for
+		// the best.
+		printf("TWAtomic error initializing mutex.\n");
+		use_mutex = false;
+	} else {
+		use_mutex = true;
+	}
+	value = initial_value;
+}
+
+TWAtomicInt::~TWAtomicInt() {
+	if (use_mutex)
+		pthread_mutex_destroy(&mutex_lock);
+}
+
+void TWAtomicInt::set_value(int new_value) {
+	if (use_mutex) {
+		pthread_mutex_lock(&mutex_lock);
+		value = new_value;
+		pthread_mutex_unlock(&mutex_lock);
+	} else {
+		value = new_value;
+	}
+}
+
+int TWAtomicInt::get_value(void) {
+	int ret_val;
+
+	if (use_mutex) {
+		pthread_mutex_lock(&mutex_lock);
+		ret_val = value;
+		pthread_mutex_unlock(&mutex_lock);
+	} else {
+		ret_val = value;
+	}
+	return ret_val;
+}
diff --git a/twrpinstall/twinstall.cpp b/twrpinstall/twinstall.cpp
new file mode 100755
index 0000000..65a83a6
--- /dev/null
+++ b/twrpinstall/twinstall.cpp
@@ -0,0 +1,478 @@
+/*
+	Copyright 2012 to 2017 bigbiff/Dees_Troy TeamWin
+	This file is part of TWRP/TeamWin Recovery Project.
+
+	TWRP is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	TWRP is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <unistd.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <cutils/properties.h>
+
+#include <android-base/unique_fd.h>
+
+#include "twcommon.h"
+#include "mtdutils/mounts.h"
+#include "mtdutils/mtdutils.h"
+
+#include "otautil/sysutil.h"
+#include <ziparchive/zip_archive.h>
+#include "twinstall/install.h"
+#include "twinstall/verifier.h"
+#include "variables.h"
+#include "data.hpp"
+#include "partitions.hpp"
+#include "twrpDigestDriver.hpp"
+#include "twrpDigest/twrpDigest.hpp"
+#include "twrpDigest/twrpMD5.hpp"
+#include "twrp-functions.hpp"
+#include "gui/gui.hpp"
+#include "gui/pages.hpp"
+#include "legacy_property_service.h"
+#include "twinstall.h"
+#include "installcommand.h"
+extern "C" {
+	#include "gui/gui.h"
+}
+
+#define AB_OTA "payload_properties.txt"
+
+#ifndef TW_NO_LEGACY_PROPS
+static const char* properties_path = "/dev/__properties__";
+static const char* properties_path_renamed = "/dev/__properties_kk__";
+static bool legacy_props_env_initd = false;
+static bool legacy_props_path_modified = false;
+#endif
+
+enum zip_type {
+	UNKNOWN_ZIP_TYPE = 0,
+	UPDATE_BINARY_ZIP_TYPE,
+	AB_OTA_ZIP_TYPE,
+	TWRP_THEME_ZIP_TYPE
+};
+
+#ifndef TW_NO_LEGACY_PROPS
+// to support pre-KitKat update-binaries that expect properties in the legacy format
+static int switch_to_legacy_properties()
+{
+	if (!legacy_props_env_initd) {
+		if (legacy_properties_init() != 0)
+			return -1;
+
+		char tmp[32];
+		int propfd, propsz;
+		legacy_get_property_workspace(&propfd, &propsz);
+		sprintf(tmp, "%d,%d", dup(propfd), propsz);
+		setenv("ANDROID_PROPERTY_WORKSPACE", tmp, 1);
+		legacy_props_env_initd = true;
+	}
+
+	if (TWFunc::Path_Exists(properties_path)) {
+		// hide real properties so that the updater uses the envvar to find the legacy format properties
+		if (rename(properties_path, properties_path_renamed) != 0) {
+			LOGERR("Renaming %s failed: %s\n", properties_path, strerror(errno));
+			return -1;
+		} else {
+			legacy_props_path_modified = true;
+		}
+	}
+
+	return 0;
+}
+
+static int switch_to_new_properties()
+{
+	if (TWFunc::Path_Exists(properties_path_renamed)) {
+		if (rename(properties_path_renamed, properties_path) != 0) {
+			LOGERR("Renaming %s failed: %s\n", properties_path_renamed, strerror(errno));
+			return -1;
+		} else {
+			legacy_props_path_modified = false;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+static int Install_Theme(const char* path, ZipArchiveHandle Zip) {
+#ifdef TW_OEM_BUILD // We don't do custom themes in OEM builds
+	CloseArchive(Zip);
+	return INSTALL_CORRUPT;
+#else
+	ZipString binary_name("ui.xml");
+	ZipEntry binary_entry;
+	if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
+		CloseArchive(Zip);
+		return INSTALL_CORRUPT;
+	}
+	if (!PartitionManager.Mount_Settings_Storage(true))
+		return INSTALL_ERROR;
+	string theme_path = DataManager::GetSettingsStoragePath();
+	theme_path += "/TWRP/theme";
+	if (!TWFunc::Path_Exists(theme_path)) {
+		if (!TWFunc::Recursive_Mkdir(theme_path)) {
+			return INSTALL_ERROR;
+		}
+	}
+	theme_path += "/ui.zip";
+	if (TWFunc::copy_file(path, theme_path, 0644) != 0) {
+		return INSTALL_ERROR;
+	}
+	LOGINFO("Installing custom theme '%s' to '%s'\n", path, theme_path.c_str());
+	PageManager::RequestReload();
+	return INSTALL_SUCCESS;
+#endif
+}
+
+static int Prepare_Update_Binary(ZipArchiveHandle Zip) {
+	char arches[PATH_MAX];
+	property_get("ro.product.cpu.abilist", arches, "error");
+	if (strcmp(arches, "error") == 0)
+		property_get("ro.product.cpu.abi", arches, "error");
+	vector<string> split = TWFunc::split_string(arches, ',', true);
+	std::vector<string>::iterator arch;
+	std::string base_name = UPDATE_BINARY_NAME;
+	base_name += "-";
+	ZipEntry binary_entry;
+	ZipString update_binary_string(UPDATE_BINARY_NAME);
+	if (FindEntry(Zip, update_binary_string, &binary_entry) != 0) {
+		for (arch = split.begin(); arch != split.end(); arch++) {
+			std::string temp = base_name + *arch;
+			ZipString binary_name(temp.c_str());
+			if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
+				ZipString binary_name(temp.c_str());
+				break;
+			}
+		}
+	}
+	LOGINFO("Extracting updater binary '%s'\n", UPDATE_BINARY_NAME);
+	unlink(TMP_UPDATER_BINARY_PATH);
+	android::base::unique_fd fd(
+		open(TMP_UPDATER_BINARY_PATH, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755));
+	if (fd == -1) {
+		return INSTALL_ERROR;
+	}
+	int32_t err = ExtractEntryToFile(Zip, &binary_entry, fd);
+	if (err != 0) {
+		CloseArchive(Zip);
+		LOGERR("Could not extract '%s'\n", UPDATE_BINARY_NAME);
+		return INSTALL_ERROR;
+	}
+
+	// If exists, extract file_contexts from the zip file
+	ZipString file_contexts("file_contexts");
+	ZipEntry file_contexts_entry;
+	if (FindEntry(Zip, file_contexts, &file_contexts_entry) != 0) {
+		LOGINFO("Zip does not contain SELinux file_contexts file in its root.\n");
+	} else {
+		const string output_filename = "/file_contexts";
+		LOGINFO("Zip contains SELinux file_contexts file in its root. Extracting to %s\n", output_filename.c_str());
+		android::base::unique_fd fd(
+			open(output_filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644));
+		if (fd == -1) {
+			return INSTALL_ERROR;
+		}
+		if (ExtractEntryToFile(Zip, &file_contexts_entry, fd)) {
+			CloseArchive(Zip);
+			LOGERR("Could not extract '%s'\n", output_filename.c_str());
+			return INSTALL_ERROR;
+		}
+	}
+	return INSTALL_SUCCESS;
+}
+
+#ifndef TW_NO_LEGACY_PROPS
+static bool update_binary_has_legacy_properties(const char *binary) {
+	const char str_to_match[] = "ANDROID_PROPERTY_WORKSPACE";
+	int len_to_match = sizeof(str_to_match) - 1;
+	bool found = false;
+
+	int fd = open(binary, O_RDONLY);
+	if (fd < 0) {
+		LOGINFO("has_legacy_properties: Could not open %s: %s!\n", binary, strerror(errno));
+		return false;
+	}
+
+	struct stat finfo;
+	if (fstat(fd, &finfo) < 0) {
+		LOGINFO("has_legacy_properties: Could not fstat %d: %s!\n", fd, strerror(errno));
+		close(fd);
+		return false;
+	}
+
+	void *data = mmap(NULL, finfo.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (data == MAP_FAILED) {
+		LOGINFO("has_legacy_properties: mmap (size=%zu) failed: %s!\n", (size_t)finfo.st_size, strerror(errno));
+	} else {
+		if (memmem(data, finfo.st_size, str_to_match, len_to_match)) {
+			LOGINFO("has_legacy_properties: Found legacy property match!\n");
+			found = true;
+		}
+		munmap(data, finfo.st_size);
+	}
+	close(fd);
+
+	return found;
+}
+#endif
+
+static int Run_Update_Binary(const char *path, int* wipe_cache, zip_type ztype) {
+	int ret_val, pipe_fd[2], status, zip_verify;
+	char buffer[1024];
+	FILE* child_data;
+
+#ifndef TW_NO_LEGACY_PROPS
+	if (!update_binary_has_legacy_properties(TMP_UPDATER_BINARY_PATH)) {
+		LOGINFO("Legacy property environment not used in updater.\n");
+	} else if (switch_to_legacy_properties() != 0) { /* Set legacy properties */
+		LOGERR("Legacy property environment did not initialize successfully. Properties may not be detected.\n");
+	} else {
+		LOGINFO("Legacy property environment initialized.\n");
+	}
+#endif
+
+	pipe(pipe_fd);
+
+	std::vector<std::string> args;
+    if (ztype == UPDATE_BINARY_ZIP_TYPE) {
+		ret_val = update_binary_command(path, 0, pipe_fd[1], &args);
+    } else if (ztype == AB_OTA_ZIP_TYPE) {
+		ret_val = abupdate_binary_command(path, 0, pipe_fd[1], &args);
+	} else {
+		LOGERR("Unknown zip type %i\n", ztype);
+		ret_val = INSTALL_CORRUPT;
+	}
+    if (ret_val) {
+        close(pipe_fd[0]);
+        close(pipe_fd[1]);
+        return ret_val;
+    }
+
+	// Convert the vector to a NULL-terminated char* array suitable for execv.
+	const char* chr_args[args.size() + 1];
+	chr_args[args.size()] = NULL;
+	for (size_t i = 0; i < args.size(); i++)
+		chr_args[i] = args[i].c_str();
+
+	pid_t pid = fork();
+	if (pid == 0) {
+		close(pipe_fd[0]);
+		execve(chr_args[0], const_cast<char**>(chr_args), environ);
+		printf("E:Can't execute '%s': %s\n", chr_args[0], strerror(errno));
+		_exit(-1);
+	}
+	close(pipe_fd[1]);
+
+	*wipe_cache = 0;
+
+	DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
+	child_data = fdopen(pipe_fd[0], "r");
+	while (fgets(buffer, sizeof(buffer), child_data) != NULL) {
+		char* command = strtok(buffer, " \n");
+		if (command == NULL) {
+			continue;
+		} else if (strcmp(command, "progress") == 0) {
+			char* fraction_char = strtok(NULL, " \n");
+			char* seconds_char = strtok(NULL, " \n");
+
+			float fraction_float = strtof(fraction_char, NULL);
+			int seconds_float = strtol(seconds_char, NULL, 10);
+
+			if (zip_verify)
+				DataManager::ShowProgress(fraction_float * (1 - VERIFICATION_PROGRESS_FRACTION), seconds_float);
+			else
+				DataManager::ShowProgress(fraction_float, seconds_float);
+		} else if (strcmp(command, "set_progress") == 0) {
+			char* fraction_char = strtok(NULL, " \n");
+			float fraction_float = strtof(fraction_char, NULL);
+			DataManager::_SetProgress(fraction_float);
+		} else if (strcmp(command, "ui_print") == 0) {
+			char* display_value = strtok(NULL, "\n");
+			if (display_value) {
+				gui_print("%s", display_value);
+			} else {
+				gui_print("\n");
+			}
+		} else if (strcmp(command, "wipe_cache") == 0) {
+			*wipe_cache = 1;
+		} else if (strcmp(command, "clear_display") == 0) {
+			// Do nothing, not supported by TWRP
+		} else if (strcmp(command, "log") == 0) {
+			printf("%s\n", strtok(NULL, "\n"));
+		} else {
+			LOGERR("unknown command [%s]\n", command);
+		}
+	}
+	fclose(child_data);
+
+	int waitrc = TWFunc::Wait_For_Child(pid, &status, "Updater");
+
+#ifndef TW_NO_LEGACY_PROPS
+	/* Unset legacy properties */
+	if (legacy_props_path_modified) {
+		if (switch_to_new_properties() != 0) {
+			LOGERR("Legacy property environment did not disable successfully. Legacy properties may still be in use.\n");
+		} else {
+			LOGINFO("Legacy property environment disabled.\n");
+		}
+	}
+#endif
+
+	if (waitrc != 0)
+		return INSTALL_ERROR;
+
+	return INSTALL_SUCCESS;
+}
+
+int TWinstall_zip(const char* path, int* wipe_cache) {
+	int ret_val, zip_verify = 1, unmount_system = 1;
+
+	gui_msg(Msg("installing_zip=Installing zip file '{1}'")(path));
+	if (strlen(path) < 9 || strncmp(path, "/sideload", 9) != 0) {
+		string digest_str;
+		string Full_Filename = path;
+
+		gui_msg("check_for_digest=Checking for Digest file...");
+
+		if (*path != '@' && !twrpDigestDriver::Check_File_Digest(Full_Filename)) {
+			LOGERR("Aborting zip install: Digest verification failed\n");
+			return INSTALL_CORRUPT;
+		}
+	}
+
+	DataManager::GetValue(TW_UNMOUNT_SYSTEM, unmount_system);
+
+#ifndef TW_OEM_BUILD
+	DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
+#endif
+	DataManager::SetProgress(0);
+
+	auto package = Package::CreateMemoryPackage(path);
+	if (!package) {
+		return INSTALL_CORRUPT;
+	}
+
+	if (zip_verify) {
+		gui_msg("verify_zip_sig=Verifying zip signature...");
+		static constexpr const char* CERTIFICATE_ZIP_FILE = "/system/etc/security/otacerts.zip";
+		std::vector<Certificate> loaded_keys = LoadKeysFromZipfile(CERTIFICATE_ZIP_FILE);
+		if (loaded_keys.empty()) {
+			LOGERR("Failed to load keys\n");
+			return -1;
+		}
+		LOGINFO("%zu key(s) loaded from %s\n", loaded_keys.size(), CERTIFICATE_ZIP_FILE);
+
+		ret_val = verify_file(package.get(), loaded_keys, std::bind(&DataManager::SetProgress, std::placeholders::_1));
+		if (ret_val != VERIFY_SUCCESS) {
+			LOGINFO("Zip signature verification failed: %i\n", ret_val);
+			gui_err("verify_zip_fail=Zip signature verification failed!");
+#ifdef USE_MINZIP
+			sysReleaseMap(&map);
+#endif
+			return -1;
+		} else {
+			gui_msg("verify_zip_done=Zip signature verified successfully.");
+		}
+	}
+
+	ZipArchiveHandle Zip = package->GetZipArchiveHandle();
+	if (!Zip) {
+		return INSTALL_CORRUPT;
+	}
+
+	if (unmount_system) {
+		gui_msg("unmount_system=Unmounting System...");
+		if(!PartitionManager.UnMount_By_Path(PartitionManager.Get_Android_Root_Path(), true)) {
+			gui_err("unmount_system_err=Failed unmounting System");
+			return -1;
+		}
+		unlink("/system");
+		mkdir("/system", 0755);
+	}
+
+	time_t start, stop;
+	time(&start);
+
+	ZipString update_binary_name(UPDATE_BINARY_NAME);
+	ZipEntry update_binary_entry;
+	if (FindEntry(Zip, update_binary_name, &update_binary_entry) == 0) {
+		LOGINFO("Update binary zip\n");
+		// Additionally verify the compatibility of the package.
+		if (!verify_package_compatibility(Zip)) {
+			gui_err("zip_compatible_err=Zip Treble compatibility error!");
+			CloseArchive(Zip);
+			ret_val = INSTALL_CORRUPT;
+		} else {
+			ret_val = Prepare_Update_Binary(Zip);
+			if (ret_val == INSTALL_SUCCESS)
+				ret_val = Run_Update_Binary(path, wipe_cache, UPDATE_BINARY_ZIP_TYPE);
+		}
+	} else {
+		ZipString ab_binary_name(AB_OTA);
+		ZipEntry ab_binary_entry;
+		if (FindEntry(Zip, ab_binary_name, &ab_binary_entry) == 0) {
+			LOGINFO("AB zip\n");
+			gui_msg(Msg(msg::kHighlight, "flash_ab_inactive=Flashing A/B zip to inactive slot: {1}")(PartitionManager.Get_Active_Slot_Display()=="A"?"B":"A"));
+			// We need this so backuptool can do its magic
+			bool system_mount_state = PartitionManager.Is_Mounted_By_Path(PartitionManager.Get_Android_Root_Path());
+			bool vendor_mount_state = PartitionManager.Is_Mounted_By_Path("/vendor");
+			PartitionManager.Mount_By_Path(PartitionManager.Get_Android_Root_Path(), true);
+			PartitionManager.Mount_By_Path("/vendor", true);
+			TWFunc::copy_file("/system/bin/sh", "/tmp/sh", 0755);
+			mount("/tmp/sh", "/system/bin/sh", "auto", MS_BIND, NULL);
+			ret_val = Run_Update_Binary(path, wipe_cache, AB_OTA_ZIP_TYPE);
+			umount("/system/bin/sh");
+			unlink("/tmp/sh");
+			if (!vendor_mount_state)
+				PartitionManager.UnMount_By_Path("/vendor", true);
+			if (!system_mount_state)
+				PartitionManager.UnMount_By_Path(PartitionManager.Get_Android_Root_Path(), true);
+			gui_warn("flash_ab_reboot=To flash additional zips, please reboot recovery to switch to the updated slot.");
+		} else {
+			ZipString binary_name("ui.xml");
+			ZipEntry binary_entry;
+			if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
+				LOGINFO("TWRP theme zip\n");
+				ret_val = Install_Theme(path, Zip);
+			} else {
+				CloseArchive(Zip);
+				ret_val = INSTALL_CORRUPT;
+			}
+		}
+	}
+	time(&stop);
+	int total_time = (int) difftime(stop, start);
+	if (ret_val == INSTALL_CORRUPT) {
+		gui_err("invalid_zip_format=Invalid zip file format!");
+	} else {
+		LOGINFO("Install took %i second(s).\n", total_time);
+	}
+	return ret_val;
+}
diff --git a/twrpinstall/verifier.cpp b/twrpinstall/verifier.cpp
new file mode 100755
index 0000000..f577961
--- /dev/null
+++ b/twrpinstall/verifier.cpp
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2008 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 "twinstall/verifier.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include <openssl/obj_mac.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <ziparchive/zip_archive.h>
+
+#include "otautil/print_sha1.h"
+#include "private/asn1_decoder.h"
+
+/*
+ * Simple version of PKCS#7 SignedData extraction. This extracts the
+ * signature OCTET STRING to be used for signature verification.
+ *
+ * For full details, see http://www.ietf.org/rfc/rfc3852.txt
+ *
+ * The PKCS#7 structure looks like:
+ *
+ *   SEQUENCE (ContentInfo)
+ *     OID (ContentType)
+ *     [0] (content)
+ *       SEQUENCE (SignedData)
+ *         INTEGER (version CMSVersion)
+ *         SET (DigestAlgorithmIdentifiers)
+ *         SEQUENCE (EncapsulatedContentInfo)
+ *         [0] (CertificateSet OPTIONAL)
+ *         [1] (RevocationInfoChoices OPTIONAL)
+ *         SET (SignerInfos)
+ *           SEQUENCE (SignerInfo)
+ *             INTEGER (CMSVersion)
+ *             SEQUENCE (SignerIdentifier)
+ *             SEQUENCE (DigestAlgorithmIdentifier)
+ *             SEQUENCE (SignatureAlgorithmIdentifier)
+ *             OCTET STRING (SignatureValue)
+ */
+static bool read_pkcs7(const uint8_t* pkcs7_der, size_t pkcs7_der_len,
+                       std::vector<uint8_t>* sig_der) {
+  CHECK(sig_der != nullptr);
+  sig_der->clear();
+
+  asn1_context ctx(pkcs7_der, pkcs7_der_len);
+
+  std::unique_ptr<asn1_context> pkcs7_seq(ctx.asn1_sequence_get());
+  if (pkcs7_seq == nullptr || !pkcs7_seq->asn1_sequence_next()) {
+    return false;
+  }
+
+  std::unique_ptr<asn1_context> signed_data_app(pkcs7_seq->asn1_constructed_get());
+  if (signed_data_app == nullptr) {
+    return false;
+  }
+
+  std::unique_ptr<asn1_context> signed_data_seq(signed_data_app->asn1_sequence_get());
+  if (signed_data_seq == nullptr || !signed_data_seq->asn1_sequence_next() ||
+      !signed_data_seq->asn1_sequence_next() || !signed_data_seq->asn1_sequence_next() ||
+      !signed_data_seq->asn1_constructed_skip_all()) {
+    return false;
+  }
+
+  std::unique_ptr<asn1_context> sig_set(signed_data_seq->asn1_set_get());
+  if (sig_set == nullptr) {
+    return false;
+  }
+
+  std::unique_ptr<asn1_context> sig_seq(sig_set->asn1_sequence_get());
+  if (sig_seq == nullptr || !sig_seq->asn1_sequence_next() || !sig_seq->asn1_sequence_next() ||
+      !sig_seq->asn1_sequence_next() || !sig_seq->asn1_sequence_next()) {
+    return false;
+  }
+
+  const uint8_t* sig_der_ptr;
+  size_t sig_der_length;
+  if (!sig_seq->asn1_octet_string_get(&sig_der_ptr, &sig_der_length)) {
+    return false;
+  }
+
+  sig_der->resize(sig_der_length);
+  std::copy(sig_der_ptr, sig_der_ptr + sig_der_length, sig_der->begin());
+  return true;
+}
+
+int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys,
+  const std::function<void(float)>& set_progress) {
+  CHECK(package);
+  package->SetProgress(0.0);
+
+  if (set_progress) {
+    set_progress(0.0);
+  }
+
+  // An archive with a whole-file signature will end in six bytes:
+  //
+  //   (2-byte signature start) $ff $ff (2-byte comment size)
+  //
+  // (As far as the ZIP format is concerned, these are part of the archive comment.) We start by
+  // reading this footer, this tells us how far back from the end we have to start reading to find
+  // the whole comment.
+
+#define FOOTER_SIZE 6
+  uint64_t length = package->GetPackageSize();
+
+  if (length < FOOTER_SIZE) {
+    LOG(ERROR) << "not big enough to contain footer";
+    return VERIFY_FAILURE;
+  }
+
+  uint8_t footer[FOOTER_SIZE];
+  if (!package->ReadFullyAtOffset(footer, FOOTER_SIZE, length - FOOTER_SIZE)) {
+    LOG(ERROR) << "Failed to read footer";
+    return VERIFY_FAILURE;
+  }
+
+  if (footer[2] != 0xff || footer[3] != 0xff) {
+    LOG(ERROR) << "footer is wrong";
+    return VERIFY_FAILURE;
+  }
+
+  size_t comment_size = footer[4] + (footer[5] << 8);
+  size_t signature_start = footer[0] + (footer[1] << 8);
+  LOG(INFO) << "comment is " << comment_size << " bytes; signature is " << signature_start
+            << " bytes from end";
+
+  if (signature_start > comment_size) {
+    LOG(ERROR) << "signature start: " << signature_start
+               << " is larger than comment size: " << comment_size;
+    return VERIFY_FAILURE;
+  }
+
+  if (signature_start <= FOOTER_SIZE) {
+    LOG(ERROR) << "Signature start is in the footer";
+    return VERIFY_FAILURE;
+  }
+
+#define EOCD_HEADER_SIZE 22
+
+  // The end-of-central-directory record is 22 bytes plus any comment length.
+  size_t eocd_size = comment_size + EOCD_HEADER_SIZE;
+
+  if (length < eocd_size) {
+    LOG(ERROR) << "not big enough to contain EOCD";
+    return VERIFY_FAILURE;
+  }
+
+  // Determine how much of the file is covered by the signature. This is everything except the
+  // signature data and length, which includes all of the EOCD except for the comment length field
+  // (2 bytes) and the comment data.
+  uint64_t signed_len = length - eocd_size + EOCD_HEADER_SIZE - 2;
+
+  uint8_t eocd[eocd_size];
+  if (!package->ReadFullyAtOffset(eocd, eocd_size, length - eocd_size)) {
+    LOG(ERROR) << "Failed to read EOCD of " << eocd_size << " bytes";
+    return VERIFY_FAILURE;
+  }
+
+  // If this is really is the EOCD record, it will begin with the magic number $50 $4b $05 $06.
+  if (eocd[0] != 0x50 || eocd[1] != 0x4b || eocd[2] != 0x05 || eocd[3] != 0x06) {
+    LOG(ERROR) << "signature length doesn't match EOCD marker";
+    return VERIFY_FAILURE;
+  }
+
+  for (size_t i = 4; i < eocd_size - 3; ++i) {
+    if (eocd[i] == 0x50 && eocd[i + 1] == 0x4b && eocd[i + 2] == 0x05 && eocd[i + 3] == 0x06) {
+      // If the sequence $50 $4b $05 $06 appears anywhere after the real one, libziparchive will
+      // find the later (wrong) one, which could be exploitable. Fail the verification if this
+      // sequence occurs anywhere after the real one.
+      LOG(ERROR) << "EOCD marker occurs after start of EOCD";
+      return VERIFY_FAILURE;
+    }
+  }
+
+  bool need_sha1 = false;
+  bool need_sha256 = false;
+  for (const auto& key : keys) {
+    switch (key.hash_len) {
+      case SHA_DIGEST_LENGTH:
+        need_sha1 = true;
+        break;
+      case SHA256_DIGEST_LENGTH:
+        need_sha256 = true;
+        break;
+    }
+  }
+
+  SHA_CTX sha1_ctx;
+  SHA256_CTX sha256_ctx;
+  SHA1_Init(&sha1_ctx);
+  SHA256_Init(&sha256_ctx);
+
+  std::vector<HasherUpdateCallback> hashers;
+  if (need_sha1) {
+    hashers.emplace_back(
+        std::bind(&SHA1_Update, &sha1_ctx, std::placeholders::_1, std::placeholders::_2));
+  }
+  if (need_sha256) {
+    hashers.emplace_back(
+        std::bind(&SHA256_Update, &sha256_ctx, std::placeholders::_1, std::placeholders::_2));
+  }
+
+  double frac = -1.0;
+  uint64_t so_far = 0;
+  while (so_far < signed_len) {
+    // On a Nexus 5X, experiment showed 16MiB beat 1MiB by 6% faster for a 1196MiB full OTA and
+    // 60% for an 89MiB incremental OTA. http://b/28135231.
+    uint64_t read_size = std::min<uint64_t>(signed_len - so_far, 16 * MiB);
+    package->UpdateHashAtOffset(hashers, so_far, read_size);
+    so_far += read_size;
+
+    double f = so_far / static_cast<double>(signed_len);
+    if (f > frac + 0.02 || read_size == so_far) {
+      package->SetProgress(f);
+      frac = f;
+      if (set_progress) {
+        set_progress(f);
+      }
+    }
+  }
+
+  uint8_t sha1[SHA_DIGEST_LENGTH];
+  SHA1_Final(sha1, &sha1_ctx);
+  uint8_t sha256[SHA256_DIGEST_LENGTH];
+  SHA256_Final(sha256, &sha256_ctx);
+
+  const uint8_t* signature = eocd + eocd_size - signature_start;
+  size_t signature_size = signature_start - FOOTER_SIZE;
+
+  LOG(INFO) << "signature (offset: " << std::hex << (length - signature_start)
+            << ", length: " << signature_size << "): " << print_hex(signature, signature_size);
+
+  std::vector<uint8_t> sig_der;
+  if (!read_pkcs7(signature, signature_size, &sig_der)) {
+    LOG(ERROR) << "Could not find signature DER block";
+    return VERIFY_FAILURE;
+  }
+
+  // Check to make sure at least one of the keys matches the signature. Since any key can match,
+  // we need to try each before determining a verification failure has happened.
+  size_t i = 0;
+  for (const auto& key : keys) {
+    const uint8_t* hash;
+    int hash_nid;
+    switch (key.hash_len) {
+      case SHA_DIGEST_LENGTH:
+        hash = sha1;
+        hash_nid = NID_sha1;
+        break;
+      case SHA256_DIGEST_LENGTH:
+        hash = sha256;
+        hash_nid = NID_sha256;
+        break;
+      default:
+        continue;
+    }
+
+    // The 6 bytes is the "(signature_start) $ff $ff (comment_size)" that the signing tool appends
+    // after the signature itself.
+    if (key.key_type == Certificate::KEY_TYPE_RSA) {
+      if (!RSA_verify(hash_nid, hash, key.hash_len, sig_der.data(), sig_der.size(),
+                      key.rsa.get())) {
+        LOG(INFO) << "failed to verify against RSA key " << i;
+        continue;
+      }
+
+      LOG(INFO) << "whole-file signature verified against RSA key " << i;
+      return VERIFY_SUCCESS;
+    } else if (key.key_type == Certificate::KEY_TYPE_EC && key.hash_len == SHA256_DIGEST_LENGTH) {
+      if (!ECDSA_verify(0, hash, key.hash_len, sig_der.data(), sig_der.size(), key.ec.get())) {
+        LOG(INFO) << "failed to verify against EC key " << i;
+        continue;
+      }
+
+      LOG(INFO) << "whole-file signature verified against EC key " << i;
+      return VERIFY_SUCCESS;
+    } else {
+      LOG(INFO) << "Unknown key type " << key.key_type;
+    }
+    i++;
+  }
+
+  if (need_sha1) {
+    LOG(INFO) << "SHA-1 digest: " << print_hex(sha1, SHA_DIGEST_LENGTH);
+  }
+  if (need_sha256) {
+    LOG(INFO) << "SHA-256 digest: " << print_hex(sha256, SHA256_DIGEST_LENGTH);
+  }
+  LOG(ERROR) << "failed to verify whole-file signature";
+  return VERIFY_FAILURE;
+}
+
+std::unique_ptr<RSA, RSADeleter> parse_rsa_key(FILE* file, uint32_t exponent) {
+    // Read key length in words and n0inv. n0inv is a precomputed montgomery
+    // parameter derived from the modulus and can be used to speed up
+    // verification. n0inv is 32 bits wide here, assuming the verification logic
+    // uses 32 bit arithmetic. However, BoringSSL may use a word size of 64 bits
+    // internally, in which case we don't have a valid n0inv. Thus, we just
+    // ignore the montgomery parameters and have BoringSSL recompute them
+    // internally. If/When the speedup from using the montgomery parameters
+    // becomes relevant, we can add more sophisticated code here to obtain a
+    // 64-bit n0inv and initialize the montgomery parameters in the key object.
+    uint32_t key_len_words = 0;
+    uint32_t n0inv = 0;
+    if (fscanf(file, " %i , 0x%x", &key_len_words, &n0inv) != 2) {
+        return nullptr;
+    }
+
+    if (key_len_words > 8192 / 32) {
+        LOG(ERROR) << "key length (" << key_len_words << ") too large";
+        return nullptr;
+    }
+
+    // Read the modulus.
+    std::unique_ptr<uint32_t[]> modulus(new uint32_t[key_len_words]);
+    if (fscanf(file, " , { %u", &modulus[0]) != 1) {
+        return nullptr;
+    }
+    for (uint32_t i = 1; i < key_len_words; ++i) {
+        if (fscanf(file, " , %u", &modulus[i]) != 1) {
+            return nullptr;
+        }
+    }
+
+    // Cconvert from little-endian array of little-endian words to big-endian
+    // byte array suitable as input for BN_bin2bn.
+    std::reverse((uint8_t*)modulus.get(),
+                 (uint8_t*)(modulus.get() + key_len_words));
+
+    // The next sequence of values is the montgomery parameter R^2. Since we
+    // generally don't have a valid |n0inv|, we ignore this (see comment above).
+    uint32_t rr_value;
+    if (fscanf(file, " } , { %u", &rr_value) != 1) {
+        return nullptr;
+    }
+    for (uint32_t i = 1; i < key_len_words; ++i) {
+        if (fscanf(file, " , %u", &rr_value) != 1) {
+            return nullptr;
+        }
+    }
+    if (fscanf(file, " } } ") != 0) {
+        return nullptr;
+    }
+
+    // Initialize the key.
+    std::unique_ptr<RSA, RSADeleter> key(RSA_new());
+    if (!key) {
+      return nullptr;
+    }
+
+    key->n = BN_bin2bn((uint8_t*)modulus.get(),
+                       key_len_words * sizeof(uint32_t), NULL);
+    if (!key->n) {
+      return nullptr;
+    }
+
+    key->e = BN_new();
+    if (!key->e || !BN_set_word(key->e, exponent)) {
+      return nullptr;
+    }
+
+    return key;
+}
+
+
+static std::vector<Certificate> IterateZipEntriesAndSearchForKeys(const ZipArchiveHandle& handle) {
+  void* cookie;
+  ZipString suffix("x509.pem");
+  int32_t iter_status = StartIteration(handle, &cookie, nullptr, &suffix);
+  if (iter_status != 0) {
+    LOG(ERROR) << "Failed to iterate over entries in the certificate zipfile: "
+               << ErrorCodeString(iter_status);
+    return {};
+  }
+
+  std::vector<Certificate> result;
+
+  ZipString name;
+  ZipEntry entry;
+  while ((iter_status = Next(cookie, &entry, &name)) == 0) {
+    std::vector<uint8_t> pem_content(entry.uncompressed_length);
+    if (int32_t extract_status =
+            ExtractToMemory(handle, &entry, pem_content.data(), pem_content.size());
+        extract_status != 0) {
+      LOG(ERROR) << "Failed to extract " << std::string(name.name, name.name + name.name_length);
+      return {};
+    }
+
+    Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
+    // Aborts the parsing if we fail to load one of the key file.
+    if (!LoadCertificateFromBuffer(pem_content, &cert)) {
+      LOG(ERROR) << "Failed to load keys from "
+                 << std::string(name.name, name.name + name.name_length);
+      return {};
+    }
+
+    result.emplace_back(std::move(cert));
+  }
+
+  if (iter_status != -1) {
+    LOG(ERROR) << "Error while iterating over zip entries: " << ErrorCodeString(iter_status);
+    return {};
+  }
+
+  return result;
+}
+
+std::vector<Certificate> LoadKeysFromZipfile(const std::string& zip_name) {
+  ZipArchiveHandle handle;
+  if (int32_t open_status = OpenArchive(zip_name.c_str(), &handle); open_status != 0) {
+    LOG(ERROR) << "Failed to open " << zip_name << ": " << ErrorCodeString(open_status);
+    return {};
+  }
+
+  std::vector<Certificate> result = IterateZipEntriesAndSearchForKeys(handle);
+  CloseArchive(handle);
+  return result;
+}
+
+bool CheckRSAKey(const std::unique_ptr<RSA, RSADeleter>& rsa) {
+  if (!rsa) {
+    return false;
+  }
+
+  const BIGNUM* out_n;
+  const BIGNUM* out_e;
+  RSA_get0_key(rsa.get(), &out_n, &out_e, nullptr /* private exponent */);
+  auto modulus_bits = BN_num_bits(out_n);
+  if (modulus_bits != 2048 && modulus_bits != 4096) {
+    LOG(ERROR) << "Modulus should be 2048 or 4096 bits long, actual: " << modulus_bits;
+    return false;
+  }
+
+  BN_ULONG exponent = BN_get_word(out_e);
+  if (exponent != 3 && exponent != 65537) {
+    LOG(ERROR) << "Public exponent should be 3 or 65537, actual: " << exponent;
+    return false;
+  }
+
+  return true;
+}
+
+bool CheckECKey(const std::unique_ptr<EC_KEY, ECKEYDeleter>& ec_key) {
+  if (!ec_key) {
+    return false;
+  }
+
+  const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key.get());
+  if (!ec_group) {
+    LOG(ERROR) << "Failed to get the ec_group from the ec_key";
+    return false;
+  }
+  auto degree = EC_GROUP_get_degree(ec_group);
+  if (degree != 256) {
+    LOG(ERROR) << "Field size of the ec key should be 256 bits long, actual: " << degree;
+    return false;
+  }
+
+  return true;
+}
+
+bool LoadCertificateFromBuffer(const std::vector<uint8_t>& pem_content, Certificate* cert) {
+  std::unique_ptr<BIO, decltype(&BIO_free)> content(
+      BIO_new_mem_buf(pem_content.data(), pem_content.size()), BIO_free);
+
+  std::unique_ptr<X509, decltype(&X509_free)> x509(
+      PEM_read_bio_X509(content.get(), nullptr, nullptr, nullptr), X509_free);
+  if (!x509) {
+    LOG(ERROR) << "Failed to read x509 certificate";
+    return false;
+  }
+
+  int nid = X509_get_signature_nid(x509.get());
+  switch (nid) {
+    // SignApk has historically accepted md5WithRSA certificates, but treated them as
+    // sha1WithRSA anyway. Continue to do so for backwards compatibility.
+    case NID_md5WithRSA:
+    case NID_md5WithRSAEncryption:
+    case NID_sha1WithRSA:
+    case NID_sha1WithRSAEncryption:
+      cert->hash_len = SHA_DIGEST_LENGTH;
+      break;
+    case NID_sha256WithRSAEncryption:
+    case NID_ecdsa_with_SHA256:
+      cert->hash_len = SHA256_DIGEST_LENGTH;
+      break;
+    default:
+      LOG(ERROR) << "Unrecognized signature nid " << OBJ_nid2ln(nid);
+      return false;
+  }
+
+  std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> public_key(X509_get_pubkey(x509.get()),
+                                                                 EVP_PKEY_free);
+  if (!public_key) {
+    LOG(ERROR) << "Failed to extract the public key from x509 certificate";
+    return false;
+  }
+
+  int key_type = EVP_PKEY_id(public_key.get());
+  if (key_type == EVP_PKEY_RSA) {
+    cert->key_type = Certificate::KEY_TYPE_RSA;
+    cert->ec.reset();
+    cert->rsa.reset(EVP_PKEY_get1_RSA(public_key.get()));
+    if (!cert->rsa || !CheckRSAKey(cert->rsa)) {
+      LOG(ERROR) << "Failed to validate the rsa key info from public key";
+      return false;
+    }
+  } else if (key_type == EVP_PKEY_EC) {
+    cert->key_type = Certificate::KEY_TYPE_EC;
+    cert->rsa.reset();
+    cert->ec.reset(EVP_PKEY_get1_EC_KEY(public_key.get()));
+    if (!cert->ec || !CheckECKey(cert->ec)) {
+      LOG(ERROR) << "Failed to validate the ec key info from the public key";
+      return false;
+    }
+  } else {
+    LOG(ERROR) << "Unrecognized public key type " << OBJ_nid2ln(key_type);
+    return false;
+  }
+
+  return true;
+}
