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

Commit 682503a3 authored by petsjonkin's avatar petsjonkin Committed by Oleg Petšjonkin
Browse files

Max brightness fix in normal brightness mode and HDR content shown

Fixed inconsistency in HBMController and BrightnessRangeControlller current maxBrightness selection
Before: BrightnessRangeController was taking into account NBC only if HBMController mode was HBM_OFF,
However HBMController was selecting transitionPoint as maxBrightness aslo in case e.g. HDR was shown, or low power mode.
Now: BrightnessRangeController takes into account NBC in sync with HBMController

Bug: b/326872826
Test: atest BrightnessRangeControllerTest, manually tested brightness slider behavior
Change-Id: I9071b27769b6a357ca9b2b7f6aa609ab0672467e
(cherry picked from commit 7d313a09)
parent ce4f1155
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.brightness.clamper.HdrClamper;
import com.android.server.display.feature.DisplayManagerFlags;

@@ -30,8 +31,7 @@ import java.util.function.BooleanSupplier;
class BrightnessRangeController {

    private final HighBrightnessModeController mHbmController;
    private final NormalBrightnessModeController mNormalBrightnessModeController =
            new NormalBrightnessModeController();
    private final NormalBrightnessModeController mNormalBrightnessModeController;

    private final HdrClamper mHdrClamper;

@@ -45,17 +45,21 @@ class BrightnessRangeController {
            Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler,
            DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) {
        this(hbmController, modeChangeCallback, displayDeviceConfig,
                new NormalBrightnessModeController(),
                new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags,
                displayToken, info);
    }

