当前位置:   article > 正文

Android电源键亮灭屏流程

android power键亮屏流程

一、整体框架介绍

  • 电源键亮灭屏流程从框架上分硬件层,驱动层,Java框架层和Natvie服务层;

  • 整个流程分为两部分,一部分是电源按键事件传递流程,一部分是亮灭屏处理流程;

  • 中间通过一个策略类来衔接,决定按键动作是做亮屏还是灭屏动作。

二、电源键传递流程

1. 内核空间电源键传递流程

各层的介绍如下:

  • 设备驱动层:将底层的硬件输入转化为统一事件形式,向核心层传递;

  • 核心层:为驱动层提供输入设备注册与操作接口,通知事件处理层对事件进行处理;

  • 事件处理层:主要是和用户空间交互,提供设备节点来给用户空间访问;

  • 用户空间: 从事件处理层获得事件,进行进一步的事件分发和业务处理。

电源键的处理流程是:

1)按键驱动初始化的时候首先通过request_irq进行中断的注册;

2)当电源键按下和抬起时候,发生中断,中断处理函数被执行,调用input接口input_report_key和input_sync来进行事件的上报;

3)事件通过核心层和事件层后,到达用户空间,这样用户空间的程序就可以通过/dev/input节点和getEvents获得按键事件。

2. 用户空间电源键传递流程

InputReader线程的loop里面,通过EventHub的getEvents函数获得按键事件,然后传递给processEventsLocked来处理。

processEventsLocked依次调用processEventsForDeviceLocked()->InputDevice::process()->KeyboardInputMapper::process()->processKey()函数。

processKey会调用listener的notifyKey,这个linstener是谁呢?

跟踪赋值流程可以找到,getListener获得的是在InputManager开始初始化时候生成的InputDispatch对象,所以按键传递给了InputDispatch的notifyKey。

InputDispatch::notifyKey对事件的处理,首先调用interceptKeyBeforeQueueing,让策略类在入队前能处理该事件。

interceptKeyBeforeQueueing经过InputManager和WindowManager的InputManagerCallback调用,最终执行到PhoneWindowManager的interceptKeyBeforeQueueing方法,具体做了如下动作:

1)将result去掉了ACTION_PASS_TO_USER标志位;

2)调用interceptPowerKeyDown和interceptPowerKeyUp分别处理电源键的按下和抬起,这两个处理函数我们在下一章的亮灭屏流程中详细介绍。

调用完interceptKeyBeforeQueueing之后,接着调enqueueInboundEventLocked将该事件入队。

InputReader线程将事件入队后,InputDispatch线程在looper处理里面,会将事件取出,然后调用dispatchKeyLocked进行事件的派发处理。

如果判断是KEYCODE_POWER,isValidGlobalKey会返回true, 接着PhoneWindowManager的interceptKeyBeforeDispatching则返回-1。

interceptKeyBeforeDispatching返回的-1赋值给InputDispatcher里面delay,判断小于0,则会将interceptKeyResult标志设置为INTERCEPT_KEY_RESULT_SKIP。

在dispatchKeyLocked函数里面会判断上面的interceptKeyResult标志,如果是INTERCEPT_KEY_RESULT_SKIP,则Power键会drop掉,不会传递给应用。

 

电源键传递流程总结一下,在入队前通过传递给策略类的interceptKeyBeforeQueueing来处理具体业务,而在派发流程里面则会忽略掉。

三、亮灭屏处理流程

1. 亮屏处理流程

亮屏的触发是电源键按下时候触发的,我们来看下interceptPowerKeyDown,判断interactive为灭屏状态,则调用wakeUpFromPowerKey唤醒系统。

wakeUpFromPowerKey调用到PowerManagerService的wakeUp函数。

PowerManagerService wakeUp进行权限检查后,调用到wakeUpInternal。

可以看到主要做了两件事,调用wakeUpNoUpdateLocked,如果返回true,则调用updatePowerStateLocked。

我们先来看下wakeUpNoUpdateLocked里面做了哪些动作,首先做了一些状态判断和变量赋值,然后执行:

1)setWakefulnessLocked,设置wakefulness为WAKEFULNESS_AWAKE唤醒状态,并发送亮屏广播;

2)mNotifier.onWakeUp,通知BatteryStatsService、AppService系统服务唤醒状态变化;

3)userActivityNoUpdateLocked更新用户活动时间,重置超时灭屏时间。

接下来我们看updatePowerStateLocked,这个里面主要是在updateDisplayPowerStateLocked里面处理亮屏的关键动作:

1)updateDisplayPowerStateLocked调用requestPowerState设置mPendingRequestLocked变量;

2)调用sendUpdatePowerStateLocked发送MSG_UPDATE_POWER_STATE消息,MSG_UPDATE_POWER_STATE的消息处理里面调用updatePowerState;

3)updatePowerState调用animateScreenStateChange;

4)根据状态判断后调用setScreenState(Display.STATE_ON)->

DisplayPowerController::setScreenState()->DisplayPowerState::setScreenState(),通过scheduleScreenUpdate启动一个mScreenUpdateRunnable;

5)mScreenUpdateRunnable里面调用mPhotonicModulator.setState(mScreenState, brightnessState),

赋值mPendingBacklight变量后通知PhotonicModulator线程去处理,调用到mBlanker.requestDisplayState;

6)DisplayManagerService在initPowerManagement初始化的时候会注册requestDisplayState的处理,具体处理步骤是:requestDisplayState->requestGlobalDisplayStateInternal->applyGlobalDisplayStateLocked->updateDisplayStateLocked;

7)LocalDisplayAdapter::requestDisplayStateLocked调用背光的设置函数setDisplayBrightness。

至此SurfaceControl再通过native方法通过binder通信通知surfaceflinger设置背光。

SurfaceFlinger通过调用Hal层的实现,操作内核背光节点,从而完成背光的设置。

2. 灭屏处理流程

灭屏是按下电源键后抬起的时候触发,流程这块我们来看interceptPowerKeyUp,做了一些长按和多次点击判断后,正常短按点击会跑到powerPress函数。

powerPress进一步调用goToSleepFromPowerButton函数。

进而调用到PowerManagerService的goToSleep,进行权限检查后调用goToSleepInternal。

这里可以看到调用了goToSleepNoUpdateLocked和updatePowerStateLocked,也就是在goToSleepNoUpdateLocked里面设置灭屏状态。

1)在goToSleepNoUpdateLocked()中完成发送了将要休眠的通知;

2) 修改了Wakefulness,将其置成WAKEFULNESS_DOZING,将mDirty置位DIRTY_WAKEFULNESS。

更多的实际动作在updatePowerStateLocked()中完成,背光变化流程和3.1章节介绍的亮屏流程是一样的。

 

亮灭屏流程总结一下,亮屏流程通过wakeUpNoUpdateLocked设置唤醒状态,灭屏流程通过goToSleepNoUpdateLocked设置灭屏状态,最终都是调用updatePowerStateLocked来完成最终背光变化动作。

 

 

参考链接:

[1] https://blog.csdn.net/qq_35865125/article/details/80637809

[2] https://www.jianshu.com/p/961207f442f9

长按关注

内核工匠微信

Linux 内核黑科技 | 技术文章 | 精选教程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/889003
推荐阅读
相关标签
  

闽ICP备14008679号