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

Commit b8357d89 authored by Oleg Petšjonkin's avatar Oleg Petšjonkin Committed by Android (Google) Code Review
Browse files

Merge "Moving HDR related logic from HBMController to dedicated clamper" into main

parents a4992d64 391c0d66
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1192,6 +1192,18 @@ public class DisplayDeviceConfig {
     */
    public float getHdrBrightnessFromSdr(float brightness, float maxDesiredHdrSdrRatio) {
        Spline sdrToHdrSpline = mHbmData != null ? mHbmData.sdrToHdrRatioSpline : null;
        return getHdrBrightnessFromSdr(brightness, maxDesiredHdrSdrRatio, sdrToHdrSpline);
    }

    /**
     * Calculate the HDR brightness for the specified SDR brightenss, restricted by the
     * maxDesiredHdrSdrRatio (the ratio between the HDR luminance and SDR luminance) and specific
     * sdrToHdrSpline
     *
     * @return the HDR brightness or BRIGHTNESS_INVALID when no mapping exists.
     */
    public float getHdrBrightnessFromSdr(float brightness, float maxDesiredHdrSdrRatio,
            @Nullable Spline sdrToHdrSpline) {
        if (sdrToHdrSpline == null) {
            return PowerManager.BRIGHTNESS_INVALID;
        }
+10 −10
Original line number Diff line number Diff line
@@ -505,14 +505,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mClock = mInjector.getClock();
        mLogicalDisplay = logicalDisplay;
        mDisplayId = mLogicalDisplay.getDisplayIdLocked();
        mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        IBinder displayToken = mDisplayDevice.getDisplayTokenLocked();
        DisplayDeviceInfo displayDeviceInfo = mDisplayDevice.getDisplayDeviceInfoLocked();
        mSensorManager = sensorManager;
        mHandler = new DisplayControllerHandler(handler.getLooper());
        mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
                .getDisplayDeviceConfig();
        mDisplayDeviceConfig = mDisplayDevice.getDisplayDeviceConfig();
        mIsEnabled = logicalDisplay.isEnabledLocked();
        mIsInTransition = logicalDisplay.isInTransitionLocked();
        mIsDisplayInternal = logicalDisplay.getPrimaryDisplayDeviceLocked()
                .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
        mIsDisplayInternal = displayDeviceInfo.type == Display.TYPE_INTERNAL;
        mWakelockController = mInjector.getWakelockController(mDisplayId, callbacks);
        mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController(
                mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(),
@@ -521,7 +522,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mTag = TAG + "[" + mDisplayId + "]";
        mThermalBrightnessThrottlingDataId =
                logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
        mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();

        mUniqueDisplayId = mDisplayDevice.getUniqueId();
        mDisplayStatsId = mUniqueDisplayId.hashCode();
        mPhysicalDisplayName = mDisplayDevice.getNameLocked();
@@ -569,8 +570,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

        mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController,
                modeChangeCallback, mDisplayDeviceConfig, mHandler, flags,
                mDisplayDevice.getDisplayTokenLocked(),
                mDisplayDevice.getDisplayDeviceInfoLocked());
                displayToken, displayDeviceInfo);

        mDisplayBrightnessController =
                new DisplayBrightnessController(context, null,
@@ -584,8 +584,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        mUniqueDisplayId,
                        mThermalBrightnessThrottlingDataId,
                        logicalDisplay.getPowerThrottlingDataIdLocked(),
                        mDisplayDeviceConfig,
                        mDisplayId), mContext, flags, mSensorManager);
                        mDisplayDeviceConfig, displayDeviceInfo.width, displayDeviceInfo.height,
                        displayToken, mDisplayId), mContext, flags, mSensorManager);
        // Seed the cached brightness
        saveBrightnessInfo(getScreenBrightnessSetting());
        mAutomaticBrightnessStrategy =
