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

Commit 265d97e9 authored by Piotr Wilczyński's avatar Piotr Wilczyński Committed by Automerger Merge Worker
Browse files

Merge "Use a brightness sensor to determine the screen's initial brightness"...

Merge "Use a brightness sensor to determine the screen's initial brightness" into tm-qpr-dev am: 7cd5d000

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20105810



Change-Id: I7c2a2240412fc8923b0262e321deda960a97f7c4
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents fc829586 7cd5d000
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ 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.IntegerArray;
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.Point;
import com.android.server.display.config.RefreshRateConfigs;
@@ -213,6 +214,10 @@ import javax.xml.datatype.DatatypeConfigurationException;
 *        <type>android.sensor.light</type>
 *        <name>1234 Ambient Light Sensor</name>
 *      </lightSensor>
 *      <screenOffBrightnessSensor>
 *        <type>com.google.sensor.binned_brightness</type>
 *        <name>Binned Brightness 0 (wake-up)</name>
 *      </screenOffBrightnessSensor>
 *      <proxSensor>
 *        <type>android.sensor.proximity</type>
 *        <name>1234 Proximity Sensor</name>
@@ -368,6 +373,13 @@ import javax.xml.datatype.DatatypeConfigurationException;
 *             </brightnessThresholdPoints>
 *         </darkeningThresholds>
 *     </displayBrightnessChangeThresholdsIdle>
 *     <screenOffBrightnessSensorValueToLux>
 *         <item>-1</item>
 *         <item>0</item>
 *         <item>5</item>
 *         <item>80</item>
 *         <item>1500</item>
 *     </screenOffBrightnessSensorValueToLux>
 *    </displayConfiguration>
 *  }
 *  </pre>
@@ -428,6 +440,9 @@ public class DisplayDeviceConfig {
    // The details of the ambient light sensor associated with this display.
    private final SensorData mAmbientLightSensor = new SensorData();

    // The details of the doze brightness sensor associated with this display.
    private final SensorData mScreenOffBrightnessSensor = new SensorData();

    // The details of the proximity sensor associated with this display.
    private final SensorData mProximitySensor = new SensorData();

@@ -523,6 +538,9 @@ public class DisplayDeviceConfig {
    private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
    private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS;

    // A mapping between screen off sensor values and lux values
    private int[] mScreenOffBrightnessSensorValueToLux;

    private Spline mBrightnessToBacklightSpline;
    private Spline mBacklightToBrightnessSpline;
    private Spline mBacklightToNitsSpline;
@@ -1197,6 +1215,10 @@ public class DisplayDeviceConfig {
        return mAmbientLightSensor;
    }

    SensorData getScreenOffBrightnessSensor() {
        return mScreenOffBrightnessSensor;
    }

    SensorData getProximitySensor() {
        return mProximitySensor;
    }
@@ -1320,6 +1342,14 @@ public class DisplayDeviceConfig {
        return mHighAmbientBrightnessThresholds;
    }

    /**
     * @return A mapping from screen off brightness sensor readings to lux values. This estimates
     * the ambient lux when the screen is off to determine the initial brightness
     */
    public int[] getScreenOffBrightnessSensorValueToLux() {
        return mScreenOffBrightnessSensorValueToLux;
    }

    @Override
    public String toString() {
        return "DisplayDeviceConfig{"
@@ -1398,6 +1428,7 @@ public class DisplayDeviceConfig {
                mScreenDarkeningPercentagesIdle)
                + "\n"
                + ", mAmbientLightSensor=" + mAmbientLightSensor
                + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor
                + ", mProximitySensor=" + mProximitySensor
                + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
                + ", mDensityMapping= " + mDensityMapping
@@ -1420,6 +1451,9 @@ public class DisplayDeviceConfig {
                + Arrays.toString(mHighDisplayBrightnessThresholds)
                + ", mHighAmbientBrightnessThresholds= "
                + Arrays.toString(mHighAmbientBrightnessThresholds)
                + "\n"
                + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
                mScreenOffBrightnessSensorValueToLux)
                + "}";
    }

@@ -1473,11 +1507,13 @@ public class DisplayDeviceConfig {
                loadQuirks(config);
                loadBrightnessRamps(config);
                loadAmbientLightSensorFromDdc(config);
                loadScreenOffBrightnessSensorFromDdc(config);
                loadProxSensorFromDdc(config);
                loadAmbientHorizonFromDdc(config);
                loadBrightnessChangeThresholds(config);
                loadAutoBrightnessConfigValues(config);
                loadRefreshRateSetting(config);
                loadScreenOffBrightnessSensorValueToLuxFromDdc(config);
            } else {
                Slog.w(TAG, "DisplayDeviceConfig file is null");
            }
@@ -2174,6 +2210,14 @@ public class DisplayDeviceConfig {
        mProximitySensor.type = "";
    }

    private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) {
        final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor();
        if (sensorDetails != null) {
            mScreenOffBrightnessSensor.type = sensorDetails.getType();
            mScreenOffBrightnessSensor.name = sensorDetails.getName();
        }
    }

    private void loadProxSensorFromDdc(DisplayConfiguration config) {
        SensorDetails sensorDetails = config.getProxSensor();
        if (sensorDetails != null) {
@@ -2586,6 +2630,19 @@ public class DisplayDeviceConfig {
                && mDdcAutoBrightnessAvailable;
    }

    private void loadScreenOffBrightnessSensorValueToLuxFromDdc(DisplayConfiguration config) {
        IntegerArray sensorValueToLux = config.getScreenOffBrightnessSensorValueToLux();
        if (sensorValueToLux == null) {
            return;
        }

        List<BigInteger> items = sensorValueToLux.getItem();
        mScreenOffBrightnessSensorValueToLux = new int[items.size()];
        for (int i = 0; i < items.size(); i++) {
            mScreenOffBrightnessSensorValueToLux[i] = items.get(i).intValue();
        }
    }

    static class SensorData {
        public String type;
        public String name;
+51 −1
Original line number Diff line number Diff line
@@ -414,7 +414,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    @Nullable
    private AutomaticBrightnessController mAutomaticBrightnessController;

    // The controller for the sensor used to estimate ambient lux while the display is off.
    @Nullable
    private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;

    private Sensor mLightSensor;
    private Sensor mScreenOffBrightnessSensor;

    // The mappers between ambient lux, display backlight values, and display brightness.
    // We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
@@ -1098,6 +1103,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

            mBrightnessEventRingBuffer =
                    new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);

            loadScreenOffBrightnessSensor();
            int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
            if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
                mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
                        mSensorManager,
                        mScreenOffBrightnessSensor,
                        mHandler,
                        SystemClock::uptimeMillis,
                        sensorValueToLux,
                        mInteractiveModeBrightnessMapper
                );
            }
        } else {
            mUseSoftwareAutoBrightnessConfig = false;
        }
