Loading services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java +29 −22 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.display.whitebalance; import android.annotation.NonNull; import android.os.Handler; import android.util.Slog; import android.util.Spline; Loading Loading @@ -124,6 +125,7 @@ public class DisplayWhiteBalanceController implements // knowing about it. private Callbacks mDisplayPowerControllerCallbacks; private final Handler mHandler; /** * @param brightnessSensor * The sensor used to detect changes in the ambient brightness. Loading @@ -138,6 +140,8 @@ public class DisplayWhiteBalanceController implements * @param throttler * The throttler used to determine whether the new display color temperature should be * updated or not. * @param sensorSubscriptionHandler * Handler for subscribing/unsubsribing sensors * @param lowLightAmbientBrightnesses * The ambient brightness used to map the ambient brightnesses to the biases used to * interpolate to lowLightAmbientColorTemperature. Loading Loading @@ -182,29 +186,21 @@ public class DisplayWhiteBalanceController implements * - colorTemperatureFilter is null; * - throttler is null. */ public DisplayWhiteBalanceController( DisplayWhiteBalanceController( @NonNull AmbientSensor.AmbientBrightnessSensor brightnessSensor, @NonNull AmbientFilter brightnessFilter, @NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor, @NonNull AmbientFilter colorTemperatureFilter, @NonNull DisplayWhiteBalanceThrottler throttler, float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBrightnessesStrong, float[] lowLightAmbientBiases, float[] lowLightAmbientBiasesStrong, float lowLightAmbientColorTemperature, float lowLightAmbientColorTemperatureStrong, float[] highLightAmbientBrightnesses, float[] highLightAmbientBrightnessesStrong, float[] highLightAmbientBiases, float[] highLightAmbientBiasesStrong, float highLightAmbientColorTemperature, float highLightAmbientColorTemperatureStrong, float[] ambientColorTemperatures, float[] displayColorTemperatures, float[] strongAmbientColorTemperatures, float[] strongDisplayColorTemperatures, boolean lightModeAllowed) { @NonNull Handler sensorSubscriptionHandler, float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBrightnessesStrong, float[] lowLightAmbientBiases, float[] lowLightAmbientBiasesStrong, float lowLightAmbientColorTemperature, float lowLightAmbientColorTemperatureStrong, float[] highLightAmbientBrightnesses, float[] highLightAmbientBrightnessesStrong, float[] highLightAmbientBiases, float[] highLightAmbientBiasesStrong, float highLightAmbientColorTemperature, float highLightAmbientColorTemperatureStrong, float[] ambientColorTemperatures, float[] displayColorTemperatures, float[] strongAmbientColorTemperatures, float[] strongDisplayColorTemperatures, boolean lightModeAllowed) { validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter, throttler); mBrightnessSensor = brightnessSensor; Loading @@ -212,6 +208,7 @@ public class DisplayWhiteBalanceController implements mColorTemperatureSensor = colorTemperatureSensor; mColorTemperatureFilter = colorTemperatureFilter; mThrottler = throttler; mHandler = sensorSubscriptionHandler; mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature; mLowLightAmbientColorTemperatureStrong = lowLightAmbientColorTemperatureStrong; mHighLightAmbientColorTemperature = highLightAmbientColorTemperature; Loading Loading @@ -465,6 +462,9 @@ public class DisplayWhiteBalanceController implements @Override // AmbientSensor.AmbientBrightnessSensor.Callbacks public void onAmbientBrightnessChanged(float value) { if (!mEnabled) { return; } final long time = System.currentTimeMillis(); mBrightnessFilter.addValue(time, value); updateAmbientColorTemperature(); Loading @@ -472,6 +472,9 @@ public class DisplayWhiteBalanceController implements @Override // AmbientSensor.AmbientColorTemperatureSensor.Callbacks public void onAmbientColorTemperatureChanged(float value) { if (!mEnabled) { return; } final long time = System.currentTimeMillis(); mColorTemperatureFilter.addValue(time, value); updateAmbientColorTemperature(); Loading Loading @@ -651,8 +654,10 @@ public class DisplayWhiteBalanceController implements Slog.d(TAG, "enabling"); } mEnabled = true; mHandler.post(() -> { mBrightnessSensor.setEnabled(true); mColorTemperatureSensor.setEnabled(true); }); return true; } Loading @@ -664,9 +669,11 @@ public class DisplayWhiteBalanceController implements Slog.d(TAG, "disabling"); } mEnabled = false; mHandler.post(() -> { mBrightnessSensor.setEnabled(false); mBrightnessFilter.clear(); mColorTemperatureSensor.setEnabled(false); }); mBrightnessFilter.clear(); mColorTemperatureFilter.clear(); mThrottler.clear(); mAmbientColorTemperature = -1.0f; Loading services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java +3 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.Handler; import android.util.TypedValue; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.server.display.utils.AmbientFilter; import com.android.server.display.utils.AmbientFilterFactory; Loading Loading @@ -117,7 +118,8 @@ public class DisplayWhiteBalanceFactory { com.android.internal.R.bool.config_displayWhiteBalanceLightModeAllowed); final DisplayWhiteBalanceController controller = new DisplayWhiteBalanceController( brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter, throttler, displayWhiteBalanceLowLightAmbientBrightnesses, throttler, BackgroundThread.getHandler(), displayWhiteBalanceLowLightAmbientBrightnesses, displayWhiteBalanceLowLightAmbientBrightnessesStrong, displayWhiteBalanceLowLightAmbientBiases, displayWhiteBalanceLowLightAmbientBiasesStrong, lowLightAmbientColorTemperature, Loading services/tests/displayservicetests/src/com/android/server/display/whitebalance/DisplayWhiteBalanceControllerTest.kt 0 → 100644 +146 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.whitebalance import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.test.LocalServiceKeeperRule import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal import com.android.server.display.utils.AmbientFilter import com.android.server.testutils.TestHandler import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions @SmallTest @RunWith(AndroidJUnit4::class) class DisplayWhiteBalanceControllerTest { @get:Rule val localServiceKeeperRule = LocalServiceKeeperRule() private val mockBrightnessSensor = mock<AmbientSensor.AmbientBrightnessSensor>() private val mockBrightnessFilter = mock<AmbientFilter>() private val mockColorTemperatureSensor = mock<AmbientSensor.AmbientColorTemperatureSensor>() private val mockColorTemperatureFilter = mock<AmbientFilter>() private val mockThrottler = mock<DisplayWhiteBalanceThrottler>() private val testHandler = TestHandler(null) @Before fun setUp() { localServiceKeeperRule.overrideLocalService( ColorDisplayServiceInternal::class.java, mock<ColorDisplayServiceInternal>() ) } @Test fun testSensorsEnabledInSuppliedHandler() { val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) verifyNoInteractions(mockBrightnessSensor, mockColorTemperatureSensor) testHandler.flush() verify(mockBrightnessSensor).setEnabled(true) verify(mockColorTemperatureSensor).setEnabled(true) } @Test fun testSensorsDisabledInSuppliedHandler() { val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) testHandler.flush() clearInvocations(mockBrightnessSensor, mockColorTemperatureSensor) controller.setEnabled(false) verifyNoInteractions(mockBrightnessSensor, mockColorTemperatureSensor) testHandler.flush() verify(mockBrightnessSensor).setEnabled(false) verify(mockColorTemperatureSensor).setEnabled(false) } @Test fun testAmbientBrightnessChange() { val brightness = 0.4f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.onAmbientBrightnessChanged(brightness) verify(mockBrightnessFilter).addValue(any<Long>(), eq(brightness)) } @Test fun testAmbientBrightnessChange_disabled() { val brightness = 0.4f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.setEnabled(false) clearInvocations(mockBrightnessFilter) controller.onAmbientBrightnessChanged(brightness) verifyNoInteractions(mockBrightnessFilter) } @Test fun testColorTemperatureChanged() { val colorTemperature = 0.45f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.onAmbientColorTemperatureChanged(colorTemperature) verify(mockColorTemperatureFilter).addValue(any<Long>(), eq(colorTemperature)) } @Test fun testColorTemperatureChanged_disabled() { val colorTemperature = 0.45f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.setEnabled(false) clearInvocations(mockColorTemperatureFilter) controller.onAmbientColorTemperatureChanged(colorTemperature) verifyNoInteractions(mockColorTemperatureFilter) } fun createDisplayWhiteBalanceController(): DisplayWhiteBalanceController { return DisplayWhiteBalanceController( mockBrightnessSensor, mockBrightnessFilter, mockColorTemperatureSensor, mockColorTemperatureFilter, mockThrottler, testHandler, floatArrayOf(), floatArrayOf(), floatArrayOf(), floatArrayOf(), 0.1f, 0.1f, floatArrayOf(), floatArrayOf(), floatArrayOf(), floatArrayOf(), 0.1f, 0.1f, floatArrayOf(), floatArrayOf(), floatArrayOf(), floatArrayOf(), true ) } } No newline at end of file Loading
services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java +29 −22 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.display.whitebalance; import android.annotation.NonNull; import android.os.Handler; import android.util.Slog; import android.util.Spline; Loading Loading @@ -124,6 +125,7 @@ public class DisplayWhiteBalanceController implements // knowing about it. private Callbacks mDisplayPowerControllerCallbacks; private final Handler mHandler; /** * @param brightnessSensor * The sensor used to detect changes in the ambient brightness. Loading @@ -138,6 +140,8 @@ public class DisplayWhiteBalanceController implements * @param throttler * The throttler used to determine whether the new display color temperature should be * updated or not. * @param sensorSubscriptionHandler * Handler for subscribing/unsubsribing sensors * @param lowLightAmbientBrightnesses * The ambient brightness used to map the ambient brightnesses to the biases used to * interpolate to lowLightAmbientColorTemperature. Loading Loading @@ -182,29 +186,21 @@ public class DisplayWhiteBalanceController implements * - colorTemperatureFilter is null; * - throttler is null. */ public DisplayWhiteBalanceController( DisplayWhiteBalanceController( @NonNull AmbientSensor.AmbientBrightnessSensor brightnessSensor, @NonNull AmbientFilter brightnessFilter, @NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor, @NonNull AmbientFilter colorTemperatureFilter, @NonNull DisplayWhiteBalanceThrottler throttler, float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBrightnessesStrong, float[] lowLightAmbientBiases, float[] lowLightAmbientBiasesStrong, float lowLightAmbientColorTemperature, float lowLightAmbientColorTemperatureStrong, float[] highLightAmbientBrightnesses, float[] highLightAmbientBrightnessesStrong, float[] highLightAmbientBiases, float[] highLightAmbientBiasesStrong, float highLightAmbientColorTemperature, float highLightAmbientColorTemperatureStrong, float[] ambientColorTemperatures, float[] displayColorTemperatures, float[] strongAmbientColorTemperatures, float[] strongDisplayColorTemperatures, boolean lightModeAllowed) { @NonNull Handler sensorSubscriptionHandler, float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBrightnessesStrong, float[] lowLightAmbientBiases, float[] lowLightAmbientBiasesStrong, float lowLightAmbientColorTemperature, float lowLightAmbientColorTemperatureStrong, float[] highLightAmbientBrightnesses, float[] highLightAmbientBrightnessesStrong, float[] highLightAmbientBiases, float[] highLightAmbientBiasesStrong, float highLightAmbientColorTemperature, float highLightAmbientColorTemperatureStrong, float[] ambientColorTemperatures, float[] displayColorTemperatures, float[] strongAmbientColorTemperatures, float[] strongDisplayColorTemperatures, boolean lightModeAllowed) { validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter, throttler); mBrightnessSensor = brightnessSensor; Loading @@ -212,6 +208,7 @@ public class DisplayWhiteBalanceController implements mColorTemperatureSensor = colorTemperatureSensor; mColorTemperatureFilter = colorTemperatureFilter; mThrottler = throttler; mHandler = sensorSubscriptionHandler; mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature; mLowLightAmbientColorTemperatureStrong = lowLightAmbientColorTemperatureStrong; mHighLightAmbientColorTemperature = highLightAmbientColorTemperature; Loading Loading @@ -465,6 +462,9 @@ public class DisplayWhiteBalanceController implements @Override // AmbientSensor.AmbientBrightnessSensor.Callbacks public void onAmbientBrightnessChanged(float value) { if (!mEnabled) { return; } final long time = System.currentTimeMillis(); mBrightnessFilter.addValue(time, value); updateAmbientColorTemperature(); Loading @@ -472,6 +472,9 @@ public class DisplayWhiteBalanceController implements @Override // AmbientSensor.AmbientColorTemperatureSensor.Callbacks public void onAmbientColorTemperatureChanged(float value) { if (!mEnabled) { return; } final long time = System.currentTimeMillis(); mColorTemperatureFilter.addValue(time, value); updateAmbientColorTemperature(); Loading Loading @@ -651,8 +654,10 @@ public class DisplayWhiteBalanceController implements Slog.d(TAG, "enabling"); } mEnabled = true; mHandler.post(() -> { mBrightnessSensor.setEnabled(true); mColorTemperatureSensor.setEnabled(true); }); return true; } Loading @@ -664,9 +669,11 @@ public class DisplayWhiteBalanceController implements Slog.d(TAG, "disabling"); } mEnabled = false; mHandler.post(() -> { mBrightnessSensor.setEnabled(false); mBrightnessFilter.clear(); mColorTemperatureSensor.setEnabled(false); }); mBrightnessFilter.clear(); mColorTemperatureFilter.clear(); mThrottler.clear(); mAmbientColorTemperature = -1.0f; Loading
services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java +3 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.Handler; import android.util.TypedValue; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.server.display.utils.AmbientFilter; import com.android.server.display.utils.AmbientFilterFactory; Loading Loading @@ -117,7 +118,8 @@ public class DisplayWhiteBalanceFactory { com.android.internal.R.bool.config_displayWhiteBalanceLightModeAllowed); final DisplayWhiteBalanceController controller = new DisplayWhiteBalanceController( brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter, throttler, displayWhiteBalanceLowLightAmbientBrightnesses, throttler, BackgroundThread.getHandler(), displayWhiteBalanceLowLightAmbientBrightnesses, displayWhiteBalanceLowLightAmbientBrightnessesStrong, displayWhiteBalanceLowLightAmbientBiases, displayWhiteBalanceLowLightAmbientBiasesStrong, lowLightAmbientColorTemperature, Loading
services/tests/displayservicetests/src/com/android/server/display/whitebalance/DisplayWhiteBalanceControllerTest.kt 0 → 100644 +146 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.whitebalance import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.test.LocalServiceKeeperRule import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal import com.android.server.display.utils.AmbientFilter import com.android.server.testutils.TestHandler import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions @SmallTest @RunWith(AndroidJUnit4::class) class DisplayWhiteBalanceControllerTest { @get:Rule val localServiceKeeperRule = LocalServiceKeeperRule() private val mockBrightnessSensor = mock<AmbientSensor.AmbientBrightnessSensor>() private val mockBrightnessFilter = mock<AmbientFilter>() private val mockColorTemperatureSensor = mock<AmbientSensor.AmbientColorTemperatureSensor>() private val mockColorTemperatureFilter = mock<AmbientFilter>() private val mockThrottler = mock<DisplayWhiteBalanceThrottler>() private val testHandler = TestHandler(null) @Before fun setUp() { localServiceKeeperRule.overrideLocalService( ColorDisplayServiceInternal::class.java, mock<ColorDisplayServiceInternal>() ) } @Test fun testSensorsEnabledInSuppliedHandler() { val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) verifyNoInteractions(mockBrightnessSensor, mockColorTemperatureSensor) testHandler.flush() verify(mockBrightnessSensor).setEnabled(true) verify(mockColorTemperatureSensor).setEnabled(true) } @Test fun testSensorsDisabledInSuppliedHandler() { val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) testHandler.flush() clearInvocations(mockBrightnessSensor, mockColorTemperatureSensor) controller.setEnabled(false) verifyNoInteractions(mockBrightnessSensor, mockColorTemperatureSensor) testHandler.flush() verify(mockBrightnessSensor).setEnabled(false) verify(mockColorTemperatureSensor).setEnabled(false) } @Test fun testAmbientBrightnessChange() { val brightness = 0.4f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.onAmbientBrightnessChanged(brightness) verify(mockBrightnessFilter).addValue(any<Long>(), eq(brightness)) } @Test fun testAmbientBrightnessChange_disabled() { val brightness = 0.4f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.setEnabled(false) clearInvocations(mockBrightnessFilter) controller.onAmbientBrightnessChanged(brightness) verifyNoInteractions(mockBrightnessFilter) } @Test fun testColorTemperatureChanged() { val colorTemperature = 0.45f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.onAmbientColorTemperatureChanged(colorTemperature) verify(mockColorTemperatureFilter).addValue(any<Long>(), eq(colorTemperature)) } @Test fun testColorTemperatureChanged_disabled() { val colorTemperature = 0.45f val controller = createDisplayWhiteBalanceController() controller.setEnabled(true) controller.setEnabled(false) clearInvocations(mockColorTemperatureFilter) controller.onAmbientColorTemperatureChanged(colorTemperature) verifyNoInteractions(mockColorTemperatureFilter) } fun createDisplayWhiteBalanceController(): DisplayWhiteBalanceController { return DisplayWhiteBalanceController( mockBrightnessSensor, mockBrightnessFilter, mockColorTemperatureSensor, mockColorTemperatureFilter, mockThrottler, testHandler, floatArrayOf(), floatArrayOf(), floatArrayOf(), floatArrayOf(), 0.1f, 0.1f, floatArrayOf(), floatArrayOf(), floatArrayOf(), floatArrayOf(), 0.1f, 0.1f, floatArrayOf(), floatArrayOf(), floatArrayOf(), floatArrayOf(), true ) } } No newline at end of file