@@ -893,7 +893,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mBrightnessClamperController.onDisplayChanged(
                    new BrightnessClamperController.DisplayDeviceData(uniqueId,
                            thermalBrightnessThrottlingDataId, powerThrottlingDataId,
                            config, mDisplayId));
                            config, info.width, info.height, token, mDisplayId));

            if (changed) {
                updatePowerState();
+79 −11
Original line number Diff line number Diff line
@@ -28,13 +28,16 @@ import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManagerInternal;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.PowerManager;
import android.provider.DeviceConfig;
import android.provider.DeviceConfigInterface;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.Spline;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.DisplayDeviceConfig.PowerThrottlingConfigData;
@@ -65,6 +68,11 @@ public class BrightnessClamperController {
    private final List<BrightnessClamper<? super DisplayDeviceData>> mClampers;

    private final List<BrightnessStateModifier> mModifiers;

    private final List<DisplayDeviceDataListener> mDisplayDeviceDataListeners = new ArrayList<>();
    private final List<StatefulModifier> mStatefulModifiers = new ArrayList<>();
    private ModifiersAggregatedState mModifiersAggregatedState = new ModifiersAggregatedState();

    private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener;
    private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;

@@ -110,7 +118,16 @@ public class BrightnessClamperController {
        mClampers = injector.getClampers(handler, clamperChangeListenerInternal, data, flags,
                context);
        mModifiers = injector.getModifiers(flags, context, handler, clamperChangeListener,
                data.mDisplayDeviceConfig);
                data);

        mModifiers.forEach(m -> {
            if (m instanceof  DisplayDeviceDataListener l) {
                mDisplayDeviceDataListeners.add(l);
            }
            if (m instanceof StatefulModifier s) {
                mStatefulModifiers.add(s);
            }
        });
        mOnPropertiesChangedListener =
                properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged);
        mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId());
@@ -123,6 +140,7 @@ public class BrightnessClamperController {
    public void onDisplayChanged(DisplayDeviceData data) {
        mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId());
        mClampers.forEach(clamper -> clamper.onDisplayChanged(data));
        mDisplayDeviceDataListeners.forEach(l -> l.onDisplayChanged(data));
        adjustLightSensorSubscription();
    }

@@ -234,14 +252,27 @@ public class BrightnessClamperController {
            customAnimationRate = minClamper.getCustomAnimationRate();
        }

        ModifiersAggregatedState newAggregatedState = new ModifiersAggregatedState();
        mStatefulModifiers.forEach((clamper) -> clamper.applyStateChange(newAggregatedState));

        if (mBrightnessCap != brightnessCap
                || mClamperType != clamperType
                || mCustomAnimationRate != customAnimationRate) {
                || mCustomAnimationRate != customAnimationRate
                || needToNotifyExternalListener(mModifiersAggregatedState, newAggregatedState)) {
            mBrightnessCap = brightnessCap;
            mClamperType = clamperType;
            mCustomAnimationRate = customAnimationRate;
            mClamperChangeListenerExternal.onChanged();
        }
        mModifiersAggregatedState = newAggregatedState;
    }

    private boolean needToNotifyExternalListener(ModifiersAggregatedState state1,
            ModifiersAggregatedState state2) {
        return !BrightnessSynchronizer.floatEquals(state1.mMaxDesiredHdrRatio,
                state2.mMaxDesiredHdrRatio)
                || state1.mSdrHdrRatioSpline != state2.mSdrHdrRatioSpline
                || state1.mHdrHbmEnabled != state2.mHdrHbmEnabled;
    }

    private void start() {
@@ -295,17 +326,16 @@ public class BrightnessClamperController {

        List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context,
                Handler handler, ClamperChangeListener listener,
                DisplayDeviceConfig displayDeviceConfig) {
                DisplayDeviceData data) {
            List<BrightnessStateModifier> modifiers = new ArrayList<>();
            modifiers.add(new DisplayDimModifier(context));
            modifiers.add(new BrightnessLowPowerModeModifier());
            if (flags.isEvenDimmerEnabled() && displayDeviceConfig != null
                    && displayDeviceConfig.isEvenDimmerAvailable()) {
            if (flags.isEvenDimmerEnabled() && data.mDisplayDeviceConfig.isEvenDimmerAvailable()) {
                modifiers.add(new BrightnessLowLuxModifier(handler, listener, context,
                        displayDeviceConfig));
                        data.mDisplayDeviceConfig));
            }
            if (flags.useNewHdrBrightnessModifier()) {
                modifiers.add(new HdrBrightnessModifier());
                modifiers.add(new HdrBrightnessModifier(handler, listener, data));
            }
            return modifiers;
        }
