Android13 DisplayManagerInternal requestPowerState流程分析

DisplayManagerInternal方法requestPowerState用于控制屏幕的亮灭,由PowerManagerService调用,整体流程如下:

概要的亮屏幕时序:

概要的灭屏时序:

代码如下

//frameworks/base/core/java/android/hardware/display/DisplayManagerInternal.java
public abstract class DisplayManagerInternal {
    public abstract boolean requestPowerState(int groupId, DisplayPowerRequest request,
            boolean waitForNegativeProximity);
}

DisplayManagerInternal是抽象类,requestPowerState是抽象方法,由DisplayManagerService的内部类LocalService实现:

//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
    final class LocalService extends DisplayManagerInternal {
        public boolean requestPowerState(int groupId, DisplayPowerRequest request,
                boolean waitForNegativeProximity) {
            synchronized (mSyncRoot) {
                final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked(
                        groupId);
                if (displayGroup == null) {
                    return true;
                }


                final int size = displayGroup.getSizeLocked();
                boolean ready = true;
                for (int i = 0; i < size; i++) {
                    final int id = displayGroup.getIdLocked(i);
                    final DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked(
                            id).getPrimaryDisplayDeviceLocked();
                    final int flags = displayDevice.getDisplayDeviceInfoLocked().flags;
                    if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
                        final DisplayPowerController displayPowerController =
                                mDisplayPowerControllers.get(id);
                        ready &= displayPowerController.requestPowerState(request,
                                waitForNegativeProximity);
                    }
                }


                return ready;
            }
        }
    }
}

调用displayPowerController(DisplayPowerController)的requestPowerState方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    public boolean requestPowerState(DisplayPowerRequest request,
            boolean waitForNegativeProximity) {
        if (DEBUG) {
            Slog.d(TAG, "requestPowerState: "
                    + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
        }


        synchronized (mLock) {
            if (mStopped) {
                return true;
            }


            boolean changed = false;


            if (waitForNegativeProximity
                    && !mPendingWaitForNegativeProximityLocked) {
                mPendingWaitForNegativeProximityLocked = true;
                changed = true;
            }


     //开机后第一次进入
            if (mPendingRequestLocked == null) {
                mPendingRequestLocked = new DisplayPowerRequest(request); //创建DisplayPowerRequest对象
                changed = true;
            } else if (!mPendingRequestLocked.equals(request)) { //如果该次请求和上次请求不同,说明有状态改变,需要更新Display
                mPendingRequestLocked.copyFrom(request);
                changed = true;
            }
         /**
          * changed为true,说明有改变发生,这个改变交给Handler异步去处理,此时说
          * 明显示没有准备好,mDisplayReadyLocked=false
          * 直到改变处理成功,mDisplayReadyLocked将被置为true,
          */


            if (changed) {
                mDisplayReadyLocked = false;
                if (!mPendingRequestChangedLocked) {
                    mPendingRequestChangedLocked = true;
                    sendUpdatePowerStateLocked();
                }
            }


            return mDisplayReadyLocked;
        }
    }
}

调用DisplayPowerController的sendUpdatePowerStateLocked方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private void sendUpdatePowerStateLocked() {
        if (!mStopped && !mPendingUpdatePowerStateLocked) {
            mPendingUpdatePowerStateLocked = true;
            Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
            mHandler.sendMessage(msg);
        }
    }
}

发送MSG_UPDATE_POWER_STATE消息,消息在中处理:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private final class DisplayControllerHandler extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_POWER_STATE:
                    updatePowerState();
                    break;
            }
        }
    }
}

DisplayPowerController updatePowerState

