Android 源码分析 - 电源 - 处理流程

        涉及源文件:

        frameworks/base/services/java/com/android/server/power/PowerManagerService.java

        前面都会调用到updatePowerStateLocked。

  1. updatePowerStateLocked
    1. updateIsPoweredLocked(更新充电状态)
    2. updateStayOnLocked(保持唤醒配置状态)
    3. updateWakeLockSummaryLocked(统计待机锁的状态)
    4. updateUserActivitySummaryLocked(用户操作状态,空闲超时)
    5. updateWakefulnessLocked(判断是否进入待机状态,如果有变化循环执行以上三步)
    6. updateDreamLocked(与屏保应用有关)
    7. updateDisplayPowerStateLocked(屏幕状态,启动自动待机)
    8. if (mDisplayReady)(检查到屏幕状态更新请求处理完成,屏幕状态更新后会有回调)
      1. sendPendingNotificationsLocked(发送状态广播)
    9. updateSuspendBlockerLocked(分别对WakeLock和Display锁进行处理)

充电状态

        与充电状态相关的变量有:mIsPowered、mPlugType、mBatteryLevel。他们都是从mBatteryService(BatteryService)获取。插入状态(mPlugType)包括电源适配器(AC)、USB、无线充电(WIRELESS)。

  1. updateIsPoweredLocked(更新充电状态)
    1. mBatteryService.isPowered
    2. mBatteryService.getPlugType
    3. mBatteryService.getBatteryLevel
    4. mWirelessChargerDetector.update
    5. if(shouldWakeUpWhenPluggedOrUnpluggedLocked)
      1. wakeUpNoUpdateLocked
        1. mNotifier.onWakeUpStarted
    6. userActivityNoUpdateLocked(充电状态更新也算作用户行为)
      1. mNotifier.onUserActivity
    7. if (dockedOnWirelessCharger)
      1. mNotifier.onWirelessChargingStarted

配置状态

        用户可以配置充电状态下保存唤醒,另外“最大关闭屏幕超时时间”(mMaximumScreenOffTimeoutFromDeviceAdmin )的配置也有影响。mStayOn最终反应在变量mStayOn上。

  1. updateStayOnLocked(保持配置状态)
    1. mBatteryService.isPowered(mStayOnWhilePluggedInSetting)

