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

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

Merge "Migrating WearBedtimeModeClamper to BrightnessStateModifier interface" into main

parents 1243a6e5 61cefe18
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -74,6 +74,5 @@ abstract class BrightnessClamper<T> {

    protected enum Type {
        POWER,
        WEAR_BEDTIME_MODE,
    }
}
+6 −8
Original line number Diff line number Diff line
@@ -218,8 +218,6 @@ public class BrightnessClamperController {
            return BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
        } else if (mClamperType == Type.POWER) {
            return BrightnessInfo.BRIGHTNESS_MAX_REASON_POWER_IC;
        } else if (mClamperType == Type.WEAR_BEDTIME_MODE) {
            return BrightnessInfo.BRIGHTNESS_MAX_REASON_WEAR_BEDTIME_MODE;
        }  else {
            Slog.wtf(TAG, "BrightnessMaxReason not mapped for type=" + mClamperType);
            return BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
@@ -350,10 +348,6 @@ public class BrightnessClamperController {
                            data, currentBrightness));
                }
            }
            if (flags.isBrightnessWearBedtimeModeClamperEnabled()) {
                clampers.add(new BrightnessWearBedtimeModeClamper(handler, context,
                        clamperChangeListener, data));
            }
            return clampers;
        }

@@ -362,6 +356,10 @@ public class BrightnessClamperController {
                DisplayDeviceData data) {
            List<BrightnessStateModifier> modifiers = new ArrayList<>();
            modifiers.add(new BrightnessThermalModifier(handler, listener, data));
            if (flags.isBrightnessWearBedtimeModeClamperEnabled()) {
                modifiers.add(new BrightnessWearBedtimeModeModifier(handler, context,
                        listener, data));
            }

            modifiers.add(new DisplayDimModifier(context));
            modifiers.add(new BrightnessLowPowerModeModifier());
@@ -395,7 +393,7 @@ public class BrightnessClamperController {
     */
    public static class DisplayDeviceData implements BrightnessThermalModifier.ThermalData,
            BrightnessPowerClamper.PowerData,
            BrightnessWearBedtimeModeClamper.WearBedtimeModeData {
            BrightnessWearBedtimeModeModifier.WearBedtimeModeData {
        @NonNull
        private final String mUniqueDisplayId;
        @NonNull
+158 −0
Original line number Diff line number Diff line
@@ -20,14 +20,21 @@ import android.annotation.NonNull;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManagerInternal;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.brightness.BrightnessReason;

public class BrightnessWearBedtimeModeClamper extends
        BrightnessClamper<BrightnessWearBedtimeModeClamper.WearBedtimeModeData> {
import java.io.PrintWriter;

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

    public static final int BEDTIME_MODE_OFF = 0;
    public static final int BEDTIME_MODE_ON = 1;
@@ -35,16 +42,23 @@ public class BrightnessWearBedtimeModeClamper extends
    private final Context mContext;

    private final ContentObserver mSettingsObserver;
    protected final Handler mHandler;
    protected final BrightnessClamperController.ClamperChangeListener mChangeListener;

    private float mBrightnessCap;
    private boolean mIsActive = false;
    private boolean mApplied = false;

    BrightnessWearBedtimeModeClamper(Handler handler, Context context,
    BrightnessWearBedtimeModeModifier(Handler handler, Context context,
            BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data) {
        this(new Injector(), handler, context, listener, data);
    }

    @VisibleForTesting
    BrightnessWearBedtimeModeClamper(Injector injector, Handler handler, Context context,
    BrightnessWearBedtimeModeModifier(Injector injector, Handler handler, Context context,
            BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data) {
        super(handler, listener);
        mHandler = handler;
        mChangeListener = listener;
        mContext = context;
        mBrightnessCap = data.getBrightnessWearBedtimeModeCap();
        mSettingsObserver = new ContentObserver(mHandler) {
@@ -61,27 +75,72 @@ public class BrightnessWearBedtimeModeClamper extends
        injector.registerBedtimeModeObserver(context.getContentResolver(), mSettingsObserver);
    }

    @NonNull
    //region BrightnessStateModifier
    @Override
    public void apply(DisplayManagerInternal.DisplayPowerRequest request,
            DisplayBrightnessState.Builder stateBuilder) {
        if (mIsActive && stateBuilder.getMaxBrightness() > mBrightnessCap) {
            stateBuilder.setMaxBrightness(mBrightnessCap);
            stateBuilder.setBrightness(Math.min(stateBuilder.getBrightness(), mBrightnessCap));
            stateBuilder.setBrightnessMaxReason(
                    BrightnessInfo.BRIGHTNESS_MAX_REASON_WEAR_BEDTIME_MODE);
            stateBuilder.getBrightnessReason().addModifier(BrightnessReason.MODIFIER_THROTTLED);
            // set fast change only when modifier is activated.
            // this will allow auto brightness to apply slow change even when modifier is active
            if (!mApplied) {
                stateBuilder.setIsSlowChange(false);
            }
            mApplied = true;
        } else {
            mApplied = false;
        }
    }

    @Override
    public void stop() {
        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
    }

    @Override
    Type getType() {
        return Type.WEAR_BEDTIME_MODE;
    public void dump(PrintWriter writer) {
        writer.println("BrightnessWearBedtimeModeModifier:");
        writer.println("  mBrightnessCap: " + mBrightnessCap);
        writer.println("  mIsActive: " + mIsActive);
        writer.println("  mApplied: " + mApplied);
    }

    @Override
    void onDeviceConfigChanged() {}
    public boolean shouldListenToLightSensor() {
        return false;
    }

    @Override
    void onDisplayChanged(WearBedtimeModeData displayData) {
    public void setAmbientLux(float lux) {
        // noop
    }
    //endregion

    //region DisplayDeviceDataListener
    @Override
    public void onDisplayChanged(BrightnessClamperController.DisplayDeviceData data) {
        mHandler.post(() -> {
            mBrightnessCap = displayData.getBrightnessWearBedtimeModeCap();
            mBrightnessCap = data.getBrightnessWearBedtimeModeCap();
            mChangeListener.onChanged();
        });
    }
    //endregion

    //region StatefulModifier
    @Override
    void stop() {
        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
    public void applyStateChange(
            BrightnessClamperController.ModifiersAggregatedState aggregatedState) {
        if (mIsActive && aggregatedState.mMaxBrightness > mBrightnessCap) {
            aggregatedState.mMaxBrightness = mBrightnessCap;
            aggregatedState.mMaxBrightnessReason =
                    BrightnessInfo.BRIGHTNESS_MAX_REASON_WEAR_BEDTIME_MODE;
        }
    }
    //endregion

    interface WearBedtimeModeData {
        float getBrightnessWearBedtimeModeCap();
+180 −0
Original line number Diff line number Diff line
@@ -16,16 +16,21 @@

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

import static com.android.server.display.brightness.clamper.BrightnessWearBedtimeModeClamper.BEDTIME_MODE_OFF;
import static com.android.server.display.brightness.clamper.BrightnessWearBedtimeModeClamper.BEDTIME_MODE_ON;
import static com.android.server.display.brightness.clamper.BrightnessWearBedtimeModeModifier.BEDTIME_MODE_OFF;
import static com.android.server.display.brightness.clamper.BrightnessWearBedtimeModeModifier.BEDTIME_MODE_ON;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.ContentResolver;
import android.database.ContentObserver;
import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManagerInternal;
import android.os.IBinder;
import android.os.PowerManager;
import android.provider.Settings;
import android.testing.TestableContext;

@@ -33,6 +38,10 @@ import androidx.annotation.NonNull;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.internal.display.BrightnessSynchronizer;
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.testutils.TestHandler;

import org.junit.Before;
@@ -41,12 +50,19 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class BrightnessWearBedtimeModeClamperTest {

public class BrightnessWearBedtimeModeModifierTest {
    private static final int NO_MODIFIER = 0;
    private static final float BRIGHTNESS_CAP = 0.3f;
    private static final String DISPLAY_ID = "displayId";

    @Mock
    private BrightnessClamperController.ClamperChangeListener mMockClamperChangeListener;
    @Mock
    private DisplayManagerInternal.DisplayPowerRequest mMockRequest;
    @Mock
    private DisplayDeviceConfig mMockDisplayDeviceConfig;
    @Mock
    private IBinder mMockBinder;

    @Rule
    public final TestableContext mContext = new TestableContext(
@@ -54,48 +70,48 @@ public class BrightnessWearBedtimeModeClamperTest {

    private final TestHandler mTestHandler = new TestHandler(null);
    private final TestInjector mInjector = new TestInjector();
    private BrightnessWearBedtimeModeClamper mClamper;
    private BrightnessWearBedtimeModeModifier mModifier;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mClamper = new BrightnessWearBedtimeModeClamper(mInjector, mTestHandler, mContext,
        mModifier = new BrightnessWearBedtimeModeModifier(mInjector, mTestHandler, mContext,
                mMockClamperChangeListener, () -> BRIGHTNESS_CAP);
        mTestHandler.flush();
    }

    @Test
    public void testBrightnessCap() {
        assertEquals(BRIGHTNESS_CAP, mClamper.getBrightnessCap(), BrightnessSynchronizer.EPSILON);
    }

    @Test
    public void testBedtimeModeOn() {
        setBedtimeModeEnabled(true);
        assertTrue(mClamper.isActive());
        verify(mMockClamperChangeListener).onChanged();
    }

    @Test
    public void testBedtimeModeOff() {
        setBedtimeModeEnabled(false);
        assertFalse(mClamper.isActive());
        assertModifierState(
                0.5f, true,
                PowerManager.BRIGHTNESS_MAX, 0.5f,
                false, true);
        verify(mMockClamperChangeListener).onChanged();
    }

    @Test
    public void testType() {
        assertEquals(BrightnessClamper.Type.WEAR_BEDTIME_MODE, mClamper.getType());
    public void testBedtimeModeOn() {
        setBedtimeModeEnabled(true);
        assertModifierState(
                0.5f, true,
                BRIGHTNESS_CAP, BRIGHTNESS_CAP,
                true, false);
        verify(mMockClamperChangeListener).onChanged();
    }

    @Test
    public void testOnDisplayChanged() {
        setBedtimeModeEnabled(true);
        clearInvocations(mMockClamperChangeListener);
        float newBrightnessCap = 0.61f;

        mClamper.onDisplayChanged(() -> newBrightnessCap);
        onDisplayChange(newBrightnessCap);
        mTestHandler.flush();

        assertEquals(newBrightnessCap, mClamper.getBrightnessCap(), BrightnessSynchronizer.EPSILON);
        assertModifierState(
                0.5f, true,
                newBrightnessCap, 0.5f,
                true, false);
        verify(mMockClamperChangeListener).onChanged();
    }

@@ -106,7 +122,45 @@ public class BrightnessWearBedtimeModeClamperTest {
        mTestHandler.flush();
    }

    private static class TestInjector extends BrightnessWearBedtimeModeClamper.Injector {
    private void onDisplayChange(float brightnessCap) {
        when(mMockDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode())
                .thenReturn(brightnessCap);
        mModifier.onDisplayChanged(ClamperTestUtilsKt.createDisplayDeviceData(
                mMockDisplayDeviceConfig, mMockBinder, DISPLAY_ID, DisplayDeviceConfig.DEFAULT_ID));
    }

    private void assertModifierState(
            float currentBrightness,
            boolean currentSlowChange,
            float maxBrightness, float brightness,
            boolean isActive,
            boolean isSlowChange) {
        ModifiersAggregatedState modifierState = new ModifiersAggregatedState();
        DisplayBrightnessState.Builder stateBuilder = DisplayBrightnessState.builder();
        stateBuilder.setBrightness(currentBrightness);
        stateBuilder.setIsSlowChange(currentSlowChange);

        int maxBrightnessReason = isActive ? BrightnessInfo.BRIGHTNESS_MAX_REASON_WEAR_BEDTIME_MODE
                : BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
        int modifier = isActive ? BrightnessReason.MODIFIER_THROTTLED : NO_MODIFIER;

        mModifier.applyStateChange(modifierState);
        assertThat(modifierState.mMaxBrightness).isEqualTo(maxBrightness);
        assertThat(modifierState.mMaxBrightnessReason).isEqualTo(maxBrightnessReason);

        mModifier.apply(mMockRequest, stateBuilder);

        assertThat(stateBuilder.getMaxBrightness())
                .isWithin(BrightnessSynchronizer.EPSILON).of(maxBrightness);
        assertThat(stateBuilder.getBrightness())
                .isWithin(BrightnessSynchronizer.EPSILON).of(brightness);
        assertThat(stateBuilder.getBrightnessMaxReason()).isEqualTo(maxBrightnessReason);
        assertThat(stateBuilder.getBrightnessReason().getModifier()).isEqualTo(modifier);
        assertThat(stateBuilder.isSlowChange()).isEqualTo(isSlowChange);
    }


    private static class TestInjector extends BrightnessWearBedtimeModeModifier.Injector {

        private ContentObserver mObserver;

Loading