您的位置:首页 > 移动开发 > Android开发

android 恢复出厂设置流程

2015-04-27 17:38 387 查看
在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) {

        
c22f
     ...

         }

         ...

     }

 }

 流程: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息