调用DisplayPowerController的updatePowerState方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private void updatePowerState() {
        // Update the power state request.
        final boolean mustNotify; //当DisplayPowerController中更新屏幕状态成功后是否必须通知PMS
        final int previousPolicy;
        boolean mustInitialize = false;
        int brightnessAdjustmentFlags = 0;
        mBrightnessReasonTemp.set(null);
        mTempBrightnessEvent.reset();
        synchronized (mLock) {
            if (mStopped) {
                return;
            }
            mPendingUpdatePowerStateLocked = false;
            if (mPendingRequestLocked == null) {
                return; // wait until first actual power request
            }


            if (mPowerRequest == null) {
                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
                updatePendingProximityRequestsLocked();
                mPendingRequestChangedLocked = false;
                mustInitialize = true;
                // Assume we're on and bright until told otherwise, since that's the state we turn
                // on in.
                previousPolicy = DisplayPowerRequest.POLICY_BRIGHT;
            } else if (mPendingRequestChangedLocked) {
                previousPolicy = mPowerRequest.policy;
 //复制mPendingRequestLocked给mPowerRequset, 即将"将要请求的电源请求状态"赋给"当前电源的请求状态"
                mPowerRequest.copyFrom(mPendingRequestLocked);
                updatePendingProximityRequestsLocked();
                mPendingRequestChangedLocked = false;
                mDisplayReadyLocked = false;
            } else {
                previousPolicy = mPowerRequest.policy;
            }


            mustNotify = !mDisplayReadyLocked;
        }


        // Compute the basic display state using the policy.
        // We might override this below based on other factors.
        // Initialise brightness as invalid.
        int state;
        float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        boolean performScreenOffTransition = false;
 //根据PMS中的请求参数决定屏幕状态和屏幕亮度值
        switch (mPowerRequest.policy) {
            case DisplayPowerRequest.POLICY_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) {
                    brightnessState = mPowerRequest.dozeScreenBrightness;
                    mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
                }
                break;
            case DisplayPowerRequest.POLICY_VR: //VR模式
                state = Display.STATE_VR;
                break;
            case DisplayPowerRequest.POLICY_DIM: //DIM
            case DisplayPowerRequest.POLICY_BRIGHT: //亮屏
            default:
                state = Display.STATE_ON;
                break;
        }
        assert(state != Display.STATE_UNKNOWN);


        // Apply the proximity sensor.
        if (mProximitySensor != null) {
            if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
                // At this point the policy says that the screen should be on, but we've been
                // asked to listen to the prox sensor to adjust the display state, so lets make
                // sure the sensor is on.
 //设置Psensor可用
                setProximitySensorEnabled(true);
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE
                        && !mIgnoreProximityUntilChanged) {
                    // Prox sensor already reporting "near" so we should turn off the screen.
                    // Also checked that we aren't currently set to ignore the proximity sensor
                    // temporarily.
                    mScreenOffBecauseOfProximity = true; //该值表示由PSensor灭屏
                    sendOnProximityPositiveWithWakelock(); //通过DisplayPowerCallback回调PMS
                }
            } else if (mWaitingForNegativeProximity
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                // The policy says that we should have the screen on, but it's off due to the prox
                // and we've been asked to wait until the screen is far from the user to turn it
                // back on. Let keep the prox sensor on so we can tell when it's far again.
                setProximitySensorEnabled(true);
            } else {
                // We haven't been asked to use the prox sensor and we're not waiting on the screen
                // to turn back on...so lets shut down the prox sensor.
                setProximitySensorEnabled(false); 
                mWaitingForNegativeProximity = false; //不满足以上条件,设置PSensor不可用
            }


            if (mScreenOffBecauseOfProximity
                    && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
                // The screen *was* off due to prox being near, but now it's "far" so lets turn
                // the screen back on.  Also turn it back on if we've been asked to ignore the
                // prox sensor temporarily.
                mScreenOffBecauseOfProximity = false;
                sendOnProximityNegativeWithWakelock();
            }
        } else {
            mWaitingForNegativeProximity = false;
            mIgnoreProximityUntilChanged = false;
        }


        if (!mLogicalDisplay.isEnabled()
                || mLogicalDisplay.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
                || mScreenOffBecauseOfProximity) {
            state = Display.STATE_OFF;
        }


        // Initialize things the first time the power state is changed.
        if (mustInitialize) {
     //初始化亮灭屏动画、mPowerState等
            initialize(state);
        }


        // 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.
        // 对屏幕状态更改进行动画处理,除非已进行动画处理。转换可能会被推迟,因此在此之后,我们将使用实际状态而不是所需的状态。
        final int oldState = mPowerState.getScreenState();
 //在这个方法中会进行屏幕状态、亮度的设置和处理亮灭屏动画
        animateScreenStateChange(state, performScreenOffTransition);
 //获取屏幕状态,此时已经设置新的屏幕状态
        state = mPowerState.getScreenState();


        if (state == Display.STATE_OFF) {
     //如果屏幕状态为灭屏,设置亮度为0
            brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
        }


        // Always use the VR brightness when in the VR state.
        if (state == Display.STATE_VR) {
            brightnessState = mScreenBrightnessForVr;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR);
        }


        if ((Float.isNaN(brightnessState))
                && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
            brightnessState = mPowerRequest.screenBrightnessOverride;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
            mAppliedScreenBrightnessOverride = true;
        } else {
            mAppliedScreenBrightnessOverride = false;
        }


        final boolean autoBrightnessEnabledInDoze =
                mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
        final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                    && Float.isNaN(brightnessState)
                    && mAutomaticBrightnessController != null;
        final boolean autoBrightnessDisabledDueToDisplayOff = mPowerRequest.useAutoBrightness
                    && !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
        final int autoBrightnessState = autoBrightnessEnabled
                ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
                : autoBrightnessDisabledDueToDisplayOff
                ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
                : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;


        final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();


        // Use the temporary screen brightness if there isn't an override, either from
        // WindowManager or based on the display state.
        if (isValidBrightnessValue(mTemporaryScreenBrightness)) {
            brightnessState = mTemporaryScreenBrightness;
            mAppliedTemporaryBrightness = true;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
        } else {
            mAppliedTemporaryBrightness = false;
        }


        final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
        if (autoBrightnessAdjustmentChanged) {
            mTemporaryAutoBrightnessAdjustment = Float.NaN;
        }


        // Use the autobrightness adjustment override if set.
        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;
        }
        // Apply brightness boost.
        // We do this here after deciding whether auto-brightness is enabled so that we don't
        // disable the light sensor during this temporary state.  That way when boost ends we will
        // be able to resume normal auto-brightness behavior without any delay.
 // mPowerRequest表示"当前的电源请求状态",初始值为null, 由mPengdingReqestLocked对象拷贝或实例化,因此只有系统开机后第一次会进入if中,之后不会进入
        if (mPowerRequest.boostScreenBrightness
                && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) {
            brightnessState = PowerManager.BRIGHTNESS_MAX;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
            mAppliedBrightnessBoost = true;
        } else {
            mAppliedBrightnessBoost = false;
        }


        // If the brightness is already set then it's been overridden by something other than the
        // user, or is a temporary adjustment.
        boolean userInitiatedChange = (Float.isNaN(brightnessState))
                && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
        boolean hadUserBrightnessPoint = false;
        // Configure auto-brightness.
        if (mAutomaticBrightnessController != null) {
            hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();
            mAutomaticBrightnessController.configure(autoBrightnessState,
                    mBrightnessConfiguration,
                    mLastUserSetScreenBrightness,
                    userSetBrightnessChanged, autoBrightnessAdjustment,
                    autoBrightnessAdjustmentChanged, mPowerRequest.policy);
        }


        if (mBrightnessTracker != null) {
            mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
        }


        boolean updateScreenBrightnessSetting = false;


        // Apply auto-brightness.
        boolean slowChange = false;
        if (Float.isNaN(brightnessState)) {
            float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
            if (autoBrightnessEnabled) { //如果自动调节亮度可用
 //从AutomaticBrightnessController中获取自动调节亮度值
                brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(
                        mTempBrightnessEvent);
                newAutoBrightnessAdjustment =
                        mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
            }
            if (isValidBrightnessValue(brightnessState)
                    || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
                // Use current auto-brightness value and slowly adjust to changes.
                brightnessState = clampScreenBrightness(brightnessState);
                if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
                    slowChange = true; // slowly adapt to auto-brightness
                }
                updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
                mAppliedAutoBrightness = true;
                mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
            } else {
                mAppliedAutoBrightness = false;
            }
            if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
                // If the autobrightness controller has decided to change the adjustment value
                // used, make sure that's reflected in settings.
                putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
            } else {
                // Adjustment values resulted in no change
                brightnessAdjustmentFlags = 0;
            }
        } else {
            // Any non-auto-brightness values such as override or temporary should still be subject
            // to clamping so that they don't go beyond the current max as specified by HBM
            // Controller.
            brightnessState = clampScreenBrightness(brightnessState);
            mAppliedAutoBrightness = false;
            brightnessAdjustmentFlags = 0;
        }


        // Use default brightness when dozing unless overridden.
        if ((Float.isNaN(brightnessState))
                && Display.isDozeState(state)) {
            brightnessState = clampScreenBrightness(mScreenBrightnessDozeConfig);
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
        }


        // Apply manual brightness.
        if (Float.isNaN(brightnessState)) {
            brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
            if (brightnessState != mCurrentScreenBrightnessSetting) {
                // The manually chosen screen brightness is outside of the currently allowed
                // range (i.e., high-brightness-mode), make sure we tell the rest of the system
                // by updating the setting.
                updateScreenBrightnessSetting = true;
            }
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
        }


        // Now that a desired brightness has been calculated, apply brightness throttling. The
        // dimming and low power transformations that follow can only dim brightness further.
        //
        // We didn't do this earlier through brightness clamping because we need to know both
        // unthrottled (unclamped/ideal) and throttled brightness levels for subsequent operations.
        // Note throttling effectively changes the allowed brightness range, so, similarly to HBM,
        // we broadcast this change through setting.
        final float unthrottledBrightnessState = brightnessState;
        if (mBrightnessThrottler.isThrottled()) {
            mTempBrightnessEvent.thermalMax = mBrightnessThrottler.getBrightnessCap();
            brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
            mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
            if (!mAppliedThrottling) {
                // Brightness throttling is needed, so do so quickly.
                // Later, when throttling is removed, we let other mechanisms decide on speed.
                slowChange = false;
            }
            mAppliedThrottling = true;
        } else if (mAppliedThrottling) {
            mAppliedThrottling = false;
        }


        if (updateScreenBrightnessSetting) {
            // Tell the rest of the system about the new brightness in case we had to change it
            // for things like auto-brightness or high-brightness-mode. Note that we do this
            // before applying the low power or dim transformations so that the slider
            // accurately represents the full possible range, even if they range changes what
            // it means in absolute terms.
            updateScreenBrightnessSetting(brightnessState);
        }


        // Apply dimming by at least some minimum amount when user activity
        // timeout is about to expire.
        if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
            if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
                brightnessState = Math.max(
                        Math.min(brightnessState - mScreenBrightnessMinimumDimAmount,
                                mScreenBrightnessDimConfig),
                        PowerManager.BRIGHTNESS_MIN);
                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
            }
            if (!mAppliedDimming) {
                slowChange = false;
            }
            mAppliedDimming = true;
        } else if (mAppliedDimming) {
            slowChange = false;
            mAppliedDimming = false;
        }
        // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
        // as long as it is above the minimum threshold.
        if (mPowerRequest.lowPowerMode) {
            if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
                final float brightnessFactor =
                        Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
                final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
                brightnessState = Math.max(lowPowerBrightnessFloat, PowerManager.BRIGHTNESS_MIN);
                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
            }
            if (!mAppliedLowPower) {
                slowChange = false;
            }
            mAppliedLowPower = true;
        } else if (mAppliedLowPower) {
            slowChange = false;
            mAppliedLowPower = false;
        }


        // The current brightness to use has been calculated at this point, and HbmController should
        // be notified so that it can accurately calculate HDR or HBM levels. We specifically do it
        // here instead of having HbmController listen to the brightness setting because certain
        // brightness sources (such as an app override) are not saved to the setting, but should be
        // reflected in HBM calculations.
        mHbmController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
                mBrightnessThrottler.getBrightnessMaxReason());


        // Animate the screen brightness when the screen is on or dozing.
        // Skip the animation when the screen is off or suspended or transition to/from VR.
        boolean brightnessAdjusted = false;
        if (!mPendingScreenOff) {
            if (mSkipScreenOnBrightnessRamp) {
                if (state == Display.STATE_ON) {
                    if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
                        mInitialAutoBrightness = brightnessState;
                        mSkipRampState = RAMP_STATE_SKIP_INITIAL;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
                            && mUseSoftwareAutoBrightnessConfig
                            && !BrightnessSynchronizer.floatEquals(brightnessState,
                            mInitialAutoBrightness)) {
                        mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
                        mSkipRampState = RAMP_STATE_SKIP_NONE;
                    }
                } else {
                    mSkipRampState = RAMP_STATE_SKIP_NONE;
                }
            }


            final boolean wasOrWillBeInVr =
                    (state == Display.STATE_VR || oldState == Display.STATE_VR);
            final boolean initialRampSkip =
                    state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
            // While dozing, sometimes the brightness is split into buckets. Rather than animating
            // through the buckets, which is unlikely to be smooth in the first place, just jump
            // right to the suggested brightness.
            final boolean hasBrightnessBuckets =
                    Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
            // If the color fade is totally covering the screen then we can change the backlight
            // level without it being a noticeable jump since any actual content isn't yet visible.
            final boolean isDisplayContentVisible =
                    mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
            final boolean brightnessIsTemporary =
                    mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
            // We only want to animate the brightness if it is between 0.0f and 1.0f.
            // brightnessState can contain the values -1.0f and NaN, which we do not want to
            // animate to. To avoid this, we check the value first.
            // If the brightnessState is off (-1.0f) we still want to animate to the minimum
            // brightness (0.0f) to accommodate for LED displays, which can appear bright to the
            // user even when the display is all black. We also clamp here in case some
            // transformations to the brightness have pushed it outside of the currently
            // allowed range.
            float animateValue = clampScreenBrightness(brightnessState);


            // If there are any HDR layers on the screen, we have a special brightness value that we
            // use instead. We still preserve the calculated brightness for Standard Dynamic Range
            // (SDR) layers, but the main brightness value will be the one for HDR.
            float sdrAnimateValue = animateValue;
            // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
            // done in HighBrightnessModeController.
            if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
                    && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
                    || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
                // We want to scale HDR brightness level with the SDR level
                animateValue = mHbmController.getHdrBrightnessValue();
            }


            final float currentBrightness = mPowerState.getScreenBrightness();
            final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
            if (isValidBrightnessValue(animateValue)
                    && (animateValue != currentBrightness
                    || sdrAnimateValue != currentSdrBrightness)) {
                if (initialRampSkip || hasBrightnessBuckets
                        || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
             //设置亮度
                    animateScreenBrightness(animateValue, sdrAnimateValue,
                            SCREEN_ANIMATION_RATE_MINIMUM);
                } else {
                    boolean isIncreasing = animateValue > currentBrightness;
                    final float rampSpeed;
                    if (isIncreasing && slowChange) {
                        rampSpeed = mBrightnessRampRateSlowIncrease;
                    } else if (isIncreasing && !slowChange) {
                        rampSpeed = mBrightnessRampRateFastIncrease;
                    } else if (!isIncreasing && slowChange) {
                        rampSpeed = mBrightnessRampRateSlowDecrease;
                    } else {
                        rampSpeed = mBrightnessRampRateFastDecrease;
                    }
     //设置亮度
                    animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed);
                }
            }


            // Report brightness to brightnesstracker:
            // If brightness is not temporary (ie the slider has been released)
            // AND if we are not in idle screen brightness mode.
            if (!brightnessIsTemporary
                    && (mAutomaticBrightnessController != null
                            && !mAutomaticBrightnessController.isInIdleMode())) {
                if (userInitiatedChange && (mAutomaticBrightnessController == null
                            || !mAutomaticBrightnessController.hasValidAmbientLux())) {
                    // If we don't have a valid lux reading we can't report a valid
                    // slider event so notify as if the system changed the brightness.
                    userInitiatedChange = false;
                }
                notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
                        hadUserBrightnessPoint);
            }


            // We save the brightness info *after* the brightness setting has been changed and
            // adjustments made so that the brightness info reflects the latest value.
            brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting(), animateValue);
        } else {
            brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting());
        }


        if (brightnessAdjusted) {
            postBrightnessChangeRunnable();
        }


        // Log any changes to what is currently driving the brightness setting.
        if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
            Slog.v(TAG, "Brightness [" + brightnessState + "] reason changing to: '"
                    + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
                    + "', previous reason: '" + mBrightnessReason + "'.");
            mBrightnessReason.set(mBrightnessReasonTemp);
        } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL
                && userSetBrightnessChanged) {
            Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment.");
        }




        // Log brightness events when a detail of significance has changed. Generally this is the
        // brightness itself changing, but also includes data like HBM cap, thermal throttling
        // brightness cap, RBC state, etc.
        mTempBrightnessEvent.time = System.currentTimeMillis();
        mTempBrightnessEvent.brightness = brightnessState;
        mTempBrightnessEvent.reason.set(mBrightnessReason);
        mTempBrightnessEvent.hbmMax = mHbmController.getCurrentBrightnessMax();
        mTempBrightnessEvent.hbmMode = mHbmController.getHighBrightnessMode();
        mTempBrightnessEvent.flags |= (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0);
        // Temporary is what we use during slider interactions. We avoid logging those so that
        // we don't spam logcat when the slider is being used.
        boolean tempToTempTransition =
                mTempBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY
                && mLastBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY;
        if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
                || brightnessAdjustmentFlags != 0) {
            mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
            BrightnessEvent newEvent = new BrightnessEvent(mTempBrightnessEvent);


            // Adjustment flags (and user-set flag) only get added after the equality checks since
            // they are transient.
            newEvent.adjustmentFlags = brightnessAdjustmentFlags;
            newEvent.flags |= (userSetBrightnessChanged ? BrightnessEvent.FLAG_USER_SET : 0);
            Slog.i(TAG, newEvent.toString(/* includeTime= */ false));


            if (mBrightnessEventRingBuffer != null) {
                mBrightnessEventRingBuffer.append(newEvent);
            }
        }


        // Update display white-balance.
        if (mDisplayWhiteBalanceController != null) {
            if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
                mDisplayWhiteBalanceController.setEnabled(true);
                mDisplayWhiteBalanceController.updateDisplayColorTemperature();
            } else {
                mDisplayWhiteBalanceController.setEnabled(false);
            }
        }


        // Determine whether the display is ready for use in the newly requested state.
        // Note that we do not wait for the brightness ramp animation to complete before
        // reporting the display is ready because we only need to ensure the screen is in the
        // right power state even as it continues to converge on the desired brightness.
        final boolean ready = mPendingScreenOnUnblocker == null &&
                (!mColorFadeEnabled ||
                        (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
                && mPowerState.waitUntilClean(mCleanListener);
        final boolean finished = ready
                && !mScreenBrightnessRampAnimator.isAnimating();


        // Notify policy about screen turned on.
        if (ready && state != Display.STATE_OFF
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON); //设置屏幕状态报告值,该值表示亮屏完成
            mWindowManagerPolicy.screenTurnedOn(mDisplayId); //通知WindowManager亮屏完成
        }


        // Grab a wake lock if we have unfinished business.
        if (!finished && !mUnfinishedBusiness) {
            if (DEBUG) {
                Slog.d(TAG, "Unfinished business...");
            }
            mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
            mUnfinishedBusiness = true;
        }


        // Notify the power manager when ready.
        if (ready && mustNotify) {
            // Send state change.
            synchronized (mLock) {
                if (!mPendingRequestChangedLocked) {
                    mDisplayReadyLocked = true;


                    if (DEBUG) {
                        Slog.d(TAG, "Display ready!");
                    }
                }
            }
     //在该方法中回调PMS方法
            sendOnStateChangedWithWakelock();
        }


        // Release the wake lock when we have no unfinished business.
        if (finished && mUnfinishedBusiness) {
            if (DEBUG) {
                Slog.d(TAG, "Finished business...");
            }
            mUnfinishedBusiness = false;
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
        }


        // Record if dozing for future comparison.
        mDozing = state != Display.STATE_ON;


        if (previousPolicy != mPowerRequest.policy) {
            logDisplayPolicyChanged(mPowerRequest.policy);
        }
    }
}

