Android7.0 PowerManagerService亮灭屏分析(二)

本文深入分析Android7.0 PowerManagerService如何处理亮屏操作,涉及DisplayPowerController、DisplayPowerState、PhoneWindowManager和WindowManagerService的角色。在亮屏过程中,系统等待所有窗口绘制完成,通过DisplayManagerService请求电源状态,更新屏幕亮度,并利用渐变动画点亮屏幕。关键步骤包括设置ScreenState、更新设备状态以及调用SurfaceControl设置显示功率模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在PowerManagerService中对各种状态进行判断后,将其数值封装进DisplayPowerRequest中传入DisplayPowerController中进一步处理。在亮屏过程中DisplayPowerController会根据传过来的数值来设置新的电源状态为亮屏,然后调用DisplayPowerState来对状态进行设置,在分析DisplayPowerState时会具体讲解。由于此时ColorFade level(就是在手机屏幕的一层surface,当level为0是为一层黑帧,level为1.0时为透明)的值为0,表示屏幕还没有绘制好,所以此时需要block screen直到window界面绘制完成。当需要亮屏时调用PhoneWindowManager的screenTurningOn函数,通知window屏幕就要点亮了。然后调用WMS中函数waitForAllWindowsDrawn函数等待将所有需要绘制的window绘制完成后回调回来,超时时间为1000ms。在WMS中获取需要绘制的window将其加入mWaitingForDrawn中等待绘制,通过检查mWaitingForDrawn是否为空来判断,window是否绘制完成。此时screenTurningOn函数就执行完了,剩下的就是等待windows绘制完成。