@@ -1275,6 +1293,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        }
        assert(state != Display.STATE_UNKNOWN);

        if (mScreenOffBrightnessSensorController != null) {
            mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
                    && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
                    && !mAllowAutoBrightnessWhileDozingConfig)));
        }

        boolean skipRampBecauseOfProximityChangeToNegative = false;
        // Apply the proximity sensor.
        if (mProximitySensor != null) {
@@ -1454,6 +1478,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
                mAppliedAutoBrightness = true;
                mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
                if (mScreenOffBrightnessSensorController != null) {
                    mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
                }
            } else {
                mAppliedAutoBrightness = false;
            }
@@ -1481,6 +1508,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
        }

        // The ALS is not available yet - use the screen off sensor to determine the initial
        // brightness
        if (Float.isNaN(brightnessState) && autoBrightnessEnabled
                && mScreenOffBrightnessSensorController != null) {
            brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
            if (isValidBrightnessValue(brightnessState)) {
                brightnessState = clampScreenBrightness(brightnessState);
                updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
                mBrightnessReasonTemp.setReason(
                        BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
            }
        }

        // Apply manual brightness.
        if (Float.isNaN(brightnessState)) {
            brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
@@ -2052,6 +2092,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                fallbackType);
    }

    private void loadScreenOffBrightnessSensor() {
        DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
                mDisplayDeviceConfig.getScreenOffBrightnessSensor();
        mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
                screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
                SensorUtils.NO_FALLBACK);
    }

    private void loadProximitySensor() {
        if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
            return;
@@ -3201,7 +3249,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        static final int REASON_OVERRIDE = 7;
        static final int REASON_TEMPORARY = 8;
        static final int REASON_BOOST = 9;
        static final int REASON_MAX = REASON_BOOST;
        static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 10;
        static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;

        static final int MODIFIER_DIMMED = 0x1;
        static final int MODIFIER_LOW_POWER = 0x2;
@@ -3311,6 +3360,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                case REASON_OVERRIDE: return "override";
                case REASON_TEMPORARY: return "temporary";
                case REASON_BOOST: return "boost";
                case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor";
                default: return Integer.toString(reason);
            }
        }
+127 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.display;

import android.annotation.Nullable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.PowerManager;
import android.util.IndentingPrintWriter;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;