从方法源码来看,这个方法可以拆分为六部分:

第一部分:初始化相关变量;

第二部分:根据PMS请求时携带的DisplayPowerState.policy以及PSensor相关确定要请求的屏幕状态state的值;

第三部分:调用animateScreenStateChange()方法设置屏幕状态(灭屏时还会先设置brightness=0);

第四部分:计算亮度值,即调节亮度时的值;

从代码看,在计算亮度值时,影响亮度值的有:自动调节亮度的亮度值、Doze状态下的亮度值(配置文件中读取)、用户手动设置的亮度值、Dim状态下的亮度值、低电量模式下的亮度值,最终会根据当前的场景来选择亮度值。

第五部分:通过animateScreenBrightness()设置亮度值调节动画;

第六部分:当完成屏幕状态更新和亮度更新后、调用WindowManagerPolicy的screenTurnedOn或screenTurnedOff方法。

DisplayPowerController animateScreenStateChange

调用animateScreenStateChange()方法设置屏幕状态,屏幕亮度(仅仅设置灭屏亮度0)、执行灭屏动画,同时调用WindowManager中的接口进行window的绘制等:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
        // If there is already an animation in progress, don't interfere with it.
//如果mColorFadeEnabled可用且有动画在执行还未结束,说明正在屏幕转换流程中
        if (mColorFadeEnabled &&
                (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
            if (target != Display.STATE_ON) {
  //如果目标状态不是亮屏状态,直接返回
                return;
            }
            // If display state changed to on, proceed and stop the color fade and turn screen on.
     //将该变量值置为false,该变量用来表示是否打算灭屏
            mPendingScreenOff = false;
        }


        if (mDisplayBlanksAfterDozeConfig
                && Display.isDozeState(mPowerState.getScreenState())
                && !Display.isDozeState(target)) {
            // Skip the screen off animation and add a black surface to hide the
            // contents of the screen.
            mPowerState.prepareColorFade(mContext,
                    mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
            if (mColorFadeOffAnimator != null) {
                mColorFadeOffAnimator.end();
            }
            // Some display hardware will blank itself on the transition between doze and non-doze
            // but still on display states. In this case we want to report to policy that the
            // display has turned off so it can prepare the appropriate power on animation, but we
            // don't want to actually transition to the fully off state since that takes
            // significantly longer to transition from.
            setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/); // 设置屏幕状态
        }


        // If we were in the process of turning off the screen but didn't quite
        // finish.  Then finish up now to prevent a jarring transition back
        // to screen on if we skipped blocking screen on as usual.
 //设置显示状态为灭屏状态,mPendingScreenOff表示打算灭屏,在进行灭屏时会设置为true
        if (mPendingScreenOff && target != Display.STATE_OFF) {
            setScreenState(Display.STATE_OFF); // 设置屏幕状态
            mPendingScreenOff = false;
            mPowerState.dismissColorFadeResources();
        }


 // 目标状态为亮屏,则调用setScreenState()设置,并根据返回值确定是否继续下面的操作
        if (target == Display.STATE_ON) {
            // Want screen on.  The contents of the screen may not yet
            // be visible if the color fade has not been dismissed because
            // its last frame of animation is solid black.
     // 设置屏幕状态
            if (!setScreenState(Display.STATE_ON)) {
                return; // screen on blocked
            }
     // 亮屏动画
            if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
                // Perform screen on animation.
                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 {
                // Skip screen on animation.
                mPowerState.setColorFadeLevel(1.0f);
                mPowerState.dismissColorFade();
            }
        } else if (target == Display.STATE_VR) {
            // Wait for brightness animation to complete beforehand when entering VR
            // from screen on to prevent a perceptible jump because brightness may operate
            // differently when the display is configured for dozing.
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() == Display.STATE_ON) {
                return;
            }


            // Set screen state.
     // 设置屏幕状态
            if (!setScreenState(Display.STATE_VR)) {
                return; // screen on blocked
            }


            // Dismiss the black surface without fanfare.
            mPowerState.setColorFadeLevel(1.0f);
            mPowerState.dismissColorFade();
        } else if (target == Display.STATE_DOZE) {
            // Want screen dozing.
            // Wait for brightness animation to complete beforehand when entering doze
            // from screen on to prevent a perceptible jump because brightness may operate
            // differently when the display is configured for dozing.
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() == Display.STATE_ON) {
                return;
            }


            // Set screen state.
     // 设置屏幕状态
            if (!setScreenState(Display.STATE_DOZE)) {
                return; // screen on blocked
            }


            // Dismiss the black surface without fanfare.
            mPowerState.setColorFadeLevel(1.0f);
            mPowerState.dismissColorFade();
        } else if (target == Display.STATE_DOZE_SUSPEND) {
            // Want screen dozing and suspended.
            // Wait for brightness animation to complete beforehand unless already
            // suspended because we may not be able to change it after suspension.
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
                return;
            }


            // If not already suspending, temporarily set the state to doze until the
            // screen on is unblocked, then suspend.
            if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
                if (!setScreenState(Display.STATE_DOZE)) { //设置屏幕状态
                    return; // screen on blocked
                }
  // 设置屏幕状态
                setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
            }


            // Dismiss the black surface without fanfare.
            mPowerState.setColorFadeLevel(1.0f);
            mPowerState.dismissColorFade();
        } else if (target == Display.STATE_ON_SUSPEND) {
            // Want screen full-power and suspended.
            // Wait for brightness animation to complete beforehand unless already
            // suspended because we may not be able to change it after suspension.
            if (mScreenBrightnessRampAnimator.isAnimating()
                    && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
                return;
            }


            // If not already suspending, temporarily set the state to on until the
            // screen on is unblocked, then suspend.
            if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
                if (!setScreenState(Display.STATE_ON)) { //设置屏幕状态
                    return;
                }
                setScreenState(Display.STATE_ON_SUSPEND); //设置屏幕状态
            }


            // Dismiss the black surface without fanfare.
            mPowerState.setColorFadeLevel(1.0f);
            mPowerState.dismissColorFade();
        } else {
            // Want screen off.
    // Want screen off.将mPendingScreenOff置为ture
            mPendingScreenOff = true;
            if (!mColorFadeEnabled) {
  //colorfadelevel和图像显示有关,正常显示时为1,灭屏后就为0了
                mPowerState.setColorFadeLevel(0.0f);
            }


     // 如果进入该语句,说明此时灭屏完成
            if (mPowerState.getColorFadeLevel() == 0.0f) {
                // Turn the screen off.
                // A black surface is already hiding the contents of the screen.
                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) {
                // Perform the screen off animation.
                mColorFadeOffAnimator.start(); //开始执行灭屏动画,ObjectAnimator集成ValueAnimator,实际上是开始一个Value动画
            } else {
                // Skip the screen off animation and add a black surface to hide the
                // contents of the screen.
                mColorFadeOffAnimator.end(); //停止执行灭屏动画
            }
        }
    }
}