@@ -319,7 +349,14 @@ public class BrightnessClamperController {
    }

    /**
     * Config Data for clampers
     * Modifier should implement this interface in order to receive display change updates
     */
    interface DisplayDeviceDataListener {
        void onDisplayChanged(DisplayDeviceData displayData);
    }

    /**
     * Config Data for clampers/modifiers
     */
    public static class DisplayDeviceData implements BrightnessThermalClamper.ThermalData,
            BrightnessPowerClamper.PowerData,
@@ -331,23 +368,34 @@ public class BrightnessClamperController {
        @NonNull
        private final String mPowerThrottlingDataId;
        @NonNull
        private final DisplayDeviceConfig mDisplayDeviceConfig;
        final DisplayDeviceConfig mDisplayDeviceConfig;

        final int mWidth;

        private final int mDisplayId;
        final int mHeight;

        final IBinder mDisplayToken;

        final int mDisplayId;

        public DisplayDeviceData(@NonNull String uniqueDisplayId,
                @NonNull String thermalThrottlingDataId,
                @NonNull String powerThrottlingDataId,
                @NonNull DisplayDeviceConfig displayDeviceConfig,
                int width,
                int height,
                IBinder displayToken,
                int displayId) {
            mUniqueDisplayId = uniqueDisplayId;
            mThermalThrottlingDataId = thermalThrottlingDataId;
            mPowerThrottlingDataId = powerThrottlingDataId;
            mDisplayDeviceConfig = displayDeviceConfig;
            mWidth = width;
            mHeight = height;
            mDisplayToken = displayToken;
            mDisplayId = displayId;
        }


        @NonNull
        @Override
        public String getUniqueDisplayId() {
@@ -406,4 +454,24 @@ public class BrightnessClamperController {
            return mDisplayId;
        }
    }

    /**
     * Stateful modifier should implement this interface and modify aggregatedState.
     * AggregatedState is used by Controller to determine if updatePowerState call is needed
     * to correctly adjust brightness
     */
    interface StatefulModifier {
        void applyStateChange(ModifiersAggregatedState aggregatedState);
    }

    /**
     * StatefulModifiers contribute to AggregatedState, that is used to decide if brightness
     * adjustement is needed
     */
    public static class ModifiersAggregatedState {
        float mMaxDesiredHdrRatio = HdrBrightnessModifier.DEFAULT_MAX_HDR_SDR_RATIO;
        @Nullable
        Spline mSdrHdrRatioSpline = null;
        boolean mHdrHbmEnabled = false;
    }
}
+186 −3
Original line number Diff line number Diff line
@@ -16,17 +16,85 @@

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

import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.hardware.display.DisplayManagerInternal;
import android.os.Handler;
import android.os.IBinder;
import android.view.SurfaceControlHdrLayerInfoListener;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.config.HdrBrightnessData;

import java.io.PrintWriter;

