Android 关机/重启原因分析
monkey测试关机/重启问题分析(一)
monkey测试关机/重启问题分析(二)
monkey测试关机/重启问题分析(三)
关机流程可以参考以下其它人的文章https://blog.csdn.net/qq_29413633/article/details/120848128
触发流程可能不同,比如长按关机、点击dialog关机按钮关机等等。
1、上层关机流程
最终回走到ShutdowmThread。
本问接monkey测试关机/重启问题分析(二)中的流程继续往下,从systemui中调用mBarService.shutdown();最终走到frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
1.1、StatusBarManagerService
public void shutdown() {
enforceStatusBarService();
String reason = PowerManager.SHUTDOWN_USER_REQUESTED;
ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);//这里就是ShutdownCheckPoints log打印的地方,用来跟踪是哪个进程调用了关机
final long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.prepareForPossibleShutdown();
// ShutdownThread displays UI, so give it a UI context.
mHandler.post(() ->
ShutdownThread.shutdown(getUiContext(), reason, false));//这里调用到ShutdownThread
} finally {
Binder.restoreCallingIdentity(identity);
}
}
1.2、ShutdowmThread.run()
public void run() {
TimingsTraceLog shutdownTimingLog = newTimingsLog();
shutdownTimingLog.traceBegin("SystemServerShutdown");
...
//关机之前关掉其它service等一系列操作。
...
// Remaining work will be done by init, including vold shutdown
rebootOrShutdown(mContext, mReboot, mReason);
}
1.3、ShutdownThread.rebootOrShutdown()
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
//add for sreen off earlier
if (sInstance.mPowerManager != null) {
Log.i(TAG, "rebootOrShutdown:goToSleep");
sInstance.mPowerManager.goToSleep(SystemClock.uptimeMillis());
}
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
PowerManagerService.lowLevelReboot(reason);//重启
Log.e(TAG, "Reboot failed, will attempt shutdown instead");
reason = null;
} else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {
// vibrate before shutting down
Vibrator vibrator = new SystemVibrator(context);
try {
vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES);
} catch (Exception e) {
// Failure to vibrate shouldn't interrupt shutdown. Just log it.
Log.w(TAG, "Failed to vibrate during shutdown.", e);
}
// vibrator is asynchronous so we need to wait to avoid shutting down too soon.
try {
Thread.sleep(SHUTDOWN_VIBRATE_MS);
} catch (InterruptedException unused) {
}
}
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown(reason);//关机
}
1.4、PowerManagerService.lowLevelShutdown(reason);
public static void lowLevelShutdown(String reason) {
if (reason == null) {
reason = "";
}
String chargeTypeString = "";
if(mChargeType) {
chargeTypeString = ",charging";
}
//通过设置系统属性关机
SystemProperties.set("sys.powerctl", "shutdown," + reason + chargeTypeString);
}
上层Java代码就到这里,关机和重启都是设置系统属性后,底层c代码监听节点进行真正的操作。
SystemProperties.set("sys.powerctl", "reboot," + reason);//重启
SystemProperties.set("sys.powerctl", "shutdown," + reason + chargeTypeString);//关机
2、底层关机流程