DisplayPowerState setScreenState

根据亮屏和灭屏分别调用setScreenState(Display.STATE_ON)和setScreenState(Display.STATE_OFF)方法,这个方法会调用进入DisplayPoweState中,以及调用Window中的接口,来通知Window进行屏幕状态设置的一些工作,当WindowManager中处理完成后,又会回调DisplayPowerController中的方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private DisplayPowerState mPowerState;
    private boolean setScreenState(int state) {
        return setScreenState(state, false /*reportOnly*/);
    }


    private boolean setScreenState(int state, boolean reportOnly) {
        final boolean isOff = (state == Display.STATE_OFF);


//如果当前屏幕状态和将要设置的状态不同,则进入
        if (mPowerState.getScreenState() != state
                || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
            // If we are trying to turn screen off, give policy a chance to do something before we
            // actually turn the screen off.
     //灭屏且非PSensor灭屏
            if (isOff && !mScreenOffBecauseOfProximity) {
                if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON
                        || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
                    //设置报告的屏幕状态
                    setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
     //Window管理策略,在没有灭屏完成时,暂时阻塞屏幕灭屏
                    blockScreenOff();
      //通知WindowManager开始灭屏
                    mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker);
     //取消灭屏阻塞
                    unblockScreenOff();
                } else if (mPendingScreenOffUnblocker != null) {
                    // Abort doing the state change until screen off is unblocked.
                    return false;
                }
            }


            if (!reportOnly && mPowerState.getScreenState() != state) {
                Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
                // TODO(b/153319140) remove when we can get this from the above trace invocation
                SystemProperties.set("debug.tracing.screen_state", String.valueOf(state));
 //将目标状态设置为屏幕状态,同时进入DisplayPowerState中的逻辑
                mPowerState.setScreenState(state);
                // Tell battery stats about the transition.
                noteScreenState(state);
            }
        }


        // Tell the window manager policy when the screen is turned off or on unless it's due
        // to the proximity sensor.  We temporarily block turning the screen on until the
        // window manager is ready by leaving a black surface covering the screen.
        // This surface is essentially the final state of the color fade animation and
        // it is only removed once the window manager tells us that the activity has
        // finished drawing underneath.
        if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                && !mScreenOffBecauseOfProximity) {
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF); //设置报告屏幕状态的值
            unblockScreenOn();
            mWindowManagerPolicy.screenTurnedOff(mDisplayId); //通知WindowManager灭屏完成
        } else if (!isOff
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {


            // We told policy already that screen was turning off, but now we changed our minds.
            // Complete the full state transition on -> turningOff -> off.
            unblockScreenOff();
            mWindowManagerPolicy.screenTurnedOff(mDisplayId); //通知WindowManager灭屏完成
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
        }
 //如果不是灭屏&&屏幕报告值为灭屏(上次是灭屏),则这次为亮屏
        if (!isOff
                && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF
                        || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
            if (mPowerState.getColorFadeLevel() == 0.0f) {
                blockScreenOn();
            } else {
                unblockScreenOn();
            }
            mWindowManagerPolicy.screenTurningOn(mDisplayId, mPendingScreenOnUnblocker);
        }


        // Return true if the screen isn't blocked.
        return mPendingScreenOnUnblocker == null;
    }
}

