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.
Change-Id: Ic82d929e052b5ba70ecf7b475e0a223d77d9687e
diff --git a/recovery.cpp b/recovery.cpp
index ff04b49..7b8e32b 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -46,6 +46,7 @@
#include <bootloader_message/bootloader_message.h>
#include <cutils/properties.h> /* for property_list */
#include <healthhalutils/HealthHalUtils.h>
+#include <volume_manager/VolumeManager.h>
#include <ziparchive/zip_archive.h>
#include "common.h"
@@ -62,6 +63,10 @@
#include "otautil/sysutil.h"
#include "recovery_ui/screen_ui.h"
#include "recovery_ui/ui.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";
@@ -206,6 +211,42 @@
return (chosen_item == 1);
}
+static int apply_update_menu(Device* device, RecoveryUI* ui, Device::BuiltinAction* reboot_action){
+ std::vector<std::string> headers{ "Apply update" };
+ std::vector<std::string> items;
+
+ const int item_sideload = 0;
+ std::vector<VolumeInfo> volumes;
+
+ int status = INSTALL_ERROR;
+
+ 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 == item_sideload) {
+ status = ApplyFromAdb(device, false /* rescue_mode */, reboot_action);
+ } else {
+ status = ApplyFromStorage(device, volumes[chosen - 1], ui);
+ }
+ }
+ 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{
@@ -538,7 +579,6 @@
switch (chosen_action) {
case Device::MENU_BASE:
- case Device::MENU_UPDATE:
case Device::MENU_WIPE:
case Device::MENU_ADVANCED:
goto change_menu;
@@ -588,29 +628,24 @@
break;
}
- case Device::APPLY_ADB_SIDELOAD:
- case Device::APPLY_SDCARD:
+ case Device::APPLY_UPDATE:
case Device::ENTER_RESCUE: {
save_current_log = true;
- 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, ui);
+ } else if (chosen_action == Device::APPLY_UPDATE) {
+ status = apply_update_menu(device, ui, &reboot_action);
}
- ui->Print("\nInstall from %s completed with status %d.\n", adb ? "ADB" : "SD card", status);
if (status == INSTALL_REBOOT) {
return reboot_action;
}
+ ui->Print("\nInstall completed with status %d.\n", status);
if (status != INSTALL_SUCCESS) {
ui->SetBackground(RecoveryUI::ERROR);
ui->Print("Installation aborted.\n");
@@ -870,6 +905,12 @@
printf("stage is [%s]\n", stage.c_str());
printf("reason is [%s]\n", reason);
+ VolumeClient* volclient = new VolumeClient(device);
+ VolumeManager* volmgr = VolumeManager::Instance();
+ if (!volmgr->start(volclient, sehandle)) {
+ 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);
@@ -1043,5 +1084,11 @@
// Save logs and clean up before rebooting or shutting down.
finish_recovery();
+ volmgr->unmountAll();
+ volmgr->stop();
+ delete volclient;
+
+ sync();
+
return next_action;
}