Merge "Add fastboot mode to recovery" am: 19a5316412
am: b0851cf8c4
Change-Id: I5bfe707e176d742f6ab1bd86b7c5fb65ce4fdc33
This commit is contained in:
+24
@@ -96,6 +96,29 @@ cc_library_static {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "librecovery_fastboot",
|
||||||
|
recovery_available: true,
|
||||||
|
defaults: [
|
||||||
|
"recovery_defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"fastboot/fastboot.cpp",
|
||||||
|
],
|
||||||
|
|
||||||
|
shared_libs: [
|
||||||
|
"libbase",
|
||||||
|
"libbootloader_message",
|
||||||
|
"libcutils",
|
||||||
|
"liblog",
|
||||||
|
],
|
||||||
|
|
||||||
|
static_libs: [
|
||||||
|
"librecovery_ui_default",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
cc_defaults {
|
cc_defaults {
|
||||||
name: "librecovery_defaults",
|
name: "librecovery_defaults",
|
||||||
|
|
||||||
@@ -125,6 +148,7 @@ cc_defaults {
|
|||||||
],
|
],
|
||||||
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
|
"librecovery_fastboot",
|
||||||
"libminui",
|
"libminui",
|
||||||
"libverifier",
|
"libverifier",
|
||||||
"libotautil",
|
"libotautil",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
static std::vector<std::pair<std::string, Device::BuiltinAction>> g_menu_actions{
|
static std::vector<std::pair<std::string, Device::BuiltinAction>> g_menu_actions{
|
||||||
{ "Reboot system now", Device::REBOOT },
|
{ "Reboot system now", Device::REBOOT },
|
||||||
{ "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
|
{ "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
|
||||||
|
{ "Enter fastboot", Device::ENTER_FASTBOOT },
|
||||||
{ "Apply update from ADB", Device::APPLY_ADB_SIDELOAD },
|
{ "Apply update from ADB", Device::APPLY_ADB_SIDELOAD },
|
||||||
{ "Apply update from SD card", Device::APPLY_SDCARD },
|
{ "Apply update from SD card", Device::APPLY_SDCARD },
|
||||||
{ "Wipe data/factory reset", Device::WIPE_DATA },
|
{ "Wipe data/factory reset", Device::WIPE_DATA },
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ class Device {
|
|||||||
RUN_GRAPHICS_TEST = 11,
|
RUN_GRAPHICS_TEST = 11,
|
||||||
RUN_LOCALE_TEST = 12,
|
RUN_LOCALE_TEST = 12,
|
||||||
KEY_INTERRUPTED = 13,
|
KEY_INTERRUPTED = 13,
|
||||||
|
ENTER_FASTBOOT = 14,
|
||||||
|
ENTER_RECOVERY = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Device(RecoveryUI* ui);
|
explicit Device(RecoveryUI* ui);
|
||||||
|
|||||||
+84
-19
@@ -6,6 +6,8 @@ on early-init
|
|||||||
|
|
||||||
start ueventd
|
start ueventd
|
||||||
|
|
||||||
|
setprop sys.usb.configfs 0
|
||||||
|
|
||||||
on init
|
on init
|
||||||
export ANDROID_ROOT /system
|
export ANDROID_ROOT /system
|
||||||
export ANDROID_DATA /data
|
export ANDROID_DATA /data
|
||||||
@@ -31,20 +33,6 @@ on init
|
|||||||
write /proc/sys/kernel/panic_on_oops 1
|
write /proc/sys/kernel/panic_on_oops 1
|
||||||
write /proc/sys/vm/max_map_count 1000000
|
write /proc/sys/vm/max_map_count 1000000
|
||||||
|
|
||||||
on fs
|
|
||||||
write /sys/class/android_usb/android0/f_ffs/aliases adb
|
|
||||||
mkdir /dev/usb-ffs 0770 shell shell
|
|
||||||
mkdir /dev/usb-ffs/adb 0770 shell shell
|
|
||||||
mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000
|
|
||||||
|
|
||||||
write /sys/class/android_usb/android0/enable 0
|
|
||||||
write /sys/class/android_usb/android0/idVendor 18D1
|
|
||||||
write /sys/class/android_usb/android0/idProduct D001
|
|
||||||
write /sys/class/android_usb/android0/functions adb
|
|
||||||
write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
|
|
||||||
write /sys/class/android_usb/android0/iProduct ${ro.product.model}
|
|
||||||
write /sys/class/android_usb/android0/iSerial ${ro.serialno}
|
|
||||||
|
|
||||||
on boot
|
on boot
|
||||||
ifup lo
|
ifup lo
|
||||||
hostname localhost
|
hostname localhost
|
||||||
@@ -86,6 +74,7 @@ service charger /charger -r
|
|||||||
seclabel u:r:charger:s0
|
seclabel u:r:charger:s0
|
||||||
|
|
||||||
service recovery /system/bin/recovery
|
service recovery /system/bin/recovery
|
||||||
|
socket recovery stream 422 system system
|
||||||
seclabel u:r:recovery:s0
|
seclabel u:r:recovery:s0
|
||||||
|
|
||||||
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
|
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
|
||||||
@@ -93,13 +82,89 @@ service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
|
|||||||
socket adbd stream 660 system system
|
socket adbd stream 660 system system
|
||||||
seclabel u:r:adbd:s0
|
seclabel u:r:adbd:s0
|
||||||
|
|
||||||
# Always start adbd on userdebug and eng builds
|
service fastbootd /system/bin/fastbootd
|
||||||
on property:ro.debuggable=1
|
disabled
|
||||||
write /sys/class/android_usb/android0/enable 1
|
group system
|
||||||
start adbd
|
seclabel u:r:fastbootd:s0
|
||||||
|
|
||||||
# Restart adbd so it can run as root
|
# Restart adbd so it can run as root
|
||||||
on property:service.adb.root=1
|
on property:service.adb.root=1
|
||||||
write /sys/class/android_usb/android0/enable 0
|
|
||||||
restart adbd
|
restart adbd
|
||||||
|
|
||||||
|
# Always start adbd on userdebug and eng builds
|
||||||
|
on fs && property:ro.debuggable=1
|
||||||
|
setprop sys.usb.config adb
|
||||||
|
|
||||||
|
on fs && property:sys.usb.configfs=1
|
||||||
|
mount configfs none /config
|
||||||
|
mkdir /config/usb_gadget/g1 0770 shell shell
|
||||||
|
write /config/usb_gadget/g1/idVendor 0x18D1
|
||||||
|
mkdir /config/usb_gadget/g1/strings/0x409 0770
|
||||||
|
write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
|
||||||
|
write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
|
||||||
|
write /config/usb_gadget/g1/strings/0x409/product ${ro.product.model}
|
||||||
|
mkdir /config/usb_gadget/g1/functions/ffs.adb
|
||||||
|
mkdir /config/usb_gadget/g1/functions/ffs.fastboot
|
||||||
|
mkdir /config/usb_gadget/g1/configs/b.1 0777 shell shell
|
||||||
|
mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell
|
||||||
|
|
||||||
|
on fs && property:sys.usb.configfs=0
|
||||||
|
write /sys/class/android_usb/android0/f_ffs/aliases adb,fastboot
|
||||||
|
write /sys/class/android_usb/android0/idVendor 18D1
|
||||||
|
write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
|
||||||
|
write /sys/class/android_usb/android0/iProduct ${ro.product.model}
|
||||||
|
write /sys/class/android_usb/android0/iSerial ${ro.serialno}
|
||||||
|
|
||||||
|
on fs
|
||||||
|
mkdir /dev/usb-ffs 0775 shell shell
|
||||||
|
mkdir /dev/usb-ffs/adb 0770 shell shell
|
||||||
|
mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000
|
||||||
|
mkdir /dev/usb-ffs/fastboot 0770 system system
|
||||||
|
mount functionfs fastboot /dev/usb-ffs/fastboot rmode=0770,fmode=0660,uid=1000,gid=1000
|
||||||
|
|
||||||
|
on property:sys.usb.config=adb
|
||||||
|
start adbd
|
||||||
|
|
||||||
|
on property:sys.usb.config=fastboot
|
||||||
|
start fastbootd
|
||||||
|
|
||||||
|
on property:sys.usb.config=none
|
||||||
|
stop adbd
|
||||||
|
stop fastbootd
|
||||||
|
|
||||||
|
on property:sys.usb.config=none && property:sys.usb.configfs=0
|
||||||
|
write /sys/class/android_usb/android0/enable 0
|
||||||
|
setprop sys.usb.state ${sys.usb.config}
|
||||||
|
|
||||||
|
on property:sys.usb.config=adb && property:sys.usb.configfs=0
|
||||||
|
write /sys/class/android_usb/android0/idProduct D001
|
||||||
|
write /sys/class/android_usb/android0/functions adb
|
||||||
write /sys/class/android_usb/android0/enable 1
|
write /sys/class/android_usb/android0/enable 1
|
||||||
|
setprop sys.usb.state ${sys.usb.config}
|
||||||
|
|
||||||
|
on property:sys.usb.config=fastboot && property:sys.usb.configfs=0
|
||||||
|
write /sys/class/android_usb/android0/idProduct 4EE0
|
||||||
|
write /sys/class/android_usb/android0/functions fastboot
|
||||||
|
write /sys/class/android_usb/android0/enable 1
|
||||||
|
setprop sys.usb.state ${sys.usb.config}
|
||||||
|
|
||||||
|
# Configfs triggers
|
||||||
|
on property:sys.usb.config=none && property:sys.usb.configfs=1
|
||||||
|
write /config/usb_gadget/g1/UDC "none"
|
||||||
|
setprop sys.usb.ffs.ready 0
|
||||||
|
rm /config/usb_gadget/g1/configs/b.1/f1
|
||||||
|
setprop sys.usb.state ${sys.usb.config}
|
||||||
|
|
||||||
|
on property:sys.usb.config=adb && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
|
||||||
|
write /config/usb_gadget/g1/idProduct 0xD001
|
||||||
|
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"
|
||||||
|
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
|
||||||
|
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
|
||||||
|
setprop sys.usb.state ${sys.usb.config}
|
||||||
|
|
||||||
|
on property:sys.usb.config=fastboot && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
|
||||||
|
write /config/usb_gadget/g1/idProduct 0x4EE0
|
||||||
|
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "fastboot"
|
||||||
|
symlink /config/usb_gadget/g1/functions/ffs.fastboot /config/usb_gadget/g1/configs/b.1/f1
|
||||||
|
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
|
||||||
|
setprop sys.usb.state ${sys.usb.config}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fastboot.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <android-base/logging.h>
|
||||||
|
#include <android-base/properties.h>
|
||||||
|
#include <bootloader_message/bootloader_message.h>
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
static const std::vector<std::pair<std::string, Device::BuiltinAction>> kFastbootMenuActions{
|
||||||
|
{ "Reboot system now", Device::REBOOT },
|
||||||
|
{ "Enter recovery", Device::ENTER_RECOVERY },
|
||||||
|
{ "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
|
||||||
|
{ "Power off", Device::SHUTDOWN },
|
||||||
|
};
|
||||||
|
|
||||||
|
Device::BuiltinAction StartFastboot(Device* device, const std::vector<std::string>& /* args */) {
|
||||||
|
RecoveryUI* ui = device->GetUI();
|
||||||
|
|
||||||
|
std::vector<std::string> title_lines = { "Android Fastboot" };
|
||||||
|
title_lines.push_back("Product name - " + android::base::GetProperty("ro.product.device", ""));
|
||||||
|
title_lines.push_back("Bootloader version - " + android::base::GetProperty("ro.bootloader", ""));
|
||||||
|
title_lines.push_back("Baseband version - " +
|
||||||
|
android::base::GetProperty("ro.build.expect.baseband", ""));
|
||||||
|
title_lines.push_back("Serial number - " + android::base::GetProperty("ro.serialno", ""));
|
||||||
|
title_lines.push_back(std::string("Secure boot - ") +
|
||||||
|
((android::base::GetProperty("ro.secure", "") == "1") ? "yes" : "no"));
|
||||||
|
title_lines.push_back("HW version - " + android::base::GetProperty("ro.revision", ""));
|
||||||
|
|
||||||
|
ui->ResetKeyInterruptStatus();
|
||||||
|
ui->SetTitle(title_lines);
|
||||||
|
ui->ShowText(true);
|
||||||
|
|
||||||
|
// Reset to normal system boot so recovery won't cycle indefinitely.
|
||||||
|
// TODO(b/112277594) Clear only if 'recovery' field of BCB is empty. If not,
|
||||||
|
// set the 'command' field of BCB to 'boot-recovery' so the next boot is into recovery
|
||||||
|
// to finish any interrupted tasks.
|
||||||
|
std::string err;
|
||||||
|
if (!clear_bootloader_message(&err)) {
|
||||||
|
LOG(ERROR) << "Failed to clear BCB message: " << err;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> fastboot_menu_items;
|
||||||
|
std::transform(kFastbootMenuActions.cbegin(), kFastbootMenuActions.cend(),
|
||||||
|
std::back_inserter(fastboot_menu_items),
|
||||||
|
[](const auto& entry) { return entry.first; });
|
||||||
|
|
||||||
|
auto chosen_item = ui->ShowMenu(
|
||||||
|
{}, fastboot_menu_items, 0, false,
|
||||||
|
std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
||||||
|
if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED)) {
|
||||||
|
return Device::KEY_INTERRUPTED;
|
||||||
|
}
|
||||||
|
if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT)) {
|
||||||
|
return Device::BuiltinAction::NO_ACTION;
|
||||||
|
}
|
||||||
|
return kFastbootMenuActions[chosen_item].second;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
|
Device::BuiltinAction StartFastboot(Device* device, const std::vector<std::string>& args);
|
||||||
+4
-1
@@ -779,6 +779,8 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
|
|||||||
case Device::REBOOT:
|
case Device::REBOOT:
|
||||||
case Device::SHUTDOWN:
|
case Device::SHUTDOWN:
|
||||||
case Device::REBOOT_BOOTLOADER:
|
case Device::REBOOT_BOOTLOADER:
|
||||||
|
case Device::ENTER_FASTBOOT:
|
||||||
|
case Device::ENTER_RECOVERY:
|
||||||
return chosen_action;
|
return chosen_action;
|
||||||
|
|
||||||
case Device::WIPE_DATA:
|
case Device::WIPE_DATA:
|
||||||
@@ -995,6 +997,7 @@ static void log_failure_code(ErrorCode code, const std::string& update_package)
|
|||||||
|
|
||||||
Device::BuiltinAction start_recovery(Device* device, const std::vector<std::string>& args) {
|
Device::BuiltinAction start_recovery(Device* device, const std::vector<std::string>& args) {
|
||||||
static constexpr struct option OPTIONS[] = {
|
static constexpr struct option OPTIONS[] = {
|
||||||
|
{ "fastboot", no_argument, nullptr, 0 },
|
||||||
{ "fsck_unshare_blocks", no_argument, nullptr, 0 },
|
{ "fsck_unshare_blocks", no_argument, nullptr, 0 },
|
||||||
{ "just_exit", no_argument, nullptr, 'x' },
|
{ "just_exit", no_argument, nullptr, 'x' },
|
||||||
{ "locale", required_argument, nullptr, 0 },
|
{ "locale", required_argument, nullptr, 0 },
|
||||||
@@ -1049,7 +1052,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
std::string option = OPTIONS[option_index].name;
|
std::string option = OPTIONS[option_index].name;
|
||||||
if (option == "fsck_unshare_blocks") {
|
if (option == "fsck_unshare_blocks") {
|
||||||
fsck_unshare_blocks = true;
|
fsck_unshare_blocks = true;
|
||||||
} else if (option == "locale") {
|
} else if (option == "locale" || option == "fastboot") {
|
||||||
// Handled in recovery_main.cpp
|
// Handled in recovery_main.cpp
|
||||||
} else if (option == "prompt_and_wipe_data") {
|
} else if (option == "prompt_and_wipe_data") {
|
||||||
should_prompt_and_wipe_data = true;
|
should_prompt_and_wipe_data = true;
|
||||||
|
|||||||
+104
-22
@@ -30,15 +30,19 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
|
#include <android-base/unique_fd.h>
|
||||||
#include <bootloader_message/bootloader_message.h>
|
#include <bootloader_message/bootloader_message.h>
|
||||||
#include <cutils/android_reboot.h>
|
#include <cutils/android_reboot.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
#include <private/android_logger.h> /* private pmsg functions */
|
#include <private/android_logger.h> /* private pmsg functions */
|
||||||
#include <selinux/android.h>
|
#include <selinux/android.h>
|
||||||
#include <selinux/label.h>
|
#include <selinux/label.h>
|
||||||
@@ -46,6 +50,7 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "fastboot/fastboot.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "minadbd/minadbd.h"
|
#include "minadbd/minadbd.h"
|
||||||
#include "otautil/paths.h"
|
#include "otautil/paths.h"
|
||||||
@@ -162,6 +167,44 @@ static std::string load_locale_from_cache() {
|
|||||||
return android::base::Trim(content);
|
return android::base::Trim(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ListenRecoverySocket(RecoveryUI* ui, std::atomic<Device::BuiltinAction>& action) {
|
||||||
|
android::base::unique_fd sock_fd(android_get_control_socket("recovery"));
|
||||||
|
if (sock_fd < 0) {
|
||||||
|
PLOG(ERROR) << "Failed to open recovery socket";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
listen(sock_fd, 4);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
android::base::unique_fd connection_fd;
|
||||||
|
connection_fd.reset(accept(sock_fd, nullptr, nullptr));
|
||||||
|
if (connection_fd < 0) {
|
||||||
|
PLOG(ERROR) << "Failed to accept socket connection";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char msg;
|
||||||
|
constexpr char kSwitchToFastboot = 'f';
|
||||||
|
constexpr char kSwitchToRecovery = 'r';
|
||||||
|
ssize_t ret = TEMP_FAILURE_RETRY(read(connection_fd, &msg, sizeof(msg)));
|
||||||
|
if (ret != sizeof(msg)) {
|
||||||
|
PLOG(ERROR) << "Couldn't read from socket";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (msg) {
|
||||||
|
case kSwitchToRecovery:
|
||||||
|
action = Device::BuiltinAction::ENTER_RECOVERY;
|
||||||
|
break;
|
||||||
|
case kSwitchToFastboot:
|
||||||
|
action = Device::BuiltinAction::ENTER_FASTBOOT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG(ERROR) << "Unrecognized char from socket " << msg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ui->InterruptKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void redirect_stdio(const char* filename) {
|
static void redirect_stdio(const char* filename) {
|
||||||
int pipefd[2];
|
int pipefd[2];
|
||||||
if (pipe(pipefd) == -1) {
|
if (pipe(pipefd) == -1) {
|
||||||
@@ -251,6 +294,11 @@ static void redirect_stdio(const char* filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool SetUsbConfig(const std::string& state) {
|
||||||
|
android::base::SetProperty("sys.usb.config", state);
|
||||||
|
return android::base::WaitForProperty("sys.usb.state", state);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// We don't have logcat yet under recovery; so we'll print error on screen and log to stdout
|
// We don't have logcat yet under recovery; so we'll print error on screen and log to stdout
|
||||||
// (which is redirected to recovery.log) as we used to do.
|
// (which is redirected to recovery.log) as we used to do.
|
||||||
@@ -281,8 +329,6 @@ int main(int argc, char** argv) {
|
|||||||
// instances with different timestamps.
|
// instances with different timestamps.
|
||||||
redirect_stdio(Paths::Get().temporary_log_file().c_str());
|
redirect_stdio(Paths::Get().temporary_log_file().c_str());
|
||||||
|
|
||||||
printf("Starting recovery (pid %d) on %s", getpid(), ctime(&start));
|
|
||||||
|
|
||||||
load_volume_table();
|
load_volume_table();
|
||||||
has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;
|
has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;
|
||||||
|
|
||||||
@@ -290,12 +336,14 @@ int main(int argc, char** argv) {
|
|||||||
auto args_to_parse = StringVectorToNullTerminatedArray(args);
|
auto args_to_parse = StringVectorToNullTerminatedArray(args);
|
||||||
|
|
||||||
static constexpr struct option OPTIONS[] = {
|
static constexpr struct option OPTIONS[] = {
|
||||||
|
{ "fastboot", no_argument, nullptr, 0 },
|
||||||
{ "locale", required_argument, nullptr, 0 },
|
{ "locale", required_argument, nullptr, 0 },
|
||||||
{ "show_text", no_argument, nullptr, 't' },
|
{ "show_text", no_argument, nullptr, 't' },
|
||||||
{ nullptr, 0, nullptr, 0 },
|
{ nullptr, 0, nullptr, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool show_text = false;
|
bool show_text = false;
|
||||||
|
bool fastboot = false;
|
||||||
std::string locale;
|
std::string locale;
|
||||||
|
|
||||||
int arg;
|
int arg;
|
||||||
@@ -310,6 +358,8 @@ int main(int argc, char** argv) {
|
|||||||
std::string option = OPTIONS[option_index].name;
|
std::string option = OPTIONS[option_index].name;
|
||||||
if (option == "locale") {
|
if (option == "locale") {
|
||||||
locale = optarg;
|
locale = optarg;
|
||||||
|
} else if (option == "fastboot") {
|
||||||
|
fastboot = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -328,8 +378,6 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("locale is [%s]\n", locale.c_str());
|
|
||||||
|
|
||||||
static constexpr const char* kDefaultLibRecoveryUIExt = "librecovery_ui_ext.so";
|
static constexpr const char* kDefaultLibRecoveryUIExt = "librecovery_ui_ext.so";
|
||||||
// Intentionally not calling dlclose(3) to avoid potential gotchas (e.g. `make_device` may have
|
// Intentionally not calling dlclose(3) to avoid potential gotchas (e.g. `make_device` may have
|
||||||
// handed out pointers to code or static [or thread-local] data and doesn't collect them all back
|
// handed out pointers to code or static [or thread-local] data and doesn't collect them all back
|
||||||
@@ -374,33 +422,67 @@ int main(int argc, char** argv) {
|
|||||||
ui->SetBackground(RecoveryUI::NONE);
|
ui->SetBackground(RecoveryUI::NONE);
|
||||||
if (show_text) ui->ShowText(true);
|
if (show_text) ui->ShowText(true);
|
||||||
|
|
||||||
|
LOG(INFO) << "Starting recovery (pid " << getpid() << ") on " << ctime(&start);
|
||||||
|
LOG(INFO) << "locale is [" << locale << "]";
|
||||||
|
|
||||||
sehandle = selinux_android_file_context_handle();
|
sehandle = selinux_android_file_context_handle();
|
||||||
selinux_android_set_sehandle(sehandle);
|
selinux_android_set_sehandle(sehandle);
|
||||||
if (!sehandle) {
|
if (!sehandle) {
|
||||||
ui->Print("Warning: No file_contexts\n");
|
ui->Print("Warning: No file_contexts\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::BuiltinAction after = start_recovery(device, args);
|
std::atomic<Device::BuiltinAction> action;
|
||||||
|
std::thread listener_thread(ListenRecoverySocket, ui, std::ref(action));
|
||||||
|
listener_thread.detach();
|
||||||
|
|
||||||
switch (after) {
|
|
||||||
case Device::SHUTDOWN:
|
|
||||||
ui->Print("Shutting down...\n");
|
|
||||||
android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Device::REBOOT_BOOTLOADER:
|
|
||||||
ui->Print("Rebooting to bootloader...\n");
|
|
||||||
android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ui->Print("Rebooting...\n");
|
|
||||||
reboot("reboot,");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true) {
|
while (true) {
|
||||||
pause();
|
std::string usb_config = fastboot ? "fastboot" : is_ro_debuggable() ? "adb" : "none";
|
||||||
|
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
|
||||||
|
if (usb_config != usb_state) {
|
||||||
|
if (!SetUsbConfig("none")) {
|
||||||
|
LOG(ERROR) << "Failed to clear USB config";
|
||||||
|
}
|
||||||
|
if (!SetUsbConfig(usb_config)) {
|
||||||
|
LOG(ERROR) << "Failed to set USB config to " << usb_config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ret = fastboot ? StartFastboot(device, args) : start_recovery(device, args);
|
||||||
|
|
||||||
|
if (ret == Device::KEY_INTERRUPTED) {
|
||||||
|
ret = action.exchange(ret);
|
||||||
|
if (ret == Device::NO_ACTION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (ret) {
|
||||||
|
case Device::SHUTDOWN:
|
||||||
|
ui->Print("Shutting down...\n");
|
||||||
|
android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Device::REBOOT_BOOTLOADER:
|
||||||
|
ui->Print("Rebooting to bootloader...\n");
|
||||||
|
android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Device::ENTER_FASTBOOT:
|
||||||
|
LOG(INFO) << "Entering fastboot";
|
||||||
|
fastboot = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Device::ENTER_RECOVERY:
|
||||||
|
LOG(INFO) << "Entering recovery";
|
||||||
|
fastboot = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ui->Print("Rebooting...\n");
|
||||||
|
reboot("reboot,");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be unreachable.
|
// Should be unreachable.
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user