diff options
8 files changed, 252 insertions, 53 deletions
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index 7ccfb448cf61..bfb77b2e9c25 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -515,7 +515,9 @@ public class DisplayDeviceConfig { private final SensorData mScreenOffBrightnessSensor = new SensorData(); // The details of the proximity sensor associated with this display. - private final SensorData mProximitySensor = new SensorData(); + // Is null when no sensor should be used for that display + @Nullable + private SensorData mProximitySensor = new SensorData(); private final List<RefreshRateLimitation> mRefreshRateLimitations = new ArrayList<>(2 /*initialCapacity*/); @@ -1337,6 +1339,7 @@ public class DisplayDeviceConfig { return mScreenOffBrightnessSensor; } + @Nullable SensorData getProximitySensor() { return mProximitySensor; } @@ -2563,46 +2566,51 @@ public class DisplayDeviceConfig { private void loadAmbientLightSensorFromDdc(DisplayConfiguration config) { final SensorDetails sensorDetails = config.getLightSensor(); if (sensorDetails != null) { - mAmbientLightSensor.type = sensorDetails.getType(); - mAmbientLightSensor.name = sensorDetails.getName(); - final RefreshRateRange rr = sensorDetails.getRefreshRate(); - if (rr != null) { - mAmbientLightSensor.minRefreshRate = rr.getMinimum().floatValue(); - mAmbientLightSensor.maxRefreshRate = rr.getMaximum().floatValue(); - } + loadSensorData(sensorDetails, mAmbientLightSensor); } else { loadAmbientLightSensorFromConfigXml(); } } private void setProxSensorUnspecified() { - mProximitySensor.name = null; - mProximitySensor.type = null; + mProximitySensor = new SensorData(); } private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) { final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor(); if (sensorDetails != null) { - mScreenOffBrightnessSensor.type = sensorDetails.getType(); - mScreenOffBrightnessSensor.name = sensorDetails.getName(); + loadSensorData(sensorDetails, mScreenOffBrightnessSensor); } } private void loadProxSensorFromDdc(DisplayConfiguration config) { SensorDetails sensorDetails = config.getProxSensor(); if (sensorDetails != null) { - mProximitySensor.name = sensorDetails.getName(); - mProximitySensor.type = sensorDetails.getType(); - final RefreshRateRange rr = sensorDetails.getRefreshRate(); - if (rr != null) { - mProximitySensor.minRefreshRate = rr.getMinimum().floatValue(); - mProximitySensor.maxRefreshRate = rr.getMaximum().floatValue(); + String name = sensorDetails.getName(); + String type = sensorDetails.getType(); + if ("".equals(name) && "".equals(type)) { + // <proxSensor> with empty values to the config means no sensor should be used + mProximitySensor = null; + } else { + mProximitySensor = new SensorData(); + loadSensorData(sensorDetails, mProximitySensor); } } else { setProxSensorUnspecified(); } } + private void loadSensorData(@NonNull SensorDetails sensorDetails, + @NonNull SensorData sensorData) { + sensorData.name = sensorDetails.getName(); + sensorData.type = sensorDetails.getType(); + final RefreshRateRange rr = sensorDetails.getRefreshRate(); + if (rr != null) { + sensorData.minRefreshRate = rr.getMinimum().floatValue(); + sensorData.maxRefreshRate = rr.getMaximum().floatValue(); + } + } + private void loadBrightnessChangeThresholdsFromXml() { loadBrightnessChangeThresholds(/* config= */ null); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 3fe1d9c14b01..ffecf2b7018d 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -2303,29 +2303,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void loadAmbientLightSensor() { - DisplayDeviceConfig.SensorData lightSensor = mDisplayDeviceConfig.getAmbientLightSensor(); final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK; - mLightSensor = SensorUtils.findSensor(mSensorManager, lightSensor.type, lightSensor.name, - fallbackType); + mLightSensor = SensorUtils.findSensor(mSensorManager, + mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType); } private void loadScreenOffBrightnessSensor() { - DisplayDeviceConfig.SensorData screenOffBrightnessSensor = - mDisplayDeviceConfig.getScreenOffBrightnessSensor(); mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, - screenOffBrightnessSensor.type, screenOffBrightnessSensor.name, - SensorUtils.NO_FALLBACK); + mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK); } private void loadProximitySensor() { if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT || mDisplayId != Display.DEFAULT_DISPLAY) { return; } - final DisplayDeviceConfig.SensorData proxSensor = - mDisplayDeviceConfig.getProximitySensor(); - mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name, - Sensor.TYPE_PROXIMITY); + mProximitySensor = SensorUtils.findSensor(mSensorManager, + mDisplayDeviceConfig.getProximitySensor(), Sensor.TYPE_PROXIMITY); if (mProximitySensor != null) { mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), TYPICAL_PROXIMITY_THRESHOLD); diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index e1af04208480..7043af863301 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -1950,19 +1950,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } private void loadAmbientLightSensor() { - DisplayDeviceConfig.SensorData lightSensor = mDisplayDeviceConfig.getAmbientLightSensor(); final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK; - mLightSensor = SensorUtils.findSensor(mSensorManager, lightSensor.type, lightSensor.name, - fallbackType); + mLightSensor = SensorUtils.findSensor(mSensorManager, + mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType); } private void loadScreenOffBrightnessSensor() { - DisplayDeviceConfig.SensorData screenOffBrightnessSensor = - mDisplayDeviceConfig.getScreenOffBrightnessSensor(); mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, - screenOffBrightnessSensor.type, screenOffBrightnessSensor.name, - SensorUtils.NO_FALLBACK); + mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK); } private float clampScreenBrightness(float value) { diff --git a/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java b/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java index c0747867b620..882c02faedf9 100644 --- a/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java +++ b/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java @@ -358,10 +358,8 @@ public final class DisplayPowerProximityStateController { if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT || mDisplayId != Display.DEFAULT_DISPLAY) { return; } - final DisplayDeviceConfig.SensorData proxSensor = - mDisplayDeviceConfig.getProximitySensor(); - mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name, - Sensor.TYPE_PROXIMITY); + mProximitySensor = SensorUtils.findSensor(mSensorManager, + mDisplayDeviceConfig.getProximitySensor(), Sensor.TYPE_PROXIMITY); if (mProximitySensor != null) { mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), TYPICAL_PROXIMITY_THRESHOLD); diff --git a/services/core/java/com/android/server/display/utils/SensorUtils.java b/services/core/java/com/android/server/display/utils/SensorUtils.java index 48bc46c88df1..56321cd01e20 100644 --- a/services/core/java/com/android/server/display/utils/SensorUtils.java +++ b/services/core/java/com/android/server/display/utils/SensorUtils.java @@ -16,10 +16,13 @@ package com.android.server.display.utils; +import android.annotation.Nullable; import android.hardware.Sensor; import android.hardware.SensorManager; import android.text.TextUtils; +import com.android.server.display.DisplayDeviceConfig; + import java.util.List; /** @@ -29,15 +32,24 @@ public class SensorUtils { public static final int NO_FALLBACK = 0; /** - * Finds the specified sensor by type and name using SensorManager. + * Finds the specified sensor for SensorData from DisplayDeviceConfig. */ - public static Sensor findSensor(SensorManager sensorManager, String sensorType, - String sensorName, int fallbackType) { - if (sensorManager == null) { + @Nullable + public static Sensor findSensor(@Nullable SensorManager sensorManager, + @Nullable DisplayDeviceConfig.SensorData sensorData, int fallbackType) { + if (sensorData == null) { return null; + } else { + return findSensor(sensorManager, sensorData.type, sensorData.name, fallbackType); } - - if ("".equals(sensorName) && "".equals(sensorType)) { + } + /** + * Finds the specified sensor by type and name using SensorManager. + */ + @Nullable + public static Sensor findSensor(@Nullable SensorManager sensorManager, + @Nullable String sensorType, @Nullable String sensorName, int fallbackType) { + if (sensorManager == null) { return null; } final boolean isNameSpecified = !TextUtils.isEmpty(sensorName); diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java index 5b0b989d478a..534a708af3c7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java @@ -34,8 +34,8 @@ import android.hardware.display.DisplayManagerInternal; import android.os.test.TestLooper; import android.view.Display; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.server.testutils.OffsettableClock; @@ -92,7 +92,7 @@ public final class DisplayPowerProximityStateControllerTest { }; mDisplayPowerProximityStateController = new DisplayPowerProximityStateController( mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(), - mNudgeUpdatePowerState, 0, + mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY, mSensorManager, injector); mSensorEventListener = mDisplayPowerProximityStateController.getProximitySensorListener(); } @@ -128,7 +128,7 @@ public final class DisplayPowerProximityStateControllerTest { enableProximitySensor(); emitAndValidatePositiveProximityEvent(); mDisplayPowerProximityStateController.ignoreProximitySensorUntilChangedInternal(); - advanceTime(1); + advanceTime(); assertTrue(mDisplayPowerProximityStateController.shouldIgnoreProximityUntilChanged()); verify(mNudgeUpdatePowerState, times(2)).run(); @@ -170,7 +170,7 @@ public final class DisplayPowerProximityStateControllerTest { } @Test - public void isProximitySensorAvailableReturnsFalseWhenNotAvailable() { + public void isProximitySensorAvailableReturnsFalseWhenNotAvailableAndNoDefault() { when(mDisplayDeviceConfig.getProximitySensor()).thenReturn( new DisplayDeviceConfig.SensorData() { { @@ -180,12 +180,63 @@ public final class DisplayPowerProximityStateControllerTest { }); mDisplayPowerProximityStateController = new DisplayPowerProximityStateController( mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(), + mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY, + mSensorManager, null); + assertFalse(mDisplayPowerProximityStateController.isProximitySensorAvailable()); + } + + @Test + public void isProximitySensorAvailableReturnsTrueWhenNotAvailableAndHasDefault() + throws Exception { + when(mDisplayDeviceConfig.getProximitySensor()).thenReturn( + new DisplayDeviceConfig.SensorData() { + { + type = null; + name = null; + } + }); + when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn( + TestUtils.createSensor(Sensor.TYPE_PROXIMITY, "proximity")); + mDisplayPowerProximityStateController = new DisplayPowerProximityStateController( + mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(), + mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY, + mSensorManager, null); + assertTrue(mDisplayPowerProximityStateController.isProximitySensorAvailable()); + } + + @Test + public void isProximitySensorAvailableReturnsFalseWhenNotAvailableHasDefaultNonDefaultDisplay() + throws Exception { + when(mDisplayDeviceConfig.getProximitySensor()).thenReturn( + new DisplayDeviceConfig.SensorData() { + { + type = null; + name = null; + } + }); + when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn( + TestUtils.createSensor(Sensor.TYPE_PROXIMITY, "proximity")); + mDisplayPowerProximityStateController = new DisplayPowerProximityStateController( + mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(), mNudgeUpdatePowerState, 1, mSensorManager, null); assertFalse(mDisplayPowerProximityStateController.isProximitySensorAvailable()); } @Test + public void isProximitySensorAvailableReturnsTrueWhenNoSensorConfigured() throws Exception { + when(mDisplayDeviceConfig.getProximitySensor()).thenReturn(null); + when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn( + TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY)); + + mDisplayPowerProximityStateController = new DisplayPowerProximityStateController( + mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(), + mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY, + mSensorManager, null); + assertFalse(mDisplayPowerProximityStateController.isProximitySensorAvailable()); + } + + @Test public void notifyDisplayDeviceChangedReloadsTheProximitySensor() throws Exception { DisplayDeviceConfig updatedDisplayDeviceConfig = mock(DisplayDeviceConfig.class); when(updatedDisplayDeviceConfig.getProximitySensor()).thenReturn( @@ -326,8 +377,8 @@ public final class DisplayPowerProximityStateControllerTest { assertEquals(mDisplayPowerProximityStateController.getPendingProximityDebounceTime(), -1); } - private void advanceTime(long timeMs) { - mClock.fastForward(timeMs); + private void advanceTime() { + mClock.fastForward(1); mTestLooper.dispatchAll(); } diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java index 708421d2a431..8b04eca69132 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -33,8 +33,8 @@ import android.os.Temperature; import android.util.SparseArray; import android.view.SurfaceControl; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; import com.android.server.display.config.ThermalStatus; diff --git a/services/tests/servicestests/src/com/android/server/display/utils/SensorUtilsTest.java b/services/tests/servicestests/src/com/android/server/display/utils/SensorUtilsTest.java new file mode 100644 index 000000000000..4494b0c412dc --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/utils/SensorUtilsTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2023 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.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; + +import android.annotation.Nullable; +import android.hardware.Sensor; +import android.hardware.SensorManager; +import android.hardware.input.InputSensorInfo; + +import androidx.test.filters.SmallTest; + +import com.android.internal.annotations.Keep; +import com.android.server.display.DisplayDeviceConfig.SensorData; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Collections; +import java.util.List; + +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; + +@SmallTest +@RunWith(JUnitParamsRunner.class) +public class SensorUtilsTest { + + private static final String TEST_SENSOR_NAME = "test_sensor_name"; + private static final String TEST_SENSOR_TYPE = "test_sensor_type"; + private static final Sensor TEST_SENSOR = createSensor(); + @Mock + private SensorManager mSensorManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testNoSensorData() { + Sensor result = SensorUtils.findSensor(mSensorManager, null, Sensor.TYPE_LIGHT); + assertNull(result); + } + + @Test + public void testNoSensorManager() { + Sensor result = SensorUtils.findSensor(null, new SensorData(), Sensor.TYPE_LIGHT); + assertNull(result); + } + + @Keep + private static Object[][] findSensorData() { + // sensorName, sensorType, fallbackType, allSensors, defaultSensor, expectedResult + return new Object[][]{ + // no data, no default + {null, null, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, null}, + // matching name, matching type, no default + {TEST_SENSOR_NAME, TEST_SENSOR_TYPE, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, TEST_SENSOR}, + // matching name, no default + {TEST_SENSOR_NAME, null, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, TEST_SENSOR}, + // not matching name, no default + {"not_matching_name", null, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, null}, + // matching type, no default + {null, TEST_SENSOR_TYPE, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, TEST_SENSOR}, + // not matching type, no default + {null, "not_matching_type", Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, null}, + // not matching type, matching name, no default + {TEST_SENSOR_NAME, "not_matching_type", Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, null}, + // not matching name, matching type, no default + {"not_matching_name", TEST_SENSOR_TYPE, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, null}, + // not matching type, not matching name, no default + {"not_matching_name", "not_matching_type", Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), null, null}, + // not matching type, not matching name, with default + {"not_matching_name", "not_matching_type", Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), TEST_SENSOR, TEST_SENSOR}, + // no data, with default + {null, null, Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), TEST_SENSOR, TEST_SENSOR}, + // empty data, with default + {"", "", Sensor.TYPE_LIGHT, + Collections.singletonList(TEST_SENSOR), TEST_SENSOR, TEST_SENSOR}, + // empty data, with default, no fallback + {"", "", SensorUtils.NO_FALLBACK, + Collections.singletonList(TEST_SENSOR), TEST_SENSOR, null}, + }; + } + + @Test + @Parameters(method = "findSensorData") + public void testFindSensor(@Nullable String sensorName, @Nullable String sensorType, + int fallbackType, List<Sensor> allSensors, @Nullable Sensor defaultSensor, + @Nullable Sensor expectedResult) { + when(mSensorManager.getSensorList(Sensor.TYPE_ALL)).thenReturn(allSensors); + when(mSensorManager.getDefaultSensor(fallbackType)).thenReturn(defaultSensor); + + SensorData sensorData = new SensorData(); + sensorData.name = sensorName; + sensorData.type = sensorType; + + Sensor result = SensorUtils.findSensor(mSensorManager, sensorData, fallbackType); + + assertEquals(expectedResult, result); + } + + private static Sensor createSensor() { + return new Sensor(new InputSensorInfo( + TEST_SENSOR_NAME, "vendor", 0, 0, 0, 1f, 1f, 1, 1, 1, 1, + TEST_SENSOR_TYPE, "", 0, 0, 0)); + } +} |