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

Commit c00e8399 authored by Fiona Campbell's avatar Fiona Campbell Committed by Android (Google) Code Review
Browse files

Merge "Even Dimmer for manual mode" into main

parents 64e23d81 2a2711b8
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread;
import com.android.server.EventLogTags;
import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.clamper.BrightnessClamperController;
import com.android.server.display.config.HysteresisLevels;
import com.android.server.display.feature.DisplayManagerFlags;

@@ -256,7 +255,6 @@ public class AutomaticBrightnessController {

    // Controls Brightness range (including High Brightness Mode).
    private final BrightnessRangeController mBrightnessRangeController;
    private final BrightnessClamperController mBrightnessClamperController;

    // Throttles (caps) maximum allowed brightness
    private final BrightnessThrottler mBrightnessThrottler;
@@ -295,7 +293,6 @@ public class AutomaticBrightnessController {
            BrightnessRangeController brightnessModeController,
            BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
            int ambientLightHorizonLong, float userLux, float userNits,
            BrightnessClamperController brightnessClamperController,
            DisplayManagerFlags displayManagerFlags) {
        this(new Injector(), callbacks, looper, sensorManager, lightSensor,
                brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin, brightnessMax,
@@ -306,7 +303,7 @@ public class AutomaticBrightnessController {
                screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
                screenBrightnessThresholdsIdle, context, brightnessModeController,
                brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux,
                userNits, brightnessClamperController, displayManagerFlags
                userNits, displayManagerFlags
        );
    }

@@ -325,7 +322,6 @@ public class AutomaticBrightnessController {
            BrightnessRangeController brightnessRangeController,
            BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
            int ambientLightHorizonLong, float userLux, float userNits,
            BrightnessClamperController brightnessClamperController,
            DisplayManagerFlags displayManagerFlags) {
        mInjector = injector;
        mClock = injector.createClock(displayManagerFlags.offloadControlsDozeAutoBrightness());
@@ -370,7 +366,6 @@ public class AutomaticBrightnessController {
        mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
        mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
        mBrightnessRangeController = brightnessRangeController;
        mBrightnessClamperController = brightnessClamperController;
        mBrightnessThrottler = brightnessThrottler;
        mBrightnessMappingStrategyMap = brightnessMappingStrategyMap;
        mDisplayManagerFlags = displayManagerFlags;
@@ -771,7 +766,6 @@ public class AutomaticBrightnessController {
                    mAmbientBrightnessThresholds.getDarkeningThreshold(lux);
        }
        mBrightnessRangeController.onAmbientLuxChange(mAmbientLux);
        mBrightnessClamperController.onAmbientLuxChange(mAmbientLux);

        // If the short term model was invalidated and the change is drastic enough, reset it.
        mShortTermModel.maybeReset(mAmbientLux);
+5 −7
Original line number Diff line number Diff line
@@ -587,7 +587,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        mUniqueDisplayId,
                        mThermalBrightnessThrottlingDataId,
                        logicalDisplay.getPowerThrottlingDataIdLocked(),
                        mDisplayDeviceConfig), mContext, flags);
                        mDisplayDeviceConfig), mContext, flags, mSensorManager);
        // Seed the cached brightness
        saveBrightnessInfo(getScreenBrightnessSetting());
        mAutomaticBrightnessStrategy =
@@ -1422,7 +1422,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;

        mBrightnessRangeController.setAutoBrightnessEnabled(autoBrightnessState);
        mBrightnessClamperController.setAutoBrightnessState(autoBrightnessState);

        boolean updateScreenBrightnessSetting =
                displayBrightnessState.shouldUpdateScreenBrightnessSetting();
@@ -1549,7 +1548,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        // we broadcast this change through setting.
        final float unthrottledBrightnessState = brightnessState;
        DisplayBrightnessState clampedState = mBrightnessClamperController.clamp(mPowerRequest,
                brightnessState, slowChange);
                brightnessState, slowChange, /* displayState= */ state);

        brightnessState = clampedState.getBrightness();
        slowChange = clampedState.isSlowChange();
@@ -2478,7 +2477,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
            boolean slowChange) {
        mBrightnessRangeController.onAmbientLuxChange(ambientLux);
        mBrightnessClamperController.onAmbientLuxChange(ambientLux);
        if (nits == BrightnessMappingStrategy.INVALID_NITS) {
            mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness, slowChange);
        } else {
@@ -3194,7 +3192,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                    screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
                    screenBrightnessThresholdsIdle, context, brightnessModeController,
                    brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux,
                    userNits, brightnessClamperController, displayManagerFlags);
                    userNits, displayManagerFlags);
        }

        BrightnessMappingStrategy getDefaultModeBrightnessMapper(Context context,
@@ -3243,10 +3241,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        BrightnessClamperController getBrightnessClamperController(Handler handler,
                BrightnessClamperController.ClamperChangeListener clamperChangeListener,
                BrightnessClamperController.DisplayDeviceData data, Context context,
                DisplayManagerFlags flags) {
                DisplayManagerFlags flags, SensorManager sensorManager) {

            return new BrightnessClamperController(handler, clamperChangeListener, data, context,
                    flags);
                    flags, sensorManager);
        }

        DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
