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

Commit 8bf124b0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add basic High Brightness Mode implementation."

parents 55ab07fd ef47c4f3
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.internal.BrightnessSynchronizer;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.server.EventLogTags;
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;

import java.io.PrintWriter;

@@ -195,6 +196,9 @@ class AutomaticBrightnessController {
    private boolean mShortTermModelValid;
    private float mShortTermModelAnchor;

    // Controls High Brightness Mode.
    private HighBrightnessModeController mHbmController;

    // Context-sensitive brightness configurations require keeping track of the foreground app's
    // package name and category, which is done by registering a TaskStackListener to call back to
    // us onTaskStackChanged, and then using the ActivityTaskManager to get the foreground app's
@@ -216,12 +220,12 @@ class AutomaticBrightnessController {
            float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
            long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
            boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
            HysteresisLevels screenBrightnessThresholds, Context context) {
            HysteresisLevels screenBrightnessThresholds, LogicalDisplay display, Context context) {
        this(new Injector(), callbacks, looper, sensorManager, lightSensor, mapper,
                lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
                lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
                darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
                ambientBrightnessThresholds, screenBrightnessThresholds, context
                ambientBrightnessThresholds, screenBrightnessThresholds, display, context
        );
    }

@@ -232,7 +236,7 @@ class AutomaticBrightnessController {
            float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
            long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
            boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
            HysteresisLevels screenBrightnessThresholds, Context context) {
            HysteresisLevels screenBrightnessThresholds, LogicalDisplay display, Context context) {
        mInjector = injector;
        mContext = context;
        mCallbacks = callbacks;
@@ -269,6 +273,20 @@ class AutomaticBrightnessController {
        mPendingForegroundAppPackageName = null;
        mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
        mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;

        final DisplayDeviceConfig ddConfig =
                display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
        HighBrightnessModeData hbmData =
                ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;

        final Runnable hbmChangeCallback = () -> {
            updateAutoBrightness(true /*sendUpdate*/, false /*userInitiatedChange*/);
            // TODO: b/175937645 - Callback to DisplayManagerService to indicate a change to the HBM
            // allowance has been made so that the brightness limits can be calculated
            // appropriately.
        };
        mHbmController = new HighBrightnessModeController(mHandler, brightnessMin, brightnessMax,
                hbmData, hbmChangeCallback);
    }

    /**
@@ -538,6 +556,7 @@ class AutomaticBrightnessController {
        mAmbientLux = lux;
        mAmbientBrighteningThreshold = mAmbientBrightnessThresholds.getBrighteningThreshold(lux);
        mAmbientDarkeningThreshold = mAmbientBrightnessThresholds.getDarkeningThreshold(lux);
        mHbmController.onAmbientLuxChange(mAmbientLux);

        // If the short term model was invalidated and the change is drastic enough, reset it.
        if (!mShortTermModelValid && mShortTermModelAnchor != -1) {
@@ -751,6 +770,7 @@ class AutomaticBrightnessController {
                    mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness));
            mScreenDarkeningThreshold = clampScreenBrightness(
                    mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness));
            mHbmController.onAutoBrightnessChanged(mScreenAutoBrightness);

            if (sendUpdate) {
                mCallbacks.updateBrightness();
@@ -761,7 +781,7 @@ class AutomaticBrightnessController {
    // Clamps values with float range [0.0-1.0]
    private float clampScreenBrightness(float value) {
        return MathUtils.constrain(value,
                mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
                mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax());
    }

    private void prepareBrightnessAdjustmentSample() {
+2 −4
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ abstract class DisplayDevice {
    private final DisplayAdapter mDisplayAdapter;
    private final IBinder mDisplayToken;
    private final String mUniqueId;
    private DisplayDeviceConfig mDisplayDeviceConfig;

    // The display device does not manage these properties itself, they are set by
    // the display manager service.  The display device shouldn't really be looking at these.
@@ -71,12 +70,11 @@ abstract class DisplayDevice {

    /*
     * Gets the DisplayDeviceConfig for this DisplayDevice.
     * Returns null for this device but is overridden in LocalDisplayDevice.
     *
     * @return The DisplayDeviceConfig.
     * @return The DisplayDeviceConfig; {@code null} if not overridden.
     */
    public DisplayDeviceConfig getDisplayDeviceConfig() {
        return mDisplayDeviceConfig;
        return null;
    }

    /**
+89 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.display;

import android.annotation.NonNull;
import android.content.Context;
import android.os.Environment;
import android.os.PowerManager;
@@ -25,6 +26,8 @@ import android.view.DisplayAddress;
import com.android.internal.BrightnessSynchronizer;
import com.android.server.display.config.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.HbmTiming;
import com.android.server.display.config.HighBrightnessMode;
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.Point;
import com.android.server.display.config.XmlParser;
@@ -61,19 +64,20 @@ public class DisplayDeviceConfig {
    private static final String STABLE_ID_SUFFIX_FORMAT = "id_%d";
    private static final String NO_SUFFIX_FORMAT = "%d";
    private static final long STABLE_FLAG = 1L << 62;

    // Float.NaN (used as invalid for brightness) cannot be stored in config.xml
    // so -2 is used instead
    private static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f;

    private final Context mContext;

    private float[] mNits;
    private float[] mBrightness;
    private float mBrightnessMinimum = Float.NaN;
    private float mBrightnessMaximum = Float.NaN;
    private float mBrightnessDefault = Float.NaN;
    private List<String> mQuirks;

    private final Context mContext;
    private boolean mIsHighBrightnessModeEnabled = false;
    private HighBrightnessModeData mHbmData;

    private DisplayDeviceConfig(Context context) {
        mContext = context;
@@ -182,6 +186,19 @@ public class DisplayDeviceConfig {
        return mQuirks != null && mQuirks.contains(quirkValue);
    }

    /**
     * @return high brightness mode configuration data for the display.
     */
    public HighBrightnessModeData getHighBrightnessModeData() {
        if (!mIsHighBrightnessModeEnabled || mHbmData == null) {
            return null;
        }

        HighBrightnessModeData hbmData = new HighBrightnessModeData();
        mHbmData.copyTo(hbmData);
        return hbmData;
    }

    @Override
    public String toString() {
        String str = "DisplayDeviceConfig{"
@@ -191,10 +208,16 @@ public class DisplayDeviceConfig {
                + ", mBrightnessMaximum=" + mBrightnessMaximum
                + ", mBrightnessDefault=" + mBrightnessDefault
                + ", mQuirks=" + mQuirks
                + ", isHbmEnabled=" + mIsHighBrightnessModeEnabled
                + ", mHbmData=" + mHbmData
                + "}";
        return str;
    }

    private float getMaxBrightness() {
        return mBrightness[mBrightness.length - 1];
    }

    private static DisplayDeviceConfig getConfigFromSuffix(Context context, File baseDirectory,
            String suffixFormat, long idNumber) {

@@ -240,6 +263,7 @@ public class DisplayDeviceConfig {
                loadBrightnessMap(config);
                loadBrightnessDefaultFromDdcXml(config);
                loadBrightnessConstraintsFromConfigXml();
                loadHighBrightnessModeData(config);
                loadQuirks(config);
            } else {
                Slog.w(TAG, "DisplayDeviceConfig file is null");
@@ -353,4 +377,66 @@ public class DisplayDeviceConfig {
            mQuirks = new ArrayList<>(quirks.getQuirk());
        }
    }

    private void loadHighBrightnessModeData(DisplayConfiguration config) {
        final HighBrightnessMode hbm = config.getHighBrightnessMode();
        if (hbm != null) {
            mIsHighBrightnessModeEnabled = hbm.getEnabled();
            mHbmData = new HighBrightnessModeData();
            mHbmData.minimumLux = hbm.getMinimumLux_all().floatValue();
            mHbmData.transitionPoint = hbm.getTransitionPoint_all().floatValue();
            if (mHbmData.transitionPoint >= getMaxBrightness()) {
                throw new IllegalArgumentException("HBM transition point invalid. "
                        + mHbmData.transitionPoint + " is not less than "
                        + getMaxBrightness());
            }
            final HbmTiming hbmTiming = hbm.getTiming_all();
            mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
            mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
            mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
        }
    }

    /**
     * Container for high brightness mode configuration data.
     */
    static class HighBrightnessModeData {
        /** Minimum lux needed to enter high brightness mode */
        public float minimumLux;

        /** Brightness level at which we transition from normal to high-brightness. */
        public float transitionPoint;

        /** Time window for HBM. */
        public long timeWindowMillis;

        /** Maximum time HBM is allowed to be during in a {@code timeWindowMillis}. */
        public long timeMaxMillis;

        /** Minimum time that HBM can be on before being enabled. */
        public long timeMinMillis;

        /**
         * Copies the HBM data to the specified parameter instance.
         * @param other the instance to copy data to.
         */
        public void copyTo(@NonNull HighBrightnessModeData other) {
            other.minimumLux = minimumLux;
            other.transitionPoint = transitionPoint;
            other.timeWindowMillis = timeWindowMillis;
            other.timeMaxMillis = timeMaxMillis;
            other.timeMinMillis = timeMinMillis;
        }

        @Override
        public String toString() {
            return "HBM{"
                    + "minLux: " + minimumLux
                    + ", transition: " + transitionPoint
                    + ", timeWindow: " + timeWindowMillis + "ms"
                    + ", timeMax: " + timeMaxMillis + "ms"
                    + ", timeMin: " + timeMinMillis
                    + "} ";
        }
    }
}
+10 −5
Original line number Diff line number Diff line
@@ -1100,7 +1100,7 @@ public final class DisplayManagerService extends SystemService {
            recordStableDisplayStatsIfNeededLocked(display);
            recordTopInsetLocked(display);
        }
        addDisplayPowerControllerLocked(displayId);
        addDisplayPowerControllerLocked(display);
        mDisplayStates.append(displayId, Display.STATE_OFF);
        mDisplayBrightnesses.append(displayId, display.getDisplayInfoLocked().brightnessDefault);

@@ -1132,6 +1132,11 @@ public final class DisplayManagerService extends SystemService {
        // this point.
        sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
        scheduleTraversalLocked(false);

        DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
        if (dpc != null) {
            dpc.onDisplayChanged();
        }
    }

    private void handleLogicalDisplayFrameRateOverridesChangedLocked(
@@ -1860,18 +1865,18 @@ public final class DisplayManagerService extends SystemService {

    private void initializeDisplayPowerControllersLocked() {
        mLogicalDisplayMapper.forEachLocked((logicalDisplay) -> addDisplayPowerControllerLocked(
                logicalDisplay.getDisplayIdLocked()));
                logicalDisplay));
    }

    private void addDisplayPowerControllerLocked(int displayId) {
    private void addDisplayPowerControllerLocked(LogicalDisplay display) {
        if (mPowerHandler == null) {
            // initPowerManagement has not yet been called.
            return;
        }
        final DisplayPowerController displayPowerController = new DisplayPowerController(
                mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
                mDisplayBlanker, mLogicalDisplayMapper.getLocked(displayId));
        mDisplayPowerControllers.append(displayId, displayPowerController);
                mDisplayBlanker, display);
        mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
    }

    private final class DisplayManagerHandler extends Handler {
+10 −1
Original line number Diff line number Diff line
@@ -523,7 +523,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
                        initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
                        autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
                        screenBrightnessThresholds, context);
                        screenBrightnessThresholds, logicalDisplay, context);
            } else {
                mUseSoftwareAutoBrightnessConfig = false;
            }
@@ -674,6 +674,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        return mAutomaticBrightnessController.getDefaultConfig();
    }

    /**
     * Notified when the display is changed. We use this to apply any changes that might be needed
     * when displays get swapped on foldable devices.  For example, different brightness properties
     * of each display need to be properly reflected in AutomaticBrightnessController.
     */
    public void onDisplayChanged() {
        // TODO: b/175821789 - Support high brightness on multiple (folding) displays
    }

    private void sendUpdatePowerState() {
        synchronized (mLock) {
            sendUpdatePowerStateLocked();
Loading