Android 11 recovery恢复出厂设置保留某些文件
/bootable/recovery/recovery.cpp
recovery的注释,流程解释!
/*
* The recovery tool communicates with the main system through /cache files.
* /cache/recovery/command - INPUT - command line for tool, one arg per line
* /cache/recovery/log - OUTPUT - combined log file from recovery run(s)
*
* The arguments which may be supplied in the recovery.command file:
* --update_package=path - verify install an OTA package file
* --install_with_fuse - install the update package with FUSE. This allows installation of large
* packages on LP32 builds. Since the mmap will otherwise fail due to out of memory.
* --wipe_data - erase user data (and cache), then reboot
* --prompt_and_wipe_data - prompt the user that data is corrupt, with their consent erase user
* data (and cache), then reboot
* --wipe_cache - wipe cache (but not user data), then reboot
* --show_text - show the recovery text menu, used by some bootloader (e.g. http://b/36872519).
* --set_encrypted_filesystem=on|off - enables / diasables encrypted fs
* --just_exit - do nothing; exit and reboot
*
* After completing, we remove /cache/recovery/command and reboot.
* Arguments may also be supplied in the bootloader control block (BCB).
* These important scenarios must be safely restartable at any point:
*
* FACTORY RESET
* 1. user selects "factory reset"
* 2. main system writes "--wipe_data" to /cache/recovery/command
* 3. main system reboots into recovery
* 4. get_args() writes BCB with "boot-recovery" and "--wipe_data"
* -- after this, rebooting will restart the erase --
* 5. erase_volume() reformats /data
* 6. erase_volume() reformats /cache
* 7. FinishRecovery() erases BCB
* -- after this, rebooting will restart the main system --
* 8. main() calls reboot() to boot main system
*
* OTA INSTALL
* 1. main system downloads OTA package to /cache/some-filename.zip
* 2. main system writes "--update_package=/cache/some-filename.zip"
* 3. main system reboots into recovery
* 4. get_args() writes BCB with "boot-recovery" and "--update_package=..."
* -- after this, rebooting will attempt to reinstall the update --
* 5. InstallPackage() attempts to install the update
* NOTE: the package install must itself be restartable from any point
* 6. FinishRecovery() erases BCB
* -- after this, rebooting will (try to) restart the main system --
* 7. ** if install failed **
* 7a. PromptAndWait() shows an error icon and waits for the user
* 7b. the user reboots (pulling the battery, etc) into the main system
*/
RK3228H开发之Rockchip Recovery及android系统升级详解
5.1 RK Log 重定向 Log re-direct
- 功能说明:Log 可以输出到串口、SD卡、/cache/recovery/、三个地方。
Function description: Log can be output to serial port, SD card, or /cache/recovery/. - 打开方式:
(1)<Android 10
bootable/recovery/Android.mk:
Enable method: modify bootable/recovery/Android.mk file:
REDIRECT_LOG_TO := UART 将日志输出到串口
REDIRECT_LOG_TO := UART output the log to serial port
REDIRECT_LOG_TO := CACHE 将日志输出到/cache/recovery/目录下
REDIRECT_LOG_TO := CACHE output the log to /cache/recovery/ directory
REDIRECT_LOG_TO := SDCARD 将日志输出到SD卡中recovery.log
REDIRECT_LOG_TO := SDCARD output the log to SD card recovery.log
(2)>=Android 10
bootable/recovery/Android.bp:
-DLogToSerial 将日志输出到串口
-DLogToSerial output the log to serial port
-DLogToCache 将日志输出到/cache/recovery/目录下
-DLogToCache output the log to /cache/recovery/ directory
-DLogToSDCard 将日志输出到SD卡中recovery.log
-DLogToSDCard output the log to SD card recovery.log
恢复出厂设置不擦除某个数据
1.创建一个新的文件分区,类似于system/(它只可读),但是可读可写,恢复出厂设置不清理
2.不新建分区,恢复出厂设置,通过代码保留某个数据
Android recovery 清除数据,跟随源码看,它自己会保留某个文件不被清理!
其实也就是保留了/cache/下的部分文件!(如果不格式化刷机,保留的东西就不会被清理掉)
bootable/recovery/install/wipe_data.cpp
//清理函数入口
bool WipeData(Device* device, bool convert_fbe) {
RecoveryUI* ui = device->GetUI();
ui->Print("\n-- Wiping data...\n");
if (!FinishPendingSnapshotMerges(device)) {
ui->Print("Unable to check update status or complete merge, cannot wipe partitions.\n");
return false;
}
bool success = device->PreWipeData();
if (success) {
success &= EraseVolume(DATA_ROOT, ui, convert_fbe);//erase_volume()重点
bool has_cache = volume_for_mount_point("/cache") != nullptr;
if (has_cache) {
success &= EraseVolume(CACHE_ROOT, ui, false);
}
if (volume_for_mount_point(METADATA_ROOT) != nullptr) {
success &= EraseVolume(METADATA_ROOT, ui, false);
}
}
if (success) {
success &= device->PostWipeData();
}
erase_baseparameter();
ui->Print("Data wipe %s.\n", success ? "complete" : "failed");
return success;
}
static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
bool is_data = (strcmp(volume, DATA_ROOT) == 0);
ui->SetBackground(RecoveryUI::ERASING);
ui->SetProgressType(RecoveryUI::INDETERMINATE);
std::vector<saved_log_file> log_files;
if (is_cache) {
// If we're reformatting /cache, we load any past logs (i.e. "/cache/recovery/last_*") and the
// current log ("/cache/recovery/log") into memory, so we can restore them after the reformat.
log_files = ReadLogFilesToMemory();//保存("/cache/recovery/log")到内存,不清理掉
}
ui->Print("Formatting %s...\n", volume);
...
}
--- a/bootable/recovery/recovery_utils/logging.cpp
+++ b/bootable/recovery/recovery_utils/logging.cpp
@@ -270,7 +270,8 @@ std::vector<saved_log_file> ReadLogFilesToMemory() {
std::vector<saved_log_file> log_files;
while ((de = readdir(d.get())) != nullptr) {
- if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0 || strncmp(de->d_name, "Recovery_", 9) == 0) {
+ if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0 || strncmp(de->d_name, "Recovery_", 9) == 0
+ || strcmp(de->d_name, "bootanimation") == 0) {
std::string path = android::base::StringPrintf("%s/%s", CACHE_LOG_DIR, de->d_name);
struct stat sb;
diff --git a/frameworks/base/core/java/android/os/RecoverySystem.java b/frameworks/base/core/java/android/os/RecoverySystem.java
index 769f1d34d4..224a0f19a6 100755
--- a/frameworks/base/core/java/android/os/RecoverySystem.java
+++ b/frameworks/base/core/java/android/os/RecoverySystem.java
@@ -1213,6 +1213,7 @@ public class RecoverySystem {
public static String handleAftermath(Context context) {
if (names[i].equals(RECOVERY_TEST_STATE)) continue;
if (reservePackage && names[i].equals(BLOCK_MAP_FILE.getName())) continue;
if (reservePackage && names[i].equals(UNCRYPT_PACKAGE_FILE.getName())) continue;
+ if (names[i].equals("bootanimation.zip")) continue;
Log.i(TAG,"names[i]:" + names[i]);//开机完成后,如果不是上面判断的东西,就都清理掉 TAG = RecoverySystem
recursiveDelete(new File(RECOVERY_DIR, names[i]));
Android7.x 通过Recovery保留特定文件实现恢复出厂设置后保留系统语言设置