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

Commit 9a90d78c authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

Add follower strategy

Bug: 241307563
Test: Flash to a device with multiple internal displays on, see that the brightness value is always shared between them.
Test: atest com.android.server.display
Change-Id: I3c54451a1ad1756060fcbaa87cf70c8ec9ba7f59
parent e83680e2
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1127,6 +1127,14 @@ class AutomaticBrightnessController {
        }
    }

    public float convertToFloatScale(float nits) {
        if (mCurrentBrightnessMapper != null) {
            return mCurrentBrightnessMapper.convertToFloatScale(nits);
        } else {
            return -1.0f;
        }
    }

    public void recalculateSplines(boolean applyAdjustment, float[] adjustment) {
        mCurrentBrightnessMapper.recalculateSplines(applyAdjustment, adjustment);

+17 −0
Original line number Diff line number Diff line
@@ -321,6 +321,13 @@ public abstract class BrightnessMappingStrategy {
     */
    public abstract float convertToNits(float brightness);

    /**
     * Converts the provided nits value to a float value if possible.
     *
     * Returns -1.0f if there's no available mapping for the nits to float.
     */
    public abstract float convertToFloatScale(float nits);

    /**
     * Adds a user interaction data point to the brightness mapping.
     *
@@ -670,6 +677,11 @@ public abstract class BrightnessMappingStrategy {
            return -1.0f;
        }

        @Override
        public float convertToFloatScale(float nits) {
            return -1.0f;
        }

        @Override
        public void addUserDataPoint(float lux, float brightness) {
            float unadjustedBrightness = getUnadjustedBrightness(lux);
@@ -912,6 +924,11 @@ public abstract class BrightnessMappingStrategy {
            return mBrightnessToNitsSpline.interpolate(brightness);
        }

        @Override
        public float convertToFloatScale(float nits) {
            return mNitsToBrightnessSpline.interpolate(nits);
        }

        @Override
        public void addUserDataPoint(float lux, float brightness) {
            float unadjustedBrightness = getUnadjustedBrightness(lux);
+3 −0
Original line number Diff line number Diff line
@@ -1655,6 +1655,9 @@ public final class DisplayManagerService extends SystemService {
                return;
            }

            // TODO (b/265793751): Set this DPC as a follower of the default DPC if needed,
            // clear this DPC's followers if it's not a lead display

            final String uniqueId = device.getUniqueId();
            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
            dpc.onDisplayChanged(hbmMetadata);
+68 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.util.MathUtils;
import android.util.MutableFloat;
import android.util.MutableInt;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
import android.view.Display;

@@ -450,6 +451,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set.
    private float mTemporaryScreenBrightness;

    // This brightness value is set in concurrent displays mode. It is the brightness value
    // of the lead display that this DPC should follow.
    private float mBrightnessToFollow;

    // The last auto brightness adjustment that was set by the user and not temporary. Set to
    // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
    private float mAutoBrightnessAdjustment;
@@ -499,6 +504,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private boolean mIsEnabled;
    private boolean mIsInTransition;

    // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
    // is one lead display, the additional displays follow the brightness value of the lead display.
    @GuardedBy("mLock")
    private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
            new SparseArray();

    /**
     * Creates the display power controller.
     */
@@ -635,6 +646,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        loadProximitySensor();

        mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
        mBrightnessToFollow = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
        mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
@@ -701,6 +713,48 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        }
    }

    @Override
    public int getDisplayId() {
        return mDisplayId;
    }

    @Override
    public void setBrightnessToFollow(float leadDisplayBrightness, float nits) {
        if (mAutomaticBrightnessController == null || nits < 0) {
            mBrightnessToFollow = leadDisplayBrightness;
        } else {
            float brightness = mAutomaticBrightnessController.convertToFloatScale(nits);
            if (isValidBrightnessValue(brightness)) {
                mBrightnessToFollow = brightness;
            } else {
                // The device does not support nits
                mBrightnessToFollow = leadDisplayBrightness;
            }
        }
        sendUpdatePowerState();
    }

    @Override
    public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
        synchronized (mLock) {
            mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
        }
        sendUpdatePowerState();
    }

    @Override
    public void clearDisplayBrightnessFollowers() {
        SparseArray<DisplayPowerControllerInterface> followers;
        synchronized (mLock) {
            followers = mDisplayBrightnessFollowers.clone();
            mDisplayBrightnessFollowers.clear();
        }
        for (int i = 0; i < followers.size(); i++) {
            DisplayPowerControllerInterface follower = followers.valueAt(i);
            follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1);
        }
    }

    @Nullable
    @Override
    public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
