recovery: Implement a volume manager
This is a copy of the pre-binderized vold which has been converted to
use direct calls instead of sockets and stripped down to only what is
needed to support recovery.
Includes:
* recovery: volmgr: remove unused IsSupported
Change-Id: If8206658fdfb6108221806c09c99bf0a30f4a586
Signed-off-by: Jesse Chan <jc@lineageos.org>
* recovery: volmgr: remove filesystem checks
Those checks are not strictly necessary and we are
not building fsck tools for recovery for now.
Remove those checks so volmgr can be useful.
Change-Id: I87756c61b933b6cdccd281c6276b686fbd36019f
Signed-off-by: Jesse Chan <jc@lineageos.org>
* recovery: fixup `EmulatedVolume creating`
Avoid dangling pointer. Instead of pointing to FstabEntry create copy.
Change-Id: I57f76006db09a6add2c173f43175f0f6b848d87b
* recovery: fix volmgr cleaning up
Don't reset pointer to netlink manager
Delete disks in stop() rather then in ~VolumeManager
Call destroy() before deleting disks cause delete expects the
disk to be destroyed
Clear the lists or we would read garbage data on the next scan
Change-Id: Idadfa1f33b7cb5f2f3c780848a99344a6608420e
* recovery: handle interrupts in apply update menu
Change-Id: I1f78f9196634353b77986545332d7d52a5f0c161
Change-Id: Ic82d929e052b5ba70ecf7b475e0a223d77d9687e
diff --git a/recovery.cpp b/recovery.cpp
index c9108df..ff1b265 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -42,6 +42,7 @@
#include <android-base/strings.h>
#include <cutils/properties.h> /* for property_list */
#include <fs_mgr/roots.h>
+#include <volume_manager/VolumeManager.h>
#include <ziparchive/zip_archive.h>
#include "bootloader_message/bootloader_message.h"
@@ -61,6 +62,10 @@
#include "recovery_utils/battery_utils.h"
#include "recovery_utils/logging.h"
#include "recovery_utils/roots.h"
+#include "volclient.h"
+
+using android::volmgr::VolumeManager;
+using android::volmgr::VolumeInfo;
static constexpr const char* COMMAND_FILE = "/cache/recovery/command";
static constexpr const char* LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
@@ -197,6 +202,47 @@
return (chosen_item == 1);
}
+static InstallResult apply_update_menu(Device* device, Device::BuiltinAction* reboot_action){
+ RecoveryUI* ui = device->GetUI();
+ std::vector<std::string> headers{ "Apply update" };
+ std::vector<std::string> items;
+
+ const int item_sideload = 0;
+ std::vector<VolumeInfo> volumes;
+
+ InstallResult status = INSTALL_NONE;
+
+ for (;;) {
+ items.clear();
+ items.push_back("Apply from ADB");
+ VolumeManager::Instance()->getVolumeInfo(volumes);
+ for (auto& vitr : volumes) {
+ items.push_back("Choose from " + vitr.mLabel);
+ }
+
+ int chosen = ui->ShowMenu(
+ headers, items, 0, false,
+ std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2),
+ true /* refreshable */);
+ if (chosen == Device::kRefresh) {
+ continue;
+ }
+ if (chosen == Device::kGoBack) {
+ break;
+ }
+ if (chosen == static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED)) {
+ return INSTALL_KEY_INTERRUPTED;
+ }
+
+ if (chosen == item_sideload) {
+ status = ApplyFromAdb(device, false /* rescue_mode */, reboot_action);
+ } else {
+ status = ApplyFromStorage(device, volumes[chosen - 1]);
+ }
+ }
+ return status;
+}
+
static InstallResult prompt_and_wipe_data(Device* device) {
// Use a single string and let ScreenRecoveryUI handles the wrapping.
std::vector<std::string> wipe_data_menu_headers{
@@ -427,7 +473,6 @@
switch (chosen_action) {
case Device::MENU_BASE:
- case Device::MENU_UPDATE:
case Device::MENU_WIPE:
case Device::MENU_ADVANCED:
goto change_menu;
@@ -492,28 +537,22 @@
break;
}
- case Device::APPLY_ADB_SIDELOAD:
- case Device::APPLY_SDCARD:
+ case Device::APPLY_UPDATE:
case Device::ENTER_RESCUE: {
save_current_log = true;
update_in_progress = true;
WriteUpdateInProgress();
- bool adb = true;
Device::BuiltinAction reboot_action;
if (chosen_action == Device::ENTER_RESCUE) {
// Switch to graphics screen.
ui->ShowText(false);
status = ApplyFromAdb(device, true /* rescue_mode */, &reboot_action);
- } else if (chosen_action == Device::APPLY_ADB_SIDELOAD) {
- status = ApplyFromAdb(device, false /* rescue_mode */, &reboot_action);
- } else {
- adb = false;
- status = ApplyFromSdcard(device);
+ } else if (chosen_action == Device::APPLY_UPDATE) {
+ status = apply_update_menu(device, &reboot_action);
}
- ui->Print("\nInstall from %s completed with status %d.\n", adb ? "ADB" : "SD card", status);
if (status == INSTALL_REBOOT) {
return reboot_action;
}
@@ -521,6 +560,7 @@
update_in_progress = false;
}
+ ui->Print("\nInstall completed with status %d.\n", status);
if (status == INSTALL_SUCCESS) {
update_in_progress = false;
if (!ui->IsTextVisible()) {
@@ -739,6 +779,12 @@
auto ui = device->GetUI();
+ VolumeClient* volclient = new VolumeClient(device);
+ VolumeManager* volmgr = VolumeManager::Instance();
+ if (!volmgr->start(volclient)) {
+ printf("Failed to start volume manager\n");
+ }
+
// Set background string to "installing security update" for security update,
// otherwise set it to "installing system update".
ui->SetSystemUpdateText(security_update);
@@ -926,5 +972,11 @@
// Save logs and clean up before rebooting or shutting down.
FinishRecovery(ui);
+ volmgr->unmountAll();
+ volmgr->stop();
+ delete volclient;
+
+ sync();
+
return next_action;
}