在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

更多相关文章

  1. C语言函数的递归(上)
  2. 【代码】android通过criteria选择合适的地理位置服务
  3. android 控件之checkbox自定义样式
  4. Android(安卓)自定义控件 GuideView 引导界面
  5. Android(安卓)-- ImageLoader简析
  6. Android(安卓)Studio 中build.gradle文件的详细解析
  7. Mac Android(安卓)Studio快捷键
  8. Android(安卓)AIDL详解
  9. Fragment的交互及管理

随机推荐

  1. SmartFoxServer: massive multiplayer ga
  2. Android之设置页面(PreferenceActivity使
  3. Dojo mobile TweetView 系列教程之五 —
  4. 2011.09.26(2)——— android sample之Note
  5. android 常用的数据库表以及操作说明
  6. 4.11笔记 android database打开方式,ios反
  7. android用户界面-组件Widget-画廊视图Gal
  8. Android动态显示隐藏密码输入框的内容
  9. Android(安卓)IPC 通讯机制源码分析
  10. 安卓入门.RelativeLayout相对布局1