美文网首页
Android DisplayManagerService--0

Android DisplayManagerService--0

作者: DarcyZhou | 来源:发表于2023-11-27 08:18 被阅读0次

    本文转载自:Android R DisplayManagerService模块(3) DMS部分亮灭屏流

    本文基于Android 11.0源码分析

    1.概述

      在分析PMS灭屏流程和亮屏流程时,侧重于PMS部分的流程,DMS中涉及到的流程没有进行分析,只说到请求DMS去设置屏幕亮度和Display状态就略过了。

      在DMS模块分析中,会将侧重点放在Display相关的流程上,这篇文章中将会对亮灭屏过程中PMS向DMS发起请求后的流程做详细分析,从而了解设置亮度、Display状态的整个逻辑。

      在DMS模块中,和PMS交互的工作由DisplayPowerController进行处理,如控制屏幕亮度、Display状态、PSensor的灭屏。DisplayPowerController属于DMS模块,但它当中的核心逻辑是运行在PMS线程的,保证了和PMS的独立性。它和PMS不共享任何状态,PMS向DMS发起请求,DisplayPowerController接收请求,并在请求处理完毕后,通过回调的方式通知PMS完成改变。

      DisplayPowerController对象是在PMS启动过程中进行创建:

    // frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
        public void systemReady(IAppOpsService appOps) {
            ......
                // Initialize display power management.
                mDisplayManagerInternal.initPowerManagement(
                        mDisplayPowerCallbacks, mHandler, sensorManager);
            ......
        }
    
    

    DMS中在Local Service中进行创建:

    // frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
            @Override
            public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
                    SensorManager sensorManager) {
                synchronized (mSyncRoot) {
                    DisplayBlanker blanker = new DisplayBlanker() {
                    ......
                    // 创建DisplayPowerController对象
                    mDisplayPowerController = new DisplayPowerController(
                            mContext, callbacks, handler, sensorManager, blanker,
                            mDisplayDevices.get(Display.DEFAULT_DISPLAY));
                    mSensorManager = sensorManager;
                }
                mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
            }
    

    DisplayPowerController在控制状态和亮度的设置时,主要通过另外两个类对象:

    • DisplayPowerState:代表当前Display整体状态,状态和亮度的更新都会交给它,让它做进一步处理;

    • LocalDisplayAdapter:代表默认屏幕的适配器,DisplayPowerState会将Display状态和亮度交给它,由它将状态和亮度设置给连接的物理屏。

      下面继续从亮灭屏流程开始。

    2.requestPowerState()发起请求

      PMS中调用updateDisplayPowerStateLocked()方法请求Display进行更新,这个方法最终调用DisplayPowerController#requesetPowerState()方法:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
    /**
     * @param request PMS中封装的请求参数
     * @param waitForNegativeProximity和Proximity wakelock释放后PSensor锁的动作有关
     * @return true表示请求处理完成,false表示请求没有处理完成
     */
    public boolean requestPowerState(DisplayPowerRequest request,
            boolean waitForNegativeProximity) {
        synchronized (mLock) {
            boolean changed = false;
            // 是否在PSensor WakeLock锁释放后,延迟解除Psensor监听
            if (waitForNegativeProximity
                    && !mPendingWaitForNegativeProximityLocked) {
                mPendingWaitForNegativeProximityLocked = true;
                changed = true;
            }
            // 开机后第一次进入
            if (mPendingRequestLocked == null) {
                mPendingRequestLocked = new DisplayPowerRequest(request);
                changed = true;
            } else if (!mPendingRequestLocked.equals(request)) {  // 请求发生变化
                mPendingRequestLocked.copyFrom(request);
                changed = true;
            }
            // 表示需要处理新请求,先给PMS返回false,表示没有完成
            if (changed) {
                mDisplayReadyLocked = false;
            }
            // 开始处理新请求
            if (changed && !mPendingRequestChangedLocked) {
                // 表示request发生变化,即将更新全局request
                mPendingRequestChangedLocked = true;
                sendUpdatePowerStateLocked();
            }
    
            return mDisplayReadyLocked;
        }
    }
    

    以上方法中,能否将此次请求作为一个新请求处理,由以下三个条件确定:

    • waitForNegativeProximity是否为true;

    • 如果开机第一次进入该函数,则mPendingRequestLocked的值为null,则实例化代表将要请求的DisplayPowerRequest对象;

    • 本次请求对象和上次请求对象是否相同。

      如果waitForNegativeProximity为true,则表示在释放PROXIMITY_SCREEN_OFF_WAKE_LOCK类型WakeLock时,如果PSenor上报靠近事件而处于灭屏状态,那么必须等待PSensor上报远离事件并亮屏后,才会解除对PSensor的监听。在释放wakelock时使用PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY的标记时,该值为true。

    可以尝试下,申请PROXIMITY_SCREEN_OFF_WAKE_LOCK锁后,在遮挡灭屏情况下,分别用release()和release(RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY)释放锁,会看到不一样的效果。

    mPendingRequestChangedLocked变量用于表示上次请求已经处理完毕。DisplayPowerRequest对象代表一个请求对象,封装了许多的请求参数:

    // frameworks/base/core/java/android/hardware/display/DisplayManagerInternal.java
    public static final class DisplayPowerRequest {
        public int policy;                      // 请求的Display状态
        public boolean useProximitySensor;      // 是否持有PROXIMITY_SCREEN_OFF_WAKE_LOCK锁
        public int screenBrightnessOverride;    // 是否要覆盖亮度,尤其是来自WindowMananger的亮度
        public boolean useAutoBrightness;       // 是否使用自动亮度
        public boolean lowPowerMode;            // 是否进入了低电量模式
        public float screenLowPowerBrightnessFactor;   // 低电量模式下调整亮度因子
        public boolean boostScreenBrightness;   // 是否使用了亮度增强
        public int dozeScreenBrightness;        // 进入Doze状态后的屏幕亮度
        public int dozeScreenState;             // 进入Doze状态后的Display状态
    

    之后将在sendUpdatePowerStateLocked()方法中,通过Handler进入到PMS线程中开始处理请求:

    private void sendUpdatePowerStateLocked() {
        if (!mPendingUpdatePowerStateLocked) {
            // 表示需要更新power state
            mPendingUpdatePowerStateLocked = true;
            Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
            mHandler.sendMessage(msg);
        }
    }
    

    之后将进入updatePowerState()方法中,这个方法是DisplayPowerController中的核心方法,对请求的解析和处理就是它来完成。

    3.updatePowerState()更新状态

      updatePowerState()方法非常庞大,处理亮灭屏、调节亮度、Display状态的更新,都会在这里进行处理。该方法的完整代码如下:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
    private void updatePowerState() {
        // Update the power state request.
        final boolean mustNotify;   // 是否要通知PMS完成请求处理
        final int previousPolicy;
        boolean mustInitialize = false;  //是否要进行初始化
        int brightnessAdjustmentFlags = 0;  // 自动亮度调整因子标记
        mBrightnessReasonTemp.set(null);   // 记录亮度变化原因
        // ####################################################Part 1####################################################
        synchronized (mLock) {
            mPendingUpdatePowerStateLocked = false;// 代表"即将开始更新",这里已经开始了,所以重置为true
            if (mPendingRequestLocked == null) {
                return; // wait until first actual power request
            }
    
            if (mPowerRequest == null) {// 只有系统开机后第一次会进入该if代码块
                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
                mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
                mPendingWaitForNegativeProximityLocked = false;
                mPendingRequestChangedLocked = false;
                mustInitialize = true;
                previousPolicy = DisplayPowerRequest.POLICY_BRIGHT;
            } else if (mPendingRequestChangedLocked) {// 更新全局DisplayPowerRequest
                previousPolicy = mPowerRequest.policy;  
                mPowerRequest.copyFrom(mPendingRequestLocked);// 更新mPowerRequest
                mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
                mPendingWaitForNegativeProximityLocked = false;
                mPendingRequestChangedLocked = false; // 重置
                mDisplayReadyLocked = false;
            } else {
                previousPolicy = mPowerRequest.policy;
            }
    
            mustNotify = !mDisplayReadyLocked;
        }
    
        if (mustInitialize) {
            initialize(); //初始化亮灭屏动画、DisplayPowerState对象...
        }
        // ####################################################Part 2####################################################
        int state;
        float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        boolean performScreenOffTransition = false;  // 是否执行灭屏动画
        switch (mPowerRequest.policy) { // 将根据policy确定Display要设置的状态
            case DisplayPowerRequest.POLICY_OFF:// policy为off,会将Display状态设置为OFF
                state = Display.STATE_OFF;
                performScreenOffTransition = true;
                break;
            case DisplayPowerRequest.POLICY_DOZE: // policy为doze,则会根据mPowerRequest.dozeScreenState确定Display的状态,默认为DOZE状态
                if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
                    state = mPowerRequest.dozeScreenState;
                } else {
                    state = Display.STATE_DOZE;
                }
                if (!mAllowAutoBrightnessWhileDozingConfig) {// 是否支持在Doze状态时使用自动亮度,默认false
                    brightnessState = mPowerRequest.dozeScreenBrightness;// 将亮度设置为PMS中指定的Doze状态亮度
                    mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);// 记录亮度变化原因——doze状态的亮度
                }
                break;
            case DisplayPowerRequest.POLICY_VR:  // policy为VR时,设置Display状态为VR
                state = Display.STATE_VR;
                break;
            case DisplayPowerRequest.POLICY_DIM:  // policy为DIM或者BRIGHT时,都表示亮屏,所以将Display状态设置为ON
            case DisplayPowerRequest.POLICY_BRIGHT:
            default:
                state = Display.STATE_ON;
                break;
        }
        assert(state != Display.STATE_UNKNOWN);
        // #################################################### Part 3 ####################################################
        if (mProximitySensor != null) {
            // 如果持有Proximity WakeLock锁,且请求Display状态不为OFF
            if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {   
                // 注册PSensor监听
                setProximitySensorEnabled(true);   
                // 上报了靠近事件
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE) {  
                    // 代表“是否由于PSensor收到靠近时间而灭屏”
                    mScreenOffBecauseOfProximity = true;    
                    // 回调通知PMS PSensor收到靠近事件
                    sendOnProximityPositiveWithWakelock();  
                }
            // 如果释放Proximity WakeLock锁时带有1标记,发现由于PSensor灭屏且还未收到远离事件,则继续等待,并保持PSensor监听
            } else if (mWaitingForNegativeProximity    
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
            } else {  
                // 在灭屏时或者释放Proximity WakeLock锁后,解除PSensor监听
                setProximitySensorEnabled(false);
                mWaitingForNegativeProximity = false;
            }
            // 收到远离事件后,重置mScreenOffBecauseOfProximity
            if (mScreenOffBecauseOfProximity
                    && mProximity != PROXIMITY_POSITIVE) {   
                mScreenOffBecauseOfProximity = false;
                // 通知PMS PSensor收到远离事件
                sendOnProximityNegativeWithWakelock();    
            }
        } else { 
            // 说明PSensor不可用,那下慢这个值也没用,直接置为false
            mWaitingForNegativeProximity = false;
        }
        // 如果PSensor收到上报靠近时间了,需要灭屏,于是将Display状态设置为OFF
        if (mScreenOffBecauseOfProximity) {   
            state = Display.STATE_OFF;
        }
        // #################################################### Part 4 ####################################################
        final int oldState = mPowerState.getScreenState();
        // 设置Display状态
        animateScreenStateChange(state, performScreenOffTransition);   
        state = mPowerState.getScreenState();
        // #################################################### Part 5 ####################################################
        // 如果Display状态设置为OFF,说明要灭屏,则将亮度设置为-1.0f
        if (state == Display.STATE_OFF) {
            brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
            // 记录亮度变化原因
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);   
        }
        // 如果Display状态设置为VR,不常用
        if (state == Display.STATE_VR) {   
            brightnessState = mScreenBrightnessForVr;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR);
        }
        // 使用PMS中的亮度覆盖,来自WindowManager如视频界面的亮度
        if ((Float.isNaN(brightnessState))
                    && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {  
            brightnessState = mPowerRequest.screenBrightnessOverride;
            // 记录亮度变化原因
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);  
            // 表示使用了覆盖亮度
            mAppliedScreenBrightnessOverride = true;   
        } else {
            mAppliedScreenBrightnessOverride = false;
        }
        // 判断是否在Doze状态下使用自动亮度,一般为false
        final boolean autoBrightnessEnabledInDoze =
                mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
        // 判断自动亮度是否可用: 开始了自动亮度&亮屏状态&未使用前几类亮度&配置了自动亮度曲线映射
        final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                    && Float.isNaN(brightnessState)
                    && mAutomaticBrightnessController != null;
        // 用来更新用户状态栏、设置中手动设置的亮度值的状态,如果用户设置亮度发生变化,返回true
        final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
        // 该亮度表示用户拖动亮度条调节且未放手时的亮度,所以是一个"临时"亮度,如果存在这个值,则必须使用这个值
        if (isValidBrightnessValue(mTemporaryScreenBrightness)) {
            brightnessState = mTemporaryScreenBrightness;
            // 表示使用了临时用户亮度
            mAppliedTemporaryBrightness = true;   
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
        } else {
            mAppliedTemporaryBrightness = false;
        }
        // 更新自动亮度曲线调整值,如果调整值发生变化,返回true
        final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
        // 由于发生变化已经更新到全局变量上,所以不需要"临时"自动变量调整值,重置
        if (autoBrightnessAdjustmentChanged) {  
            mTemporaryAutoBrightnessAdjustment = Float.NaN;
        }
    
        final float autoBrightnessAdjustment;
        // 如果临时自动变量调整值存在,则使用它作为全局自动变量调整值,随后它的值将更新到全局自动变量调整值上,并将它重置,如前五行看到的
        if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) { 
            autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
            brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;  
            // 表示使用了临时自动亮度调整值
            mAppliedTemporaryAutoBrightnessAdjustment = true; 
        // 否则使用全局自动亮度调整值
        } else {   
            autoBrightnessAdjustment = mAutoBrightnessAdjustment;
            brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;  
            mAppliedTemporaryAutoBrightnessAdjustment = false;
        }
        // 如果使用了亮度增强,Display状态不处于灭屏,会将亮度设置到最大
        if (mPowerRequest.boostScreenBrightness
                && brightness != PowerManager.BRIGHTNESS_OFF) {   
            brightnessState = PowerManager.BRIGHTNESS_ON;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
            // 表示使用了亮度增强
            mAppliedBrightnessBoost = true;    
        } else {
            mAppliedBrightnessBoost = false;
        }
        // 表示是否用户发起了亮度的改变:没有使用以上几类亮度&(自动亮度调整值发生变化||用户设置了亮度)
        // 这个值若为true,说明亮度被用户拖动发生改变了
        boolean userInitiatedChange = (Float.isNaN(brightnessState))
                && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
        // 是否用户手动调节过自动亮度
        boolean hadUserBrightnessPoint = false;   
        if (mAutomaticBrightnessController != null) {
            hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();
            // 配置自动亮度相关参数
        mAutomaticBrightnessController.configure(autoBrightnessEnabled,
                mBrightnessConfiguration,
                mLastUserSetScreenBrightness,
                userSetBrightnessChanged, autoBrightnessAdjustment,
                autoBrightnessAdjustmentChanged, mPowerRequest.policy);    }
    
        // #################################################### Part 6 ####################################################
        boolean slowChange = false;
        if (brightness < 0) {   // 如果前面几类亮度未使用,则使用自动亮度
            float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
            if (autoBrightnessEnabled) {
                // 获取自动亮度
                brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(); 
                // 获取新的自动亮度调整值
                newAutoBrightnessAdjustment =
                   mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); 
            }
            // 说明使用了自动亮度
            if (isValidBrightnessValue(brightnessState)) {  
                // 对得到的自动亮度限制范围
                brightnessState = clampScreenBrightness(brightness);  
                // 这俩条件说明是由自动亮度的调节
                if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {  
                     // 用来控制亮度调节速率
                    slowChange = true;
                }
                // 将亮度值更新到settings中
                putScreenBrightnessSetting(brightnessState);
                // 表示使用了自动亮度
                mAppliedAutoBrightness = true;   
                mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
            } else {
                mAppliedAutoBrightness = false;
            }
            // 如果自动亮度调整值发生变化,更新自动亮度调整值到settings中
            if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {   
                putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
            } else {
                // 说明是纯自动亮度,并没有调整
                brightnessAdjustmentFlags = 0;  
            }
        } else {
            mAppliedAutoBrightness = false;
            brightnessAdjustmentFlags = 0;
        }
        // #################################################### Part 7 ####################################################
        // 如果进入Doze状态后,PMS中未指定Doze状态亮度,使用默认的doze亮度
        if ((Float.isNaN(brightnessState))
                && Display.isDozeState(state)) {   
            brightnessState = mScreenBrightnessDozeConfig;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
        }
    
        // #################################################### Part 8 ####################################################
        // 如果这里还没有亮度,那么将使用用户设置的亮度
        if (Float.isNaN(brightnessState)) {   
            brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
        }
        // #################################################### Part 9 ####################################################
        // 设置进入Dim后的亮度
        if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {   
            if (brightnessState > mScreenBrightnessRangeMinimum) {
                brightnessState = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
                        mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED); 
            }
            if (!mAppliedDimming) {
                slowChange = false;   // 表示需要快速设置亮度
            }
            mAppliedDimming = true;  // 表示使用了Dim亮度
        } else if (mAppliedDimming) {
            slowChange = false;
            mAppliedDimming = false;
        }
        // #################################################### Part 10 ####################################################
        // 低电量模式下,需要调低亮度以节约功耗
        if (mPowerRequest.lowPowerMode) {   
            if (brightnessState > mScreenBrightnessRangeMinimum) {
                final float brightnessFactor =
                        Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
                final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
                brightnessState = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
            }
            if (!mAppliedLowPower) {
                slowChange = false;
            }
            // 表示使用了低电量模式的亮度
            mAppliedLowPower = true;  
        } else if (mAppliedLowPower) {
            slowChange = false;
            mAppliedLowPower = false;
        }
        // #################################################### Part 11 ####################################################
        if (!mPendingScreenOff) {
            if (mSkipScreenOnBrightnessRamp) {   // mSkipScreenOnBrightnessRamp表示亮屏时不使用亮度动画
                if (state == Display.STATE_ON) {
                    if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
                        mInitialAutoBrightness = brightness;
                        mSkipRampState = RAMP_STATE_SKIP_INITIAL;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
                            && mUseSoftwareAutoBrightnessConfig
                            && brightness != mInitialAutoBrightness) {
                        mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
                        mSkipRampState = RAMP_STATE_SKIP_NONE;
                    }
                } else {
                    mSkipRampState = RAMP_STATE_SKIP_NONE;
                }
            }
            // 是否处于或原本处于VR状态
            final boolean wasOrWillBeInVr =
                    (state == Display.STATE_VR || oldState == Display.STATE_VR);
            // 表示是否在亮屏时,使用亮度动画,使用亮度动画,在亮屏时可能会出现缓慢的设置亮度。由mSkipScreenOnBrightnessRamp决定
            final boolean initialRampSkip =
                    state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
            // display硬件是否支持全范围亮度值,如果不支持,设置亮度时就不使用亮度动画设置
            final boolean hasBrightnessBuckets =
                    Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;    // 表示doze状态时,display硬件是否支持全范围亮度值
            // 是否colorfade已经完成对显示内容的覆盖,如果已经覆盖,那么就没必要使用亮度动画了,因为已经看不到显示内容了
            final boolean isDisplayContentVisible =
                    mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
            // 是否使用到了临时亮度
            final boolean brightnessIsTemporary =
                    mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
    
            float animateValue = brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT
                        ? PowerManager.BRIGHTNESS_MIN : brightnessState;
                if (isValidBrightnessValue(animateValue)) {
                    // 以下条件,直接设置亮度,没有亮度动画(rate=0)
                    if (initialRampSkip || hasBrightnessBuckets
                            || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
                        animateScreenBrightness(animateValue, SCREEN_ANIMATION_RATE_MINIMUM);
                    } else {
                        animateScreenBrightness(animateValue,
                                slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
                    }
            // #################################################### Part 12 ####################################################
            // 每次亮度发生变化后,对这次变化进行记录, 依据就是brightnessIsTemporary和userInitiatedChange
            // brightnessIsTemporary表示是否使用临时亮度,默认为false,并且在拖动过程中,这个值为ture,拖动亮度条结束后,将重回false
            // userInitiatedChange表示用户是否调整过亮度调整过程中为false,调整完成后将变为ture,并在下一次执行到该方法时又重回false
            // 因此,只要亮度发生变化,就会进入下面进行统计,userInitiatedChange则表示是否是用户发起的变化,perfect!
            // 不过,notifyBrightnessChanged()中则对统计条件进行了限制:只统计使用自动亮度情况下的变化,关闭自动亮度,使用windowOverlay亮度都是不会统计的
            if (!brightnessIsTemporary) { 
                if (userInitiatedChange && (mAutomaticBrightnessController == null
                        || !mAutomaticBrightnessController.hasValidAmbientLux())) {
                    userInitiatedChange = false;
                }
                notifyBrightnessChanged(brightness, userInitiatedChange, hadUserBrightnessPoint);
            }
        }
        // 每次亮度调整后,log的输出,日常处理问题相当有用
        if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
            Slog.v(TAG, "Brightness [" + brightnessState + "] reason changing to: '"
                    + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
                    + "', previous reason: '" + mBrightnessReason + "'.");
            mBrightnessReason.set(mBrightnessReasonTemp);
        }
    
        // #################################################### Part 13 ####################################################
        if (mDisplayWhiteBalanceController != null) {    // 自调节色温
            if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
                mDisplayWhiteBalanceController.setEnabled(true);
                mDisplayWhiteBalanceController.updateDisplayColorTemperature();
            } else {
                mDisplayWhiteBalanceController.setEnabled(false);
            }
        }
        // #################################################### Part 14 ####################################################
        // mPendingScreenOnUnblocker用于亮屏过程,非空表示屏幕目前被阻塞,等待WindowManager模块完成亮屏操作后回调将它置为null
        // Colorfade是一个暗层动画,亮灭屏时会淡入淡出
        final boolean ready = mPendingScreenOnUnblocker == null &&
                (!mColorFadeEnabled ||                       
                        (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))   // 是否正在有colorfade动画进行
                && mPowerState.waitUntilClean(mCleanListener);   // 判断屏幕状态和ColorFade是否设置完成,两个都完成时返回true
        // 所以ready表示display状态是否设置完成
        // 表示display状态设置完毕,亮度也设置完毕
        final boolean finished = ready
                && !mScreenBrightnessRampAnimator.isAnimating();   // 亮度动画是否在进行
        // mReportedScreenStateToPolicy表示向PhoneWindowManager报告亮灭屏阶段的值
        if (ready && state != Display.STATE_OFF
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);   // 将mReportedScreenStateToPolicy设置为REPORTED_TO_POLICY_SCREEN_ON,表示亮屏完成
            mWindowManagerPolicy.screenTurnedOn();    // 报告PhoneWindowManager
        }
        // 表示更新display的设置或者亮度的设置还没有完成,需要持锁保证它们的完成
        if (!finished && !mUnfinishedBusiness) {
            mCallbacks.acquireSuspendBlocker();
            mUnfinishedBusiness = true;
        }
        // 回调通知PMS,display状态完成更新,PMS将会再次发起请求
        if (ready && mustNotify) {
            synchronized (mLock) {
                if (!mPendingRequestChangedLocked) {
                    mDisplayReadyLocked = true;    // 表示更新完成了
                }
            }
            sendOnStateChangedWithWakelock();  // 回调PMS
        }
        // 表示更新display和亮度的设置全部完成,释放锁
        if (finished && mUnfinishedBusiness) {
            mUnfinishedBusiness = false;
            mCallbacks.releaseSuspendBlocker();
        }
        // 用来记录上次设置Display状态是否为ON
        mDozing = state != Display.STATE_ON;
    }
    

    根据具体功能将它按功能划分成了几部分来看:

    • Part 1:mPowerRequest的更新,mPowerRequest代表当前PMS中的请求封装对象;

    • Part 2:根据mPowerRequest对象中的policy参数确定要设置的Display状态;

    • Part 3:针对Proximity Sensor的处理;

    • Part 4:根据Part2、Part3确定的state开始设置Display状态;

    • Part 5:确定屏幕亮度;

    • Part 6:应用自动亮度;

    • Part 7:Doze状态时,使用Doze默认亮度;

    • Part 8:应用用户手动调节亮度;

    • Part 9:设置Dim时亮度;

    • Part 10:设置低电量状态时的亮度;

    • Part 11:确定是否使用亮度动画和亮度的设置;

    • Part 12:亮度变化后的log输出和记录;

    • Part 13:更新色温调节状态;

    • Part 14:Display状态和亮度设置完成后的处理。

      在这里,对涉及亮灭屏的如下关键流程进行分析:Part1、2、4、11、14,其中Part1、2两部分,是根据PMS中的policy来确定要设置的Display状态,这个好理解,并且都在代码中注释了,所以下面直接从Part4开始。

    4.animateScreenStateChange()灭屏动画执行和更新Display状态

      当确定好将要设置的Display State后,通过animateScreenStateChange()方法进行设置:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
    private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
        if (mColorFadeEnabled &&
                (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {   // 如果在已经在进行ColorFade动画,非Display.ON时直接返回
            if (target != Display.STATE_ON) {
                return;
            }
            // 代表是否已开始设置灭屏动画(ColorFade淡入,屏幕变黑)
            mPendingScreenOff = false;
        }
    
        // 在退出Doze状态时,是否需要是先过渡到OFF状态
        if (mDisplayBlanksAfterDozeConfig     // 默认为fale
                && Display.isDozeState(mPowerState.getScreenState())
                && !Display.isDozeState(target)) {
            mPowerState.prepareColorFade(mContext,
                    mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
            if (mColorFadeOffAnimator != null) {
                mColorFadeOffAnimator.end();
            }
            // 先过渡到OFF状态
            setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
        }
    
        // 如果已经开始设置灭屏动画,但又收到非Display OFF请求,则不再等待灭屏动画完成,直接将Display状态设置为OFF
        if (mPendingScreenOff && target != Display.STATE_OFF) {
            setScreenState(Display.STATE_OFF);
            mPendingScreenOff = false;   // 重置
            mPowerState.dismissColorFadeResources();  // 移除ColorFade
        }
        // 按照请求状态进行
        if (target == Display.STATE_ON) {     // Display目标状态为亮屏
            // 通过DisplayPowerState去设置Display,并向PhoneWindowManager发出通知,WMS回调后返回true
            if (!setScreenState(Display.STATE_ON)) {  
                return; 
            }
            // 是否使用了亮屏动画,默认false
            if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {  
                if (mPowerState.getColorFadeLevel() == 1.0f) {
                    mPowerState.dismissColorFade();
                } else if (mPowerState.prepareColorFade(mContext,
                        mColorFadeFadesConfig ?
                                ColorFade.MODE_FADE :
                                        ColorFade.MODE_WARM_UP)) {
                    mColorFadeOnAnimator.start();   // 开始亮屏动画的转变
                } else {
                    mColorFadeOnAnimator.end();
                }
            } else {     // 如果没有使用ColorFade动画,则直接将ColorFade级别设置为1(全透明)
                mPowerState.setColorFadeLevel(1.0f);
                mPowerState.dismissColorFade();
            }
        } else if (target == Display.STATE_VR) {   // Display目标状态为VR,这个状态略去
            // ..........
        } else if (target == Display.STATE_DOZE) {   // Display目标状态为DOZE
            // 如果正在亮屏状态下进行亮度设置过程,先返回
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() == Display.STATE_ON) {  
                return;
            }
            // 去设置Doze状态
            if (!setScreenState(Display.STATE_DOZE)) {    
                return;
            }
    
            mPowerState.setColorFadeLevel(1.0f);   
            mPowerState.dismissColorFade();
        } else if (target == Display.STATE_DOZE_SUSPEND) {    // Display目标状态为STATE_DOZE_SUSPEND
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
                return;
            }
            // Display设置成STATE_DOZE_SUSPEND前,状态必须为STATE_DOZE才可以
            if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {   
                if (!setScreenState(Display.STATE_DOZE)) {
                    return; 
                }
                setScreenState(Display.STATE_DOZE_SUSPEND); 
            }
    
            mPowerState.setColorFadeLevel(1.0f); 
            mPowerState.dismissColorFade();
        } else if (target == Display.STATE_ON_SUSPEND) {   // Display目标状态为STATE_ON_SUSPEND
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
                return;
            }
            // Display设置成STATE_ON_SUSPEND前,状态必须为STATE_ON才可以
            if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {    
                if (!setScreenState(Display.STATE_ON)) {
                    return;
                }
                setScreenState(Display.STATE_ON_SUSPEND);
            }
    
            mPowerState.setColorFadeLevel(1.0f);
            mPowerState.dismissColorFade();
        } else { // 只剩下STATE_OFF,说明要灭屏
            mPendingScreenOff = true;   // 表示开始执行灭屏ColorFade动画
            if (!mColorFadeEnabled) {   // 如果不支持ColorFade,则直接添加
                mPowerState.setColorFadeLevel(0.0f); 
            }
            // 说明ColorFade动画已经执行完毕,于是开始去设置STATE_OFF状态
            if (mPowerState.getColorFadeLevel() == 0.0f) {   
                setScreenState(Display.STATE_OFF);
                mPendingScreenOff = false;   // 重置
                mPowerState.dismissColorFadeResources();
            } else if (performScreenOffTransition         
                    && mPowerState.prepareColorFade(mContext,
                            mColorFadeFadesConfig ?
                                    ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
                    && mPowerState.getScreenState() != Display.STATE_OFF) {    // 如果以上条件不满足,进入这里,开始执行灭屏动画,第一次都会进入该else-if块
                mColorFadeOffAnimator.start();    // 开始执行灭屏动画
            } else {
                mColorFadeOffAnimator.end();    // 灭屏动画执行完毕
            }
        }
    }
    

    这个方法也很长,但只有两个作用:

    • 调用setScreenState()方法来继续设置Display状态;

    • 通过ColorFade执行亮灭屏动画。

    ColorFade是一个蒙层,它的level设置为1时全透明,0时全黑。在亮屏时,将该层级逐渐设置为1,产生逐渐亮屏的效果。灭屏时,将该层级逐渐设置为0,产生逐渐灭屏的效果。

      这个方法可以看出,亮屏时,先设置Display的状态,再设置ColorFadelevel为1;灭屏时,先设置ColorFade level为0,再设置Display状态。这个区别导致了最终亮灭屏过程中设置状态和亮度的先后。

      接下来,看下一步setScreenState()方法的执行:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
    private boolean setScreenState(int state, boolean reportOnly) {
        // 是否设置OFF状态
        final boolean isOff = (state == Display.STATE_OFF);
        // 如果当前状态和目标状态不同
        if (mPowerState.getScreenState() != state) {   
            // 说明非PSensor导致的设置OFF操作,向PhoneWindowManger报告状态
            if (isOff && !mScreenOffBecauseOfProximity) {  
                if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
                    // 记录状态
                    setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);   
                    blockScreenOff();
                    // 通知PhoneWindowManager灭屏
                    mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);  
                    unblockScreenOff();
                } else if (mPendingScreenOffUnblocker != null) {
                    return false;
                }
            }
            // reportOnly忽略即可,一般都为false
            if (!reportOnly) {
                // 进入DisplayPowerState中设置Display状态
                mPowerState.setScreenState(state);  
            }
        }
    
        if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                && !mScreenOffBecauseOfProximity) {
            // 记录状态
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
            // 解除阻塞
            unblockScreenOn();  
            mWindowManagerPolicy.screenTurnedOff();   // 通知PhoneWindowManager灭屏完毕
        } else if (!isOff
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {   //这种情况说明已经灭屏到一半儿了用户又打算亮屏,这时也应该走完灭屏的流程
            unblockScreenOff();
            mWindowManagerPolicy.screenTurnedOff();  // 通知PhoneWindowManager灭屏完毕
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
        }
        // 说明由OFF状态切换为其他状态
        if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {   
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON); 
            if (mPowerState.getColorFadeLevel() == 0.0f) {  
                // ColorFade level一直为0,从而导致无法设置亮屏亮度,从而阻塞了亮屏流程,直到WMS中收到回调
                blockScreenOn();    
            } else {
                unblockScreenOn();  // 解除阻塞
            }
            mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);   // 通知PhoneWindowManager灭屏完毕
        }
        // mPendingScreenOnUnblocker会在unblockScreenOn()中置为null,表示解除阻塞
        return mPendingScreenOnUnblocker == null;
    }
    

    这个方法中,设置Display状态,同时向PhoneWindowManager进行通知。mReportedScreenStateToPolicy变量用来记录当前状态,根据不同状态向PhoneWindowManager进行通知。在Display状态发生变化过程中,每当进行到某一步,会将该值设置成对应的值,共有四个值:

    // 设置非OFF状态完成,或者说灭屏状态
    private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;  
    // 开始设置非OFF状态
    private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;  
    // 非OFF状态完成
    private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;   
    // 开始设置非OFF状态
    private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
    

    根据这些值通知PhoneWindowManger去执行对应操作。如在开始亮屏时,会调用mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker),WMS模块中收到调用后会做相应处理,这个过程中,由于mPendingScreenOnUnblocker对象非空,因此setScreenState()将返回false,导致阻塞colorFade的设置,从而会无法设置屏幕亮度。

      在WMS处理完毕后,又通过mPendingScreenOnUnblocker参数回调DMS,并通过unblockScreenOn()方法,将mPendingScreenOnUnblocker对象置为null:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
    private void unblockScreenOn() {
        if (mPendingScreenOnUnblocker != null) {
            mPendingScreenOnUnblocker = null;
            long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
        }
    }
    

    再次进入setScreenState()后,由于mPendingScreenOnUnblocker已经为null,因此不会阻塞ColorFade和亮度的设置。接下来,进入DisplayPowerState#setScreenState()来进一步设置Display的状态。

    5.DisplayPowerState#setScreenState()设置状态

      DisplayPowerState代表了当前Display的整体状态,包括Display的状态、亮度、ColorFade Level值,凡是涉及到Display的值,最后都会进入DisplayPowerState中进行设置,setScreenState()如下:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
    public void setScreenState(int state) {
        if (mScreenState != state) {
            mScreenState = state;   // 更新当前Display状态
            mScreenReady = false;   // 表示更新Display状态、亮度、ColorFade level未完成
            scheduleScreenUpdate(); // 执行更新操作
        }
    }
    

    这里将更新mScreenState变量,更新mScreenReady为false,表示Display状态未更新完成,然后调用scheduleScreenUpdate()方法。scheduleScreenUpdate()方法,在分析完DisplayController中的流程后再进行分析。

    6.animateScreenBrightness()更新亮度

      回到updatePowerState()中,执行完Part4后,下面来看Part11部分亮度的设置。设置亮度值使用animateScreenBrightness()方法:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
    private void animateScreenBrightness(float target, int rate) {
        // mScreenBrightnessRampAnimator中开始设置亮度
        if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {   
            .......
        }
    }
    

    第一个参数表示要设置的亮度值,第二个表示设置亮度的速率,关于亮度值和亮度设置速率值的获取、以及亮度动画,会在后面亮度设置部分详细分析,本片文章还是侧重于设置过程。

      亮度的设置,不像设置Display状态那样烦琐,mScreenBrightnessRampAnimator是一个RampAnimator对象,该类是一个自定义动画类,专门用于更新亮度。进入该类的animateTo()后,最终会调用到DisplayPowerState的setScreenBrightness()方法,将亮度设置给DisplayPowerState。

    7.DisplayPowerState#setScreenBrightness()设置亮度

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
    public void setScreenBrightness(float brightness) {
        if (mScreenBrightness != brightness) {
            // 更新当前亮度值
            mScreenBrightness = brightness;    
            if (mScreenState != Display.STATE_OFF) {
                // 表示更新Display状态、亮度、ColorFade level未完成
                mScreenReady = false;
                // 执行更新操作
                scheduleScreenUpdate();   
            }
        }
    }
    

    这里更新了mScreenBrightness变量,也调用了scheduleScreenUpdate()开始执行更新操作。现在,Display的状态和亮度都传到了DisplayPowerState中,下面将通过scheduleScreenUpdate()方法开始更新。

    8.scheduleScreenUpdate()执行更新

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
    private void scheduleScreenUpdate() {
        if (!mScreenUpdatePending) {    // 表示将开始更新Display整体状态
            mScreenUpdatePending = true;
            postScreenUpdateThreadSafe();
        }
    }
    //------------------------------
    private void postScreenUpdateThreadSafe() {
        mHandler.removeCallbacks(mScreenUpdateRunnable);
        mHandler.post(mScreenUpdateRunnable);
    }
    

    以上两个方法中,先将mScreenUpdatePending设置为true,表示将开始更新Display整体状态,然后通过Handler将在mScreenUpdateRunnable这个runnable中进行处理:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
        private final Runnable mScreenUpdateRunnable = new Runnable() {
            @Override
            public void run() {
                mScreenUpdatePending = false;
                // 确认最终的亮度,在Display状态为OFF时,或者ColorFade level为0时,将设置为0,其他情况下设置为DPC中传入的亮度值
                float brightnessState = mScreenState != Display.STATE_OFF
                        && mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
                // PhotonicModulator是一个独立的线程,专门用来更新Display状态和亮度
                if (mPhotonicModulator.setState(mScreenState, brightnessState)) {
                    // 更新完成
                    mScreenReady = true;
                    invokeCleanListenerIfNeeded();
                } else {
                }
            }
        };
    

    这里会对要更新的亮度值再做一次确认,根据Display状态、ColorFade来确定一个最终亮度值,然后在mPhotonicModulator中开始更新。

    9.PhotonicModulator#setState()子线程进行更新

      PhotonicModulator是一个继承于Thread的类,专门用于更新Display状态和亮度,因此更新屏幕状态和背光是在独立的线程中异步进行的,setState()方法如下:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
    public boolean setState(int state, int backlight) {
        synchronized (mLock) {
            // Display状态是否发生变化,mPendingState表示即将开始设置的状态,设置完成后也不会清除
            boolean stateChanged = state != mPendingState;    
            // 亮度是否发生变化,mPendingBacklight表示即将开始设置的亮度,设置完成后也不会清除
            boolean backlightChanged = backlight != mPendingBacklight;  
            // Display状态或亮度任意一个发生变化,就开始更新
            if (stateChanged || backlightChanged) {  
                mPendingState = state;           // 更新mPendingState值
                mPendingBacklight = backlight;   // 更新mPendingBacklight值
                // 表示是否处于change过程中
                boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
                mStateChangeInProgress = stateChanged || mStateChangeInProgress;   
                mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
                // 当不处于change过程中时,唤起PhotonicModulator线程
                if (!changeInProgress) { 
                    mLock.notifyAll();
                }
            }
            return !mStateChangeInProgress;  // 只要State更新完成,就返回true
        }
    }
    

    当屏幕状态和亮度任意一个发生变化,将通过notifyAll()唤醒PhotonicModulator线程,然后执行该线程的run()方法,这是一个生产-消费者模型,肯定有其他地方对其进行了wait()操作。接下来看下它的run()方法:

    // frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
    public void run() {
        for (;;) {
            final int state;
            final boolean stateChanged;
            final int backlight;
            final boolean backlightChanged;
            synchronized (mLock) {
                state = mPendingState;
                // mActualState表示实际Display状态
                stateChanged = (state != mActualState);   
                backlight = mPendingBacklight;
                // mActualBacklight表示实际亮度
                backlightChanged = (backlight != mActualBacklight);   
                if (!stateChanged) {
                    // 再一次发起更新流程
                    postScreenUpdateThreadSafe();   
                    mStateChangeInProgress = false;
                }
                if (!backlightChanged) {
                    mBacklightChangeInProgress = false;
                }
                if (!stateChanged && !backlightChanged) {
                    try {
                        // state和亮度都设置完成后,该线程进入wait状态
                        mLock.wait();
                    } catch (InterruptedException ex) { }
                    continue;
                }
                mActualState = state;
                mActualBacklight = backlight;
            }
            // 调用DisplayBlanker中去请求Display
            mBlanker.requestDisplayState(state, backlight);    
        }
    }
    

    在Display状态和亮度都更新完成之后,通过Object.wait()方法,让该线程进入WAITTING状态了。通过这种方式,不断设置过来的Display状态和亮度。

      最终,调用mBlanker.requestDisplayState()进行下一步设置,这里又经过DMS,最后会对具体的DisplayDevice对象进行状态和亮度的设置中,这中间的逻辑就略过。

    10.LocalDisplayDevice#requestDisplayStateLocked()

      requestDisplayStateLocked()为具体的物理屏设置新的Display状态和亮度值:

     // frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
            @Override
            public Runnable requestDisplayStateLocked(final int state, final float brightnessState) {
                final boolean stateChanged = (mState != state);
                final boolean brightnessChanged = (!BrightnessSynchronizer.floatEquals(
                        mBrightnessState, brightnessState))
                        && mBacklight != null;
                if (stateChanged || brightnessChanged) {
                    ......
                    return new Runnable() {
                        @Override
                        public void run() {
                            ......
                            // 设置亮度
                            if (brightnessChanged || vrModeChange) {
                                setDisplayBrightness(brightnessState);
                            }
                            // 设置状态
                            if (state != currentState) {
                                setDisplayState(state);
                            }
                        }
    
                        private void setDisplayState(int state) {
                            ......
                            try {
                                SurfaceControl.setDisplayPowerMode(token, mode);
                            } finally {}
                        }
    
                        private void setDisplayBrightness(float brightness) {
                            try {
                                if (mBacklight != null) {
                                    mBacklight.setBrightness(brightness);
                                }
                            } finally {
                            }
                        }
                    };
                }
                return null;
            }
    

    最终,将亮度设置给了LightsService,将状态则是给了SurfaceControl,并由这两模块将分别将亮度和状态SurfaceFlinger中,最终完成整个设置。

      回到updatePowerState()中,在Part14部分中,当Display状态和亮度都设置完成后,会将mDisplayReadyLocked值设置为true,表示Display状态更新完成,并在sendOnStateChangedWithWakelock()方法中回调PMS,PMS再次发起请求时,由于mDisplayReadyLocked已经变为true,因此将返回true,PMS将认为DMS对请求处理完成。

    11.总结

      以上就是display模块中涉及到的亮灭屏流程。结合之前PMS中的两篇亮灭屏流程,Framework层的亮灭屏流程全部分析完成。

    (1)亮屏时序图

    DMS3-1.png

    (2)灭屏时序图

    DMS3-2.png

    相关文章

      网友评论

          本文标题:Android DisplayManagerService--0

          本文链接:https://www.haomeiwen.com/subject/vuzobdtx.html