调用mPowerState(DisplayPowerState)的setScreenState方法,设置屏幕状态:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
final class DisplayPowerState {
    public void setScreenState(int state) {
        if (mScreenState != state) {
            if (DEBUG) {
                Slog.d(TAG, "setScreenState: state=" + state);
            }


            mScreenState = state;
            mScreenReady = false;
            scheduleScreenUpdate();
        }
    }
}

调用DisplayPowerState的scheduleScreenUpdate方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
final class DisplayPowerState {
    private void scheduleScreenUpdate() {
        if (!mScreenUpdatePending) {
            mScreenUpdatePending = true;
            postScreenUpdateThreadSafe();
        }
    }
}

调用DisplayPowerState的postScreenUpdateThreadSafe方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
final class DisplayPowerState {
    private void postScreenUpdateThreadSafe() {
        mHandler.removeCallbacks(mScreenUpdateRunnable);
        mHandler.post(mScreenUpdateRunnable);
    }
}

调用DisplayPowerState的mScreenUpdateRunnable:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
final class DisplayPowerState {
    private final PhotonicModulator mPhotonicModulator;
    private final Runnable mScreenUpdateRunnable = new Runnable() {
        @Override
        public void run() {
            mScreenUpdatePending = false;


            float brightnessState = mScreenState != Display.STATE_OFF
                    && mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
            float sdrBrightnessState = mScreenState != Display.STATE_OFF
                    && mColorFadeLevel > 0f
                            ? mSdrScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
            if (mPhotonicModulator.setState(mScreenState, brightnessState, sdrBrightnessState)) {
                if (DEBUG) {
                    Slog.d(TAG, "Screen ready");
                }
                mScreenReady = true;
                invokeCleanListenerIfNeeded();
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Screen not ready");
                }
            }
        }
    }
}