/**
 * Controls the light sensor when the screen is off. The sensor used here does not report lux values
 * but an index that needs to be mapped to a lux value.
 */
public class ScreenOffBrightnessSensorController implements SensorEventListener {
    private static final String TAG = "ScreenOffBrightnessSensorController";

    private static final int SENSOR_INVALID_VALUE = -1;
    private static final long SENSOR_VALUE_VALID_TIME_MILLIS = 1500;

    private final Handler mHandler;
    private final Clock mClock;
    private final SensorManager mSensorManager;
    private final Sensor mLightSensor;
    private final int[] mSensorValueToLux;

    private boolean mRegistered;
    private int mLastSensorValue = SENSOR_INVALID_VALUE;
    private long mSensorDisableTime = -1;

    // The mapper to translate ambient lux to screen brightness in the range [0, 1.0].
    @Nullable
    private final BrightnessMappingStrategy mBrightnessMapper;

    public ScreenOffBrightnessSensorController(
            SensorManager sensorManager,
            Sensor lightSensor,
            Handler handler,
            Clock clock,
            int[] sensorValueToLux,
            BrightnessMappingStrategy brightnessMapper) {
        mSensorManager = sensorManager;
        mLightSensor = lightSensor;
        mHandler = handler;
        mClock = clock;
        mSensorValueToLux = sensorValueToLux;
        mBrightnessMapper = brightnessMapper;
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (mRegistered) {
            mLastSensorValue = (int) event.values[0];
        }
    }

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

    void setLightSensorEnabled(boolean enabled) {
        if (enabled && !mRegistered) {
            // Wait until we get an event from the sensor indicating ready.
            mRegistered = mSensorManager.registerListener(this, mLightSensor,
                    SensorManager.SENSOR_DELAY_NORMAL, mHandler);
            mLastSensorValue = SENSOR_INVALID_VALUE;
        } else if (!enabled && mRegistered) {
            mSensorManager.unregisterListener(this);
            mRegistered = false;
            mSensorDisableTime = mClock.uptimeMillis();
        }
    }

    float getAutomaticScreenBrightness() {
        if (mLastSensorValue < 0 || mLastSensorValue >= mSensorValueToLux.length
                || (!mRegistered
                && mClock.uptimeMillis() - mSensorDisableTime > SENSOR_VALUE_VALID_TIME_MILLIS)) {
            return PowerManager.BRIGHTNESS_INVALID_FLOAT;
        }

        int lux = mSensorValueToLux[mLastSensorValue];
        if (lux < 0) {
            return PowerManager.BRIGHTNESS_INVALID_FLOAT;
        }

        return mBrightnessMapper.getBrightness(lux);
    }

    /** Dump current state */
    public void dump(PrintWriter pw) {
        pw.println("ScreenOffBrightnessSensorController:");
        IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
        idpw.increaseIndent();
        idpw.println("registered=" + mRegistered);
        idpw.println("lastSensorValue=" + mLastSensorValue);
    }

    /** Functional interface for providing time. */
    @VisibleForTesting
    interface Clock {
        /**
         * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
         */
        long uptimeMillis();
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -74,6 +74,9 @@
                <xs:element type="sensorDetails" name="lightSensor">
                    <xs:annotation name="final"/>
                </xs:element>
                <xs:element type="sensorDetails" name="screenOffBrightnessSensor">
                    <xs:annotation name="final"/>
                </xs:element>
                <xs:element type="sensorDetails" name="proxSensor">
                    <xs:annotation name="final"/>
                </xs:element>
@@ -109,6 +112,11 @@
                <xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1">
                    <xs:annotation name="final"/>
                </xs:element>
                <!-- Table that translates sensor values from the screenOffBrightnessSensor
                to lux values; -1 means the lux reading is not available. -->
                <xs:element type="integer-array" name="screenOffBrightnessSensorValueToLux">
                    <xs:annotation name="final"/>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
@@ -485,4 +493,10 @@
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="integer-array">
        <xs:sequence>
            <xs:element name="item" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
+9 −0
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@ package com.android.server.display.config {
    method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
    method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
    method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
    method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor();
    method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux();
    method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling();
    method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
    method public final void setAmbientBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
@@ -120,6 +122,8 @@ package com.android.server.display.config {
    method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger);
    method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
    method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal);
    method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails);
    method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray);
    method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling);
  }

@@ -160,6 +164,11 @@ package com.android.server.display.config {
    method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
  }

  public class IntegerArray {
    ctor public IntegerArray();
    method public java.util.List<java.math.BigInteger> getItem();
  }

  public class NitsMap {
    ctor public NitsMap();
    method public String getInterpolation();
Loading