@@ -1241,6 +1295,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        int brightnessAdjustmentFlags = 0;
        mBrightnessReasonTemp.set(null);
        mTempBrightnessEvent.reset();
        SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
        synchronized (mLock) {
            if (mStopped) {
                return;
@@ -1269,6 +1324,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            }

            mustNotify = !mDisplayReadyLocked;

            displayBrightnessFollowers = mDisplayBrightnessFollowers.clone();
        }

        // Compute the basic display state using the policy.
@@ -1376,6 +1433,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
        }

        if (Float.isNaN(brightnessState) && isValidBrightnessValue(mBrightnessToFollow)) {
            brightnessState = mBrightnessToFollow;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_FOLLOWER);
        }

        if ((Float.isNaN(brightnessState))
                && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
            brightnessState = mPowerRequest.screenBrightnessOverride;
@@ -1557,6 +1619,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mAppliedThrottling = false;
        }

        for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
            DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
            follower.setBrightnessToFollow(brightnessState, convertToNits(brightnessState));
        }

        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
@@ -2668,6 +2735,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        pw.println("  mPendingScreenBrightnessSetting="
                + mPendingScreenBrightnessSetting);
        pw.println("  mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
        pw.println("  mBrightnessToFollow=" + mBrightnessToFollow);
        pw.println("  mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
        pw.println("  mBrightnessReason=" + mBrightnessReason);
        pw.println("  mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
+58 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.util.MathUtils;
import android.util.MutableFloat;
import android.util.MutableInt;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;

import com.android.internal.R;
@@ -409,6 +410,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal

    private boolean mIsEnabled;
    private boolean mIsInTransition;

    // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
    // is one lead display, the additional displays follow the brightness value of the lead display.
    @GuardedBy("mLock")
    private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
            new SparseArray();

    /**
     * Creates the display power controller.
     */
@@ -1110,6 +1118,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        boolean mustInitialize = false;
        int brightnessAdjustmentFlags = 0;
        mTempBrightnessEvent.reset();
        SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
        synchronized (mLock) {
            if (mStopped) {
                return;
@@ -1138,6 +1147,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
            }

            mustNotify = !mDisplayReadyLocked;

            displayBrightnessFollowers = mDisplayBrightnessFollowers.clone();
        }

        int state = mDisplayStateController
@@ -1321,6 +1332,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
            mAppliedThrottling = false;
        }

        for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
            DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
            follower.setBrightnessToFollow(brightnessState, convertToNits(brightnessState));
        }

        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
@@ -2097,6 +2113,27 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        mDisplayBrightnessController.setBrightness(brightnessValue);
    }

    @Override
    public int getDisplayId() {
        return mDisplayId;
    }

    @Override
    public void setBrightnessToFollow(float leadDisplayBrightness, float nits) {
        if (mAutomaticBrightnessController == null || nits < 0) {
            mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
        } else {
            float brightness = mAutomaticBrightnessController.convertToFloatScale(nits);
            if (BrightnessUtils.isValidBrightnessValue(brightness)) {
                mDisplayBrightnessController.setBrightnessToFollow(brightness);
            } else {
                // The device does not support nits
                mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
            }
        }
        sendUpdatePowerState();
    }

    private void putAutoBrightnessAdjustmentSetting(float adjustment) {
        if (mDisplayId == Display.DEFAULT_DISPLAY) {
            mAutoBrightnessAdjustment = adjustment;
@@ -2146,6 +2183,27 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        return mAutomaticBrightnessController.convertToNits(brightness);
    }

    @Override
    public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
        synchronized (mLock) {
            mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
        }
        sendUpdatePowerState();
    }

    @Override
    public void clearDisplayBrightnessFollowers() {
        SparseArray<DisplayPowerControllerInterface> followers;
        synchronized (mLock) {
            followers = mDisplayBrightnessFollowers.clone();
            mDisplayBrightnessFollowers.clear();
        }
        for (int i = 0; i < followers.size(); i++) {
            DisplayPowerControllerInterface follower = followers.valueAt(i);
            follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1);
        }
    }

    @Override
    public void dump(final PrintWriter pw) {
        synchronized (mLock) {
Loading