调用mPhotonicModulator(PhotonicModulator)的setState方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
final class DisplayPowerState {
    private final class PhotonicModulator extends Thread {
        public boolean setState(int state, float brightnessState, float sdrBrightnessState) {
            synchronized (mLock) {
                boolean stateChanged = state != mPendingState;
                boolean backlightChanged = brightnessState != mPendingBacklight
                        || sdrBrightnessState != mPendingSdrBacklight;
                if (stateChanged || backlightChanged) {
                    if (DEBUG) {
                        Slog.d(TAG, "Requesting new screen state: state="
                                + Display.stateToString(state) + ", backlight=" + brightnessState);
                    }


                    mPendingState = state;
                    mPendingBacklight = brightnessState;
                    mPendingSdrBacklight = sdrBrightnessState;
                    boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
                    mStateChangeInProgress = stateChanged || mStateChangeInProgress;
                    mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;


                    if (!changeInProgress) {
                        mLock.notifyAll(); //释放锁
                    }
                }
                return !mStateChangeInProgress;
            }
        }
    }
}

调用mLock.notifyAll方法进行锁的释放,之后会运行PhotonicModulator的run方法中mLock.wait();后的代码:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
final class DisplayPowerState {
    private final DisplayBlanker mBlanker;
    private final class PhotonicModulator extends Thread {
        public void run() {
            for (;;) {
                // Get pending change.
                final int state;
                final boolean stateChanged;
                final float brightnessState;
                final float sdrBrightnessState;
                final boolean backlightChanged;
                synchronized (mLock) {
                    state = mPendingState;
                    stateChanged = (state != mActualState);
                    brightnessState = mPendingBacklight;
                    sdrBrightnessState = mPendingSdrBacklight;
                    backlightChanged = brightnessState != mActualBacklight
                            || sdrBrightnessState != mActualSdrBacklight;
                    if (!stateChanged) {
                        // State changed applied, notify outer class.
                        postScreenUpdateThreadSafe();
                        mStateChangeInProgress = false;
                    }
                    if (!backlightChanged) {
                        mBacklightChangeInProgress = false;
                    }
                    boolean valid = state != Display.STATE_UNKNOWN && !Float.isNaN(brightnessState);
                    boolean changed = stateChanged || backlightChanged;
                    if (!valid || !changed) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException ex) {
                            if (mStopped) {
                                return;
                            }
                        }
                        continue;
                    }
                    mActualState = state;
                    mActualBacklight = brightnessState;
                    mActualSdrBacklight = sdrBrightnessState;
                }


                // Apply pending change.
                if (DEBUG) {
                    Slog.d(TAG, "Updating screen state: id=" + mDisplayId +  ", state="
                            + Display.stateToString(state) + ", backlight=" + brightnessState
                            + ", sdrBacklight=" + sdrBrightnessState);
                }
                mBlanker.requestDisplayState(mDisplayId, state, brightnessState,
                        sdrBrightnessState);
            }
        }
    }
}

调用mBlanker(DisplayBlanker)的requestDisplayState方法,DisplayBlanker是一个接口,再DisplayManagerService中实现:

//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
    private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
        // Synchronized to avoid race conditions when updating multiple display states.
        @Override
        public synchronized void requestDisplayState(int displayId, int state, float brightness,
                float sdrBrightness) {
            boolean allInactive = true;
            boolean allOff = true;
            final boolean stateChanged;
            synchronized (mSyncRoot) {
                final int index = mDisplayStates.indexOfKey(displayId);
                if (index > -1) {
                    final int currentState = mDisplayStates.valueAt(index);
                    stateChanged = state != currentState;
                    if (stateChanged) {
                        final int size = mDisplayStates.size();
                        for (int i = 0; i < size; i++) {
                            final int displayState = i == index ? state : mDisplayStates.valueAt(i);
                            if (displayState != Display.STATE_OFF) {
                                allOff = false;
                            }
                            if (Display.isActiveState(displayState)) {
                                allInactive = false;
                            }
                            if (!allOff && !allInactive) {
                                break;
                            }
                        }
                    }
                } else {
                    stateChanged = false;
                }
            }


            // The order of operations is important for legacy reasons.
            if (state == Display.STATE_OFF) {
                requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
            }


            if (stateChanged) {
                mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff);
            }


            if (state != Display.STATE_OFF) {
                requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
            }
        }
    }
}

调用DisplayManagerService的requestDisplayStateInternal方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
    private void requestDisplayStateInternal(int displayId, int state, float brightnessState,
            float sdrBrightnessState) {
        if (state == Display.STATE_UNKNOWN) {
            state = Display.STATE_ON;
        }


        brightnessState = clampBrightness(state, brightnessState);
        sdrBrightnessState = clampBrightness(state, sdrBrightnessState);


        // Update the display state within the lock.
        // Note that we do not need to schedule traversals here although it
        // may happen as a side-effect of displays changing state.
        final Runnable runnable;
        final String traceMessage;
        synchronized (mSyncRoot) {
            final int index = mDisplayStates.indexOfKey(displayId);


            final BrightnessPair brightnessPair =
                    index < 0 ? null : mDisplayBrightnesses.valueAt(index);
            if (index < 0 || (mDisplayStates.valueAt(index) == state
                    && brightnessPair.brightness == brightnessState
                    && brightnessPair.sdrBrightness == sdrBrightnessState)) {
                return; // Display no longer exists or no change.
            }


            traceMessage = "requestDisplayStateInternal("
                    + displayId + ", "
                    + Display.stateToString(state)
                    + ", brightness=" + brightnessState
                    + ", sdrBrightness=" + sdrBrightnessState + ")";
            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId);


            mDisplayStates.setValueAt(index, state);
            brightnessPair.brightness = brightnessState;
            brightnessPair.sdrBrightness = sdrBrightnessState;
            runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId)
                    .getPrimaryDisplayDeviceLocked());
        }


        // Setting the display power state can take hundreds of milliseconds
        // to complete so we defer the most expensive part of the work until
        // after we have exited the critical section to avoid blocking other
        // threads for a long time.
        if (runnable != null) {
            runnable.run();
        }
        Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, traceMessage, displayId);
    }
}

调用DisplayManagerService的updateDisplayStateLocked方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
    private Runnable updateDisplayStateLocked(DisplayDevice device) {
        // Blank or unblank the display immediately to match the state requested
        // by the display power controller (if known).
        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
            final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
            if (display == null) {
                return null;
            }
            final int displayId = display.getDisplayIdLocked();
            final int state = mDisplayStates.get(displayId);


            // Only send a request for display state if display state has already been initialized.
            if (state != Display.STATE_UNKNOWN) {
                final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
                return device.requestDisplayStateLocked(state, brightnessPair.brightness,
                        brightnessPair.sdrBrightness);
            }
        }
        return null;
    }
}

调用device(DisplayDevice)的requestDisplayStateLocked方法,DisplayDevice是一个抽象类,在LocalDisplayAdapter的内部类LocalDisplayDevice实现:

