Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90d60031 authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

Doze brightness strategy

Move the remaining doze brightness logic to DozeBrightnessStrategy. The strategy computes the brightness in one of the following ways:
- a brightness override from Dream Manager
- current brightness setting * doze scale factor (if there's an offload session)
- default doze brightness

Add a missing test to AutomaticBrightnessControllerTest and DisplayBrightnessStrategySelectorTest.

Bug: 341894395
Test: atest DisplayServiceTests
Flag: com.android.server.display.feature.flags.doze_brightness_strategy
Change-Id: I213fba54d8a03f1dfd3a120a579ae3491a3b834e
parent 0a91f032
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -487,6 +487,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private boolean mBootCompleted;
    private final DisplayManagerFlags mFlags;

    @Nullable
    private DisplayOffloadSession mDisplayOffloadSession;

    // Used to scale the brightness in doze mode
@@ -598,7 +599,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                new DisplayBrightnessController(context, null,
                        mDisplayId, mLogicalDisplay.getDisplayInfoLocked().brightnessDefault,
                        brightnessSetting, () -> postBrightnessChangeRunnable(),
                        new HandlerExecutor(mHandler), flags);
                        new HandlerExecutor(mHandler), flags, mDisplayDeviceConfig);

        String thermalBrightnessThrottlingDataId =
                logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
@@ -974,6 +975,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        reloadReduceBrightColours();
        setAnimatorRampSpeeds(/* isIdleMode= */ false);

        mDisplayBrightnessController.onDisplayChanged(mDisplayDeviceConfig);
        mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
    }

@@ -1506,7 +1508,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            brightnessState = clampScreenBrightness(brightnessState);
        }

        if (useDozeBrightness && (Float.isNaN(brightnessState)
        if (!mFlags.isDozeBrightnessStrategyEnabled() && useDozeBrightness
                && (Float.isNaN(brightnessState)
                || displayBrightnessState.getDisplayBrightnessStrategyName()
                .equals(DisplayBrightnessStrategyConstants.FALLBACK_BRIGHTNESS_STRATEGY_NAME))) {
            if (mFlags.isDisplayOffloadEnabled() && mDisplayOffloadSession != null
@@ -2518,8 +2521,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    }

    public float getDozeBrightnessForOffload() {
        if (mFlags.isDozeBrightnessStrategyEnabled()) {
            return mDisplayBrightnessController.getManualDozeBrightness();
        } else {
            return mDisplayBrightnessController.getCurrentBrightness() * mDozeScaleFactor;
        }
    }

    public void setBrightness(float brightness) {
        // After HBMController and NBMController migration to Clampers framework
+29 −7
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ public final class DisplayBrightnessController {
    public DisplayBrightnessController(Context context, Injector injector, int displayId,
            float defaultScreenBrightness, BrightnessSetting brightnessSetting,
            Runnable onBrightnessChangeRunnable, HandlerExecutor brightnessChangeExecutor,
            DisplayManagerFlags flags) {
            DisplayManagerFlags flags, DisplayDeviceConfig config) {
        if (injector == null) {
            injector = new Injector();
        }
@@ -131,7 +131,7 @@ public final class DisplayBrightnessController {
        mCurrentScreenBrightness = getScreenBrightnessSetting();
        mOnBrightnessChangeRunnable = onBrightnessChangeRunnable;
        mDisplayBrightnessStrategySelector = injector.getDisplayBrightnessStrategySelector(context,
                displayId, flags);
                displayId, flags, config);
        mBrightnessChangeExecutor = brightnessChangeExecutor;
        mPersistBrightnessNitsForDefaultDisplay = context.getResources().getBoolean(
                com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay);
@@ -158,7 +158,8 @@ public final class DisplayBrightnessController {
                    constructStrategySelectionRequest(displayPowerRequest, targetDisplayState,
                            displayOffloadSession, isBedtimeModeWearEnabled));
            state = mDisplayBrightnessStrategy
                        .updateBrightness(constructStrategyExecutionRequest(displayPowerRequest));
                        .updateBrightness(constructStrategyExecutionRequest(displayPowerRequest,
                                displayOffloadSession));
        }

        // This is a temporary measure until AutomaticBrightnessStrategy works as a traditional
@@ -445,6 +446,26 @@ public final class DisplayBrightnessController {
        return mAutomaticBrightnessController.getBrightnessFromNits(nits);
    }

    /**
     * @return The brightness manually selected by the user, scaled for doze.
     */
    public float getManualDozeBrightness() {
        synchronized (mLock) {
            return mDisplayBrightnessStrategySelector.getDozeBrightnessStrategy()
                    .getManualDozeBrightness(getCurrentBrightness());
        }
    }

    /**
     * Update the config values. Needs to be called when the underlying display device changes.
     * @param config The Display Device Config
     */
    public void onDisplayChanged(DisplayDeviceConfig config) {
        synchronized (mLock) {
            mDisplayBrightnessStrategySelector.onDisplayChanged(config);
        }
    }

    /**
     * Stops the associated listeners when the display is stopped. Invoked when the {@link
     * #mDisplayId} is being removed.
@@ -536,9 +557,9 @@ public final class DisplayBrightnessController {
    @VisibleForTesting
    static class Injector {
        DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(Context context,
                int displayId, DisplayManagerFlags flags) {
                int displayId, DisplayManagerFlags flags, DisplayDeviceConfig config) {
            return new DisplayBrightnessStrategySelector(context, /* injector= */ null, displayId,
                    flags);
                    flags, config);
        }
    }

@@ -657,9 +678,10 @@ public final class DisplayBrightnessController {
    }

    private StrategyExecutionRequest constructStrategyExecutionRequest(
            DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
            DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
            DisplayManagerInternal.DisplayOffloadSession offloadSession) {
        float currentScreenBrightness = getCurrentBrightness();
        return new StrategyExecutionRequest(displayPowerRequest, currentScreenBrightness,
                mUserSetScreenBrightnessUpdated, mIsStylusBeingUsed);
                mUserSetScreenBrightnessUpdated, mIsStylusBeingUsed, offloadSession);
    }
}
+54 −12
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.display.brightness;

