Android 關機、重啟、recovery流程分析
以Android5.1的程式碼來分析。
上層應用可以透過PowerManager來實現關機、重啟、進recovery等功能。比如RecoverySystem 中就是使用PM使系統進入recovery模式:
原始碼路徑:frameworks/base/core/java/android/os/RecoverySystem.java
private static void bootCommand(Context context, String... args) throws IOException { ...... // Having written the command file, go ahead and reboot PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); pm.reboot(PowerManager.REBOOT_RECOVERY); ...... }
PowerManager會透過aidl與PowerManagerService互動,reboot帶reason引數,像重啟、關機、恢復出廠設定等等;
原始碼路徑:frameworks/base/core/java/android/os/IPowerManager.aidl
interface IPowerManager{ // WARNING: The first five methods must remain the first five methods because their // transaction numbers must not change unless IPowerManager.cpp is also updated. void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws, String historyTag); void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, int uidtoblame); void releaseWakeLock(IBinder lock, int flags); void updateWakeLockUids(IBinder lock, in int[] uids); ...... void reboot(boolean confirm, String reason, boolean wait); void shutdown(boolean confirm, boolean wait); void crash(String message); void setStayOnSetting(int val); void boostScreenBrightness(long time); // temporarily overrides the screen brightness settings to allow the user to // see the effect of a settings change without applying it immediately void setTemporaryScreenBrightnessSettingOverride(int brightness); void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj); // sets the attention light (used by phone app only) void setAttentionLight(boolean on, int color); }
原始碼路徑:frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
@Override // Binder call public void reboot(boolean confirm, String reason, boolean wait) { ...... final long ident = Binder.clearCallingIdentity(); try { shutdownOrRebootInternal(false, confirm, reason, wait); } finally { Binder.restoreCallingIdentity(ident); } }
public static void lowLevelShutdown() { SystemProperties.set("sys.powerctl", "shutdown"); }
public static void lowLevelReboot(String reason) { if (reason == null) { reason = ""; } long duration; if (reason.equals(PowerManager.REBOOT_RECOVERY)) { SystemProperties.set("ctl.start", "pre-recovery"); duration = 300 * 1000L; } else { SystemProperties.set("sys.powerctl", "reboot," + reason); duration = 20 * 1000L; } try { Thread.sleep(duration); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }
shutdownOrRebootInternal根據reason來決定是呼叫ShutdownThread的reboot或者shutdown:
private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm, final String reason, boolean wait) { ...... Runnable runnable = new Runnable() { @Override public void run() { synchronized (this) { if (shutdown) { ShutdownThread.shutdown(mContext, confirm); } else { ShutdownThread.reboot(mContext, reason, confirm); } ......
不管是關機還是重啟都是走shutdownInner 原始碼路徑:frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
public static void reboot(final Context context, String reason, boolean confirm) { mReboot = true; mRebootSafeMode = false; mRebootReason = reason; shutdownInner(context, confirm); } ...... public static void shutdown(final Context context, boolean confirm) { mReboot = false; mRebootSafeMode = false; shutdownInner(context, confirm); } ...... static void shutdownInner(final Context context, boolean confirm) { ...... beginShutdownSequence(context); } }
看一下beginShutdownSequence
private static void beginShutdownSequence(Context context) { ...... // start the thread that initiates shutdown sInstance.mHandler = new Handler() { }; sInstance.start(); }
已經start了,我們就去run裡面瞧一瞧幹了什麼事,就對“REBOOT_SAFEMODE_PROPERTY”設定了1或者0,然後呼叫rebootOrShutdown。
/** * Makes sure we handle the shutdown gracefully. * Shuts off power regardless of radio and bluetooth state if the alloted time has passed. */ public void run() { ....//關機或者重啟前的一些處理 String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : ""); SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);...... if (mRebootSafeMode) { SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1"); } ...... rebootOrShutdown(mReboot, mRebootReason); }
rebootOrShutdown中會呼叫PMS的lowLevelReboot或者lowLevelShutdown,這兩個函式在上面有展示
public static void rebootOrShutdown(boolean reboot, String reason) { if (reboot) { Log.i(TAG, "Rebooting, reason: " + reason); PowerManagerService.lowLevelReboot(reason);//重啟 Log.e(TAG, "Reboot failed, will attempt shutdown instead"); } else if (SHUTDOWN_VIBRATE_MS > 0) { ....//關機震動相關處理 // Shutdown power Log.i(TAG, "Performing low-level shutdown..."); PowerManagerService.lowLevelShutdown();//關機 }
再回過頭去看PowerManagerService裡面的lowLevelShutdown,發現關機、重啟、recovery等是透過設定Properties來實現控制的:SystemProperties.set("sys.powerctl"......
Android系統開始會執行init,而init會去解析執行init.rc中的內容。其中就有對於Properties “sys.powerctl ”的處理(當“sys.powerctl 發生改變時觸發進行powerctl 操作)。 位於原始碼:system/core/rootdir/init.rc
on property:sys.powerctl=* powerctl ${sys.powerctl}
而powerctl 是init的內嵌命令,在init原始碼中: 原始碼路徑:system/core/init/builtins.c
int do_powerctl(int nargs, char **args) { ...... if (strncmp(command, "shutdown", 8) == 0) { cmd = ANDROID_RB_POWEROFF; len = 8; } else if (strncmp(command, "reboot", 6) == 0) { cmd = ANDROID_RB_RESTART2; len = 6; } else { ERROR("powerctl: unrecognized command '%s'n", command); return -EINVAL; } if (command[len] == ',') { reboot_target = &command[len + 1]; } else if (command[len] == '
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/430/viewspace-2809611/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux 關機重啟流程分析(轉)Linux
- Android關機重啟實現Android
- Android使用程式碼實現關機/重啟Android
- Android應用啟動流程分析Android
- Android Activity啟動流程原始碼分析Android原始碼
- Android原始碼分析:Activity啟動流程Android原始碼
- [譯]Android Application 啟動流程分析AndroidAPP
- Android 7.0 應用啟動流程分析Android
- Android應用關閉,重啟Android
- centos關機與重啟命令CentOS
- Linux重啟和關機Linux
- Ubuntu關機、重啟、登出命令Ubuntu
- android 系統重啟與關機:java 程式碼實現AndroidJava
- Linux關機和重啟命令Linux
- redhat shutdown關機及重啟示例Redhat
- Solaris關機重啟命令小結
- Android8.1 開關VOLTE流程分析Android
- Android系統原始碼分析–Service啟動流程Android原始碼
- Android系統原始碼分析--Service啟動流程Android原始碼
- Centos6.7關機和重啟命令CentOS
- Mac 設定定時關機、重啟、睡眠Mac
- Linux關機重啟命令詳解Linux
- centos關機與重啟命令詳解CentOS
- Linux的關機與重啟命令Linux
- Flutter Android 端 FlutterView 相關流程原始碼分析FlutterAndroidView原始碼
- android展訊平臺 重啟案例分析(二)Android
- Activity啟動流程分析
- activity 啟動流程分析
- Unbound啟動流程分析
- Flutter Android 端 FlutterEngine Java 相關流程原始碼分析FlutterAndroidJava原始碼
- win10關機後重啟怎麼回事_win10電腦一關機就重啟如何解決Win10
- win10為什麼關機後自動重啟 win10關機後自動重啟的方法Win10
- win10關機後自動重啟怎麼辦 win10關機都會重啟解決方法Win10
- FlutterEngin啟動流程&androidFlutterAndroid
- win10怎麼強制關機重啟 win10當機強制重啟快捷鍵Win10
- Linux關機與重啟的命令詳解Linux
- 關於整合抽取程式重啟後的現象分析
- Android 系統原始碼-1:Android 系統啟動流程原始碼分析Android原始碼