//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
    private final SurfaceControlProxy mSurfaceControlProxy;
    private final class LocalDisplayDevice extends DisplayDevice {
        private final BacklightAdapter mBacklightAdapter;
        public Runnable requestDisplayStateLocked(final int state, final float brightnessState,
                final float sdrBrightnessState) {
            // Assume that the brightness is off if the display is being turned off.
            assert state != Display.STATE_OFF
                    || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT;
            final boolean stateChanged = (mState != state);
            final boolean brightnessChanged = mBrightnessState != brightnessState
                    || mSdrBrightnessState != sdrBrightnessState;
            if (stateChanged || brightnessChanged) {
                final long physicalDisplayId = mPhysicalDisplayId;
                final IBinder token = getDisplayTokenLocked();
                final int oldState = mState;


                if (stateChanged) {
                    mState = state;
                    updateDeviceInfoLocked();
                }


                // Defer actually setting the display state until after we have exited
                // the critical section since it can take hundreds of milliseconds
                // to complete.
                return new Runnable() {
                    @Override
                    public void run() {
                        // Exit a suspended state before making any changes.
                        int currentState = oldState;
                        if (Display.isSuspendedState(oldState)
                                || oldState == Display.STATE_UNKNOWN) {
                            if (!Display.isSuspendedState(state)) {
                                setDisplayState(state);
                                currentState = state;
                            } else if (state == Display.STATE_DOZE_SUSPEND
                                    || oldState == Display.STATE_DOZE_SUSPEND) {
                                setDisplayState(Display.STATE_DOZE);
                                currentState = Display.STATE_DOZE;
                            } else if (state == Display.STATE_ON_SUSPEND
                                    || oldState == Display.STATE_ON_SUSPEND) {
                                setDisplayState(Display.STATE_ON);
                                currentState = Display.STATE_ON;


                            // If UNKNOWN, we still want to set the initial display state,
                            // otherwise, return early.
                            } else if (oldState != Display.STATE_UNKNOWN) {
                                return; // old state and new state is off
                            }
                        }


                        // If the state change was from or to VR, then we need to tell the light
                        // so that it can apply appropriate VR brightness settings. Also, update the
                        // brightness so the state is propogated to light.
                        boolean vrModeChange = false;
                        if ((state == Display.STATE_VR || currentState == Display.STATE_VR) &&
                                currentState != state) {
                            setVrMode(state == Display.STATE_VR);
                            vrModeChange = true;
                        }


                        // Apply brightness changes given that we are in a non-suspended state.
                        if (brightnessChanged || vrModeChange) {
                            setDisplayBrightness(brightnessState, sdrBrightnessState);
                            mBrightnessState = brightnessState;
                            mSdrBrightnessState = sdrBrightnessState;
                        }


                        // Enter the final desired state, possibly suspended.
                        if (state != currentState) {
                            setDisplayState(state);
                        }
                    }


                    private void setVrMode(boolean isVrEnabled) {
                        if (DEBUG) {
                            Slog.d(TAG, "setVrMode("
                                    + "id=" + physicalDisplayId
                                    + ", state=" + Display.stateToString(state) + ")");
                        }
                        mBacklightAdapter.setVrMode(isVrEnabled);
                    }


                    private void setDisplayState(int state) {
                        if (DEBUG) {
                            Slog.d(TAG, "setDisplayState("
                                    + "id=" + physicalDisplayId
                                    + ", state=" + Display.stateToString(state) + ")");
                        }


                        // We must tell sidekick to stop controlling the display before we
                        // can change its power mode, so do that first.
                        if (mSidekickActive) {
                            Trace.traceBegin(Trace.TRACE_TAG_POWER,
                                    "SidekickInternal#endDisplayControl");
                            try {
                                mSidekickInternal.endDisplayControl();
                            } finally {
                                Trace.traceEnd(Trace.TRACE_TAG_POWER);
                            }
                            mSidekickActive = false;
                        }
                        final int mode = getPowerModeForState(state);
                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
                                + "id=" + physicalDisplayId
                                + ", state=" + Display.stateToString(state) + ")");
                        try {
                            mSurfaceControlProxy.setDisplayPowerMode(token, mode);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                        // If we're entering a suspended (but not OFF) power state and we
                        // have a sidekick available, tell it now that it can take control.
                        if (Display.isSuspendedState(state) && state != Display.STATE_OFF
                                && mSidekickInternal != null && !mSidekickActive) {
                            Trace.traceBegin(Trace.TRACE_TAG_POWER,
                                    "SidekickInternal#startDisplayControl");
                            try {
                                mSidekickActive = mSidekickInternal.startDisplayControl(state);
                            } finally {
                                Trace.traceEnd(Trace.TRACE_TAG_POWER);
                            }
                        }
                    }


                    private void setDisplayBrightness(float brightnessState,
                            float sdrBrightnessState) {
                        // brightnessState includes invalid, off and full range.
                        if (Float.isNaN(brightnessState) || Float.isNaN(sdrBrightnessState)) {
                            return;
                        }


                        if (DEBUG) {
                            Slog.d(TAG, "setDisplayBrightness("
                                    + "id=" + physicalDisplayId
                                    + ", brightnessState=" + brightnessState
                                    + ", sdrBrightnessState=" + sdrBrightnessState + ")");
                        }


                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
                                + "id=" + physicalDisplayId + ", brightnessState="
                                + brightnessState + ", sdrBrightnessState=" + sdrBrightnessState
                                + ")");
                        try {
                            final float backlight = brightnessToBacklight(brightnessState);
                            final float sdrBacklight = brightnessToBacklight(sdrBrightnessState);


                            final float nits = backlightToNits(backlight);
                            final float sdrNits = backlightToNits(sdrBacklight);


                            mBacklightAdapter.setBacklight(sdrBacklight, sdrNits, backlight, nits);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "ScreenBrightness",
                                    BrightnessSynchronizer.brightnessFloatToInt(brightnessState));
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "SdrScreenBrightness",
                                    BrightnessSynchronizer.brightnessFloatToInt(
                                            sdrBrightnessState));
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }


                    private float brightnessToBacklight(float brightness) {
                        if (brightness == PowerManager.BRIGHTNESS_OFF_FLOAT) {
                            return PowerManager.BRIGHTNESS_OFF_FLOAT;
                        } else {
                            return getDisplayDeviceConfig().getBacklightFromBrightness(brightness);
                        }
                    }


                    private float backlightToNits(float backlight) {
                        return getDisplayDeviceConfig().getNitsFromBacklight(backlight);
                    }
                };
            }
            return null;
        }
    }
}

上面方法主要处理如下:

1、调用setDisplayState方法,在方法中调用mSurfaceControlProxy(SurfaceControlProxy)的setDisplayPowerMode方法。

//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
    static class SurfaceControlProxy {
        public void setDisplayPowerMode(IBinder displayToken, int mode) {
            SurfaceControl.setDisplayPowerMode(displayToken, mode);
        }
    }
}

调用SurfaceControl的setDisplayPowerMode方法:

待更新

2、调用setDisplayBrightness方法,在方法中调用mBacklightAdapter(BacklightAdapter)的setBacklight方法。

//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
    static class BacklightAdapter {
        private final LogicalLight mBacklight;
        void setBacklight(float sdrBacklight, float sdrNits, float backlight, float nits) {
            if (mUseSurfaceControlBrightness || mForceSurfaceControl) { //如果使用SurfaceControl的Brightness
                if (BrightnessSynchronizer.floatEquals(
                        sdrBacklight, PowerManager.BRIGHTNESS_INVALID_FLOAT)) {
                    mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, backlight);
                } else {
                    mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, sdrBacklight, sdrNits,
                            backlight, nits);
                }
            } else if (mBacklight != null) {
                mBacklight.setBrightness(backlight);
            }
        }
    }
}

上面方法判断是否使用SurfaceControl的Brightness,如果使用就调用mSurfaceControlProxy(SurfaceControlProxy)的setBrightness方法:

