Android恢复出厂设置代码流程分析

工作中排查到了恢复出厂设置的bug, 有一些细节是需要注意的,于是把这块的代码流程看一下:
代码基于:Android9.0

应用层:
就发送MASTER_CLEAR的广播, 这里没有带参数的

private final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
...
Intent intent = new Intent(ACTION_MASTER_CLEAR);
intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(intent);

框架层:

接受广播:
frameworks/base/services/core/java/com/android/server/MasterClearReceiver.java

final boolean shutdown = intent.getBooleanExtra("shutdown", false);
final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
mWipeExternalStorage = intent.getBooleanExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
mWipeEsims = intent.getBooleanExtra(Intent.EXTRA_WIPE_ESIMS, false);
final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false)
        || intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false);

Slog.w(TAG, "!!! FACTORY RESET !!!");
// 子线程中执行,防止blocking
// The reboot call is blocking, so we need to do it on another thread.
Thread thr = new Thread("Reboot") {
   
    @Override
    public void run() {
   
        try {
   
            // 这里的四个参数就是默认值了,应用层并没有传进来
            // shutdown:false
            // reason:null
            // forceWipe:false
            // mWipeEsims:false
            // 重启擦除user data and cache partitions
            RecoverySystem
                            .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims);
            Log.wtf(TAG, "Still running after master clear?!");
            } catch (IOException e) {
   
                Slog.e(TAG, "Can't perform master clear/factory reset", e);
            } catch (SecurityException e) {
   
                Slog.e(TAG, "Can't perform master clear/factory reset", e);
            }
        }
};

// mWipeExternalStorage & mWipeEsims都是false,所以这里不走
if (mWipeExternalStorage || mWipeEsims) {
   
    // thr will be started at the end of this task.
    new WipeDataTask(context, thr).execute();
    } else {
   
        thr.start();
}

frameworks/base/core/java/android/os/RecoverySystem.java

public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
        boolean force, boolean wipeEuicc) throws IOException {
   
    ...
    final ConditionVariable condition = new ConditionVariable();

    Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
    // 注意这里发了MASTER_CLEAR_NOTIFICATION这个有序广播,而且是block的,
    // 也就是接受这个广播的所有接受者处理完成之后才会继续往下执行,
    // 所以需要恢复出厂设置进行的一些操作可以接收这个广播进行处理.
    // 比如:除了用户数据&缓存数据,还有别的数据需要擦除、
    // 比如:车载系统需要通知MCU层做一些操作,也是接收这个广播发命令到MCU.
    context.sendOrderedBroadcastAsUser(intent, UserHandle.SYSTEM,
            android.Manifest.permission.MASTER_CLEAR,
            new BroadcastReceiver() {
   
                @Override
                public void onReceive(Context context, Intent intent) {
   
                    condition.open();
                }
                }, null, 0, null, null);

    // Block until the ordered broadcast has completed.
    condition.block();
    ...
    final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ;
    // shutdownArg:--shutdown_after
    // reasonArg:--reason=
    // localeArg:--locale=zh_CN
    // --wipe_data: 擦除data分区,同时擦除cache分区.
    bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
}
...
private static void bootCommand(Context context, String... args) throws IOException {
   
    // 这里删除的是cache/recovery/log
    LOG_FILE.delete();

    StringBuilder command = new StringBuilder();
    for (String arg : args) {
   
        if (!TextUtils.isEmpty(arg)) {
   
            command.append(arg);
            command.append("\n");
        }
    }

    // Write the command into BCB (bootloader control block) and boot from
    // there. Will not return unless failed.
    // 上面的command参数会写进BCB, 重启读BCB的数据从而进入Recovery
    RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE);
    rs.
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值