Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac9c13cf authored by Nikita Ioffe's avatar Nikita Ioffe Committed by Automerger Merge Worker
Browse files

Merge "Revert "Move otadexopt-related logic to otapreopt_chroot binary"" am: fb2bda2d

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1757570

Change-Id: Ic122825d6294788edcddcbeff980d8d518c73c0c
parents b6c915a6 fb2bda2d
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -191,10 +191,6 @@ cc_binary {
        "libbase",
        "liblog",
        "libutils",
        "libbinder",
    ],
    static_libs: [
      "ota_dexopt_aidl_interface-cpp",
    ],
    required: [
      "apexd"
+30 −93
Original line number Diff line number Diff line
@@ -21,21 +21,15 @@
#include <sys/wait.h>

#include <array>
#include <chrono>
#include <fstream>
#include <sstream>
#include <thread>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <android/content/pm/IOtaDexopt.h>
#include <binder/IServiceManager.h>
#include <libdm/dm.h>
#include <selinux/android.h>

@@ -51,8 +45,6 @@ using android::base::StringPrintf;
namespace android {
namespace installd {

using namespace std::literals::chrono_literals;

static void CloseDescriptor(int fd) {
    if (fd >= 0) {
        int result = close(fd);
@@ -61,6 +53,15 @@ static void CloseDescriptor(int fd) {
    }
}

static void CloseDescriptor(const char* descriptor_string) {
    int fd = -1;
    std::istringstream stream(descriptor_string);
    stream >> fd;
    if (!stream.fail()) {
        CloseDescriptor(fd);
    }
}

static void ActivateApexPackages() {
    std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--otachroot-bootstrap"};
    std::string apexd_error_msg;
@@ -112,38 +113,6 @@ static void TryExtraMount(const char* name, const char* slot, const char* target
    UNUSED(mount_result);
}

static android::sp<android::content::pm::IOtaDexopt> GetDexoptService() {
    auto binder = android::defaultServiceManager()->getService(android::String16("otadexopt"));
    if (binder == nullptr) {
        return nullptr;
    }
    return android::interface_cast<android::content::pm::IOtaDexopt>(binder);
}

static bool RunDexoptCommand(int argc, char **arg, const std::string& dexopt_cmd) {
    // Incoming:  cmd + status-fd + target-slot + cmd...      | Incoming | = argc
    // Outgoing:  cmd             + target-slot + cmd...      | Outgoing | = argc - 1
    std::vector<std::string> cmd;
    cmd.reserve(argc);
    cmd.push_back("/system/bin/otapreopt");

    // The first parameter is the status file descriptor, skip.
    for (size_t i = 2; i < static_cast<size_t>(argc); ++i) {
        cmd.push_back(arg[i]);
    }
    for (const std::string& part : android::base::Split(dexopt_cmd, " ")) {
        cmd.push_back(part);
    }

    // Fork and execute otapreopt in its own process.
    std::string error_msg;
    bool exec_result = Exec(cmd, &error_msg);
    if (!exec_result) {
        LOG(ERROR) << "Running otapreopt failed: " << error_msg;
    }
    return exec_result;
}

// Entry for otapreopt_chroot. Expected parameters are:
//   [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params]
// The file descriptor denoted by status-fd will be closed. The rest of the parameters will
@@ -161,18 +130,8 @@ static int otapreopt_chroot(const int argc, char **arg) {
    CloseDescriptor(STDIN_FILENO);
    CloseDescriptor(STDOUT_FILENO);
    CloseDescriptor(STDERR_FILENO);

    int fd;
    if (!android::base::ParseInt(arg[1], &fd)) {
        LOG(ERROR) << "Failed to parse " << arg[1];
        exit(225);
    }
    // Add O_CLOEXEC to status channel, since we don't want to pass it across fork/exec, but we need
    // to keep it open in otapreopt_chroot to report progress
    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
        PLOG(ERROR) << "Failed to set O_CLOEXEC on " << fd;
        exit(226);
    }
    // 2) The status channel.
    CloseDescriptor(arg[1]);

    // We need to run the otapreopt tool from the postinstall partition. As such, set up a
    // mount namespace and change root.
@@ -354,50 +313,28 @@ static int otapreopt_chroot(const int argc, char **arg) {
        exit(218);
    }

    android::sp<android::content::pm::IOtaDexopt> dexopt = GetDexoptService();
    if (dexopt == nullptr) {
        LOG(ERROR) << "Failed to find otadexopt service";
        exit(222);
    }

    android::base::borrowed_fd status_fd(fd);
    // Now go on and run otapreopt.
    constexpr const int kMaximumPackages = 1000;
    for (int iter = 0; iter < kMaximumPackages; iter++) {
        android::String16 cmd;
        android::binder::Status status = dexopt->nextDexoptCommand(&cmd);
        if (!status.isOk()) {
            LOG(ERROR) << "Failed to retrieve next dexopt command";
            // Should we fail instead?
            exit(224);
        }
        if (!RunDexoptCommand(argc, arg, android::String8(cmd).string())) {
            exit(213);
        }

        float progress;
        status = dexopt->getProgress(&progress);
        if (!status.isOk()) {
            LOG(ERROR) << "Failed to retrieve dexopt progress";
            continue;
        }
        LOG(VERBOSE) << "Progress: " << progress;
        std::string progress_str = StringPrintf("global_progress %.2f\n", progress);
        if (!android::base::WriteStringToFd(progress_str, status_fd)) {
            PLOG(ERROR) << "Failed to write '" << progress_str << "' to " << status_fd.get();
        }
    // Incoming:  cmd + status-fd + target-slot + cmd...      | Incoming | = argc
    // Outgoing:  cmd             + target-slot + cmd...      | Outgoing | = argc - 1
    std::vector<std::string> cmd;
    cmd.reserve(argc);
    cmd.push_back("/system/bin/otapreopt");

        bool done;
        status = dexopt->isDone(&done);
        if (!status.isOk()) {
            LOG(WARNING) << "Failed to check if dexopt is done";
            continue;
    // The first parameter is the status file descriptor, skip.
    for (size_t i = 2; i < static_cast<size_t>(argc); ++i) {
        cmd.push_back(arg[i]);
    }
        if (done) {
            LOG(INFO) << "dexopt is done";
            break;

    // Fork and execute otapreopt in its own process.
    std::string error_msg;
    bool exec_result = Exec(cmd, &error_msg);
    if (!exec_result) {
        LOG(ERROR) << "Running otapreopt failed: " << error_msg;
    }
        std::this_thread::sleep_for(1s);

    if (!exec_result) {
        exit(213);
    }

    return 0;
+17 −1
Original line number Diff line number Diff line
@@ -58,8 +58,24 @@ PREPARE=$(cmd otadexopt prepare)
PROGRESS=$(cmd otadexopt progress)
print -u${STATUS_FD} "global_progress $PROGRESS"

i=0
while ((i<MAXIMUM_PACKAGES)) ; do
  DEXOPT_PARAMS=$(cmd otadexopt next)

  /system/bin/otapreopt_chroot $STATUS_FD $TARGET_SLOT_SUFFIX $DEXOPT_PARAMS >&- 2>&-

  PROGRESS=$(cmd otadexopt progress)
  print -u${STATUS_FD} "global_progress $PROGRESS"

  DONE=$(cmd otadexopt done)
  if [ "$DONE" = "OTA incomplete." ] ; then
    sleep 1
    i=$((i+1))
    continue
  fi
  break
done

DONE=$(cmd otadexopt done)
if [ "$DONE" = "OTA incomplete." ] ; then
  echo "Incomplete."