DisplayManagerService.java中的LocalService继承了DisplayManagerInternal.java, 所以就会调用LocalService的requestPowerState函数请求电源状态. 

    private final class LocalService extends DisplayManagerInternal {
        @Override
        public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
                SensorManager sensorManager) {    //初始化函数在PowerManagerService的systemReady函数中调用
            synchronized (mSyncRoot) {
                DisplayBlanker blanker = new DisplayBlanker() {   //创建blanker对象
                    @Override
                    public void requestDisplayState(int state, int brightness) {
                        // The order of operations is important for legacy reasons.
                        if (state == Display.STATE_OFF) {
                            requestGlobalDisplayStateInternal(state, brightness);
                        }

                        callbacks.onDisplayStateChange(state);

                        if (state != Display.STATE_OFF) {
                            requestGlobalDisplayStateInternal(state, brightness);
                        }
                    }
                };
                mDisplayPowerController = new DisplayPowerController(    //创建DisplayPowerController对象
                        mContext, callbacks, handler, sensorManager, blanker);
            }
        }

        @Override
        public boolean requestPowerState(DisplayPowerRequest request,
                boolean waitForNegativeProximity) {
            return mDisplayPowerController.requestPowerState(request,
                    waitForNegativeProximity);     //调用DisplayPowerController请求电源状态
        }
       //.....
}

    在DisplayPowerController中通过Handler发送MSG_UPDATE_POWER_STATE消息调用updatePowerState来更新电源状态. updatePowerState也是一个非常核心的函数,在该函数中将PowerManagerService中传过来的参数获取出来根据policy获取设备的请求状态是ON, OFF还是DOZE, 应用距离传感器, 将最终的请求状态调用DisplayPowerState进行设置. 判断设备是否打开了自动亮度调节, 计算最终屏幕要达到的目标亮度并通过亮度渐变动画慢慢的点亮屏幕,最终变为高亮.

    private void updatePowerState() {
        // Update the power state request.
        final boolean mustNotify;
        boolean mustInitialize = false;
        boolean autoBrightnessAdjustmentChanged = false;

        synchronized (mLock) {
            mPendingUpdatePowerStateLocked = false;
            if (mPendingRequestLocked == null) {
                return; // wait until first actual power request
            }

            if (mPowerRequest == null) { //判断mPowerRequest是否为NULL,如果为空新创建一个, 否则直接将mPendingRequestLocked复制给他  
                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
                mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
                mPendingWaitForNegativeProximityLocked = false;
                mPendingRequestChangedLocked = false;
                mustInitialize = true;
            } else if (mPendingRequestChangedLocked) {
                autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
                        != mPendingRequestLocked.screenAutoBrightnessAdjustment);
                mPowerRequest.copyFrom(mPendingRequestLocked);
                mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
                mPendingWaitForNegativeProximityLocked = false;
                mPendingRequestChangedLocked = false;
                mDisplayReadyLocked = false;
            }

            mustNotify = !mDisplayReadyLocked;
        }

        // Initialize things the first time the power state is changed.
        if (mustInitialize) {
            initialize();//power state第一次发生变化时需要做一些初始化,如:创建DisplayPowerState, 亮灭屏动画,亮度渐变动画实例等 
        }

        // Compute the basic display state using the policy.
        // We might override this below based on other factors.
        int state;
        int brightness = PowerManager.BRIGHTNESS_DEFAULT;//设置屏幕默认亮度
        boolean performScreenOffTransition = false;
        switch (mPowerRequest.policy) {
            case DisplayPowerRequest.POLICY_OFF: //设置设备状态为OFF 
                state = Display.STATE_OFF;
                performScreenOffTransition = true; //灭屏有过渡动画  
                break;
            case DisplayPowerRequest.POLICY_DOZE:  //设置设备状态为DOZE
                if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
                    state = mPowerRequest.dozeScreenState;
                } else {
                    state = Display.STATE_DOZE;
                }
                if (!mAllowAutoBrightnessWhileDozingConfig) {
                    brightness = mPowerRequest.dozeScreenBrightness;//如果在xml文件中配置了相关属性,就将dozeScreenBrightness赋给亮度值
                }
                break;
            case DisplayPowerRequest.POLICY_DIM:
            case DisplayPowerRequest.POLICY_BRIGHT:
            default:
                state = Display.STATE_ON;//如果policy为DIM, BRIGHT的话,设备状态都为ON
                break;
        }
        assert(state != Display.STATE_UNKNOWN);

        // Apply the proximity sensor.
        if (mProximitySensor != null) {  //距离传感器相关处理
            if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE) {
                    mScreenOffBecauseOfProximity = true;
                    sendOnProximityPositiveWithWakelock();
                }
            } else if (mWaitingForNegativeProximity
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
            } else {
                setProximitySensorEnabled(false);
                mWaitingForNegativeProximity = false;
            }
            if (mScreenOffBecauseOfProximity
                    && mProximity != PROXIMITY_POSITIVE) {
                mScreenOffBecauseOfProximity = false;
                sendOnProximityNegativeWithWakelock();
            }
        } else {
            mWaitingForNegativeProximity = false;
        }
        if (mScreenOffBecauseOfProximity) {
            state = Display.STATE_OFF;//如果因为距离传感器灭屏设置设备状态为OFF
        }

        // Animate the screen state change unless already animating.
        // The transition may be deferred, so after this point we will use the
        // actual state instead of the desired one.
        animateScreenStateChange(state, performScreenOffTransition);//处理屏幕状态改变
        state = mPowerState.getScreenState();//获取新的屏幕状态 

        // Use zero brightness when screen is off.
        if (state == Display.STATE_OFF) {
            brightness = PowerManager.BRIGHTNESS_OFF; //如果新的状态是灭屏的话设置brightness为0
        }

        // Configure auto-brightness.
        boolean autoBrightnessEnabled = false;
        if (mAutomaticBrightnessController != null) {
            final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
                    && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
            autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                    && brightness < 0;
            final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
                    && mPowerRequest.brightnessSetByUser;
            mAutomaticBrightnessController.configure(autoBrightnessEnabled,
                    mPowerRe
<think>好的,我现在要处理用户关于Android 11电源键唤醒设备的具体流程的问题。首先,我需要回忆一下Android系统处理电源键事件的机制,尤其是Android 11中的变化。根据用户提供的引用,特别是引用[1]和[2],涉及InputManagerService和PowerManagerService的交互。 首先,当用户按下电源键时,这会触发一个硬件中断,然后被Linux内核的输入子系统捕获,生成一个Input事件。接下来,这个事件会被传递到Android框架层。根据引用[2]中的代码流程,InputManagerService负责处理这个事件,然后调用PowerManagerService的相关方法。需要确认Android 11中是否有流程上的变化,但根据引用[3]提到的Android 7.0的流程,可能基本结构相似,但可能有新的类或方法。 接下来,需要详细描述从按键按下到设备唤醒的各个阶段。可能涉及PhoneWindowManager的interceptKeyBeforeQueueing方法,这里判断是否是电源键事件,并调用相应的wakeUp方法。引用[5]提到在时处理电源键的长按事件,但用户的问题是关于唤醒,所以可能需要关注设备处于休眠状态时按下电源键的流程。 另外,引用[4]提到Linux下的休眠和唤醒机制,包括GPIO和UART等唤醒源,这可能与硬件层相关,Android系统在此基础上进行封装。在Android 11中,电源键作为唤醒源,通过驱动上报事件,然后逐层传递到框架层。 需要确保步骤中的每个关键点都有对应的引用支持,例如InputManagerService和PowerManagerService的交互,以及具体的代码调用链。同时,注意用户提供的引用中的方法名和类名是否正确,例如PhoneWindowManager的interceptPowerKeyDown和wakeUpFromPowerKey方法。 可能还需要考虑电源键的长按和短按处理,但用户问题聚焦在唤醒,所以主要关注短按唤醒流程。同时,确保区分休眠和唤醒的不同路径,引用[1]提到InputManagerService处理PowerKey事件后调用PowerManagerService的唤醒接口,这应该是唤醒流程的核心。 总结步骤:硬件中断 → 内核驱动 → Input子系统 → InputManagerService → PhoneWindowManager → PowerManagerService → 唤醒显示等操作。每个步骤需要对应到具体的引用,例如引用[2]中的调用链。 最后,生成相关问题时要围绕电源键处理、休眠唤醒机制、涉及的组件等,确保问题与主题相关,并引导进一步学习。</think>### Android 11电源键唤醒设备流程分析Android 11中,电源键唤醒设备的流程涉及**硬件驱动层、Linux内核层和Android框架层**的协同工作,核心流程如下: --- #### **1. 硬件与驱动层** - **电源键触发**:用户按下电源键时,硬件生成中断信号。 - **GPIO驱动响应**:通过GPIO驱动捕获电源键状态变化,上报给Linux内核输入子系统[^4]。 --- #### **2. Linux内核层** - **输入事件传递**:内核的输入子系统将事件封装为`KeyEvent`(类型为`KEY_POWER`),通过`/dev/input`节点传递到用户空间的`InputReader`。 --- #### **3. Android框架层** **a. InputManagerService处理** - **事件解析**:`InputReader`读取事件后,由`InputDispatcher`将事件分发到`PhoneWindowManager`。 - **按键拦截**:调用`PhoneWindowManager.interceptKeyBeforeQueueing()`,判断是否为电源键事件并拦截[^2]。 **b. 唤醒流程触发** - **短按唤醒逻辑**:若设备处于休眠状态,触发`interceptPowerKeyDown()`方法,调用`wakeUpFromPowerKey()`。 - **唤醒接口调用**:通过`PowerManagerService.wakeUp()`唤醒设备,最终执行`wakeDisplayGroup()`以点幕[^2][^3]。 **代码调用链简化**: ``` PhoneWindowManager.interceptKeyBeforeQueueing() → interceptPowerKeyDown() → wakeUpFromPowerKey() → PowerManager.wakeUp()PowerManagerService.wakeUp() → wakeDisplayGroup() ``` --- #### **4. 显示与系统状态更新** - **幕点**:`DisplayPowerController`控制背光与显示状态,完成。 - **系统唤醒**:`PowerManagerService`更新全局电源状态为`AWAKE`,并释放唤醒锁[^1]。 --- ### **关键设计特点** 1. **分层处理**:硬件事件逐层传递至应用框架,确保模块化。 2. **状态机管理**:`PowerManagerService`通过状态机管理休眠/唤醒逻辑[^3]。 3. **超时撤销机制**:若电源键抬起前未超时,会取消延时触发的长按事件[^5]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值