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

Commit 66029080 authored by Fiona Campbell's avatar Fiona Campbell
Browse files

Load even dimmer config mappings

- Allow minimum nits to be specified in even dimmer config
- Adjust strength based on requested nits
- Add tests

Bug: 369217612
Flag: com.android.server.display.feature.flags.even_dimmer
Test: atest DisplayServiceTests
Change-Id: Idcdaf087f13e74f7f61b1ad510db6d1eb9b17d67
parent 544ef065
Loading
Loading
Loading
Loading
+18 −19
Original line number Diff line number Diff line
@@ -1080,7 +1080,7 @@ public class DisplayDeviceConfig {
     */
    public float[] getNits() {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mNits;
            return mEvenDimmerBrightnessData.nits;
        }
        return mNits;
    }
@@ -1093,7 +1093,7 @@ public class DisplayDeviceConfig {
    @VisibleForTesting
    public float[] getBacklight() {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mBacklight;
            return mEvenDimmerBrightnessData.backlight;
        }
        return mBacklight;
    }
@@ -1107,7 +1107,7 @@ public class DisplayDeviceConfig {
     */
    public float getBacklightFromBrightness(float brightness) {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mBrightnessToBacklight.interpolate(brightness);
            return mEvenDimmerBrightnessData.brightnessToBacklight.interpolate(brightness);
        }
        return mBrightnessToBacklightSpline.interpolate(brightness);
    }
@@ -1120,7 +1120,7 @@ public class DisplayDeviceConfig {
     */
    public float getBrightnessFromBacklight(float backlight) {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mBacklightToBrightness.interpolate(backlight);
            return mEvenDimmerBrightnessData.backlightToBrightness.interpolate(backlight);
        }
        return mBacklightToBrightnessSpline.interpolate(backlight);
    }
@@ -1131,7 +1131,7 @@ public class DisplayDeviceConfig {
     */
    private Spline getBacklightToBrightnessSpline() {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mBacklightToBrightness;
            return mEvenDimmerBrightnessData.backlightToBrightness;
        }
        return mBacklightToBrightnessSpline;
    }
