涉及源文件:
frameworks/base/services/java/com/android/server/power/PowerManagerService.java
前面都会调用到updatePowerStateLocked。
- updatePowerStateLocked
- updateIsPoweredLocked(更新充电状态)
- updateStayOnLocked(保持唤醒配置状态)
- updateWakeLockSummaryLocked(统计待机锁的状态)
- updateUserActivitySummaryLocked(用户操作状态,空闲超时)
- updateWakefulnessLocked(判断是否进入待机状态,如果有变化循环执行以上三步)
- updateDreamLocked(与屏保应用有关)
- updateDisplayPowerStateLocked(屏幕状态,启动自动待机)
- if (mDisplayReady)(检查到屏幕状态更新请求处理完成,屏幕状态更新后会有回调)
- sendPendingNotificationsLocked(发送状态广播)
- updateSuspendBlockerLocked(分别对WakeLock和Display锁进行处理)
充电状态
与充电状态相关的变量有:mIsPowered、mPlugType、mBatteryLevel。他们都是从mBatteryService(BatteryService)获取。插入状态(mPlugType)包括电源适配器(AC)、USB、无线充电(WIRELESS)。
- updateIsPoweredLocked(更新充电状态)
- mBatteryService.isPowered
- mBatteryService.getPlugType
- mBatteryService.getBatteryLevel
- mWirelessChargerDetector.update
- if(shouldWakeUpWhenPluggedOrUnpluggedLocked)
- wakeUpNoUpdateLocked
- mNotifier.onWakeUpStarted
- wakeUpNoUpdateLocked
- userActivityNoUpdateLocked(充电状态更新也算作用户行为)
- mNotifier.onUserActivity
- if (dockedOnWirelessCharger)
- mNotifier.onWirelessChargingStarted
配置状态
用户可以配置充电状态下保存唤醒,另外“最大关闭屏幕超时时间”(mMaximumScreenOffTimeoutFromDeviceAdmin )的配置也有影响。mStayOn最终反应在变量mStayOn上。
- updateStayOnLocked(保持配置状态)
- mBatteryService.isPowered(mStayOnWhilePluggedInSetting)
唤醒锁状态
唤醒锁状态记录在mWakeLockSummary中,对每种类型的硬件,用一位表示。类型包括:
- 处理器(CPU)
- 屏幕灯光(SCREEN_BRIGHT)
- 屏幕灰暗(SCREEN_DIM)
- 按钮灯光(BUTTON_BRIGHT)
- 屏幕贴近关闭(PROXIMITY_SCREEN_OFF)
- 保持唤醒(STAY_AWAKE))
每种锁都需要CPU保持。然而,在请求待机时,只有PARTIAL_WAKE_LOCK能够阻止待机,其他类型的锁都失效。保持唤醒也只有在当前处于唤醒状态时才会设置。屏幕贴近关闭有些特殊,是指用户靠近(靠近传感器)设备时,需要关闭屏幕。
用户操作状态
用户操作状态记录在mUserActivitySummary中,状态包括屏幕点亮(SCREEN_BRIGHT)、屏幕灰暗(SCREEN_DIM)、屏幕关闭(0)。屏幕保持时间是下面三个值的最小值,但是至少10秒(MINIMUM_SCREEN_OFF_TIMEOUT):
screen_off_timeout,存在与系统配置数据库Settings.System
setMaximumScreenOffTimeoutFromDeviceAdmin(),由设备管理员策略管理设置
setUserActivityTimeoutOverrideFromWindowManager(),由WindowManager根据前台Activity设置
屏幕灰暗时间占整个时间的20%,但是不超过7秒(SCREEN_DIM_DURATION)。
如果还存在点亮状态,将设置一个定时器,定时发送MSG_USER_ACTIVITY_TIMEOUT消息。
决定唤醒状态
决定是否要进入睡眠、打盹状态。下列状态将保持设备唤醒:
- mStayOn,根据充电状态和保持唤醒配置,需要保持唤醒
- mProximityPositive,检测到靠近
- mWakeLockSummary,WAKE_LOCK_STAY_AWAKE,根据唤醒锁状态,需要保持唤醒
- mUserActivitySummary,最近有用户操作,保持唤醒
下面的设置打开会进入打盹状态:
- mDreamsActivateOnSleepSetting
- mDreamsActivateOnDockSetting且mDockState,接在底座上
在进入睡眠状态时(goToSleepNoUpdateLocked),发送通知mNotifier.onGoToSleepStarted。下面是大概的流程:
- updateWakefulnessLocked
- if (isItBedTimeYetLocked -> isBeingKeptAwakeLocked)
- if (shouldNapAtBedTimeLocked)
- napNoUpdateLocked
- else
- goToSleepNoUpdateLocked
- if (shouldNapAtBedTimeLocked)
- if (isItBedTimeYetLocked -> isBeingKeptAwakeLocked)
更新梦境状态
- PowerManagerService处理状态更新。
- updatePowerStateLocked
- updateDreamLocked
- scheduleSandmanLocked
- mHandler.sendMessage(MSG_SANDMAN)(异步)
- scheduleSandmanLocked
- updateDreamLocked
- PowerManagerService异步处理
- handleSandman
- canDreamLocked
- mIsPowered
- isBeingKeptAwakeLocked
- mDreamManager.startDream
- handleDreamFinishedLocked
- if(isItBedTimeYetLocked)
- goToSleepNoUpdateLocked
- else
- wakeUpNoUpdateLocked
- updatePowerStateLocked
- if(isItBedTimeYetLocked)
- mDreamManager.stopDream()
- canDreamLocked
更新显示状态
DisplayPowerController,控制逻辑,包含DisplayPowerState,使用PowerManagerService的线程处理事件。
DisplayPowerState,状态管理,包含一个DisplayBlanker
DisplayBlanker,执行功能接口,由PowerManagerService.DisplayBlankerImpl实现,最终调用了mDisplayManagerService的功能。
- PowerManagerService处理状态更新。
- updatePowerStateLocked
- updateDisplayPowerStateLocked
- DisplayPowerController.requestPowerState
- updateDisplayPowerStateLocked
- DisplayPowerController处理更新请求。
- requestPowerState
- sendUpdatePowerStateLocked
- mHandler.sendMessage(MSG_UPDATE_POWER_STATE,外部传入的looper线程,即PowerManagerService的线程)
- sendUpdatePowerStateLocked
- updatePowerState
- animateScreenBrightness(屏幕渐渐变亮)
- mScreenBrightnessRampAnimator.animateTo
- postCallback
- mChoreographer.postCallback (Choreographer.CALLBACK_ANIMATION, mCallback)(图形驱动的回调)
- postCallback
- mScreenBrightnessRampAnimator.animateTo
- setScreenOn
- DisplayPowerState.setScreenOn
- animateScreenBrightness(屏幕渐渐变亮)
- RampAnimator<T>.mCallback.run
- mProperty.setValue
- DisplayPowerState.SCREEN_BRIGHTNESS
- DisplayPowerState.setScreenBrightness
- DisplayPowerState.SCREEN_BRIGHTNESS
- postCallback
- mProperty.setValue
- DisplayPowerState处理更新请求。
- setScreenOn
- scheduleScreenUpdate(排队处理)
- postScreenUpdateThreadSafe
- mHandler.post(mScreenUpdateRunnable)(当前线程队列)
- postScreenUpdateThreadSafe
- scheduleScreenUpdate(排队处理)
- scheduleScreenUpdate
- scheduleScreenUpdate
- mScreenUpdateRunnable.run
- mPhotonicModulator.setState
- AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask)
- mPhotonicModulator.setState
- PhotonicModulator.mTask.run
- mDisplayBlanker.unblankAllDisplays
- LightsService.Light.setBrightness(背光,LIGHT_ID_BACKLIGHT)
- mDisplayBlanker.blankAllDisplays
- postScreenUpdateThreadSafe(再次检查是否有排队请求)
- PowerManagerService.DisplayBlankerImpl转发屏幕开关请求。
- blankAllDisplays
- mDisplayManagerService.blankAllDisplaysFromPowerManager
- nativeSetInteractive(false)
- nativeSetAutoSuspend(true)
- unblankAllDisplays
- nativeSetAutoSuspend(false)
- nativeSetInteractive(true)
- mDisplayManagerService.unblankAllDisplaysFromPowerManager
- DisplayManagerService开关显示设备
- blankAllDisplaysFromPowerManager
- updateAllDisplayBlankingLocked
- updateDisplayBlankingLocked
- DisplayDevice.blankLocked
- DisplayDevice.unblankLocked
- updateDisplayBlankingLocked
- unblankAllDisplaysFromPowerManager
- updateDisplayBlankingLocked
- updateAllDisplayBlankingLocked
- LightsService设置背光亮度
- setBrightness
- setLightLocked
- setLight_native
- setLightLocked
- PowerManagerService的native层转发请求
- nativeSetInteractive
- power_module->setInteractive(power HAL该接口是空实现)
- nativeSetAutoSuspend
- autosuspend_enable(实现在libsuspend中)
- autosuspend_earlysuspend_enable
- write(“sys/power/state”, “mem”)
- autosuspend_earlysuspend_enable
- autosuspend_disable(实现在libsuspend中)
- autosuspend_earlysuspend_disable
- write(“sys/power/state”, “on”)
- autosuspend_earlysuspend_disable
- autosuspend_enable(实现在libsuspend中)
更新唤醒锁
涉及源文件:
frameworks/base/services/java/com/android/server/power/PowerManagerService.java
frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp
hardware/libhardware_legacy/power/power.c
根据唤醒锁状态(mWakeLockSummary)中是否需要CPU(WAKE_LOCK_CPU)决定是否需要持有驱动层锁:“PowerManagerService.WakeLocks”。
判断是否需要持有驱动层锁:“PowerManagerService.Display”。在屏幕状态更新的过程中,需要持有,或者靠近屏幕关闭的情况下也需要。
- PowerManagerService处理状态更新。
- updatePowerStateLocked
- updateSuspendBlockerLocked(分别对WakeLocks和Display锁进行处理)
- SuspendBlockerImpl.acquire
- nativeAcquireSuspendBlocker
- SuspendBlockerImpl.release
- nativeReleaseSuspendBlocker(mName)
- SuspendBlockerImpl.acquire
- updateSuspendBlockerLocked(分别对WakeLocks和Display锁进行处理)
- PowerManagerService的native层转发请求。
- nativeAcquireSuspendBlocker
- acquire_wake_lock
- nativeReleaseSuspendBlocker
- release_wake_lock
- HAL层处理。
write(/sys/power/wake_lock, id, strlen(id));
write(/sys/power/wake_unlock, id, strlen(id));
状态通知
Notifier运行在system server 主线程。
持有驱动层唤醒锁“PowerManagerService.Broadcasts”和ScreenOnBlocker。在更新显示状态时,更新请求(mDisplayPowerRequest)中有一个变量(blockScreenOn)记录屏幕保持。
通知到电池统计mBatteryStats
- onWakeLockAcquired
- onWakeLockReleased
- onScreenOn
- onScreenOff
- onScreenBrightness
具体的:
- onWakeLockAcquired
- mBatteryStats.noteStartWakelockFromSource电池服务统计进程、用户持有锁的状态、时间
- mBatteryStats.noteStartWakelock(workSource为NULL)
- onWakeLockReleased
- mBatteryStats.noteStopWakelockFromSource电池服务统计进程、用户持有锁的状态、时间
- mBatteryStats.noteStopWakelock(workSource为NULL)
- onScreenOn
- mBatteryStats.noteScreenOn
- onScreenOff
- mBatteryStats.noteScreenOff
- onScreenBrightness
- mBatteryStats.noteScreenBrightness
- onWakeUpStarted
- mScreenOnBlocker.acquire(在通知WindowManagerPolicy时,保持屏幕开启)
- updatePendingBroadcastLocked
- onGoToSleepFinished
- updatePendingBroadcastLocked
- onUserActivity
- mBatteryStats.noteUserActivity
- mHandler.sendMessage(MSG_USER_ACTIVITY)
- onWirelessChargingStarted
- mSuspendBlocker.acquire
- mHandler.sendMessage(MSG_WIRELESS_CHARGING_STARTED)
内部广播排队处理
- updatePendingBroadcastLocked
- mSuspendBlocker.acquire(发送广播,广播处理过程中保持CPU不待机)
- mHandler.sendMessage(MSG_BROADCAST)
- mSuspendBlocker.acquire(发送广播,广播处理过程中保持CPU不待机)
处理消息(MSG_USER_ACTIVITY)
- sendUserActivity
- mPolicy.userActivity
处理消息(MSG_WIRELESS_CHARGING_STARTED)
- sendUserActivity
- playWirelessChargingStartedSound
- mSuspendBlocker.release
- playWirelessChargingStartedSound
处理消息(MSG_BROADCAST)
- sendNextBroadcast
- sendWakeUpBroadcast
- WindowManagerPolicy.screenTurningOn(mScreenOnListener)
- ActivityManagerNative.wakingUp()
- 发送Intent.ACTION_SCREEN_ON
- sendGoToSleepBroadcast (goToSleepReason)
- WindowManagerPolicy.screenTurnedOff
- ActivityManagerNative.goingToSleep()
- 发送Intent.ACTION_SCREEN_OFF
- finishPendingBroadcastLocked
- mSuspendBlocker.release
- sendWakeUpBroadcast
处理回调
- mScreenOnListener
- mScreenOnBlocker.release
- mWakeUpBroadcastDone
- sendNextBroadcast
- mGoToSleepBroadcastDone.onReceive
- sendNextBroadcast
关机流程
Android4.4的关机流程与4.2的区别在于,4.2使用jni调用顶层的reboot功能,而4.4中通过系统属性实现java到c的调用。
涉及源文件:
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
frameworks/base/policy/src/com/android/internal/policy/impl/GlobalActions.java
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
frameworks/base/services/java/com/android/server/power/ShutdownThread.java
frameworks/base/services/java/com/android/server/power/PowerManagerService.java
system/core/rootdir/init.rc
system/core/init/builtins.c
system/core/libcutils/android_reboot.c
- PhoneWindowManager处理关机按键。
- interceptKeyBeforeQueueing
- interceptPowerKeyDown
- mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout())
- interceptPowerKeyDown
- mPowerLongPress.run()
- com.android.internal.R.integer.config_longPressOnPowerBehavior
- FactoryTest.isLongPressOnPowerOffEnabled()
- SystemProperties.getInt("factory.long_press_power_off", 0)
- case LONG_PRESS_POWER_GLOBAL_ACTIONS
- showGlobalActionsDialog
- GlobalActions.showDialog
- showGlobalActionsDialog
- GlobalActions显示对话框。
- showDialog
- handleShow
- GlobalActionsDialog.createDialog
- handleShow
- onClick
- SinglePressAction.onPress
- WindowManagerFuncs.shutdown(true)
- SinglePressAction.onPress
- WindowManagerFuncs实际由WindowManagerService实现。
- shutdown
- ShutdownThread.shutdown(mContext, confirm)
- ShutdownThread执行关机。
- shutdown
- shutdownInner(context, confirm)
- if (confirm)(确认对话框)
- sConfirmDialog = new AlertDialog.Builder (context)
- else
- beginShutdownSequence(context)
- if (confirm)(确认对话框)
- shutdownInner(context, confirm)
- sConfirmDialog.onClick
- beginShutdownSequence(context)
- beginShutdownSequence
- new ProgressDialog(context)(关机进度条,圆圈)
- sInstance.start()
- run
- shutdownRadios
- rebootOrShutdown
- PowerManagerService.lowLevelReboot(reason)
- SystemProperties.set("sys.powerctl", "reboot," + reason);
- PowerManagerService.lowLevelShutdown()
- SystemProperties.set("sys.powerctl", "shutdown");
- PowerManagerService.lowLevelReboot(reason)
- 在init.rc里面,响应属性sys.powerctl的变化
on property:sys.powerctl=* powerctl ${sys.powerctl} |
- powerctl命令由do_powerctl处理
- do_powerctl
- android_reboot(cmd, 0, reboot_target)
- android_reboot调用c库的reboot
- android_reboot
- reboot(RB_AUTOBOOT)
- reboot(RB_POWER_OFF)