Android电源键亮灭屏流程
内核工匠 2022-09-29

一、整体框架介绍


  • 电源键亮灭屏流程从框架上分硬件层,驱动层,Java框架层和Natvie服务层;
  • 整个流程分为两部分,一部分是电源按键事件传递流程,一部分是亮灭屏处理流程;
  • 中间通过一个策略类来衔接,决定按键动作是做亮屏还是灭屏动作。


二、电源键传递流程

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

各层的介绍如下:
  • 设备驱动层:将底层的硬件输入转化为统一事件形式,向核心层传递;
  • 核心层:为驱动层提供输入设备注册与操作接口,通知事件处理层对事件进行处理;
  • 事件处理层:主要是和用户空间交互,提供设备节点来给用户空间访问;
  • 用户空间: 从事件处理层获得事件,进行进一步的事件分发和业务处理。


电源键的处理流程是:

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

2)当电源键按下和抬起时候,发生中断,中断处理函数被执行,调用input接口input_report_keyinput_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里面处理亮屏的关键动作:

1updateDisplayPowerStateLocked调用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;


7LocalDisplayAdapter::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来完成最终背光变化动作。
声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • 电源
  • DC
  • AC
  • 稳压
  • 直流稳压电源的组成

    直流稳压电源的组成直流稳压电源主要由四部分组成:电源变压器、整流电路、滤波电路和稳压电路。1.电源变压器电源变压器是一种软磁电磁元件,功能是功率传送、电压变换和

    昨天
  • 图解小型电源变压器组成

    小型电源变压器主要由铁心、绕组、固定支架、绝缘骨架及绝缘物等组成,如图4—3所示。(1)铁心。常见小型电源变压器的铁心有E形、口形、C形(分cD和ED形)和F形

    昨天
  • 揭秘新老款MacBook Pro的USB Type-C有何不同

      尽管参与USB-IF的多家巨头,像是苹果与Intel都以具体移动告诉市场,USBtype-c就是未来,不过在未来的美好来临前,使用者却仍需面对连接埠的阵痛期

    11-24
  • 利用无线探头测量感应电源的电压频率转换器

    为执行长期监视任务的便携式遥测系统供电,向人们提出了有趣的设计挑战。电池不适合于某些关键性应用,且在这些环境中,设计人员一般用无线感应链路来传输功率与数据。感应链路由一个驱动固定初级线圈的射频发射器与一个为便携式装置提供电源的松耦合次级线圈组成。对设计工程师来说,测量发射功率相当重要,因为它会限制设计人员可包含至便携式装置中的电路数量。但不幸的是,传统测试设备不适合执行该任务,因为标准电压探头会拾...

    11-24
  • 全面讲解pwm波形发生器

    波形发生器在生活中有诸多应用,不过对于波形发生器,大家并非均有所了解。此外,波形发生器种类较多,无法在短时间内全部掌握。本文中,将为大家讲解pwm波形发生器,并

    11-24
  • 线交互式UPS逆变器特性

    一、功能部件输入开关市电正常时,开关导通;市电停电时,开关自动断开,防止逆变器向电网反向馈电。自动稳压有市电供电时,可粗略稳压并吸收部分电网干扰。其稳压方式与后

    11-23
  • LTC3643 用作针对 3.3V 电压轨的备份电源解决方案

    在嵌入式系统需要可靠供电的电信、工业和汽车应用中,数据丢失是一个关切的问题。供电的突然中断会在硬盘和闪存器执行读写操作时损坏数据。我们常常使用电池、电容器和超级

    11-23
  • 如何测量开关电源稳定性

    随着电子,自控,航天,通讯,医疗器械等技术不断向深度和广度的发展,势必要求为期供电的电源要有更高的稳定性,即不仅要有好的线性调节率、负载调节率还要有快速的动态负

    11-23
  • 如何对一个简单的峰值电流限制进行改进

    故障保护是所有电源控制器都有的一个重要功能。几乎所有应用都要求使用过载保护。对于峰值电流模式控制器而言,可以通过限制最大峰值电流来轻松实现这个功能。在非连续反向

    11-23
  • NTC PTC热敏电阻在电源电路中的作用

    本文以问答的形式介绍了NTC PTC热敏电阻在电源电路中的作用。问题1: NTC电阻串联在交流电路中主要是起什么作用!它是怎样工作!请大侠指点!谢谢!问题2:

    11-23
下载排行榜
更多
广告