@@ -1144,11 +1144,11 @@ public class DisplayDeviceConfig {
     */
    public float getNitsFromBacklight(float backlight) {
        if (mEvenDimmerBrightnessData != null) {
            if (mEvenDimmerBrightnessData.mBacklightToNits == null) {
            if (mEvenDimmerBrightnessData.backlightToNits == null) {
                return INVALID_NITS;
            }
            backlight = Math.max(backlight, mBacklightMinimum);
            return mEvenDimmerBrightnessData.mBacklightToNits.interpolate(backlight);
            return mEvenDimmerBrightnessData.backlightToNits.interpolate(backlight);
        }

        if (mBacklightToNitsSpline == null) {
@@ -1165,14 +1165,14 @@ public class DisplayDeviceConfig {
     */
    public float getBacklightFromNits(float nits) {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mNitsToBacklight.interpolate(nits);
            return mEvenDimmerBrightnessData.nitsToBacklight.interpolate(nits);
        }
        return mNitsToBacklightSpline.interpolate(nits);
    }

    private Spline getNitsToBacklightSpline() {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mNitsToBacklight;
            return mEvenDimmerBrightnessData.nitsToBacklight;
        }
        return mNitsToBacklightSpline;
    }
@@ -1186,7 +1186,7 @@ public class DisplayDeviceConfig {
        if (mEvenDimmerBrightnessData == null) {
            return INVALID_NITS;
        }
        return mEvenDimmerBrightnessData.mMinLuxToNits.interpolate(lux);
        return mEvenDimmerBrightnessData.minLuxToNits.interpolate(lux);
    }

    /**
@@ -1197,7 +1197,7 @@ public class DisplayDeviceConfig {
        if (mEvenDimmerBrightnessData == null) {
            return PowerManager.BRIGHTNESS_MIN;
        }
        return mEvenDimmerBrightnessData.mTransitionPoint;
        return mEvenDimmerBrightnessData.transitionPoint;
    }

    /**
@@ -1268,7 +1268,7 @@ public class DisplayDeviceConfig {
     */
    public float[] getBrightness() {
        if (mEvenDimmerBrightnessData != null) {
            return mEvenDimmerBrightnessData.mBrightness;
            return mEvenDimmerBrightnessData.brightness;
        }
        return mBrightness;
    }
@@ -2617,13 +2617,13 @@ public class DisplayDeviceConfig {
                List<NonNegativeFloatToFloatPoint> points = map.getMap().getPoint();
                for (NonNegativeFloatToFloatPoint point : points) {
                    float lux = point.getFirst().floatValue();
                    float maxBrightness = point.getSecond().floatValue();
                    if (maxBrightness > hbmTransitionPoint) {
                    float maxBacklight = point.getSecond().floatValue();
                    if (maxBacklight > hbmTransitionPoint) {
                        Slog.wtf(TAG,
                                "Invalid NBM config: maxBrightness is greater than hbm"
                                "Invalid NBM config: maxBacklight is greater than hbm"
                                        + ".transitionPoint. type="
                                        + type + "; lux=" + lux + "; maxBrightness="
                                        + maxBrightness);
                                        + type + "; lux=" + lux + "; maxBacklight="
                                        + maxBacklight);
                        continue;
                    }
                    if (luxToTransitionPointMap.containsKey(lux)) {
@@ -2632,8 +2632,7 @@ public class DisplayDeviceConfig {
                                        + lux);
                        continue;
                    }
                    luxToTransitionPointMap.put(lux,
                            getBrightnessFromBacklight(maxBrightness));
                    luxToTransitionPointMap.put(lux, getBrightnessFromBacklight(maxBacklight));
                }
                if (!luxToTransitionPointMap.isEmpty()) {
                    mLuxThrottlingData.put(mappedType, luxToTransitionPointMap);
+5 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.hardware.display.DisplayManagerInternal.DisplayPowerReques
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
import static com.android.server.display.brightness.BrightnessEvent.FLAG_EVEN_DIMMER;
import static com.android.server.display.config.DisplayBrightnessMappingConfig.autoBrightnessPresetToString;

import android.animation.Animator;
@@ -1748,6 +1749,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        final float brightnessOnAvailableScale = MathUtils.constrainedMap(0.0f, 1.0f,
                clampedState.getMinBrightness(), clampedMax,
                brightnessState);
        final boolean evenDimmerModeOn =
                mCdsi != null && mCdsi.getReduceBrightColorsActivatedForEvenDimmer();
        mTempBrightnessEvent.setPercent(Math.round(
                1000.0f * com.android.internal.display.BrightnessUtils.convertLinearToGamma(
                        brightnessOnAvailableScale) / 10)); // rounded to one dp
@@ -1762,7 +1765,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
        mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
                | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
                | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
                | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0)
                | (evenDimmerModeOn ? FLAG_EVEN_DIMMER : 0));
        mTempBrightnessEvent.setRbcStrength(mCdsi != null
                ? mCdsi.getReduceBrightColorsStrength() : -1);
        mTempBrightnessEvent.setPowerFactor(mPowerRequest.screenLowPowerBrightnessFactor);
+39 −22
Original line number Diff line number Diff line
@@ -37,9 +37,9 @@ import android.os.SystemProperties;
import android.os.Trace;
import android.util.DisplayUtils;
import android.util.LongSparseArray;
import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.Spline;
import android.view.Display;
import android.view.DisplayAddress;
import android.view.DisplayCutout;
@@ -81,10 +81,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
    private static final String UNIQUE_ID_PREFIX = "local:";

    private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.boot.emulator.circular";
    // Min and max strengths for even dimmer feature.
    private static final float EVEN_DIMMER_MIN_STRENGTH = 0.0f;
    private static final float EVEN_DIMMER_MAX_STRENGTH = 90.0f;
    private static final float BRIGHTNESS_MIN = 0.0f;

    private final LongSparseArray<LocalDisplayDevice> mDevices = new LongSparseArray<>();

@@ -99,7 +95,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
    private Context mOverlayContext;

    private int mEvenDimmerStrength = -1;
    private boolean mEvenDimmerEnabled = false;
    private ColorDisplayService.ColorDisplayServiceInternal mCdsi;
    private Spline mNitsToEvenDimmerStrength;

    // Called with SyncRoot lock held.
    LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context,
@@ -279,7 +277,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
            mIsFirstDisplay = isFirstDisplay;
            updateDisplayPropertiesLocked(staticDisplayInfo, dynamicInfo, modeSpecs);
            mSidekickInternal = LocalServices.getService(SidekickInternal.class);
            mBacklightAdapter = new BacklightAdapter(displayToken, isFirstDisplay,
            mBacklightAdapter = mInjector.getBacklightAdapter(displayToken, isFirstDisplay,
                    mSurfaceControlProxy);
            mActiveSfDisplayModeAtStartId = dynamicInfo.activeDisplayModeId;
        }
@@ -998,26 +996,36 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                    }

                    private void applyColorMatrixBasedDimming(float brightnessState) {
                        int strength = (int) (MathUtils.constrainedMap(
                                // to this range:
                                EVEN_DIMMER_MAX_STRENGTH, EVEN_DIMMER_MIN_STRENGTH,
                                // from this range:
                                BRIGHTNESS_MIN, mDisplayDeviceConfig.getEvenDimmerTransitionPoint(),
                                // map this (+ rounded up):
                                brightnessState) + 0.5);

                        if (mEvenDimmerStrength < 0 // uninitialised
                                || MathUtils.abs(mEvenDimmerStrength - strength) > 1
                                || strength <= 1) {
                            mEvenDimmerStrength = strength;
                        }
                        boolean enabled = mEvenDimmerStrength > 0.0f;

                        if (mCdsi == null) {
                            mCdsi = LocalServices.getService(
                                    ColorDisplayService.ColorDisplayServiceInternal.class);
                        }
                        if (mCdsi != null) {
                        if (mCdsi == null) {
                            return;
                        }

                        final float minHardwareNits = backlightToNits(brightnessToBacklight(
                                mDisplayDeviceConfig.getEvenDimmerTransitionPoint()));
                        final float requestedNits =
                                backlightToNits(brightnessToBacklight(brightnessState));
                        mNitsToEvenDimmerStrength =
                                mCdsi.fetchEvenDimmerSpline(minHardwareNits);

                        if (mNitsToEvenDimmerStrength == null) {
                            return;
                        }

                        // Find required dimming strength, rounded up.
                        int strength = Math.round(mNitsToEvenDimmerStrength
                                .interpolate(requestedNits));
                        boolean enabled = strength > 0.0f;
                        if (mEvenDimmerEnabled != enabled) {
                            Slog.i(TAG, "Setting Extra Dim; strength: " + strength
                                    + ", " + (enabled ? "enabled" : "disabled"));
                        }
                        if (mEvenDimmerStrength != strength || mEvenDimmerEnabled != enabled) {
                            mEvenDimmerEnabled = enabled;
                            mEvenDimmerStrength = strength;
                            mCdsi.applyEvenDimmerColorChanges(enabled, strength);
                        }
                    }
@@ -1290,6 +1298,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
            pw.println("DisplayDeviceConfig: ");
            pw.println("---------------------");
            pw.println(mDisplayDeviceConfig);
            pw.println("mEvenDimmerEnabled=" + mEvenDimmerEnabled);
            pw.println("mEvenDimmerStrength=" + mEvenDimmerStrength);
            pw.println("mNitsToEvenDimmerStrength=" + mNitsToEvenDimmerStrength);
        }

        private int findSfDisplayModeIdLocked(int displayModeId, int modeGroup) {
@@ -1461,6 +1472,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
            return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay, flags);
        }

        public BacklightAdapter getBacklightAdapter(IBinder displayToken, boolean isFirstDisplay,
                SurfaceControlProxy surfaceControlProxy) {
            return new BacklightAdapter(displayToken, isFirstDisplay, surfaceControlProxy);

        }
    }

    public interface DisplayEventListener {
+3 −1
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ public final class BrightnessEvent {
    public static final int FLAG_DOZE_SCALE = 0x4;
    public static final int FLAG_USER_SET = 0x8;
    public static final int FLAG_LOW_POWER_MODE = 0x20;
    public static final int FLAG_EVEN_DIMMER = 0x40;

    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");

@@ -492,6 +493,7 @@ public final class BrightnessEvent {
                + ((mFlags & FLAG_RBC) != 0 ? "rbc " : "")
                + ((mFlags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
                + ((mFlags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "")
                + ((mFlags & FLAG_LOW_POWER_MODE) != 0 ? "low_power_mode " : "");
                + ((mFlags & FLAG_LOW_POWER_MODE) != 0 ? "low_power_mode " : "")
                + ((mFlags & FLAG_EVEN_DIMMER) != 0 ? "even_dimmer " : "");
    }
}
+56 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import android.provider.Settings.System;
import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.Spline;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.accessibility.AccessibilityManager;
@@ -114,6 +115,8 @@ public final class ColorDisplayService extends SystemService {
        Matrix.setIdentityM(MATRIX_IDENTITY, 0);
    }

    private static final int EVEN_DIMMER_MAX_PERCENT_ALLOWED = 100;

    private static final int MSG_USER_CHANGED = 0;
    private static final int MSG_SET_UP = 1;
    private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 2;
@@ -193,6 +196,9 @@ public final class ColorDisplayService extends SystemService {
    private final boolean mVisibleBackgroundUsersEnabled;
    private final UserManagerService mUserManager;

    private Spline mEvenDimmerSpline;
    private boolean mEvenDimmerActivated;

    public ColorDisplayService(Context context) {
        super(context);
        mHandler = new TintHandler(DisplayThread.get().getLooper());
@@ -1624,6 +1630,16 @@ public final class ColorDisplayService extends SystemService {
            return isDisplayWhiteBalanceSettingEnabled();
        }

        /**
         * Gets the adjusted nits, given a strength and nits.
         * @param strength of reduce bright colors
         * @param nits target nits
         * @return the actual nits that would be output, given input nits and rbc strength.
         */
        public float getAdjustedNitsForStrength(float nits, int strength) {
            return mReduceBrightColorsTintController.getAdjustedNitsForStrength(nits, strength);
        }

        /**
         * Sets the listener and returns whether reduce bright colors is currently enabled.
         */
@@ -1643,6 +1659,14 @@ public final class ColorDisplayService extends SystemService {
            return mReduceBrightColorsTintController.getStrength();
        }

        /**
         *
         * @return whether reduce bright colors is on, due to even dimmer being activated
         */
        public boolean getReduceBrightColorsActivatedForEvenDimmer() {
            return mEvenDimmerActivated;
        }

        /**
         * Gets the computed brightness, in nits, when the reduce bright colors feature is applied
         * at the current strength.
@@ -1667,10 +1691,42 @@ public final class ColorDisplayService extends SystemService {
         * Applies tint changes for even dimmer feature.
         */
        public void applyEvenDimmerColorChanges(boolean enabled, int strength) {
            mEvenDimmerActivated = enabled;
            mReduceBrightColorsTintController.setActivated(enabled);
            mReduceBrightColorsTintController.setMatrix(strength);
            mHandler.sendEmptyMessage(MSG_APPLY_REDUCE_BRIGHT_COLORS);
        }

        /**
         * Get spline to map between requested nits, and required even dimmer strength.
         * @return nits to strength spline
         */
        public Spline fetchEvenDimmerSpline(float nits) {
            if (mEvenDimmerSpline == null) {
                mEvenDimmerSpline = createNitsToStrengthSpline(nits);
            }
            return mEvenDimmerSpline;
        }

        /**
         * Creates a spline mapping requested nits values, for each resulting strength value
         * (in percent) for even dimmer.
         * Returns null if coefficients are not initialised.
         * @return spline from nits to strength
         */
        private Spline createNitsToStrengthSpline(float nits) {
            final float[] requestedNits = new float[EVEN_DIMMER_MAX_PERCENT_ALLOWED + 1];
            final float[] resultingStrength = new float[EVEN_DIMMER_MAX_PERCENT_ALLOWED + 1];
            for (int i = 0; i <= EVEN_DIMMER_MAX_PERCENT_ALLOWED; i++) {
                resultingStrength[EVEN_DIMMER_MAX_PERCENT_ALLOWED - i] = i;
                requestedNits[EVEN_DIMMER_MAX_PERCENT_ALLOWED - i] =
                        getAdjustedNitsForStrength(nits, i);
                if (requestedNits[EVEN_DIMMER_MAX_PERCENT_ALLOWED - i] == 0) {
                    return null;
                }
            }
            return new Spline.LinearSpline(requestedNits, resultingStrength);
        }
    }

    /**
Loading