唤醒锁状态

        唤醒锁状态记录在mWakeLockSummary中,对每种类型的硬件,用一位表示。类型包括:

  1. 处理器(CPU)
  2. 屏幕灯光(SCREEN_BRIGHT)
  3. 屏幕灰暗(SCREEN_DIM)
  4. 按钮灯光(BUTTON_BRIGHT)
  5. 屏幕贴近关闭(PROXIMITY_SCREEN_OFF)
  6. 保持唤醒(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消息。

决定唤醒状态

        决定是否要进入睡眠、打盹状态。下列状态将保持设备唤醒:

  1. mStayOn,根据充电状态和保持唤醒配置,需要保持唤醒
  2. mProximityPositive,检测到靠近
  3. mWakeLockSummary,WAKE_LOCK_STAY_AWAKE,根据唤醒锁状态,需要保持唤醒
  4. mUserActivitySummary,最近有用户操作,保持唤醒

        下面的设置打开会进入打盹状态:

  1. mDreamsActivateOnSleepSetting
  2. mDreamsActivateOnDockSetting且mDockState,接在底座上

     在进入睡眠状态时(goToSleepNoUpdateLocked),发送通知mNotifier.onGoToSleepStarted。下面是大概的流程:

  1. updateWakefulnessLocked
    1. if (isItBedTimeYetLocked -> isBeingKeptAwakeLocked)
      1. if (shouldNapAtBedTimeLocked)
        1. napNoUpdateLocked
      2. else
        1. goToSleepNoUpdateLocked

更新梦境状态

  • PowerManagerService处理状态更新。
  1. updatePowerStateLocked
    1. updateDreamLocked
      1. scheduleSandmanLocked
        1. mHandler.sendMessage(MSG_SANDMAN)(异步)
  • PowerManagerService异步处理
  1. handleSandman
    1. canDreamLocked
      1. mIsPowered
      2. isBeingKeptAwakeLocked
    2. mDreamManager.startDream
    3. handleDreamFinishedLocked
      1. if(isItBedTimeYetLocked)
        1. goToSleepNoUpdateLocked
      2. else
        1. wakeUpNoUpdateLocked
      3. updatePowerStateLocked
    4. mDreamManager.stopDream()

更新显示状态

DisplayPowerController,控制逻辑,包含DisplayPowerState,使用PowerManagerService的线程处理事件。

DisplayPowerState,状态管理,包含一个DisplayBlanker

DisplayBlanker,执行功能接口,由PowerManagerService.DisplayBlankerImpl实现,最终调用了mDisplayManagerService的功能。

  • PowerManagerService处理状态更新。
  1. updatePowerStateLocked
    1. updateDisplayPowerStateLocked
      1. DisplayPowerController.requestPowerState
  • DisplayPowerController处理更新请求。
  1. requestPowerState
    1. sendUpdatePowerStateLocked
      1. mHandler.sendMessage(MSG_UPDATE_POWER_STATE,外部传入的looper线程,即PowerManagerService的线程
  2. updatePowerState
    1. animateScreenBrightness(屏幕渐渐变亮)
      1. mScreenBrightnessRampAnimator.animateTo
        1. postCallback
          1. mChoreographer.postCallback (Choreographer.CALLBACK_ANIMATION, mCallback)(图形驱动的回调)
    2. setScreenOn
      1. DisplayPowerState.setScreenOn
  3. RampAnimator<T>.mCallback.run
    1. mProperty.setValue
      1. DisplayPowerState.SCREEN_BRIGHTNESS
        1. DisplayPowerState.setScreenBrightness
    2. postCallback
  • DisplayPowerState处理更新请求。
  1. setScreenOn
    1. scheduleScreenUpdate(排队处理)
      1. postScreenUpdateThreadSafe
        1. mHandler.post(mScreenUpdateRunnable)(当前线程队列)
  2. scheduleScreenUpdate
    1. scheduleScreenUpdate
  3. mScreenUpdateRunnable.run
    1. mPhotonicModulator.setState
      1. AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask)
  4. PhotonicModulator.mTask.run
    1. mDisplayBlanker.unblankAllDisplays
    2. LightsService.Light.setBrightness(背光,LIGHT_ID_BACKLIGHT)
    3. mDisplayBlanker.blankAllDisplays
    4. postScreenUpdateThreadSafe(再次检查是否有排队请求)
  • PowerManagerService.DisplayBlankerImpl转发屏幕开关请求。
  1. blankAllDisplays
    1. mDisplayManagerService.blankAllDisplaysFromPowerManager
    2. nativeSetInteractive(false)
    3. nativeSetAutoSuspend(true)
  2. unblankAllDisplays
    1. nativeSetAutoSuspend(false)
    2. nativeSetInteractive(true)
    3. mDisplayManagerService.unblankAllDisplaysFromPowerManager
  • DisplayManagerService开关显示设备
  1. blankAllDisplaysFromPowerManager
    1. updateAllDisplayBlankingLocked
      1. updateDisplayBlankingLocked
        1. DisplayDevice.blankLocked
        2. DisplayDevice.unblankLocked
    2. unblankAllDisplaysFromPowerManager
      1. updateDisplayBlankingLocked
  • LightsService设置背光亮度
  1. setBrightness
    1. setLightLocked
      1. setLight_native
  • PowerManagerService的native层转发请求
  1. nativeSetInteractive
    1. power_module->setInteractive(power HAL该接口是空实现)
  2. nativeSetAutoSuspend
    1. autosuspend_enable(实现在libsuspend中)
      1. autosuspend_earlysuspend_enable
        1. write(“sys/power/state”, “mem”)
    2. autosuspend_disable(实现在libsuspend中)
      1. autosuspend_earlysuspend_disable
        1. write(“sys/power/state”, “on”)

更新唤醒锁

        涉及源文件:

        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处理状态更新。
  1. updatePowerStateLocked
    1. updateSuspendBlockerLocked(分别对WakeLocks和Display锁进行处理)
      1. SuspendBlockerImpl.acquire
        1. nativeAcquireSuspendBlocker
      2. SuspendBlockerImpl.release
        1. nativeReleaseSuspendBlocker(mName)
  • PowerManagerService的native层转发请求。
  1. nativeAcquireSuspendBlocker
    1. acquire_wake_lock
  2. nativeReleaseSuspendBlocker
    1. 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

  1. onWakeLockAcquired
  2. onWakeLockReleased
  3. onScreenOn
  4. onScreenOff
  5. onScreenBrightness

        具体的:

  1. onWakeLockAcquired
    1. mBatteryStats.noteStartWakelockFromSource电池服务统计进程、用户持有锁的状态、时间
    2. mBatteryStats.noteStartWakelock(workSource为NULL)
  2. onWakeLockReleased
    1. mBatteryStats.noteStopWakelockFromSource电池服务统计进程、用户持有锁的状态、时间
    2. mBatteryStats.noteStopWakelock(workSource为NULL)
  3. onScreenOn
    1. mBatteryStats.noteScreenOn
  4. onScreenOff
    1. mBatteryStats.noteScreenOff
  5. onScreenBrightness
    1. mBatteryStats.noteScreenBrightness
  6. onWakeUpStarted
    1. mScreenOnBlocker.acquire(在通知WindowManagerPolicy时,保持屏幕开启)
    2. updatePendingBroadcastLocked
  7. onGoToSleepFinished
    1. updatePendingBroadcastLocked
  8. onUserActivity
    1. mBatteryStats.noteUserActivity
    2. mHandler.sendMessage(MSG_USER_ACTIVITY)
  9. onWirelessChargingStarted
    1. mSuspendBlocker.acquire
    2. mHandler.sendMessage(MSG_WIRELESS_CHARGING_STARTED)

        内部广播排队处理

  1. updatePendingBroadcastLocked
    1. mSuspendBlocker.acquire(发送广播,广播处理过程中保持CPU不待机)
      1. mHandler.sendMessage(MSG_BROADCAST)

        处理消息(MSG_USER_ACTIVITY)

  1. sendUserActivity
    1. mPolicy.userActivity

        处理消息(MSG_WIRELESS_CHARGING_STARTED)

  1. sendUserActivity
    1. playWirelessChargingStartedSound
      1. mSuspendBlocker.release

        处理消息(MSG_BROADCAST)

  1. sendNextBroadcast
    1. sendWakeUpBroadcast
      1. WindowManagerPolicy.screenTurningOn(mScreenOnListener)
      2. ActivityManagerNative.wakingUp()
      3. 发送Intent.ACTION_SCREEN_ON
    2. sendGoToSleepBroadcast (goToSleepReason)
      1. WindowManagerPolicy.screenTurnedOff
      2. ActivityManagerNative.goingToSleep()
      3. 发送Intent.ACTION_SCREEN_OFF
    3. finishPendingBroadcastLocked
      1. mSuspendBlocker.release

        处理回调

  1. mScreenOnListener
    1. mScreenOnBlocker.release
  2. mWakeUpBroadcastDone
    1. sendNextBroadcast
  3. mGoToSleepBroadcastDone.onReceive
    1. 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处理关机按键。
  1. interceptKeyBeforeQueueing
    1. interceptPowerKeyDown
      1. mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout())
  2. mPowerLongPress.run()
    1. com.android.internal.R.integer.config_longPressOnPowerBehavior
    2. FactoryTest.isLongPressOnPowerOffEnabled()
      1. SystemProperties.getInt("factory.long_press_power_off", 0)
    3. case LONG_PRESS_POWER_GLOBAL_ACTIONS
      1. showGlobalActionsDialog
        1. GlobalActions.showDialog
  • GlobalActions显示对话框。
  1. showDialog
    1. handleShow
      1. GlobalActionsDialog.createDialog
  2. onClick
    1. SinglePressAction.onPress
      1. WindowManagerFuncs.shutdown(true)
  • WindowManagerFuncs实际由WindowManagerService实现。
  1. shutdown
    1. ShutdownThread.shutdown(mContext, confirm)
  • ShutdownThread执行关机。
  1. shutdown
    1. shutdownInner(context, confirm)
      1. if (confirm)(确认对话框)
        1. sConfirmDialog = new AlertDialog.Builder (context)
      2. else
        1. beginShutdownSequence(context)
  2. sConfirmDialog.onClick
    1. beginShutdownSequence(context)
  3. beginShutdownSequence
    1. new ProgressDialog(context)(关机进度条,圆圈)
    2. sInstance.start()
  4. run
    1. shutdownRadios
    2. rebootOrShutdown
      1. PowerManagerService.lowLevelReboot(reason)
        1. SystemProperties.set("sys.powerctl", "reboot," + reason);
      2. PowerManagerService.lowLevelShutdown()
        1. SystemProperties.set("sys.powerctl", "shutdown");
  • 在init.rc里面,响应属性sys.powerctl的变化

on property:sys.powerctl=*

    powerctl ${sys.powerctl}

  • powerctl命令由do_powerctl处理
  1. do_powerctl
    1. android_reboot(cmd, 0, reboot_target)
  • android_reboot调用c库的reboot
  1. android_reboot
    1. reboot(RB_AUTOBOOT)
    2. reboot(RB_POWER_OFF)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值