admin管理员组文章数量:1597414
工作中排查到了恢复出厂设置的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.
版权声明:本文标题:Android恢复出厂设置代码流程分析 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1728285328a1152218.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论