android 恢复出厂设置流程

在MasterClearConfirm.java中显示恢复出厂提示和对应button,点击button后调用button的
click方法 
1. 如果选中erase sd card, 则startService(ExternalStorageFormatter) 
2. 如果没有则直接发送广播,sendbroadcast(android.intent.action.MASTER_CLEAR), 对应的在
MasterClearReceiver会接受此广播,在onReceive()方法中会调用
RecoverySystem.rebootWipeUserData()方法. 
3. RecoverySystem.rebootWipeUserData()的流程如下: 
 3.1. 广播intent “android.intent.action.MASTER_CLEAR_NOTIFICATION” 通知所有接
收端处理相关行为. 
 3.2. 等待所有接收完成动作. 
 3.3. 写入一个command file于/cache/recovery/command, 內容为” --wipe_data” 
 3.4. 重新开机进入recovery mode. 
4.进入recovery mode之后,读取/cache/recovery/command, 內容為” --wipe_data” 
5.按照读取的command,进行wipe data操作。 
6.操作成功之后重新开机进去normal mode



1.  上层应用的设置->隐私权->恢复出厂设置对应的java代码在如下路径文件:

 packages/apps/Settings/src/com/android/settings/MasterClear.java
 MasterClear:mFinalClickListener()函数会发送一个广播出去:
 sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));

2.  这个广播的接收者在收到广播之后会开启一个java服务线程:MasterClearReceiver:RebootThread
 frameworks/base/services/java/com/android/server/MasterClearReceiver.java  -- TAG = "MasterClear"
 public void onReceive(Context context, Intent intent) {
        RebootThread mThread = new RebootThread(context, intent);
        mThread.start();
    }
    在线程的run函数中会调用函数:RecoverySystem.rebootWipeUserData(mContext);这个方法是RecoverySystem类的静态方法。

3.  RecoverySystem类定义于文件:frameworks/base/core/java/android/os/RecoverySystem.java   --  TAG = "RecoverySystem"
 public class RecoverySystem {
  /** Used to communicate with recovery.  See bootable/recovery/recovery.c. */
      private static File RECOVERY_DIR = new File("/cache/recovery");
     private static File COMMAND_FILE = new File(RECOVERY_DIR, "command");
     private static File LOG_FILE = new File(RECOVERY_DIR, "log");
  
  public static void rebootWipeUserData(Context context)
         throws IOException {
         bootCommand(context, "--wipe_data");
     }
     
     private static void bootCommand(Context context, String arg) 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 {
             command.write(arg);  // 往文件/cache/recovery/command中写入recovery ELF的执行参数。
             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");  // 调用PowerManager类中的reboot方法
 
         throw new IOException("Reboot failed (no permissions?)");
     }
 }
 
4.  PowerManager类定义于文件:frameworks/base/core/java/android/os/PowerManager.java  --  TAG = "PowerManager"
 public class PowerManager
 {
  ...
  public void reboot(String reason)
     {
         try {
             mService.reboot(reason);
         } catch (RemoteException e) {
         }
     }
  
   public PowerManager(IPowerManager service, Handler handler)
     {
         mService = service;
         mHandler = handler;
     }
  
  IPowerManager mService;
     Handler mHandler;
 }

5.  mService指向的是PowerManagerService类,这个类定义于文件:
 frameworks/base/services/java/com/android/server/PowerManagerService.java  --  TAG = "PowerManagerService"
 /**
     * Reboot the device immediately, passing 'reason' (may be null)
     * to the underlying __reboot system call.  Should not return.
     */
    public void reboot(String reason)
    {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

        if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
            throw new IllegalStateException("Too early to call reboot()");
        }

        final String finalReason = reason;
        Runnable runnable = new Runnable() {
            public void run() {
                synchronized (this) {
                    ShutdownThread.reboot(mContext, finalReason, false);
                } // 调用ShutdownThread服务中的reboot方法
               
            }
        };
        // ShutdownThread must run on a looper capable of displaying the UI.
        mHandler.post(runnable);

        // PowerManager.reboot() is documented not to return so just wait for the inevitable.
        synchronized (runnable) {
            while (true) {
                try {
                    runnable.wait();
                } catch (InterruptedException e) {
                }
            }
        }
    }
 
