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

Commit 8fc8f39b authored by Tianjie Xu's avatar Tianjie Xu Committed by Gerrit Code Review
Browse files

Merge "Support wipe command in rescue mode"

parents 42168c4a fedeef6f
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@

#include "fuse_sideload.h"
#include "install/install.h"
#include "install/wipe_data.h"
#include "minadbd_types.h"
#include "otautil/sysutil.h"
#include "recovery_ui/device.h"
@@ -330,7 +331,7 @@ static void CreateMinadbdServiceAndExecuteCommands(
  signal(SIGPIPE, SIG_DFL);
}

int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode, Device::BuiltinAction* reboot_action) {
int ApplyFromAdb(Device* device, bool rescue_mode, 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.
@@ -339,13 +340,7 @@ int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode, Device::BuiltinAction* reboot
    return INSTALL_ERROR;
  }

  if (!rescue_mode) {
    ui->Print(
        "\n\nNow send the package you want to apply\n"
        "to the device with \"adb sideload <filename>\"...\n");
  } else {
    ui->Print("\n\nWaiting for rescue commands...\n");
  }
  RecoveryUI* ui = device->GetUI();

  int install_result = INSTALL_ERROR;
  std::map<MinadbdCommand, CommandFunction> command_map{
@@ -363,6 +358,18 @@ int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode, Device::BuiltinAction* reboot
      std::bind(&AdbRebootHandler, MinadbdCommand::kRebootRescue, &install_result, reboot_action) },
  };

  if (!rescue_mode) {
    ui->Print(
        "\n\nNow send the package you want to apply\n"
        "to the device with \"adb sideload <filename>\"...\n");
  } else {
    ui->Print("\n\nWaiting for rescue commands...\n");
    command_map.emplace(MinadbdCommand::kWipeData, [&device]() {
      bool result = WipeData(device, false);
      return std::make_pair(result, true);
    });
  }

  CreateMinadbdServiceAndExecuteCommands(ui, command_map, rescue_mode);

  // Clean up before switching to the older state, for example setting the state
+1 −2
Original line number Diff line number Diff line
@@ -17,9 +17,8 @@
#pragma once

#include <recovery_ui/device.h>
#include <recovery_ui/ui.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 ApplyFromAdb(RecoveryUI* ui, bool rescue_mode, Device::BuiltinAction* reboot_action);
int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot_action);
+40 −6
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static MinadbdErrorCode RunAdbFuseSideload(int sfd, const std::string& args,
  if (pieces.size() != 2 || !android::base::ParseInt(pieces[0], &file_size) || file_size <= 0 ||
      !android::base::ParseInt(pieces[1], &block_size) || block_size <= 0) {
    LOG(ERROR) << "bad sideload-host arguments: " << args;
    return kMinadbdPackageSizeError;
    return kMinadbdHostCommandArgumentError;
  }

  LOG(INFO) << "sideload-host file size " << file_size << ", block size " << block_size;
@@ -124,17 +124,17 @@ static MinadbdErrorCode RunAdbFuseSideload(int sfd, const std::string& args,
    return kMinadbdMessageFormatError;
  }

  // Signal host-side adb to stop. For sideload mode, we always send kSideloadServiceExitSuccess
  // Signal host-side adb to stop. For sideload mode, we always send kMinadbdServicesExitSuccess
  // (i.e. "DONEDONE") regardless of the install result. For rescue mode, we send failure message on
  // install error.
  if (!rescue_mode || *status == MinadbdCommandStatus::kSuccess) {
    if (!android::base::WriteFully(sfd, kSideloadServiceExitSuccess,
                                   strlen(kSideloadServiceExitSuccess))) {
    if (!android::base::WriteFully(sfd, kMinadbdServicesExitSuccess,
                                   strlen(kMinadbdServicesExitSuccess))) {
      return kMinadbdHostSocketIOError;
    }
  } else {
    if (!android::base::WriteFully(sfd, kSideloadServiceExitFailure,
                                   strlen(kSideloadServiceExitFailure))) {
    if (!android::base::WriteFully(sfd, kMinadbdServicesExitFailure,
                                   strlen(kMinadbdServicesExitFailure))) {
      return kMinadbdHostSocketIOError;
    }
  }
@@ -200,6 +200,34 @@ static void RebootHostService(unique_fd /* sfd */, const std::string& target) {
  }
}

static void WipeDeviceService(unique_fd fd, const std::string& args) {
  auto pieces = android::base::Split(args, ":");
  if (pieces.size() != 2 || pieces[0] != "userdata") {
    LOG(ERROR) << "Failed to parse wipe device command arguments " << args;
    exit(kMinadbdHostCommandArgumentError);
  }

  size_t message_size;
  if (!android::base::ParseUint(pieces[1], &message_size) ||
      message_size < strlen(kMinadbdServicesExitSuccess)) {
    LOG(ERROR) << "Failed to parse wipe device message size in " << args;
    exit(kMinadbdHostCommandArgumentError);
  }

  WriteCommandToFd(MinadbdCommand::kWipeData, minadbd_socket);
  MinadbdCommandStatus status;
  if (!WaitForCommandStatus(minadbd_socket, &status)) {
    exit(kMinadbdMessageFormatError);
  }

  std::string response = (status == MinadbdCommandStatus::kSuccess) ? kMinadbdServicesExitSuccess
                                                                    : kMinadbdServicesExitFailure;
  response += std::string(message_size - response.size(), '\0');
  if (!android::base::WriteFully(fd, response.c_str(), response.size())) {
    exit(kMinadbdHostSocketIOError);
  }
}

unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport */) {
  // Common services that are supported both in sideload and rescue modes.
  if (ConsumePrefix(&name, "reboot:")) {
@@ -225,7 +253,13 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport *
      std::string args(name);
      return create_service_thread(
          "rescue-getprop", std::bind(RescueGetpropHostService, std::placeholders::_1, args));
    } else if (ConsumePrefix(&name, "rescue-wipe:")) {
      // rescue-wipe:target:<message-size>
      std::string args(name);
      return create_service_thread("rescue-wipe",
                                   std::bind(WipeDeviceService, std::placeholders::_1, args));
    }

    return unique_fd{};
  }

+1 −1
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ class MinadbdServicesTest : public ::testing::Test {

TEST_F(MinadbdServicesTest, SideloadHostService_wrong_size_argument) {
  ASSERT_EXIT(ExecuteCommandAndWaitForExit("sideload-host:abc:4096"),
              ::testing::ExitedWithCode(kMinadbdPackageSizeError), "");
              ::testing::ExitedWithCode(kMinadbdHostCommandArgumentError), "");
}

TEST_F(MinadbdServicesTest, SideloadHostService_wrong_block_size) {
+3 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ enum MinadbdErrorCode : int {
  kMinadbdSocketIOError = 2,
  kMinadbdMessageFormatError = 3,
  kMinadbdAdbVersionError = 4,
  kMinadbdPackageSizeError = 5,
  kMinadbdHostCommandArgumentError = 5,
  kMinadbdFuseStartError = 6,
  kMinadbdUnsupportedCommandError = 7,
  kMinadbdCommandExecutionError = 8,
@@ -51,6 +51,8 @@ enum class MinadbdCommand : uint32_t {
  kRebootFastboot = 4,
  kRebootRecovery = 5,
  kRebootRescue = 6,
  kWipeCache = 7,
  kWipeData = 8,

  // Last but invalid command.
  kError,
Loading