import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -27,6 +29,7 @@ import android.view.Display;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.brightness.strategy.AutoBrightnessFallbackStrategy;
import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2;
@@ -115,14 +118,16 @@ public class DisplayBrightnessStrategySelector {
     * The constructor of DozeBrightnessStrategy.
     */
    public DisplayBrightnessStrategySelector(Context context, Injector injector, int displayId,
            DisplayManagerFlags flags) {
            DisplayManagerFlags flags, DisplayDeviceConfig config) {
        if (injector == null) {
            injector = new Injector();
        }
        mContext = context;
        mDisplayManagerFlags = flags;
        mDisplayId = displayId;
        mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy();
        mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy(mDisplayManagerFlags, context,
                displayId, BrightnessUtils.clampAbsoluteBrightness(
                        config.getDefaultDozeBrightness()));
        mScreenOffBrightnessStrategy = injector.getScreenOffBrightnessStrategy();
        mOverrideBrightnessStrategy = injector.getOverrideBrightnessStrategy();
        mTemporaryBrightnessStrategy = injector.getTemporaryBrightnessStrategy();
@@ -176,7 +181,7 @@ public class DisplayBrightnessStrategySelector {
        setAllowAutoBrightnessWhileDozing(strategySelectionRequest.getDisplayOffloadSession());
        if (targetDisplayState == Display.STATE_OFF) {
            displayBrightnessStrategy = mScreenOffBrightnessStrategy;
        } else if (shouldUseDozeBrightnessStrategy(displayPowerRequest)) {
        } else if (shouldUseDozeBrightnessStrategy(displayPowerRequest, targetDisplayState)) {
            displayBrightnessStrategy = mDozeBrightnessStrategy;
        } else if (BrightnessUtils.isValidBrightnessValue(
                mFollowerBrightnessStrategy.getBrightnessToFollow())) {
@@ -265,6 +270,19 @@ public class DisplayBrightnessStrategySelector {
        return mOverrideBrightnessStrategy;
    }

    public DozeBrightnessStrategy getDozeBrightnessStrategy() {
        return mDozeBrightnessStrategy;
    }

    /**
     * Update the config values. Needs to be called when the underlying display device changes.
     * @param config The Display Device Config
     */
    void onDisplayChanged(DisplayDeviceConfig config) {
        getDozeBrightnessStrategy().setDefaultDozeBrightness(
                BrightnessUtils.clampAbsoluteBrightness(config.getDefaultDozeBrightness()));
    }

    /**
     * Dumps the state of this class.
     */
@@ -345,16 +363,39 @@ public class DisplayBrightnessStrategySelector {
    /**
     * Validates if the conditions are met to qualify for the DozeBrightnessStrategy.
     */
    private boolean shouldUseDozeBrightnessStrategy(DisplayPowerRequest displayPowerRequest) {
    private boolean shouldUseDozeBrightnessStrategy(
            DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
            int targetDisplayState) {
        // Check mAllowAutoBrightnessWhileDozingConfig, not mAllowAutoBrightnessWhileDozing. If
        // the first one is true but the second is false, it means that the offload session
        // temporarily disabled auto-brightness, in which case we want to use
        // FallbackBrightnessStrategy to keep the current brightness, not DozeBrightnessStrategy.
        if (mAutomaticBrightnessStrategy.shouldUseAutoBrightness()
                && mAllowAutoBrightnessWhileDozingConfig) {
            // Auto-brightness in doze is enabled so we shouldn't use this strategy
            return false;
        }

        // Exception check (controlled by feature flag) - use doze brightness if one of following is
        // true:
        // 1. The target `state` isDozeState
        // 2. There's no exception (useNormalBrightnessForDoze)
        boolean normalBrightnessExceptionCheck =
                !mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
                        || !displayPowerRequest.useNormalBrightnessForDoze || Display.isDozeState(
                        targetDisplayState);

        // If the flag is disabled, only use the strategy if there's a valid override from Dream
        // Manager (the original behavior)
        boolean overrideDozeBrightnessCheck = mDisplayManagerFlags.isDozeBrightnessStrategyEnabled()
                || BrightnessUtils.isValidBrightnessValue(displayPowerRequest.dozeScreenBrightness);

        // We are not checking the targetDisplayState, but rather relying on the policy because
        // a user can define a different display state (displayPowerRequest.dozeScreenState) too
        // in the request with the Doze policy and user might request an override to force certain
        // brightness.
        return (!mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
                || !displayPowerRequest.useNormalBrightnessForDoze)
                && displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
                && !mAllowAutoBrightnessWhileDozing
                && BrightnessUtils.isValidBrightnessValue(displayPowerRequest.dozeScreenBrightness);
        return displayPowerRequest.policy == POLICY_DOZE && normalBrightnessExceptionCheck
                && overrideDozeBrightnessCheck;
    }

    @VisibleForTesting
@@ -363,8 +404,9 @@ public class DisplayBrightnessStrategySelector {
            return new ScreenOffBrightnessStrategy();
        }

        DozeBrightnessStrategy getDozeBrightnessStrategy() {
            return new DozeBrightnessStrategy();
        DozeBrightnessStrategy getDozeBrightnessStrategy(DisplayManagerFlags flags,
                Context context, int displayId, float defaultDozeBrightness) {
            return new DozeBrightnessStrategy(flags, context, displayId, defaultDozeBrightness);
        }

        OverrideBrightnessStrategy getOverrideBrightnessStrategy() {
+14 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.display.brightness;

import android.annotation.Nullable;
import android.hardware.display.DisplayManagerInternal;

import java.util.Objects;
@@ -34,13 +35,18 @@ public final class StrategyExecutionRequest {

    private boolean mIsStylusBeingUsed;

    @Nullable
    private final DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession;

    public StrategyExecutionRequest(DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
            float currentScreenBrightness, boolean userSetBrightnessChanged,
            boolean isStylusBeingUsed) {
            boolean isStylusBeingUsed,
            DisplayManagerInternal.DisplayOffloadSession offloadSession) {
        mDisplayPowerRequest = displayPowerRequest;
        mCurrentScreenBrightness = currentScreenBrightness;
        mUserSetBrightnessChanged = userSetBrightnessChanged;
        mIsStylusBeingUsed = isStylusBeingUsed;
        mDisplayOffloadSession = offloadSession;
    }

    public DisplayManagerInternal.DisplayPowerRequest getDisplayPowerRequest() {
@@ -59,6 +65,10 @@ public final class StrategyExecutionRequest {
        return mIsStylusBeingUsed;
    }

    public DisplayManagerInternal.DisplayOffloadSession getOffloadSession() {
        return mDisplayOffloadSession;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof StrategyExecutionRequest)) {
@@ -68,12 +78,13 @@ public final class StrategyExecutionRequest {
        return Objects.equals(mDisplayPowerRequest, other.getDisplayPowerRequest())
                && mCurrentScreenBrightness == other.getCurrentScreenBrightness()
                && mUserSetBrightnessChanged == other.isUserSetBrightnessChanged()
                && mIsStylusBeingUsed == other.isStylusBeingUsed();
                && mIsStylusBeingUsed == other.isStylusBeingUsed()
                && mDisplayOffloadSession == other.mDisplayOffloadSession;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mDisplayPowerRequest, mCurrentScreenBrightness,
                mUserSetBrightnessChanged, mIsStylusBeingUsed);
                mUserSetBrightnessChanged, mIsStylusBeingUsed, mDisplayOffloadSession);
    }
}
+86 −7
Original line number Diff line number Diff line
@@ -16,27 +16,84 @@

package com.android.server.display.brightness.strategy;

import android.content.Context;
import android.service.dreams.DreamService;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.brightness.BrightnessUtils;
import com.android.server.display.brightness.StrategyExecutionRequest;
import com.android.server.display.brightness.StrategySelectionNotifyRequest;
import com.android.server.display.feature.DisplayManagerFlags;

import java.io.PrintWriter;

/**
 * Manages the brightness of the display when the system is in the doze state.
 * Manages the brightness of the display when the system is in the doze state. There are different
 * ways to determine the brightness:
 * - an override coming from Dream Manager (see {@link DreamService#setDozeScreenBrightnessFloat})
 * - the current brightness setting multiplied by the doze scale factor (if there is an offload
 *   session) (similar to how auto-brightness in doze is scaled)
 * - the default doze brightness
 */
public class DozeBrightnessStrategy implements DisplayBrightnessStrategy {
    private final DisplayManagerFlags mFlags;
    private final float mDozeScaleFactor;
    private float mDefaultDozeBrightness;
    private final Injector mInjector;

    // The DisplayId of the associated logical display
    private final int mDisplayId;

    public DozeBrightnessStrategy(DisplayManagerFlags flags, Context context, int displayId,
            float defaultDozeBrightness) {
        this(/* injector= */ null, flags, context, displayId, defaultDozeBrightness);
    }

    @VisibleForTesting
    DozeBrightnessStrategy(Injector injector, DisplayManagerFlags flags, Context context,
            int displayId, float defaultDozeBrightness) {
        mFlags = flags;
        mDisplayId = displayId;
        mDozeScaleFactor = context.getResources().getFraction(
                R.fraction.config_screenAutoBrightnessDozeScaleFactor,
                1, 1);
        mDefaultDozeBrightness = defaultDozeBrightness;
        mInjector = (injector == null) ? new Injector() : injector;
    }

    @Override
    public DisplayBrightnessState updateBrightness(
            StrategyExecutionRequest strategyExecutionRequest) {
        // Todo(b/241308599): Introduce a validator class and add validations before setting
        // the brightness
        return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_DOZE,
                strategyExecutionRequest.getDisplayPowerRequest().dozeScreenBrightness,
                getName());
        // Validate DreamManager's override
        float dozeScreenBrightness =
                strategyExecutionRequest.getDisplayPowerRequest().dozeScreenBrightness;
        if (BrightnessUtils.isValidBrightnessValue(dozeScreenBrightness)) {
            return BrightnessUtils.constructDisplayBrightnessState(
                    BrightnessReason.REASON_DOZE,
                    dozeScreenBrightness,
                    getName(), /* slowChange= */ false);
        }

        if (mFlags.isDisplayOffloadEnabled()
                && strategyExecutionRequest.getOffloadSession() != null) {
            BrightnessEvent brightnessEvent = mInjector.getBrightnessEvent(mDisplayId);
            brightnessEvent.setFlags(BrightnessEvent.FLAG_DOZE_SCALE);
            return new DisplayBrightnessState.Builder()
                    .setBrightness(getManualDozeBrightness(strategyExecutionRequest
                            .getCurrentScreenBrightness()))
                    .setBrightnessReason(BrightnessReason.REASON_DOZE_MANUAL)
                    .setDisplayBrightnessStrategyName(getName())
                    .setIsSlowChange(false)
                    .setBrightnessEvent(brightnessEvent)
                    .build();
        }

        return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_DOZE_DEFAULT,
                mDefaultDozeBrightness, getName(), /* slowChange= */ false);
    }

    @Override
@@ -45,7 +102,11 @@ public class DozeBrightnessStrategy implements DisplayBrightnessStrategy {
    }

    @Override
    public void dump(PrintWriter writer) {}
    public void dump(PrintWriter writer) {
        writer.println("DozeBrightnessStrategy:");
        writer.println("  mDozeScaleFactor:" + mDozeScaleFactor);
        writer.println("  mDefaultDozeBrightness:" + mDefaultDozeBrightness);
    }

    @Override
    public void strategySelectionPostProcessor(
@@ -57,4 +118,22 @@ public class DozeBrightnessStrategy implements DisplayBrightnessStrategy {
    public int getReason() {
        return BrightnessReason.REASON_DOZE;
    }

    /**
     * @param currentScreenBrightness The current screen brightness
     * @return The brightness manually selected by the user, scaled for doze.
     */
    public float getManualDozeBrightness(float currentScreenBrightness) {
        return currentScreenBrightness * mDozeScaleFactor;
    }

    public void setDefaultDozeBrightness(float brightness) {
        mDefaultDozeBrightness = brightness;
    }

    static class Injector {
        public BrightnessEvent getBrightnessEvent(int displayId) {
            return new BrightnessEvent(displayId);
        }
    }
}
Loading