6.  ShutdownThread类在下列文件中实现:
 frameworks/base/core/java/com/android/internal/app/ShutdownThread.java   -- TAG = "ShutdownThread"
 public final class ShutdownThread extends Thread {
  ...
  public static void reboot(final Context context, String reason, boolean confirm) {
         mReboot = true;
         mRebootReason = reason;
         shutdown(context, confirm);
     }
    
     ...
     public void run() {
      ...
      if (mReboot) {
             Log.i(TAG, "Rebooting, reason: " + mRebootReason);
             try {
                 Power.reboot(mRebootReason);
             } catch (Exception e) {
                 Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
             }
         } else if (SHUTDOWN_VIBRATE_MS > 0) {
             ...
         }
         ...
     }
 }
 流程:reboot() --> shutdown() --> beginShutdownSequence() --> sInstance.start() --> run() --> Power.reboot(mRebootReason).
 最后调用Power类的reboot方法。

7.  Power类定义于文件:
 frameworks/base/core/java/android/os/Power.java    ---
 public class Power
 {
  ...
  public static void reboot(String reason) throws IOException
     {
         rebootNative(reason);
     }

     private static native void rebootNative(String reason) throws IOException ;
 }
 调用本地JNI接口rebootNative().

8. Power类对应的JNI接口函数定义于文件:
 frameworks/base/core/jni/android_os_Power.cpp
 static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
 {
     sync();
 #ifdef HAVE_ANDROID_OS
     if (reason == NULL) {
         reboot(RB_AUTOBOOT);
     } else {
         const char *chars = env->GetStringUTFChars(reason, NULL);
         __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                  LINUX_REBOOT_CMD_RESTART2, (char*) chars);
         env->ReleaseStringUTFChars(reason, chars);  // In case it fails.
     }
     jniThrowIOException(env, errno);
 #endif
 }
 上面的各种宏定义于文件:bionic/libc/kernel/common/linux/reboot.h
 #define LINUX_REBOOT_MAGIC1 0xfee1dead
 #define LINUX_REBOOT_MAGIC2 672274793
 #define LINUX_REBOOT_MAGIC2A 85072278
 #define LINUX_REBOOT_MAGIC2B 369367448
 #define LINUX_REBOOT_MAGIC2C 537993216
 
 /*
  * Commands accepted by the _reboot() system call.
  *
  * RESTART     Restart system using default command and mode.
  * HALT        Stop OS and give system control to ROM monitor, if any.
  * CAD_ON      Ctrl-Alt-Del sequence causes RESTART command.
  * CAD_OFF     Ctrl-Alt-Del sequence sends SIGINT to init task.
  * POWER_OFF   Stop OS and remove all power from system, if possible.
  * RESTART2    Restart system using given command string.
  * SW_SUSPEND  Suspend system using software suspend if compiled in.
  * KEXEC       Restart system using a previously loaded Linux kernel
  */
 #define LINUX_REBOOT_CMD_RESTART 0x01234567
 #define LINUX_REBOOT_CMD_HALT 0xCDEF0123
 #define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
 #define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
 #define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
 #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
 #define LINUX_REBOOT_CMD_KEXEC 0x45584543
 
 bionic/libc/include/sys/reboot.h
 #define RB_AUTOBOOT     LINUX_REBOOT_CMD_RESTART
 #define RB_HALT_SYSTEM  LINUX_REBOOT_CMD_HALT
 #define RB_ENABLE_CAD   LINUX_REBOOT_CMD_CAD_ON
 #define RB_DISABLE_CAD  LINUX_REBOOT_CMD_CAD_OFF
 #define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF

你可能感兴趣的:(android,恢复出厂设置)