Android7.0恢复出厂设置过程分析

今天跟了一下Android7.0的恢复出厂设置的流程,记录如下:

首先是在设置里面点击“ERASE EVERYTHING”按钮, 那就从这里入手,先搜索这个 ERASE EVERYTHING字符串 吧:
grep -ri "ERASE EVERYTHING" ../../packages/apps/Settings/
packages/apps/Settings/res/values-en-rGB/strings.xml:    "Erase everything"
packages/apps/Settings/res/values-en-rIN/strings.xml:    "Erase everything"
packages/apps/Settings/res/values-en-rAU/strings.xml:    "Erase everything"
packages/apps/Settings/res/values/strings.xml:    Erase everything

再搜索 master_clear_final_button_text,除了大量的各种语言的字符串的定义,还有下面这个:
packages/apps/Settings/res/layout/master_clear_confirm.xml: android:text="@string/master_clear_final_button_text"

那就查看master_clear_confirm.xml文件,找到button的id为execute_master_clear:
android/packages/apps/Settings/res/layout/master_clear_confirm.xml
 32     

根据id再搜索,找到java源文件:
android/packages/apps/Settings/src/com/android/settings/MasterClearConfirm.java
128     private void establishFinalConfirmationState() {
129         mContentView.findViewById(R.id.execute_master_clear)
130                 .setOnClickListener(mFinalClickListener);
131     }

再来看看该button的事件监听器mFinalClickListener的实现:
 60     private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
 61
 62         public void onClick(View v) {
 63             if (Utils.isMonkeyRunning()) {
 64                 return;
 65             }
 66
 67             final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager)
 68                     getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
 69
 70             if (pdbManager != null && !pdbManager.getOemUnlockEnabled() &&
 71                     Utils.isDeviceProvisioned(getActivity())) {
 72                 new AsyncTask() {
 73                     int mOldOrientation;
 74                     ProgressDialog mProgressDialog;
 75
 76                     @Override
 77                     protected Void doInBackground(Void... params) {
 78                         pdbManager.wipe();
 79                         return null;
 80                     }
 81
 82                     @Override
 83                     protected void onPostExecute(Void aVoid) {
 84                         mProgressDialog.hide();
 85                         if (getActivity() != null) {
 86                             getActivity().setRequestedOrientation(mOldOrientation);
 87                             doMasterClear();
 88                         }
 89                     }
 90
 91                     @Override
 92                     protected void onPreExecute() {
 93                         mProgressDialog = getProgressDialog();
 94                         mProgressDialog.show();
 95                         mOldOrientation = getActivity().getRequestedOrientation();
 96                         getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
 97                     }
 98                 }.execute();
 99             } else {
100                 doMasterClear();
101             }
102         }

再来看看doMasterClear的实现,主要就是 发送包含 ACTION_MASTER_CLEAR的intent出去
116     private void doMasterClear() {
117         Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
118         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
119         intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
120         intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard);
121         getActivity().sendBroadcast(intent);
122         // Intent handling is asynchronous -- assume it will happen soon.
123     }

这个ACTION_MASTER_CLEAR的定义是在这里:
android/ frameworks/base/ core/java/android/content/Intent.java
3173     /** {@hide} */
3174     public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";

那android.intent.action.MASTER_CLEAR的接收是在哪里呢,在这里:
android/frameworks/base/core/res/AndroidManifest.xml
3111         
3113             
3115                 
3116                 android.intent.action.MASTER_CLEAR" />
3117
3118                 
3119                 
3120                 
3121             
3122         

原来是MasterClearReceiver去处理这个消息,那就看看它的处理:
android/frameworks/base/services/core/java/com/android/server/MasterClearReceiver.java
 54         Slog.w(TAG, "!!! FACTORY RESET !!!");
 55         // The reboot call is blocking, so we need to do it on another thread.
 56         Thread thr = new Thread("Reboot") {
 57             @Override
 58             public void run() {
 59                 try {
 61                     RecoverySystem.rebootWipeUserData(context, shutdown, reason);
 62                     Log.wtf(TAG, "Still running after master clear?!");
 63                 } catch (IOException e) {
 64                     Slog.e(TAG, "Can't perform master clear/factory reset", e);
 65                 } catch (SecurityException e) {
 66                     Slog.e(TAG, "Can't perform master clear/factory reset", e);
 67                 }
 68             }
 69         };

后面的流程就到了 RecoverySystem中:
android/frameworks/base/core/java/android/os/RecoverySystem.java
606     public static void rebootWipeUserData(Context context, boolean shutdown, String reason)
607             throws IOException {
608         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
609         if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
610             throw new SecurityException("Wiping data is not allowed for this user.");
611         }
612         final ConditionVariable condition = new ConditionVariable();
613
614         Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
615         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
616         context.sendOrderedBroadcastAsUser(intent, UserHandle.SYSTEM,
617                 android.Manifest.permission.MASTER_CLEAR,
618                 new BroadcastReceiver() {
619                     @Override
620                     public void onReceive(Context context, Intent intent) {
621                         condition.open();
622                     }
623                 }, null, 0, null, null);
624
625         // Block until the ordered broadcast has completed.
626         condition.block();
627
628         String shutdownArg = null;
629         if (shutdown) {
630             shutdownArg = "--shutdown_after";
631         }
632
633         String reasonArg = null;
634         if (!TextUtils.isEmpty(reason)) {
635             reasonArg = "--reason=" + sanitizeArg(reason);
636         }
637
638         final String localeArg = "--locale=" + Locale.getDefault().toString();
639         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
640     }

还是在RecoverySystem.java中,最后再来看看bootCommand的实现:
666     private static void bootCommand(Context context, String... args) throws IOException {
667         synchronized (sRequestLock) {
669             LOG_FILE.delete();
670
671             StringBuilder command = new StringBuilder();
672             for (String arg : args) {
673                 if (!TextUtils.isEmpty(arg)) {
674                     command.append(arg);
675                     command.append("\n");
676                 }
677             }
678
679             // Write the command into BCB (bootloader control block).
680             RecoverySystem rs = (RecoverySystem) context.getSystemService(
681                     Context.RECOVERY_SERVICE);
682             rs.setupBcb(command.toString());
700
701             // Having set up the BCB, go ahead and reboot.
702             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
703             pm.reboot(PowerManager.REBOOT_RECOVERY);
704
705             throw new IOException("Reboot failed (no permissions?)");
706         }
707     }
这里的的pm.reboot()实现了重启机器的功能,当然,重启之后首先会擦除数据,经过一系列处理完成后,最后又重启回到Android系统,这时候就是刚出厂时的系统了,用户自己安装的APK都会被擦除掉。

其实可以在这里的reboot之前做一些定制化的修改,比如写文件置标志等,重启后,可以按照自己的Recovery逻辑进行处理等。

你可能感兴趣的:(android系统)