+127 −32
Original line number Diff line number Diff line
@@ -16,21 +16,30 @@

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

import static android.view.Display.STATE_ON;

import static com.android.server.display.brightness.clamper.BrightnessClamper.Type;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManagerInternal;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.provider.DeviceConfigInterface;
import android.util.IndentingPrintWriter;
import android.util.Slog;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.DisplayDeviceConfig;
@@ -41,20 +50,30 @@ import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.config.SensorData;
import com.android.server.display.feature.DeviceConfigParameterProvider;
import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.utils.AmbientFilter;
import com.android.server.display.utils.AmbientFilterFactory;
import com.android.server.display.utils.DebugUtils;
import com.android.server.display.utils.SensorUtils;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * Clampers controller, all in DisplayControllerHandler
 */
public class BrightnessClamperController {
    private static final String TAG = "BrightnessClamperController";
    // To enable these logs, run:
    // 'adb shell setprop persist.log.tag.BrightnessClamperController DEBUG && adb reboot'
    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
    public static final float INVALID_LUX = -1f;

    private final DeviceConfigParameterProvider mDeviceConfigParameterProvider;
    private final Handler mHandler;
    private final SensorManager mSensorManager;
    private final ClamperChangeListener mClamperChangeListenerExternal;
    private final Executor mExecutor;
    private final List<BrightnessClamper<? super DisplayDeviceData>> mClampers;
@@ -66,24 +85,55 @@ public class BrightnessClamperController {
    private float mCustomAnimationRate = DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET;
    @Nullable
    private Type mClamperType = null;
    private int mAutoBrightnessState = -1;
    private final SensorEventListener mLightSensorListener;
    private Sensor mRegisteredLightSensor = null;
    private Sensor mLightSensor;
    private String mLightSensorType;
    private String mLightSensorName;
    private AmbientFilter mAmbientFilter;
    private final DisplayDeviceConfig mDisplayDeviceConfig;
    private final Resources mResources;
    private final int mLightSensorRate;

    private final Injector mInjector;
    private boolean mClamperApplied = false;

    public BrightnessClamperController(Handler handler,
            ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
            DisplayManagerFlags flags) {
        this(new Injector(), handler, clamperChangeListener, data, context, flags);
            DisplayManagerFlags flags, SensorManager sensorManager) {
        this(null, handler, clamperChangeListener, data, context, flags, sensorManager);
    }

    @VisibleForTesting
    BrightnessClamperController(Injector injector, Handler handler,
            ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
            DisplayManagerFlags flags) {
        mDeviceConfigParameterProvider = injector.getDeviceConfigParameterProvider();
            DisplayManagerFlags flags, SensorManager sensorManager) {
        mInjector = injector == null ? new Injector() : injector;
        mDeviceConfigParameterProvider = mInjector.getDeviceConfigParameterProvider();
        mHandler = handler;
        mSensorManager = sensorManager;
        mDisplayDeviceConfig = data.mDisplayDeviceConfig;
        mLightSensorListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                long now = SystemClock.elapsedRealtime();
                mAmbientFilter.addValue(TimeUnit.NANOSECONDS.toMillis(event.timestamp),
                        event.values[0]);
                final float lux = mAmbientFilter.getEstimate(now);
                mModifiers.forEach(mModifier -> mModifier.setAmbientLux(lux));
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {
                // unused
            }
        };

        mClamperChangeListenerExternal = clamperChangeListener;
        mExecutor = new HandlerExecutor(handler);
        mResources = context.getResources();
        mLightSensorRate = context.getResources().getInteger(
                R.integer.config_autoBrightnessLightSensorRate);

        Runnable clamperChangeRunnableInternal = this::recalculateBrightnessCap;

@@ -93,10 +143,10 @@ public class BrightnessClamperController {
            }
        };

