android N 恢复出厂设置流程简析

本文深入分析了Android N系统中执行恢复出厂设置的流程,从设置应用触发,经由广播接收器MasterClearReceiver,调用RecoverySystem的rebootWipeUserData方法,最终进入recovery模式完成数据清除。涉及关键类包括MasterClearConfirm.java、MasterClearReceiver.java、RecoverySystem.java等。
摘要由CSDN通过智能技术生成

前言:

恢复出厂设置的本质上是先写入command到BCB中,然后让手机进入recovery模式,此时会根据BCB中的命令来执行对应的操作,本文主要分析java层的流程。力有不逮,如有错漏,请多指教。

流程图:

这里写图片描述

流程分析:

packages/apps/Settings/src/com/android/settings/MasterClearConfirm.java
恢复出厂设置的功能在设置中,源生版本中用户通过点击恢复出厂设置的button就可以了

    private void doMasterClear() {
        Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
        //参数的意思是是否擦除SdCard,默认为false
        intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard);
        //step:[1]
        getActivity().sendBroadcast(intent);
        // Intent handling is asynchronous -- assume it will happen soon.
    }

可以看出设置中只是简单的发送了一个广播,理所当然的需要找到广播的接受者–MasterClearReceiver.java

frameworks/base/services/core/java/com/android/server/MasterClearReceiver.java
接收到设置发出的恢复出厂设置的广播之后,将会调用RecoverySystem的rebootWipeUserData方法

    @Override
    public void onReceive(final Context context, final Intent intent) {
        //过滤
        if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
            if (!"google.com".equals(intent.getStringExtra("from"))) {
                Slog.w(TAG, "Ignoring master clear request -- not from trusted server.");
                return;
            }
        }

        final boolean shutdown = intent.getBooleanExtra("shutdown", false);
        final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
        final boolean wipeExternalStorage = intent.getBooleanExtra(
                Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
        final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false);

        Slog.w(TAG, "!!! FACTORY RESET !!!");
        // The reboot call is blocking, so we need to do it on another thread.
        Thread thr = new Thread("Reboot") {
            @Override
            public void run() {
                try {
                    //step:[2]
                    RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe);
                    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);
                }
            }
        };

        if (wipeExternalStorage) {
            // thr will be started at the end of this task.
            // 继承AsyncTask的类,发现此处擦除的SdCard指的是android M 新加入的使用外部存储卡扩容为
            // 内置存储设备的功能中的存储位置--SD卡或者USB存储设备,不是传统data分区下的SdCard
            // 另一方面分析,手机进入recovery模式之后,直接擦除data分区,SdCard目录包含在内,这
            // 样SdCard必然会被擦除,那么不必在此做多余擦除操作。
            new WipeAdoptableDisksTask(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) throws IOException {
        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
        if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
            throw new SecurityException("Wiping data is not allowed for this user.");
        }
        final ConditionVariable condition = new ConditionVariable();

        Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        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();

        String shutdownArg = null;
        if (shutdown) {
            shutdownArg = "--shutdown_after";
        }

        String reasonArg = null;
        if (!TextUtils.isEmpty(reason)) {
            reasonArg = "--reason=" + sanitizeArg(reason);
        }

        final String localeArg = "--locale=" + Locale.getDefault().toString();
        //step:[3]
        bootCommand(context, shutd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值