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

Commit b0c536ee authored by Michael Wright's avatar Michael Wright Committed by Automerger Merge Worker
Browse files

Merge "Brightnessthrottler updateable through DeviceConfig" into tm-qpr-dev am: c5f1c156

parents 4a02e46b c5f1c156
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -1448,5 +1448,15 @@ public final class DisplayManager {
         * @hide
         * @hide
         */
         */
        String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";
        String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";

        /**
         * Key for the brightness throttling data as a String formatted:
         * <displayId>,<no of throttling levels>,[<severity as string>,<brightness cap>]
         * Where the latter part is repeated for each throttling level, and the entirety is repeated
         * for each display, separated by a semicolon.
         * For example:
         * 123,1,critical,0.8;456,2,moderate,0.9,critical,0.7
         */
        String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data";
    }
    }
}
}
+195 −10
Original line number Original line Diff line number Diff line
@@ -16,21 +16,31 @@


package com.android.server.display;
package com.android.server.display;


import android.annotation.NonNull;
import android.content.Context;
import android.content.Context;
import android.hardware.display.BrightnessInfo;
import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IThermalEventListener;
import android.os.IThermalEventListener;
import android.os.IThermalService;
import android.os.IThermalService;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.Temperature;
import android.os.Temperature;
import android.provider.DeviceConfig;
import android.provider.DeviceConfigInterface;
import android.util.Slog;
import android.util.Slog;


import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData;
import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData;
import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel;


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