        mClampers = injector.getClampers(handler, clamperChangeListenerInternal, data, flags,
        mClampers = mInjector.getClampers(handler, clamperChangeListenerInternal, data, flags,
                context);
        mModifiers = injector.getModifiers(flags, context, handler, clamperChangeListener,
                data.mDisplayDeviceConfig);
        mModifiers = mInjector.getModifiers(flags, context, handler, clamperChangeListener,
                data.mDisplayDeviceConfig, mSensorManager);
        mOnPropertiesChangedListener =
                properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged);
        start();
@@ -114,7 +164,7 @@ public class BrightnessClamperController {
     * Called in DisplayControllerHandler
     */
    public DisplayBrightnessState clamp(DisplayManagerInternal.DisplayPowerRequest request,
            float brightnessValue, boolean slowChange) {
            float brightnessValue, boolean slowChange, int displayState) {
        float cappedBrightness = Math.min(brightnessValue, mBrightnessCap);

        DisplayBrightnessState.Builder builder = DisplayBrightnessState.builder();
@@ -133,6 +183,12 @@ public class BrightnessClamperController {
            mClamperApplied = false;
        }

        if (displayState != STATE_ON) {
            unregisterSensorListener();
        } else {
            maybeRegisterLightSensor();
        }

        for (int i = 0; i < mModifiers.size(); i++) {
            mModifiers.get(i).apply(request, builder);
        }
@@ -175,6 +231,8 @@ public class BrightnessClamperController {
        writer.println("  mBrightnessCap: " + mBrightnessCap);
        writer.println("  mClamperType: " + mClamperType);
        writer.println("  mClamperApplied: " + mClamperApplied);
        writer.println("  mLightSensor=" + mLightSensor);
        writer.println("  mRegisteredLightSensor=" + mRegisteredLightSensor);
        IndentingPrintWriter ipw = new IndentingPrintWriter(writer, "    ");
        mClampers.forEach(clamper -> clamper.dump(ipw));
        mModifiers.forEach(modifier -> modifier.dump(ipw));
@@ -191,26 +249,6 @@ public class BrightnessClamperController {
        mModifiers.forEach(BrightnessStateModifier::stop);
    }

    /**
     * Notifies modifiers that ambient lux has changed.
     * @param ambientLux current lux, debounced
     */
    public void onAmbientLuxChange(float ambientLux) {
        mModifiers.forEach(modifier -> modifier.onAmbientLuxChange(ambientLux));
    }

    /**
     * Sets the autobrightness state for clampers that need to be aware of the state.
     * @param state autobrightness state
     */
    public void setAutoBrightnessState(int state) {
        if (state == mAutoBrightnessState) {
            return;
        }
        mModifiers.forEach(modifier -> modifier.setAutoBrightnessState(state));
        mAutoBrightnessState = state;
        recalculateBrightnessCap();
    }

    // Called in DisplayControllerHandler
    private void recalculateBrightnessCap() {
@@ -243,6 +281,10 @@ public class BrightnessClamperController {
        if (!mClampers.isEmpty()) {
            mDeviceConfigParameterProvider.addOnPropertiesChangedListener(
                    mExecutor, mOnPropertiesChangedListener);
            reloadLightSensorData(mDisplayDeviceConfig);
            mLightSensor = mInjector.getLightSensor(
                    mSensorManager, mLightSensorType, mLightSensorName);
            maybeRegisterLightSensor();
        }
    }

@@ -281,7 +323,7 @@ public class BrightnessClamperController {

        List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context,
                Handler handler, ClamperChangeListener listener,
                DisplayDeviceConfig displayDeviceConfig) {
                DisplayDeviceConfig displayDeviceConfig, SensorManager sensorManager) {
            List<BrightnessStateModifier> modifiers = new ArrayList<>();
            modifiers.add(new DisplayDimModifier(context));
            modifiers.add(new BrightnessLowPowerModeModifier());
@@ -292,6 +334,12 @@ public class BrightnessClamperController {
            }
            return modifiers;
        }

        Sensor getLightSensor(SensorManager sensorManager, String type, String name) {
            return SensorUtils.findSensor(sensorManager, type,
                    name, Sensor.TYPE_LIGHT);
        }

    }

    /**
@@ -368,4 +416,51 @@ public class BrightnessClamperController {
            return mDisplayDeviceConfig.getTempSensor();
        }
    }

    private void maybeRegisterLightSensor() {
        if (mModifiers.stream().noneMatch(BrightnessStateModifier::shouldListenToLightSensor)) {
            return;
        }

        if (mRegisteredLightSensor == mLightSensor) {
            return;
        }

        if (mRegisteredLightSensor != null) {
            unregisterSensorListener();
        }

        mAmbientFilter = AmbientFilterFactory.createBrightnessFilter(TAG, mResources);
        mSensorManager.registerListener(mLightSensorListener,
                mLightSensor, mLightSensorRate * 1000, mHandler);
        mRegisteredLightSensor = mLightSensor;

        if (DEBUG) {
            Slog.d(TAG, "maybeRegisterLightSensor");
        }
    }

    private void unregisterSensorListener() {
        mSensorManager.unregisterListener(mLightSensorListener);
        mRegisteredLightSensor = null;
        mModifiers.forEach(mModifier -> mModifier.setAmbientLux(INVALID_LUX)); // set lux to invalid
        if (DEBUG) {
            Slog.d(TAG, "unregisterSensorListener");
        }
    }

    private void reloadLightSensorData(DisplayDeviceConfig displayDeviceConfig) {
        // The displayDeviceConfig (ddc) contains display specific preferences. When loaded,
        // it naturally falls back to the global config.xml.
        if (displayDeviceConfig != null
                && displayDeviceConfig.getAmbientLightSensor() != null) {
            // This covers both the ddc and the config.xml fallback
            mLightSensorType = displayDeviceConfig.getAmbientLightSensor().type;
            mLightSensorName = displayDeviceConfig.getAmbientLightSensor().name;
        } else if (mLightSensorName == null && mLightSensorType == null) {
            mLightSensorType = mResources.getString(
                    com.android.internal.R.string.config_displayLightSensorType);
            mLightSensorName = "";
        }
    }
}
+14 −14
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

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

import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;

import android.content.ContentResolver;
import android.content.Context;
@@ -30,6 +29,7 @@ import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.BrightnessMappingStrategy;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.brightness.BrightnessReason;
@@ -56,7 +56,6 @@ public class BrightnessLowLuxModifier extends BrightnessModifier {
    private float mBrightnessLowerBound;
    private float mMinNitsAllowed;
    private boolean mIsActive;
    private boolean mAutoBrightnessEnabled;
    private float mAmbientLux;
    private final DisplayDeviceConfig mDisplayDeviceConfig;

@@ -87,15 +86,15 @@ public class BrightnessLowLuxModifier extends BrightnessModifier {
                mContentResolver, Settings.Secure.EVEN_DIMMER_MIN_NITS,
                /* def= */ MIN_NITS_DEFAULT, userId);

        boolean isActive = isSettingEnabled() && mAutoBrightnessEnabled;

        float luxBasedNitsLowerBound = mDisplayDeviceConfig.getMinNitsFromLux(mAmbientLux);
        boolean isActive = isSettingEnabled()
                && mAmbientLux != BrightnessMappingStrategy.INVALID_LUX;

        final int reason;
        float minNitsAllowed = -1f; // undefined, if setting is off.
        final float minBrightnessAllowed;

        if (isActive) {
            float luxBasedNitsLowerBound = mDisplayDeviceConfig.getMinNitsFromLux(mAmbientLux);
            minNitsAllowed = Math.max(settingNitsLowerBound,
                    luxBasedNitsLowerBound);
            minBrightnessAllowed = getBrightnessFromNits(minNitsAllowed);
@@ -126,6 +125,12 @@ public class BrightnessLowLuxModifier extends BrightnessModifier {
        }
    }

    @VisibleForTesting
    public void setAmbientLux(float lux) {
        mAmbientLux = lux;
        recalculateLowerBound();
    }

    @VisibleForTesting
    public boolean isActive() {
        return mIsActive;
@@ -164,10 +169,10 @@ public class BrightnessLowLuxModifier extends BrightnessModifier {
    @Override
    public void apply(DisplayManagerInternal.DisplayPowerRequest request,
            DisplayBrightnessState.Builder stateBuilder) {

        stateBuilder.setMinBrightness(mBrightnessLowerBound);
        float boundedBrightness = Math.max(mBrightnessLowerBound, stateBuilder.getBrightness());
        stateBuilder.setBrightness(boundedBrightness);

        if (BrightnessSynchronizer.floatEquals(stateBuilder.getBrightness(),
                mBrightnessLowerBound)) {
            stateBuilder.getBrightnessReason().addModifier(mReason);
@@ -180,14 +185,8 @@ public class BrightnessLowLuxModifier extends BrightnessModifier {
    }

    @Override
    public void onAmbientLuxChange(float ambientLux) {
        mAmbientLux = ambientLux;
        recalculateLowerBound();
    }

    @Override
    public void setAutoBrightnessState(int state) {
        mAutoBrightnessEnabled = state == AUTO_BRIGHTNESS_ENABLED;
    public boolean shouldListenToLightSensor() {
        return isSettingEnabled();
    }

    @Override
@@ -217,6 +216,7 @@ public class BrightnessLowLuxModifier extends BrightnessModifier {
    }

    private final class SettingsObserver extends ContentObserver {

        SettingsObserver(Handler handler) {
            super(handler);
            mContentResolver.registerContentObserver(
+10 −0
Original line number Diff line number Diff line
@@ -51,4 +51,14 @@ class BrightnessLowPowerModeModifier extends BrightnessModifier {
        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
        super.dump(ipw);
    }

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

    @Override
    public void setAmbientLux(float lux) {
        // unused
    }
}
Loading