美文网首页
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