/**
/**
 * This class monitors various conditions, such as skin temperature throttling status, and limits
 * This class monitors various conditions, such as skin temperature throttling status, and limits
@@ -44,28 +54,54 @@ class BrightnessThrottler {


    private final Injector mInjector;
    private final Injector mInjector;
    private final Handler mHandler;
    private final Handler mHandler;
    private BrightnessThrottlingData mThrottlingData;
    // We need a separate handler for unit testing. These two handlers are the same throughout the
    // non-test code.
    private final Handler mDeviceConfigHandler;
    private final Runnable mThrottlingChangeCallback;
    private final Runnable mThrottlingChangeCallback;
    private final SkinThermalStatusObserver mSkinThermalStatusObserver;
    private final SkinThermalStatusObserver mSkinThermalStatusObserver;
    private final DeviceConfigListener mDeviceConfigListener;
    private final DeviceConfigInterface mDeviceConfig;

    private int mThrottlingStatus;
    private int mThrottlingStatus;
    private BrightnessThrottlingData mThrottlingData;
    private BrightnessThrottlingData mDdcThrottlingData;
    private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
    private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
    private @BrightnessInfo.BrightnessMaxReason int mBrightnessMaxReason =
    private @BrightnessInfo.BrightnessMaxReason int mBrightnessMaxReason =
        BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
        BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
    private String mUniqueDisplayId;

    // The most recent string that has been set from DeviceConfig
    private String mBrightnessThrottlingDataString;

    // This is a collection of brightness throttling data that has been written as overrides from
    // the DeviceConfig. This will always take priority over the display device config data.
    private HashMap<String, BrightnessThrottlingData> mBrightnessThrottlingDataOverride =
            new HashMap<>(1);


    BrightnessThrottler(Handler handler, BrightnessThrottlingData throttlingData,
    BrightnessThrottler(Handler handler, BrightnessThrottlingData throttlingData,
            Runnable throttlingChangeCallback) {
            Runnable throttlingChangeCallback, String uniqueDisplayId) {
        this(new Injector(), handler, throttlingData, throttlingChangeCallback);
        this(new Injector(), handler, handler, throttlingData, throttlingChangeCallback,
                uniqueDisplayId);
    }
    }


    BrightnessThrottler(Injector injector, Handler handler, BrightnessThrottlingData throttlingData,
    @VisibleForTesting
            Runnable throttlingChangeCallback) {
    BrightnessThrottler(Injector injector, Handler handler, Handler deviceConfigHandler,
            BrightnessThrottlingData throttlingData, Runnable throttlingChangeCallback,
            String uniqueDisplayId) {
        mInjector = injector;
        mInjector = injector;

        mHandler = handler;
        mHandler = handler;
        mDeviceConfigHandler = deviceConfigHandler;
        mThrottlingData = throttlingData;
        mThrottlingData = throttlingData;
        mDdcThrottlingData = throttlingData;
        mThrottlingChangeCallback = throttlingChangeCallback;
        mThrottlingChangeCallback = throttlingChangeCallback;
        mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
        mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);


        resetThrottlingData(mThrottlingData);
        mUniqueDisplayId = uniqueDisplayId;
        mDeviceConfig = injector.getDeviceConfig();
        mDeviceConfigListener = new DeviceConfigListener();

        resetThrottlingData(mThrottlingData, mUniqueDisplayId);
    }
    }


    boolean deviceSupportsThrottling() {
    boolean deviceSupportsThrottling() {
@@ -86,7 +122,7 @@ class BrightnessThrottler {


    void stop() {
    void stop() {
        mSkinThermalStatusObserver.stopObserving();
        mSkinThermalStatusObserver.stopObserving();

        mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener);
        // We're asked to stop throttling, so reset brightness restrictions.
        // We're asked to stop throttling, so reset brightness restrictions.
        mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
        mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
        mBrightnessMaxReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
        mBrightnessMaxReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
@@ -97,9 +133,19 @@ class BrightnessThrottler {
        mThrottlingStatus = THROTTLING_INVALID;
        mThrottlingStatus = THROTTLING_INVALID;
    }
    }


    void resetThrottlingData(BrightnessThrottlingData throttlingData) {
    private void resetThrottlingData() {
        resetThrottlingData(mDdcThrottlingData, mUniqueDisplayId);
    }

    void resetThrottlingData(BrightnessThrottlingData throttlingData, String displayId) {
        stop();
        stop();
        mThrottlingData = throttlingData;

        mUniqueDisplayId = displayId;
        mDdcThrottlingData = throttlingData;
        mDeviceConfigListener.startListening();
        reloadBrightnessThrottlingDataOverride();
        mThrottlingData = mBrightnessThrottlingDataOverride.getOrDefault(mUniqueDisplayId,
                throttlingData);


        if (deviceSupportsThrottling()) {
        if (deviceSupportsThrottling()) {
            mSkinThermalStatusObserver.startObserving();
            mSkinThermalStatusObserver.startObserving();
@@ -173,14 +219,148 @@ class BrightnessThrottler {
    private void dumpLocal(PrintWriter pw) {
    private void dumpLocal(PrintWriter pw) {
        pw.println("BrightnessThrottler:");
        pw.println("BrightnessThrottler:");
        pw.println("  mThrottlingData=" + mThrottlingData);
        pw.println("  mThrottlingData=" + mThrottlingData);
        pw.println("  mDdcThrottlingData=" + mDdcThrottlingData);
        pw.println("  mUniqueDisplayId=" + mUniqueDisplayId);
        pw.println("  mThrottlingStatus=" + mThrottlingStatus);
        pw.println("  mThrottlingStatus=" + mThrottlingStatus);
        pw.println("  mBrightnessCap=" + mBrightnessCap);
        pw.println("  mBrightnessCap=" + mBrightnessCap);
        pw.println("  mBrightnessMaxReason=" +
        pw.println("  mBrightnessMaxReason=" +
            BrightnessInfo.briMaxReasonToString(mBrightnessMaxReason));
            BrightnessInfo.briMaxReasonToString(mBrightnessMaxReason));
        pw.println("  mBrightnessThrottlingDataOverride=" + mBrightnessThrottlingDataOverride);
        pw.println("  mBrightnessThrottlingDataString=" + mBrightnessThrottlingDataString);


        mSkinThermalStatusObserver.dump(pw);
        mSkinThermalStatusObserver.dump(pw);
    }
    }


    private String getBrightnessThrottlingDataString() {
        return mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                DisplayManager.DeviceConfig.KEY_BRIGHTNESS_THROTTLING_DATA,
                /* defaultValue= */ null);
    }

    private boolean parseAndSaveData(@NonNull String strArray,
            @NonNull HashMap<String, BrightnessThrottlingData> tempBrightnessThrottlingData) {
        boolean validConfig = true;
        String[] items = strArray.split(",");
        int i = 0;

        try {
            String uniqueDisplayId = items[i++];

            // number of throttling points
            int noOfThrottlingPoints = Integer.parseInt(items[i++]);
            List<ThrottlingLevel> throttlingLevels = new ArrayList<>(noOfThrottlingPoints);

            // throttling level and point
            for (int j = 0; j < noOfThrottlingPoints; j++) {
                String severity = items[i++];
                int status = parseThermalStatus(severity);

                float brightnessPoint = parseBrightness(items[i++]);

                throttlingLevels.add(new ThrottlingLevel(status, brightnessPoint));
            }
            BrightnessThrottlingData toSave =
                    DisplayDeviceConfig.BrightnessThrottlingData.create(throttlingLevels);
            tempBrightnessThrottlingData.put(uniqueDisplayId, toSave);
        } catch (NumberFormatException | IndexOutOfBoundsException
                | UnknownThermalStatusException e) {
            validConfig = false;
            Slog.e(TAG, "Throttling data is invalid array: '" + strArray + "'", e);
        }

        if (i != items.length) {
            validConfig = false;
        }

        return validConfig;
    }

    public void reloadBrightnessThrottlingDataOverride() {
        HashMap<String, BrightnessThrottlingData> tempBrightnessThrottlingData =
                new HashMap<>(1);
        mBrightnessThrottlingDataString = getBrightnessThrottlingDataString();
        boolean validConfig = true;
        mBrightnessThrottlingDataOverride.clear();
        if (mBrightnessThrottlingDataString != null) {
            String[] throttlingDataSplits = mBrightnessThrottlingDataString.split(";");
            for (String s : throttlingDataSplits) {
                if (!parseAndSaveData(s, tempBrightnessThrottlingData)) {
                    validConfig = false;
                    break;
                }
            }

            if (validConfig) {
                mBrightnessThrottlingDataOverride.putAll(tempBrightnessThrottlingData);
                tempBrightnessThrottlingData.clear();
            }

        } else {
            Slog.w(TAG, "DeviceConfig BrightnessThrottlingData is null");
        }
    }

    /**
     * Listens to config data change and updates the brightness throttling data using
     * DisplayManager#KEY_BRIGHTNESS_THROTTLING_DATA.
     * The format should be a string similar to: "local:4619827677550801152,2,moderate,0.5,severe,
     * 0.379518072;local:4619827677550801151,1,moderate,0.75"
     * In this order:
     * <displayId>,<no of throttling levels>,[<severity as string>,<brightness cap>]
     * Where the latter part is repeated for each throttling level, and the entirety is repeated
     * for each display, separated by a semicolon.
     */
    public class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
        public Executor mExecutor = new HandlerExecutor(mDeviceConfigHandler);

        public void startListening() {
            mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                    mExecutor, this);
        }

        @Override
        public void onPropertiesChanged(DeviceConfig.Properties properties) {
            reloadBrightnessThrottlingDataOverride();
            resetThrottlingData();
        }
    }

    private float parseBrightness(String intVal) throws NumberFormatException {
        float value = Float.parseFloat(intVal);
        if (value < PowerManager.BRIGHTNESS_MIN || value > PowerManager.BRIGHTNESS_MAX) {
            throw new NumberFormatException("Brightness constraint value out of bounds.");
        }
        return value;
    }

    @PowerManager.ThermalStatus private int parseThermalStatus(@NonNull String value)
            throws UnknownThermalStatusException {
        switch (value) {
            case "none":
                return PowerManager.THERMAL_STATUS_NONE;
            case "light":
                return PowerManager.THERMAL_STATUS_LIGHT;
            case "moderate":
                return PowerManager.THERMAL_STATUS_MODERATE;
            case "severe":
                return PowerManager.THERMAL_STATUS_SEVERE;
            case "critical":
                return PowerManager.THERMAL_STATUS_CRITICAL;
            case "emergency":
                return PowerManager.THERMAL_STATUS_EMERGENCY;
            case "shutdown":
                return PowerManager.THERMAL_STATUS_SHUTDOWN;
            default:
                throw new UnknownThermalStatusException("Invalid Thermal Status: " + value);
        }
    }

    private static class UnknownThermalStatusException extends Exception {
        UnknownThermalStatusException(String message) {
            super(message);
        }
    }

    private final class SkinThermalStatusObserver extends IThermalEventListener.Stub {
    private final class SkinThermalStatusObserver extends IThermalEventListener.Stub {
        private final Injector mInjector;
        private final Injector mInjector;
        private final Handler mHandler;
        private final Handler mHandler;
@@ -258,5 +438,10 @@ class BrightnessThrottler {
            return IThermalService.Stub.asInterface(
            return IThermalService.Stub.asInterface(
                    ServiceManager.getService(Context.THERMAL_SERVICE));
                    ServiceManager.getService(Context.THERMAL_SERVICE));
        }
        }

        @NonNull
        public DeviceConfigInterface getDeviceConfig() {
            return DeviceConfigInterface.REAL;
        }
    }
    }
}
}
+51 −5
Original line number Original line Diff line number Diff line
@@ -279,9 +279,13 @@ public class DisplayDeviceConfig {
    private HighBrightnessModeData mHbmData;
    private HighBrightnessModeData mHbmData;
    private DensityMapping mDensityMapping;
    private DensityMapping mDensityMapping;
    private String mLoadedFrom = null;
    private String mLoadedFrom = null;
    private Spline mSdrToHdrRatioSpline;


    // Brightness Throttling data may be updated via the DeviceConfig. Here we store the original
    // data, which comes from the ddc, and the current one, which may be the DeviceConfig
    // overwritten value.
    private BrightnessThrottlingData mBrightnessThrottlingData;
    private BrightnessThrottlingData mBrightnessThrottlingData;
    private Spline mSdrToHdrRatioSpline;
    private BrightnessThrottlingData mOriginalBrightnessThrottlingData;


    private DisplayDeviceConfig(Context context) {
    private DisplayDeviceConfig(Context context) {
        mContext = context;
        mContext = context;
@@ -422,6 +426,10 @@ public class DisplayDeviceConfig {
        return config;
        return config;
    }
    }


    void setBrightnessThrottlingData(BrightnessThrottlingData brightnessThrottlingData) {
        mBrightnessThrottlingData = brightnessThrottlingData;
    }

    /**
    /**
     * Return the brightness mapping nits array.
     * Return the brightness mapping nits array.
     *
     *
@@ -637,6 +645,7 @@ public class DisplayDeviceConfig {
                + ", mHbmData=" + mHbmData
                + ", mHbmData=" + mHbmData
                + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
                + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
                + ", mBrightnessThrottlingData=" + mBrightnessThrottlingData
                + ", mBrightnessThrottlingData=" + mBrightnessThrottlingData
                + ", mOriginalBrightnessThrottlingData=" + mOriginalBrightnessThrottlingData
                + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
                + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
                + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
                + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
                + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
                + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
@@ -932,6 +941,7 @@ public class DisplayDeviceConfig {


        if (!badConfig) {
        if (!badConfig) {
            mBrightnessThrottlingData = BrightnessThrottlingData.create(throttlingLevels);
            mBrightnessThrottlingData = BrightnessThrottlingData.create(throttlingLevels);
            mOriginalBrightnessThrottlingData = mBrightnessThrottlingData;
        }
        }
    }
    }


@@ -1407,7 +1417,9 @@ public class DisplayDeviceConfig {
    /**
    /**
     * Container for brightness throttling data.
     * Container for brightness throttling data.
     */
     */
    static class BrightnessThrottlingData {
    public static class BrightnessThrottlingData {
        public List<ThrottlingLevel> throttlingLevels;

        static class ThrottlingLevel {
        static class ThrottlingLevel {
            public @PowerManager.ThermalStatus int thermalStatus;
            public @PowerManager.ThermalStatus int thermalStatus;
            public float brightness;
            public float brightness;
@@ -1421,9 +1433,25 @@ public class DisplayDeviceConfig {
            public String toString() {
            public String toString() {
                return "[" + thermalStatus + "," + brightness + "]";
                return "[" + thermalStatus + "," + brightness + "]";
            }
            }

            @Override
            public boolean equals(Object obj) {
                if (!(obj instanceof ThrottlingLevel)) {
                    return false;
                }
                }
                ThrottlingLevel otherThrottlingLevel = (ThrottlingLevel) obj;


        public List<ThrottlingLevel> throttlingLevels;
                return otherThrottlingLevel.thermalStatus == this.thermalStatus
                        && otherThrottlingLevel.brightness == this.brightness;
            }
            @Override
            public int hashCode() {
                int result = 1;
                result = 31 * result + thermalStatus;
                result = 31 * result + Float.hashCode(brightness);
                return result;
            }
        }


        static public BrightnessThrottlingData create(List<ThrottlingLevel> throttlingLevels)
        static public BrightnessThrottlingData create(List<ThrottlingLevel> throttlingLevels)
        {
        {
@@ -1482,12 +1510,30 @@ public class DisplayDeviceConfig {
                + "} ";
                + "} ";
        }
        }


        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (!(obj instanceof BrightnessThrottlingData)) {
                return false;
            }

            BrightnessThrottlingData otherBrightnessThrottlingData = (BrightnessThrottlingData) obj;
            return throttlingLevels.equals(otherBrightnessThrottlingData.throttlingLevels);
        }

        @Override
        public int hashCode() {
            return throttlingLevels.hashCode();
        }

        private BrightnessThrottlingData(List<ThrottlingLevel> inLevels) {
        private BrightnessThrottlingData(List<ThrottlingLevel> inLevels) {
            throttlingLevels = new ArrayList<>(inLevels.size());
            throttlingLevels = new ArrayList<>(inLevels.size());
            for (ThrottlingLevel level : inLevels) {
            for (ThrottlingLevel level : inLevels) {
                throttlingLevels.add(new ThrottlingLevel(level.thermalStatus, level.brightness));
                throttlingLevels.add(new ThrottlingLevel(level.thermalStatus, level.brightness));
            }
            }
        }
        }

    }
    }
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -861,7 +861,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                    }
                    }
                });
                });
        mBrightnessThrottler.resetThrottlingData(
        mBrightnessThrottler.resetThrottlingData(
                mDisplayDeviceConfig.getBrightnessThrottlingData());
                mDisplayDeviceConfig.getBrightnessThrottlingData(), mUniqueDisplayId);
    }
    }


    private void sendUpdatePowerState() {
    private void sendUpdatePowerState() {
@@ -1816,7 +1816,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                () -> {
                () -> {
                    sendUpdatePowerStateLocked();
                    sendUpdatePowerStateLocked();
                    postBrightnessChangeRunnable();
                    postBrightnessChangeRunnable();
                });
                }, mUniqueDisplayId);
    }
    }


    private void blockScreenOn() {
    private void blockScreenOn() {
+174 −7

File changed.

Preview size limit exceeded, changes collapsed.

Loading