android 恢复出厂设置原理,Android恢复出厂设置流程分析【Android源码解析十】

本文详细分析了Android设备执行恢复出厂设置的完整流程,从用户界面操作到系统内部的广播接收、权限验证、数据清除、系统重启等关键步骤,涉及Setting、PowerManagerService、ShutdownThread等多个组件。主要步骤包括:用户触发清除操作、发送广播、执行RecoverySystem.rebootWipeUserData()、PowerManager.reboot()以及后续的系统关机和重启流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程;

在setting-->备份与重置--->恢复出厂设置--->重置手机--->清除全部内容--->手机关机--->开机--->进行恢复出厂的操作--->开机流程;

Step 1:前面找settings中的布局我就省略了,这部分相对简单一些,直接到清除全部内容这个按钮的操作,

对应的java类是setting中的MasterClearConfirm.java这个类,

privateButton.OnClickListener mFinalClickListener =newButton.OnClickListener() {

publicvoidonClick(View v) {

if(Utils.isMonkeyRunning()) {

return;

}

if(mEraseSdCard) {

Intent intent = newIntent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);

intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);

getActivity().startService(intent);

} else{

getActivity().sendBroadcast(newIntent("android.intent.action.MASTER_CLEAR"));

// Intent handling is asynchronous -- assume it will happen soon.

}

}

};

通过上述的代码,可以看出,实际上点击清除全部内容的时候,如果前面勾选上格式哈SD卡,就会执行mEraseSdCard为true里面的逻辑,如果没有勾选,就执行mEraseSdCard=false的逻辑,其实就是发送一个广播,

"font-size:14px;">“android.intent.action.MASTER_CLEAR”

Step 2:这个广播接受的地方,参见AndroidManifest.xml中的代码,如下:

android:permission="android.permission.MASTER_CLEAR"

android:priority="100">

intent-filter>

receiver>

找这个MasterClearReceiver.java这个receiver,下面来看看这个onReceiver()里面做了什么操作:

publicvoidonReceive(finalContext context,finalIntent 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;

}

}

Slog.w(TAG, "!!! FACTORY RESET !!!");

// The reboot call is blocking, so we need to do it on another thread.

Thread thr = newThread("Reboot") {

@Override

publicvoidrun() {

try{

RecoverySystem.rebootWipeUserData(context);

Log.wtf(TAG, "Still running after master clear?!");

} catch(IOException e) {

Slog.e(TAG, "Can't perform master clear/factory reset", e);

}

}

};

thr.start();

}

这个里面主要的操作是:RecoverySystem.rebootWipeUserData(context);准备做重启的动作,告诉手机要清除userData的数据;

Step 3:接着来看看RecoverySystem.rebootWipeUserData()这个方法做了哪些操作:

publicstaticvoidrebootWipeUserData(Context context)throwsIOException {

finalConditionVariable condition =newConditionVariable();

Intent intent = newIntent("android.intent.action.MASTER_CLEAR_NOTIFICATION");

context.sendOrderedBroadcastAsUser(intent, UserHandle.OWNER,

android.Manifest.permission.MASTER_CLEAR,

newBroadcastReceiver() {

@Override

publicvoidonReceive(Context context, Intent intent) {

condition.open();

}

}, null,0,null,null);

// Block until the ordered broadcast has completed.

condition.block();

bootCommand(context, "--wipe_data\n--locale="+ Locale.getDefault().toString());

}

这个里面的广播可以先忽略不计,重点来看看bootCommand()这个方法,注意这个参数“--wipe_data\n--locale=”

privatestaticvoidbootCommand(Context context, String arg)throwsIOException {

RECOVERY_DIR.mkdirs();  // In case we need it

COMMAND_FILE.delete();  // In case it's not writable

LOG_FILE.delete();

FileWriter command = newFileWriter(COMMAND_FILE);

try{

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("recovery");

thrownewIOException("Reboot failed (no permissions?)");

}

这个方法的操作大致是“写节点/cache/recovery/command”,把传递过来的字符串写进去;然后调用PowerManager进行重启操作,reboot();

Step 4:接着我们来看看PowerManager的reboot方法做了哪些操作:

publicvoidreboot(String reason) {

try{

mService.reboot(false, reason,true);

} catch(RemoteException e) {

}

}

这个调用到了PowerManagerService.java这个类的reboot方法中了:

@Override// Binder call

publicvoidreboot(booleanconfirm, String reason,booleanwait) {

mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

finallongident = Binder.clearCallingIdentity();

try{

shutdownOrRebootInternal(false, confirm, reason, wait);

} finally{

Binder.restoreCallingIdentity(ident);

}

}

重点来看看shutdownOrRebootInternal()这个方法,

privatevoidshutdownOrRebootInternal(finalbooleanshutdown,finalbooleanconfirm,

finalString reason,booleanwait) {

if(mHandler ==null|| !mSystemReady) {

thrownewIllegalStateException("Too early to call 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值