近段时间关注Android系统的reboot部分,在应用程序调用reboot函数可以实现重启。顺着流程看看reboot如何运作。
在Watchdog.java文件里,有一例:
void rebootSystem(String reason) {
Slog.i(TAG, "Rebooting system because: " + reason);
//注册PowerManager服务
PowerManagerService pms = (PowerManagerService) ServiceManager.getService("power");
//调用reboot()方法
pms.reboot(reason);
}
下面顺着往下走,
Step1:
在PowerManagerService.java文件
public void reboot(String reason)
{
// REBOOT权限
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
…
final String finalReason = reason;
Runnable runnable = new Runnable() {
public void run() {
synchronized (this) {
//这里执行reboot
ShutdownThread.reboot(mContext, finalReason, false);
}
}
};
…..
}
Step2:
在ShutdownThread.java文件:
public final class ShutdownThread extends Thread {
…
//这里是reboot函数
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;// mReboot为true
….
}
public void run() {
…
rebootOrShutdown(mReboot, mRebootReason);//其实这里执行是reboot
}
public static void rebootOrShutdown(boolean reboot, String reason) {
// reboot为真,执行Power.reboot()方法
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
try {
Power.reboot(reason);
} catch (Exception e) {
Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
}
} else if (SHUTDOWN_VIBRATE_MS > 0) {
…
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
Power.shutdown();//执行Power类的shutdown方法
}
}
Step3:
在Power.java文件:
public class Power{
…
public static void reboot(String reason) throws IOException
{
rebootNative(reason);//调用JNI的reboo方法
}
//声明rebootNative
private static native void rebootNative(String reason) throws IOException ;
…
}
Step4:
在android_os_Power.cpp文件:
// #define HAVE_ANDROID_OS 1
static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
{
sync();
#ifdef HAVE_ANDROID_OS
// 字符reason为空的话,执行自动重起
if (reason == NULL) {
reboot(RB_AUTOBOOT);
} else {
//有原因的重启
const char *chars = env->GetStringUTFChars(reason, NULL);
//调用__reboot()
__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
}
Step5:
关于reboot()方法的来头,在bionic\libc\unistd\reboot.c文件里:
int reboot (int mode)
{
//传NULL到__reboot函数
return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL );
}
总的来说,归结一点是__reboot()函数。
Step6:
看看__reboot()的来由,在bionic\libc\arch-arm\syscalls\__reboot.S文件里:
// # define __NR_SYSCALL_BASE 0x900000
//#define __NR_reboot (__NR_SYSCALL_BASE + 88)
.text
.type __reboot, #function
.globl __reboot
.align 4
.fnstart
__reboot:
.save {r4, r7}
stmfd sp!, {r4, r7}
ldr r7, =__NR_reboot
swi #0
ldmfd sp!, {r4, r7}
movs r0, r0
bxpl lr
b __set_syscall_errno
.fnend
这是__reboot函数用汇编实现,用C语言来调用。关机部分可以这样来分析。