//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
    static class SurfaceControlProxy {
        public boolean setDisplayBrightness(IBinder displayToken, float brightness) {
            return SurfaceControl.setDisplayBrightness(displayToken, brightness);
        }
    }
}
SurfaceControl setDisplayBrightness

调用SurfaceControl的setDisplayBrightness方法:

待更新

LightsService LightImpl setBrightness

如果不使用SurfaceControl的Brightness,就调用mBacklight(LogicalLight)的setBrightness方法,LogicalLight是一个抽象类,由LightsService的内部类LightImpl实现:

待更新

DisplayPowerController animateScreenBrightness

通过animateScreenBrightness()设置亮度值(背光值):

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private void animateScreenBrightness(float target, float sdrTarget, float rate) {
        if (DEBUG) {
            Slog.d(TAG, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
                    + ", rate=" + rate);
        }
        if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) {
            Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
            // TODO(b/153319140) remove when we can get this from the above trace invocation
            SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target));
            noteScreenBrightness(target);
        }
    }
}

在这个方法中,只有调用了一个对象的animateTo()方法,并将其参数传给了animateTo(),其他什么也没有做。在这个方法中,第一个参数是updatePowerState()中获得的最终亮度值,第二个参数则和亮度设置时的动画效果有关系,如果设置为大于0的数,那么会在animateTo()方法中根据这个数逐渐地设置亮度,如果设置为小于等于0,那么则不会有动画效果,直接将亮度值一次性设置。

//frameworks/base/services/core/java/com/android/server/display/RampAnimator.java
class RampAnimator<T> {
    public boolean animateTo(float targetLinear, float rate) {
        // Convert the target from the linear into the HLG space.
        final float target = BrightnessUtils.convertLinearToGamma(targetLinear);


        // Immediately jump to the target the first time.
        if (mFirstTime || rate <= 0) {
            if (mFirstTime || target != mCurrentValue) {
                mFirstTime = false;
                mRate = 0;
                mTargetValue = target;
                mCurrentValue = target;
                setPropertyValue(target);
                if (mAnimating) {
                    mAnimating = false;
                    cancelAnimationCallback();
                }
                if (mListener != null) {
                    mListener.onAnimationEnd();
                }
                return true;
            }
            return false;
        }


        // Adjust the rate so that we do not exceed our maximum animation time.
        if (target > mCurrentValue && mAnimationIncreaseMaxTimeSecs > 0.0f
                && ((target - mCurrentValue) / rate) > mAnimationIncreaseMaxTimeSecs) {
            rate = (target - mCurrentValue) / mAnimationIncreaseMaxTimeSecs;
        } else if (target < mCurrentValue && mAnimationDecreaseMaxTimeSecs > 0.0f
                && ((mCurrentValue - target) / rate) > mAnimationDecreaseMaxTimeSecs) {
            rate = (mCurrentValue - target) / mAnimationDecreaseMaxTimeSecs;
        }


        // Adjust the rate based on the closest target.
        // If a faster rate is specified, then use the new rate so that we converge
        // more rapidly based on the new request.
        // If a slower rate is specified, then use the new rate only if the current
        // value is somewhere in between the new and the old target meaning that
        // we will be ramping in a different direction to get there.
        // Otherwise, continue at the previous rate.
        if (!mAnimating
                || rate > mRate
                || (target <= mCurrentValue && mCurrentValue <= mTargetValue)
                || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {
            mRate = rate;
        }


        final boolean changed = (mTargetValue != target);
        mTargetValue = target;


        // Start animating.
        if (!mAnimating && target != mCurrentValue) {
            mAnimating = true;
            mAnimatedValue = mCurrentValue;
            mLastFrameTimeNanos = System.nanoTime();
            postAnimationCallback();
        }


        return changed;
    }
}

动画结束调用postAnimationCallback方法:

//frameworks/base/services/core/java/com/android/server/display/RampAnimator.java
class RampAnimator<T> {
    private Listener mListener;
    private void postAnimationCallback() {
        mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
    }


    private final Runnable mAnimationCallback = new Runnable() {
        @Override // Choreographer callback
        public void run() {
            final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
            final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
                    * 0.000000001f;
            mLastFrameTimeNanos = frameTimeNanos;


            // Advance the animated value towards the target at the specified rate
            // and clamp to the target. This gives us the new current value but
            // we keep the animated value around to allow for fractional increments
            // towards the target.
            final float scale = ValueAnimator.getDurationScale();
            if (scale == 0) {
                // Animation off.
                mAnimatedValue = mTargetValue;
            } else {
                final float amount = timeDelta * mRate / scale;
                if (mTargetValue > mCurrentValue) {
                    mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue);
                } else {
                    mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue);
                }
            }
            final float oldCurrentValue = mCurrentValue;
            mCurrentValue = mAnimatedValue;
            if (oldCurrentValue != mCurrentValue) {
                setPropertyValue(mCurrentValue);
            }
            if (mTargetValue != mCurrentValue) {
                postAnimationCallback();
            } else {
                mAnimating = false;
                if (mListener != null) {
                    mListener.onAnimationEnd();
                }
            }
        }
    }


    public interface Listener {
        void onAnimationEnd();
    }
}

DisplayPowerController onAnimationEnd

调用RampAnimator.Listener的onAnimationEnd方法,在DisplayPowerController中实现:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
        @Override
        public void onAnimationEnd() {
            sendUpdatePowerState();
            Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_RAMP_DONE);
            mHandler.sendMessage(msg);
        }
    };
}

发送MSG_BRIGHTNESS_RAMP_DONE消息,发送的消息在DisplayPowerController的内部类DisplayControllerHandler的handleMessage方法中处理:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private final class DisplayControllerHandler extends Handler {
        public DisplayControllerHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }


        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_BRIGHTNESS_RAMP_DONE:
                    if (mPowerState != null)  {
                        final float brightness = mPowerState.getScreenBrightness();
                        reportStats(brightness);
                    }
                    break;
            }
        }
    }
}

调用DisplayPowerController的reportStats方法:

//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
        DisplayWhiteBalanceController.Callbacks {
    private void reportStats(float brightness) {
        if (mLastStatsBrightness == brightness) {
            return;
        }


        float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX;
        synchronized(mCachedBrightnessInfo) {
            if (mCachedBrightnessInfo.hbmTransitionPoint == null) {
                return;
            }
            hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value;
        }


        final boolean aboveTransition = brightness > hbmTransitionPoint;
        final boolean oldAboveTransition = mLastStatsBrightness > hbmTransitionPoint;


        if (aboveTransition || oldAboveTransition) {
            mLastStatsBrightness = brightness;
            mHandler.removeMessages(MSG_STATSD_HBM_BRIGHTNESS);
            if (aboveTransition != oldAboveTransition) {
                // report immediately
                logHbmBrightnessStats(brightness, mDisplayStatsId);
            } else {
                // delay for rate limiting
                Message msg = mHandler.obtainMessage();
                msg.what = MSG_STATSD_HBM_BRIGHTNESS;
                msg.arg1 = Float.floatToIntBits(brightness);
                msg.arg2 = mDisplayStatsId;
                mHandler.sendMessageDelayed(msg, BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
            }
        }
    }
}

PhoneWindowManager screenTurnedOn

调用WindowManagerPolicy的screenTurnedOn方法,WindowManagerPolicy是一个接口,PhoneWindowManager实现这个接口:

待更新

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值