关于恢复出厂设置的说明

恢复出厂设置分为两种 ,要么清除sdcard么不清除。无论哪种都是通过发送广播的形式来执行这个操作。

private void doMasterClear() {
    if (mEraseSdCard) {
        Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
        intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
        intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
        getActivity().startService(intent);
    } else {
        Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
        getActivity().sendBroadcast(intent);
        // Intent handling is asynchronous -- assume it will happen soon.
    }

}

其中接收广播并执行操作的是com.android.server.MasterClearReceiver这个类。

public class MasterClearReceiver extends BroadcastReceiver {
private static final String TAG = “MasterClear”;

@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);

    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 {
                RecoverySystem.rebootWipeUserData(context, shutdown, reason);
                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);
            }
        }
    };
    thr.start();
}

}

其中 RecoverySystem.rebootWipeUserData(context, shutdown, reason);做了实际清除userdata等等操作
中rebootWipeUserData 代码如下。

/**
 * Reboots the device and wipes the user data and cache
 * partitions.  This is sometimes called a "factory reset", which
 * is something of a misnomer because the system partition is not
 * restored to its factory state.  Requires the
 * {@link android.Manifest.permission#REBOOT} permission.
 *
 * @param context   the Context to use
 * @param shutdown  if true, the device will be powered down after
 *                  the wipe completes, rather than being rebooted
 *                  back to the regular system.
 *
 * @throws IOException  if writing the recovery command file
 * fails, or if the reboot itself fails.
 * @throws SecurityException if the current user is not allowed to wipe data.
 *
 * @hide
 */
public static void rebootWipeUserData(Context context, boolean shutdown, String reason)
        throws IOException {
    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    if (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.OWNER,
            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();
    bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);

}

其中:
/**
* Reboot into the recovery system with the supplied argument.
* @param args to pass to the recovery utility.
* @throws IOException if something goes wrong.
*/
private static void bootCommand(Context context, String… args) throws IOException {
RECOVERY_DIR.mkdirs(); // In case we need it
COMMAND_FILE.delete(); // In case it’s not writable
LOG_FILE.delete();

    FileWriter command = new FileWriter(COMMAND_FILE);
    try {
        for (String arg : args) {
            if (!TextUtils.isEmpty(arg)) {
                command.write(arg);
                command.write("\n");
            }
        }
    } finally {
        command.close();
    }

    // Having written the command file, go ahead and reboot
    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    pm.reboot(PowerManager.REBOOT_RECOVERY);

    throw new IOException("Reboot failed (no permissions?)");
}

关机,然后开机,底层判断节点后进入恢复出厂模式,recevory.img释放完全后,进入开机的流程。。。至于具体想知道系统做了什么可以查看源代码找一下后续逻辑和行为。
我这仅仅是发送广播。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值