对于回复出厂设置,应用层能做的就是发一个广播或者直接调用RecoverySystem的一个方法,剩下的都是系统完成的。通过发广播的方式最终也是调用RecoverySystem的方法来回复出厂设置,这里以发广播的方式来恢复出厂设置
一, 发送恢复出厂设置的广播,发送广播需要相应的权限 android.permission.MASTER_CLEAR
Intent intent = new Intent("android.intent.action.FACTORY_RESET");
intent.setPackage("android");
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra("android.intent.extra.REASON", "MasterClearConfirm");
intent.putExtra("android.intent.extra.WIPE_EXTERNAL_STORAGE", false);
intent.putExtra("com.android.internal.intent.extra.WIPE_ESIMS", false);
context.sendBroadcast(intent);
二,广播的处理
广播的处理在./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); //是否清楚ESIMS数据,嵌入式sim开,直接嵌入到设备芯片上
final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false)
|| intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, 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 {
RecoverySystem
.rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims); //重启之后启动到Recovery系统去删除数据
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 (mWipeExternalStorage || mWipeEsims) {
// thr will be started at the end of this task. //如果广播中携带的数据中需要清楚外部存储和ESIMS数据,则先执行这些数据的清除之后再重启删除userData数据
new WipeDataTask(context, thr).execute();
} else {
thr.start();
}
private class WipeDataTask extends AsyncTask<Void, Void, Void> {
private final Thread mChainedTask;
private final Context mContext;
private final ProgressDialog mProgressDialog;
public WipeDataTask(Context context, Thread chainedTask) {
mContext = context;
mChainedTask = chainedTask;
mProgressDialog = new ProgressDialog(context);
}
@Override
protected void onPreExecute() {
mProgressDialog.setIndeterminate(true);
mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mProgressDialog.setMessage(mContext.getText(R.string.progress_erasing));
mProgressDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
Slog.w(TAG, "Wiping adoptable disks");
if (mWipeExternalStorage) {
//调用 StorageManager 清除外部存储
StorageManager sm = (StorageManager