Merge "Support wipe command in rescue mode"
This commit is contained in:
+15
-8
@@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
#include "fuse_sideload.h"
|
#include "fuse_sideload.h"
|
||||||
#include "install/install.h"
|
#include "install/install.h"
|
||||||
|
#include "install/wipe_data.h"
|
||||||
#include "minadbd_types.h"
|
#include "minadbd_types.h"
|
||||||
#include "otautil/sysutil.h"
|
#include "otautil/sysutil.h"
|
||||||
#include "recovery_ui/device.h"
|
#include "recovery_ui/device.h"
|
||||||
@@ -330,7 +331,7 @@ static void CreateMinadbdServiceAndExecuteCommands(
|
|||||||
signal(SIGPIPE, SIG_DFL);
|
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.
|
// Save the usb state to restore after the sideload operation.
|
||||||
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
|
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
|
||||||
// Clean up state and stop adbd.
|
// Clean up state and stop adbd.
|
||||||
@@ -339,13 +340,7 @@ int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode, Device::BuiltinAction* reboot
|
|||||||
return INSTALL_ERROR;
|
return INSTALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rescue_mode) {
|
RecoveryUI* ui = device->GetUI();
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
int install_result = INSTALL_ERROR;
|
int install_result = INSTALL_ERROR;
|
||||||
std::map<MinadbdCommand, CommandFunction> command_map{
|
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) },
|
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);
|
CreateMinadbdServiceAndExecuteCommands(ui, command_map, rescue_mode);
|
||||||
|
|
||||||
// Clean up before switching to the older state, for example setting the state
|
// Clean up before switching to the older state, for example setting the state
|
||||||
|
|||||||
@@ -17,9 +17,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <recovery_ui/device.h>
|
#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
|
// 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
|
// InstallResult`). When a reboot has been requested, INSTALL_REBOOT will be the return value, with
|
||||||
// the reboot target set in reboot_action.
|
// 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);
|
||||||
|
|||||||
@@ -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 ||
|
if (pieces.size() != 2 || !android::base::ParseInt(pieces[0], &file_size) || file_size <= 0 ||
|
||||||
!android::base::ParseInt(pieces[1], &block_size) || block_size <= 0) {
|
!android::base::ParseInt(pieces[1], &block_size) || block_size <= 0) {
|
||||||
LOG(ERROR) << "bad sideload-host arguments: " << args;
|
LOG(ERROR) << "bad sideload-host arguments: " << args;
|
||||||
return kMinadbdPackageSizeError;
|
return kMinadbdHostCommandArgumentError;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "sideload-host file size " << file_size << ", block size " << block_size;
|
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;
|
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
|
// (i.e. "DONEDONE") regardless of the install result. For rescue mode, we send failure message on
|
||||||
// install error.
|
// install error.
|
||||||
if (!rescue_mode || *status == MinadbdCommandStatus::kSuccess) {
|
if (!rescue_mode || *status == MinadbdCommandStatus::kSuccess) {
|
||||||
if (!android::base::WriteFully(sfd, kSideloadServiceExitSuccess,
|
if (!android::base::WriteFully(sfd, kMinadbdServicesExitSuccess,
|
||||||
strlen(kSideloadServiceExitSuccess))) {
|
strlen(kMinadbdServicesExitSuccess))) {
|
||||||
return kMinadbdHostSocketIOError;
|
return kMinadbdHostSocketIOError;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!android::base::WriteFully(sfd, kSideloadServiceExitFailure,
|
if (!android::base::WriteFully(sfd, kMinadbdServicesExitFailure,
|
||||||
strlen(kSideloadServiceExitFailure))) {
|
strlen(kMinadbdServicesExitFailure))) {
|
||||||
return kMinadbdHostSocketIOError;
|
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 */) {
|
unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport */) {
|
||||||
// Common services that are supported both in sideload and rescue modes.
|
// Common services that are supported both in sideload and rescue modes.
|
||||||
if (ConsumePrefix(&name, "reboot:")) {
|
if (ConsumePrefix(&name, "reboot:")) {
|
||||||
@@ -225,7 +253,13 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport *
|
|||||||
std::string args(name);
|
std::string args(name);
|
||||||
return create_service_thread(
|
return create_service_thread(
|
||||||
"rescue-getprop", std::bind(RescueGetpropHostService, std::placeholders::_1, args));
|
"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{};
|
return unique_fd{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class MinadbdServicesTest : public ::testing::Test {
|
|||||||
|
|
||||||
TEST_F(MinadbdServicesTest, SideloadHostService_wrong_size_argument) {
|
TEST_F(MinadbdServicesTest, SideloadHostService_wrong_size_argument) {
|
||||||
ASSERT_EXIT(ExecuteCommandAndWaitForExit("sideload-host:abc:4096"),
|
ASSERT_EXIT(ExecuteCommandAndWaitForExit("sideload-host:abc:4096"),
|
||||||
::testing::ExitedWithCode(kMinadbdPackageSizeError), "");
|
::testing::ExitedWithCode(kMinadbdHostCommandArgumentError), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MinadbdServicesTest, SideloadHostService_wrong_block_size) {
|
TEST_F(MinadbdServicesTest, SideloadHostService_wrong_block_size) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ enum MinadbdErrorCode : int {
|
|||||||
kMinadbdSocketIOError = 2,
|
kMinadbdSocketIOError = 2,
|
||||||
kMinadbdMessageFormatError = 3,
|
kMinadbdMessageFormatError = 3,
|
||||||
kMinadbdAdbVersionError = 4,
|
kMinadbdAdbVersionError = 4,
|
||||||
kMinadbdPackageSizeError = 5,
|
kMinadbdHostCommandArgumentError = 5,
|
||||||
kMinadbdFuseStartError = 6,
|
kMinadbdFuseStartError = 6,
|
||||||
kMinadbdUnsupportedCommandError = 7,
|
kMinadbdUnsupportedCommandError = 7,
|
||||||
kMinadbdCommandExecutionError = 8,
|
kMinadbdCommandExecutionError = 8,
|
||||||
@@ -51,6 +51,8 @@ enum class MinadbdCommand : uint32_t {
|
|||||||
kRebootFastboot = 4,
|
kRebootFastboot = 4,
|
||||||
kRebootRecovery = 5,
|
kRebootRecovery = 5,
|
||||||
kRebootRescue = 6,
|
kRebootRescue = 6,
|
||||||
|
kWipeCache = 7,
|
||||||
|
kWipeData = 8,
|
||||||
|
|
||||||
// Last but invalid command.
|
// Last but invalid command.
|
||||||
kError,
|
kError,
|
||||||
|
|||||||
+4
-4
@@ -551,9 +551,9 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
|
|||||||
if (chosen_action == Device::ENTER_RESCUE) {
|
if (chosen_action == Device::ENTER_RESCUE) {
|
||||||
// Switch to graphics screen.
|
// Switch to graphics screen.
|
||||||
ui->ShowText(false);
|
ui->ShowText(false);
|
||||||
status = ApplyFromAdb(ui, true /* rescue_mode */, &reboot_action);
|
status = ApplyFromAdb(device, true /* rescue_mode */, &reboot_action);
|
||||||
} else if (chosen_action == Device::APPLY_ADB_SIDELOAD) {
|
} else if (chosen_action == Device::APPLY_ADB_SIDELOAD) {
|
||||||
status = ApplyFromAdb(ui, false /* rescue_mode */, &reboot_action);
|
status = ApplyFromAdb(device, false /* rescue_mode */, &reboot_action);
|
||||||
} else {
|
} else {
|
||||||
adb = false;
|
adb = false;
|
||||||
status = ApplyFromSdcard(device, ui);
|
status = ApplyFromSdcard(device, ui);
|
||||||
@@ -946,7 +946,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
if (!sideload_auto_reboot) {
|
if (!sideload_auto_reboot) {
|
||||||
ui->ShowText(true);
|
ui->ShowText(true);
|
||||||
}
|
}
|
||||||
status = ApplyFromAdb(ui, false /* rescue_mode */, &next_action);
|
status = ApplyFromAdb(device, false /* rescue_mode */, &next_action);
|
||||||
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
|
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
|
||||||
if (sideload_auto_reboot) {
|
if (sideload_auto_reboot) {
|
||||||
status = INSTALL_REBOOT;
|
status = INSTALL_REBOOT;
|
||||||
@@ -954,7 +954,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
}
|
}
|
||||||
} else if (rescue) {
|
} else if (rescue) {
|
||||||
save_current_log = true;
|
save_current_log = true;
|
||||||
status = ApplyFromAdb(ui, true /* rescue_mode */, &next_action);
|
status = ApplyFromAdb(device, true /* rescue_mode */, &next_action);
|
||||||
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
|
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
|
||||||
} else if (fsck_unshare_blocks) {
|
} else if (fsck_unshare_blocks) {
|
||||||
if (!do_fsck_unshare_blocks()) {
|
if (!do_fsck_unshare_blocks()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user