    @VisibleForTesting
    BrightnessRangeController(HighBrightnessModeController hbmController,
            Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig,
            NormalBrightnessModeController normalBrightnessModeController,
            HdrClamper hdrClamper, DisplayManagerFlags flags, IBinder displayToken,
            DisplayDeviceInfo info) {
        mHbmController = hbmController;
        mModeChangeCallback = modeChangeCallback;
        mHdrClamper = hdrClamper;
        mNormalBrightnessModeController = normalBrightnessModeController;
        mUseHdrClamper = flags.isHdrClamperEnabled();
        mUseNbmController = flags.isNbmControllerEnabled();
        if (mUseNbmController) {
@@ -126,8 +130,11 @@ class BrightnessRangeController {


    float getCurrentBrightnessMax() {
        if (mUseNbmController && mHbmController.getHighBrightnessMode()
                == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF) {
        // nbmController might adjust maxBrightness only if device does not support HBM or
        // hbm is currently not allowed
        if (mUseNbmController
                && (!mHbmController.deviceSupportsHbm()
                || !mHbmController.isHbmCurrentlyAllowed())) {
            return Math.min(mHbmController.getCurrentBrightnessMax(),
                    mNormalBrightnessModeController.getCurrentBrightnessMax());
        }
+5 −5
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ class HighBrightnessModeController {
    }

    float getCurrentBrightnessMax() {
        if (!deviceSupportsHbm() || isCurrentlyAllowed()) {
        if (!deviceSupportsHbm() || isHbmCurrentlyAllowed()) {
            // Either the device doesn't support HBM, or HBM range is currently allowed (device
            // it in a high-lux environment). In either case, return the highest brightness
            // level supported by the device.
@@ -356,7 +356,7 @@ class HighBrightnessModeController {
        return event.getStartTimeMillis();
    }

    private boolean isCurrentlyAllowed() {
    boolean isHbmCurrentlyAllowed() {
        // Returns true if HBM is allowed (above the ambient lux threshold) and there's still
        // time within the current window for additional HBM usage. We return false if there is an
        // HDR layer because we don't want the brightness MAX to change for HDR, which has its
@@ -369,7 +369,7 @@ class HighBrightnessModeController {
                && !mIsBlockedByLowPowerMode);
    }

    private boolean deviceSupportsHbm() {
    boolean deviceSupportsHbm() {
        return mHbmData != null && mHighBrightnessModeMetadata != null;
    }

@@ -462,7 +462,7 @@ class HighBrightnessModeController {
                    + ", isOnlyAllowedToStayOn: " + isOnlyAllowedToStayOn
                    + ", remainingAllowedTime: " + remainingTime
                    + ", isLuxHigh: " + mIsInAllowedAmbientRange
                    + ", isHBMCurrentlyAllowed: " + isCurrentlyAllowed()
                    + ", isHBMCurrentlyAllowed: " + isHbmCurrentlyAllowed()
                    + ", isHdrLayerPresent: " + mIsHdrLayerPresent
                    + ", mMaxDesiredHdrSdrRatio: " + mMaxDesiredHdrSdrRatio
                    + ", isAutoBrightnessEnabled: " +  mIsAutoBrightnessEnabled
@@ -575,7 +575,7 @@ class HighBrightnessModeController {
            return BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
        } else if (mIsHdrLayerPresent) {
            return BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR;
        } else if (isCurrentlyAllowed()) {
        } else if (isHbmCurrentlyAllowed()) {
            return BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT;
        }

+95 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.display

import android.os.IBinder
import androidx.test.filters.SmallTest
import com.android.server.display.brightness.clamper.HdrClamper
import com.android.server.display.feature.DisplayManagerFlags
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever

private const val MAX_BRIGHTNESS = 1.0f
private const val TRANSITION_POINT = 0.7f
private const val NORMAL_BRIGHTNESS_HIGH = 0.8f
private const val NORMAL_BRIGHTNESS_LOW = 0.6f

@SmallTest
class BrightnessRangeControllerTest {

    private val mockHbmController = mock<HighBrightnessModeController>()
    private val mockCallback = mock<Runnable>()
    private val mockConfig = mock<DisplayDeviceConfig>()
    private val mockNormalBrightnessController = mock<NormalBrightnessModeController>()
    private val mockHdrClamper = mock<HdrClamper>()
    private val mockFlags = mock<DisplayManagerFlags>()
    private val mockToken = mock<IBinder>()

    @Test
    fun `returns HBC max brightness if HBM supported and ON`() {
        val controller = createController()
        assertThat(controller.currentBrightnessMax).isEqualTo(MAX_BRIGHTNESS)
    }

    @Test
    fun `returns NBC max brightness if device does not support HBM`() {
        val controller = createController(hbmSupported = false)
        assertThat(controller.currentBrightnessMax).isEqualTo(NORMAL_BRIGHTNESS_LOW)
    }

    @Test
    fun `returns NBC max brightness if HBM not allowed`() {
        val controller = createController(hbmAllowed = false)
        assertThat(controller.currentBrightnessMax).isEqualTo(NORMAL_BRIGHTNESS_LOW)
    }

    @Test
    fun `returns HBC max brightness if NBM is disabled`() {
        val controller = createController(nbmEnabled = false, hbmAllowed = false)
        assertThat(controller.currentBrightnessMax).isEqualTo(MAX_BRIGHTNESS)
    }

    @Test
    fun `returns HBC max brightness if lower than NBC max brightness`() {
        val controller = createController(
            hbmAllowed = false,
            hbmMaxBrightness = TRANSITION_POINT,
            nbmMaxBrightness = NORMAL_BRIGHTNESS_HIGH
        )
        assertThat(controller.currentBrightnessMax).isEqualTo(TRANSITION_POINT)
    }

    private fun createController(
        nbmEnabled: Boolean = true,
        hbmSupported: Boolean = true,
        hbmAllowed: Boolean = true,
        hbmMaxBrightness: Float = MAX_BRIGHTNESS,
        nbmMaxBrightness: Float = NORMAL_BRIGHTNESS_LOW
    ): BrightnessRangeController {
        whenever(mockFlags.isNbmControllerEnabled).thenReturn(nbmEnabled)
        whenever(mockHbmController.deviceSupportsHbm()).thenReturn(hbmSupported)
        whenever(mockHbmController.isHbmCurrentlyAllowed).thenReturn(hbmAllowed)
        whenever(mockHbmController.currentBrightnessMax).thenReturn(hbmMaxBrightness)
        whenever(mockNormalBrightnessController.currentBrightnessMax).thenReturn(nbmMaxBrightness)

        return BrightnessRangeController(mockHbmController, mockCallback, mockConfig,
            mockNormalBrightnessController, mockHdrClamper, mockFlags, mockToken,
            DisplayDeviceInfo())
    }
}
 No newline at end of file
+10 −2
Original line number Diff line number Diff line
@@ -1850,6 +1850,8 @@ public final class DisplayPowerControllerTest {
                mock(ScreenOffBrightnessSensorController.class);
        final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
        final HdrClamper hdrClamper = mock(HdrClamper.class);
        final NormalBrightnessModeController normalBrightnessModeController = mock(
                NormalBrightnessModeController.class);
        BrightnessClamperController clamperController = mock(BrightnessClamperController.class);

        when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
@@ -1862,7 +1864,8 @@ public final class DisplayPowerControllerTest {

        TestInjector injector = spy(new TestInjector(displayPowerState, animator,
                automaticBrightnessController, wakelockController, brightnessMappingStrategy,
                hysteresisLevels, screenOffBrightnessSensorController, hbmController, hdrClamper,
                hysteresisLevels, screenOffBrightnessSensorController,
                hbmController, normalBrightnessModeController, hdrClamper,
                clamperController, mDisplayManagerFlagsMock));

        final LogicalDisplay display = mock(LogicalDisplay.class);
@@ -1950,6 +1953,8 @@ public final class DisplayPowerControllerTest {
        private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
        private final HighBrightnessModeController mHighBrightnessModeController;

        private final NormalBrightnessModeController mNormalBrightnessModeController;

        private final HdrClamper mHdrClamper;

        private final BrightnessClamperController mClamperController;
@@ -1963,6 +1968,7 @@ public final class DisplayPowerControllerTest {
                HysteresisLevels hysteresisLevels,
                ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
                HighBrightnessModeController highBrightnessModeController,
                NormalBrightnessModeController normalBrightnessModeController,
                HdrClamper hdrClamper,
                BrightnessClamperController clamperController,
                DisplayManagerFlags flags) {
@@ -1974,6 +1980,7 @@ public final class DisplayPowerControllerTest {
            mHysteresisLevels = hysteresisLevels;
            mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
            mHighBrightnessModeController = highBrightnessModeController;
            mNormalBrightnessModeController = normalBrightnessModeController;
            mHdrClamper = hdrClamper;
            mClamperController = clamperController;
            mFlags = flags;
@@ -2086,7 +2093,8 @@ public final class DisplayPowerControllerTest {
                DisplayDeviceConfig displayDeviceConfig, Handler handler,
                DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) {
            return new BrightnessRangeController(hbmController, modeChangeCallback,
                    displayDeviceConfig, mHdrClamper, mFlags, displayToken, info);
                    displayDeviceConfig, mNormalBrightnessModeController, mHdrClamper,
                    mFlags, displayToken, info);
        }

        @Override