public class HdrBrightnessModifier implements BrightnessStateModifier {
public class HdrBrightnessModifier implements BrightnessStateModifier,
        BrightnessClamperController.DisplayDeviceDataListener,
        BrightnessClamperController.StatefulModifier {

    static final float DEFAULT_MAX_HDR_SDR_RATIO = 1.0f;
    private static final float DEFAULT_HDR_LAYER_SIZE = -1.0f;

    private final SurfaceControlHdrLayerInfoListener mHdrListener =
            new SurfaceControlHdrLayerInfoListener() {
                @Override
                public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers, int maxW,
                        int maxH, int flags, float maxDesiredHdrSdrRatio) {
                    boolean hdrLayerPresent = numberOfHdrLayers > 0;
                    mHandler.post(() -> HdrBrightnessModifier.this.onHdrInfoChanged(
                            hdrLayerPresent ? (float) (maxW * maxH) : DEFAULT_HDR_LAYER_SIZE,
                            hdrLayerPresent ? maxDesiredHdrSdrRatio : DEFAULT_MAX_HDR_SDR_RATIO));
                }
            };

    private final Handler mHandler;
    private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener;
    private final Injector mInjector;

    private IBinder mRegisteredDisplayToken;

    private float mScreenSize;
    private float mHdrLayerSize = DEFAULT_HDR_LAYER_SIZE;
    private HdrBrightnessData mHdrBrightnessData;
    private DisplayDeviceConfig mDisplayDeviceConfig;
    private float mMaxDesiredHdrRatio = DEFAULT_MAX_HDR_SDR_RATIO;
    private Mode mMode = Mode.NO_HDR;

    HdrBrightnessModifier(Handler handler,
            BrightnessClamperController.ClamperChangeListener clamperChangeListener,
            BrightnessClamperController.DisplayDeviceData displayData) {
        this(handler, clamperChangeListener, new Injector(), displayData);
    }

    @VisibleForTesting
    HdrBrightnessModifier(Handler handler,
            BrightnessClamperController.ClamperChangeListener clamperChangeListener,
            Injector injector,
            BrightnessClamperController.DisplayDeviceData displayData) {
        mHandler = handler;
        mClamperChangeListener = clamperChangeListener;
        mInjector = injector;
        onDisplayChanged(displayData);
    }

    // Called in DisplayControllerHandler
    @Override
    public void apply(DisplayManagerInternal.DisplayPowerRequest request,
            DisplayBrightnessState.Builder stateBuilder) {
        // noop
        if (mHdrBrightnessData  == null) { // no hdr data
            return;
        }
        if (mMode == Mode.NO_HDR) {
            return;
        }

        float hdrBrightness = mDisplayDeviceConfig.getHdrBrightnessFromSdr(
                stateBuilder.getBrightness(), mMaxDesiredHdrRatio,
                mHdrBrightnessData.sdrToHdrRatioSpline);
        stateBuilder.setHdrBrightness(hdrBrightness);
    }

    @Override
@@ -34,11 +102,13 @@ public class HdrBrightnessModifier implements BrightnessStateModifier {
        // noop
    }

    // Called in DisplayControllerHandler
    @Override
    public void stop() {
        // noop
        unregisterHdrListener();
    }


    @Override
    public boolean shouldListenToLightSensor() {
        return false;
@@ -48,4 +118,117 @@ public class HdrBrightnessModifier implements BrightnessStateModifier {
    public void setAmbientLux(float lux) {
        // noop
    }

    @Override
    public void onDisplayChanged(BrightnessClamperController.DisplayDeviceData displayData) {
        mHandler.post(() -> onDisplayChanged(displayData.mDisplayToken, displayData.mWidth,
                displayData.mHeight, displayData.mDisplayDeviceConfig));
    }

    // Called in DisplayControllerHandler
    @Override
    public void applyStateChange(
            BrightnessClamperController.ModifiersAggregatedState aggregatedState) {
        if (mMode != Mode.NO_HDR) {
            aggregatedState.mMaxDesiredHdrRatio = mMaxDesiredHdrRatio;
            aggregatedState.mSdrHdrRatioSpline = mHdrBrightnessData.sdrToHdrRatioSpline;
            aggregatedState.mHdrHbmEnabled = (mMode == Mode.HBM_HDR);
        }
    }

    // Called in DisplayControllerHandler
    private void onDisplayChanged(IBinder displayToken, int width, int height,
            DisplayDeviceConfig config) {
        mDisplayDeviceConfig = config;
        mScreenSize = (float) width * height;
        HdrBrightnessData data = config.getHdrBrightnessData();
        if (data == null) {
            unregisterHdrListener();
        } else {
            registerHdrListener(displayToken);
        }
        recalculate(data, mMaxDesiredHdrRatio);
    }

    // Called in DisplayControllerHandler
    private void recalculate(@Nullable HdrBrightnessData data, float maxDesiredHdrRatio) {
        Mode newMode = recalculateMode(data);
        // if HDR mode changed, notify changed
        boolean needToNotifyChange = mMode != newMode;
        // If HDR mode is active, we need to check if other HDR params are changed
        if (mMode != HdrBrightnessModifier.Mode.NO_HDR) {
            if (!BrightnessSynchronizer.floatEquals(mMaxDesiredHdrRatio, maxDesiredHdrRatio)
                    || data != mHdrBrightnessData) {
                needToNotifyChange = true;
            }
        }

        mMode = newMode;
        mHdrBrightnessData = data;
        mMaxDesiredHdrRatio = maxDesiredHdrRatio;

        if (needToNotifyChange) {
            mClamperChangeListener.onChanged();
        }
    }

    // Called in DisplayControllerHandler
    private Mode recalculateMode(@Nullable HdrBrightnessData data) {
        // no config
        if (data == null) {
            return Mode.NO_HDR;
        }
        // HDR layer < minHdr % for Nbm
        if (mHdrLayerSize < mScreenSize * data.minimumHdrPercentOfScreenForNbm) {
            return Mode.NO_HDR;
        }
        // HDR layer < minHdr % for Hbm, and HDR layer >= that minHdr % for Nbm
        if (mHdrLayerSize < mScreenSize * data.minimumHdrPercentOfScreenForHbm) {
            return Mode.NBM_HDR;
        }
        // HDR layer > that minHdr % for Hbm
        return Mode.HBM_HDR;
    }

    // Called in DisplayControllerHandler
    private void onHdrInfoChanged(float hdrLayerSize, float maxDesiredHdrSdrRatio) {
        mHdrLayerSize = hdrLayerSize;
        recalculate(mHdrBrightnessData, maxDesiredHdrSdrRatio);
    }

    // Called in DisplayControllerHandler
    private void registerHdrListener(IBinder displayToken) {
        if (mRegisteredDisplayToken == displayToken) {
            return;
        }
        unregisterHdrListener();
        if (displayToken != null) {
            mInjector.registerHdrListener(mHdrListener, displayToken);
            mRegisteredDisplayToken = displayToken;
        }
    }

    // Called in DisplayControllerHandler
    private void unregisterHdrListener() {
        if (mRegisteredDisplayToken != null) {
            mInjector.unregisterHdrListener(mHdrListener, mRegisteredDisplayToken);
            mRegisteredDisplayToken = null;
            mHdrLayerSize = DEFAULT_HDR_LAYER_SIZE;
        }
    }

    private enum Mode {
        NO_HDR, NBM_HDR, HBM_HDR
    }

    @SuppressLint("MissingPermission")
    static class Injector {
        void registerHdrListener(SurfaceControlHdrLayerInfoListener listener, IBinder token) {
            listener.register(token);
        }

        void unregisterHdrListener(SurfaceControlHdrLayerInfoListener listener, IBinder token) {
            listener.unregister(token);
        }
    }
}
+47 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -41,8 +42,8 @@ import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.brightness.clamper.BrightnessClamperController.ModifiersAggregatedState;
import com.android.server.display.config.SensorData;
import com.android.server.display.feature.DeviceConfigParameterProvider;
import com.android.server.display.feature.DisplayManagerFlags;
@@ -89,6 +90,10 @@ public class BrightnessClamperControllerTest {
    @Mock
    private BrightnessModifier mMockModifier;
    @Mock
    private TestStatefulModifier mMockStatefulModifier;
    @Mock
    private TestDisplayListenerModifier mMockDisplayListenerModifier;
    @Mock
    private DisplayManagerInternal.DisplayPowerRequest mMockRequest;

    @Mock
@@ -99,7 +104,8 @@ public class BrightnessClamperControllerTest {
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mTestInjector = new TestInjector(List.of(mMockClamper), List.of(mMockModifier));
        mTestInjector = new TestInjector(List.of(mMockClamper),
                List.of(mMockModifier, mMockStatefulModifier, mMockDisplayListenerModifier));
        when(mMockDisplayDeviceData.getDisplayId()).thenReturn(DISPLAY_ID);
        when(mMockDisplayDeviceData.getAmbientLightSensor()).thenReturn(mMockSensorData);

@@ -167,6 +173,13 @@ public class BrightnessClamperControllerTest {
        verify(mMockClamper).onDisplayChanged(mMockDisplayDeviceData);
    }

    @Test
    public void testOnDisplayChanged_DelegatesToDisplayListeners() {
        mClamperController.onDisplayChanged(mMockDisplayDeviceData);

        verify(mMockDisplayListenerModifier).onDisplayChanged(mMockDisplayDeviceData);
    }

    @Test
    public void testOnDisplayChanged_doesNotRestartLightSensor() {
        mClamperController.onDisplayChanged(mMockDisplayDeviceData);
@@ -189,6 +202,8 @@ public class BrightnessClamperControllerTest {
        mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_ON);

        verify(mMockModifier).apply(eq(mMockRequest), any());
        verify(mMockDisplayListenerModifier).apply(eq(mMockRequest), any());
        verify(mMockStatefulModifier).apply(eq(mMockRequest), any());
    }

    @Test
@@ -326,11 +341,40 @@ public class BrightnessClamperControllerTest {
        verify(mMockClamper).stop();
    }

    @Test
    public void test_doesNotNotifyExternalListener_aggregatedStateNotChanged() {
        mTestInjector.mCapturedChangeListener.onChanged();
        mTestHandler.flush();

        verify(mMockExternalListener, never()).onChanged();
    }

    @Test
    public void test_notifiesExternalListener_aggregatedStateChanged() {
        doAnswer((invocation) -> {
            ModifiersAggregatedState argument = invocation.getArgument(0);
            argument.mHdrHbmEnabled = true;
            return null;
        }).when(mMockStatefulModifier).applyStateChange(any());
        mTestInjector.mCapturedChangeListener.onChanged();
        mTestHandler.flush();

        verify(mMockExternalListener).onChanged();
    }

    private BrightnessClamperController createBrightnessClamperController() {
        return new BrightnessClamperController(mTestInjector, mTestHandler, mMockExternalListener,
                mMockDisplayDeviceData, mMockContext, mFlags, mSensorManager);
    }

    interface TestDisplayListenerModifier extends BrightnessStateModifier,
            BrightnessClamperController.DisplayDeviceDataListener {
    }

    interface TestStatefulModifier extends BrightnessStateModifier,
            BrightnessClamperController.StatefulModifier {
    }

    private class TestInjector extends BrightnessClamperController.Injector {

        private final List<BrightnessClamper<? super BrightnessClamperController.DisplayDeviceData>>
@@ -366,7 +410,7 @@ public class BrightnessClamperControllerTest {
        @Override
        List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context,
                Handler handler, BrightnessClamperController.ClamperChangeListener listener,
                DisplayDeviceConfig displayDeviceConfig) {
                BrightnessClamperController.DisplayDeviceData displayDeviceData) {
            return mModifiers;
        }

Loading