diff options
5 files changed, 270 insertions, 684 deletions
diff --git a/services/core/java/com/android/server/input/InputFeatureFlagProvider.java b/services/core/java/com/android/server/input/InputFeatureFlagProvider.java deleted file mode 100644 index a646d1e9bcb0..000000000000 --- a/services/core/java/com/android/server/input/InputFeatureFlagProvider.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 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.input; - -import android.sysprop.InputProperties; - -import java.util.Optional; - -/** - * A component of {@link InputManagerService} responsible for managing the input sysprop flags - * - * @hide - */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") -public final class InputFeatureFlagProvider { - - // To disable Keyboard backlight control via Framework, run: - // 'adb shell setprop persist.input.keyboard_backlight_control.enabled false' (requires restart) - private static final boolean KEYBOARD_BACKLIGHT_CONTROL_ENABLED = - InputProperties.enable_keyboard_backlight_control().orElse(true); - - // To disable Framework controlled keyboard backlight animation run: - // adb shell setprop persist.input.keyboard.backlight_animation.enabled false (requires restart) - private static final boolean KEYBOARD_BACKLIGHT_ANIMATION_ENABLED = - InputProperties.enable_keyboard_backlight_animation().orElse(false); - - // To disable Custom keyboard backlight levels support via IDC files run: - // adb shell setprop persist.input.keyboard.backlight_custom_levels.enabled false (requires - // restart) - private static final boolean KEYBOARD_BACKLIGHT_CUSTOM_LEVELS_ENABLED = - InputProperties.enable_keyboard_backlight_custom_levels().orElse(true); - - // To disable als based ambient keyboard backlight control run: - // adb shell setprop persist.input.keyboard.ambient_backlight_control.enabled false (requires - // restart) - private static final boolean AMBIENT_KEYBOARD_BACKLIGHT_CONTROL_ENABLED = - InputProperties.enable_ambient_keyboard_backlight_control().orElse(true); - - private static Optional<Boolean> sKeyboardBacklightControlOverride = Optional.empty(); - private static Optional<Boolean> sKeyboardBacklightAnimationOverride = Optional.empty(); - private static Optional<Boolean> sKeyboardBacklightCustomLevelsOverride = Optional.empty(); - private static Optional<Boolean> sAmbientKeyboardBacklightControlOverride = Optional.empty(); - - public static boolean isKeyboardBacklightControlEnabled() { - return sKeyboardBacklightControlOverride.orElse(KEYBOARD_BACKLIGHT_CONTROL_ENABLED); - } - - public static boolean isKeyboardBacklightAnimationEnabled() { - return sKeyboardBacklightAnimationOverride.orElse(KEYBOARD_BACKLIGHT_ANIMATION_ENABLED); - } - - public static boolean isKeyboardBacklightCustomLevelsEnabled() { - return sKeyboardBacklightCustomLevelsOverride.orElse( - KEYBOARD_BACKLIGHT_CUSTOM_LEVELS_ENABLED); - } - - public static boolean isAmbientKeyboardBacklightControlEnabled() { - return sAmbientKeyboardBacklightControlOverride.orElse( - AMBIENT_KEYBOARD_BACKLIGHT_CONTROL_ENABLED); - } - - public static void setKeyboardBacklightControlEnabled(boolean enabled) { - sKeyboardBacklightControlOverride = Optional.of(enabled); - } - - public static void setKeyboardBacklightAnimationEnabled(boolean enabled) { - sKeyboardBacklightAnimationOverride = Optional.of(enabled); - } - - public static void setKeyboardBacklightCustomLevelsEnabled(boolean enabled) { - sKeyboardBacklightCustomLevelsOverride = Optional.of(enabled); - } - - public static void setAmbientKeyboardBacklightControlEnabled(boolean enabled) { - sAmbientKeyboardBacklightControlOverride = Optional.of(enabled); - } - - /** - * Clears all input feature flag overrides. - */ - public static void clearOverrides() { - sKeyboardBacklightControlOverride = Optional.empty(); - sKeyboardBacklightAnimationOverride = Optional.empty(); - sKeyboardBacklightCustomLevelsOverride = Optional.empty(); - sAmbientKeyboardBacklightControlOverride = Optional.empty(); - } -} diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 1adf1c99024a..4454dd41a3c1 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -471,11 +471,9 @@ public class InputManagerService extends IInputManager.Stub } KeyboardBacklightControllerInterface getKeyboardBacklightController( - NativeInputManagerService nativeService, PersistentDataStore dataStore) { - return InputFeatureFlagProvider.isKeyboardBacklightControlEnabled() - ? new KeyboardBacklightController(mContext, nativeService, dataStore, - mLooper, mUEventManager) - : new KeyboardBacklightControllerInterface() {}; + NativeInputManagerService nativeService) { + return new KeyboardBacklightController(mContext, nativeService, mLooper, + mUEventManager); } } @@ -500,7 +498,7 @@ public class InputManagerService extends IInputManager.Stub injector.getLooper(), this) : null; mBatteryController = new BatteryController(mContext, mNative, injector.getLooper(), injector.getUEventManager()); - mKeyboardBacklightController = injector.getKeyboardBacklightController(mNative, mDataStore); + mKeyboardBacklightController = injector.getKeyboardBacklightController(mNative); mStickyModifierStateController = new StickyModifierStateController(); mKeyGestureController = new KeyGestureController(mContext, injector.getLooper()); mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(), diff --git a/services/core/java/com/android/server/input/KeyboardBacklightController.java b/services/core/java/com/android/server/input/KeyboardBacklightController.java index 0defd27eaae2..16368c7678d1 100644 --- a/services/core/java/com/android/server/input/KeyboardBacklightController.java +++ b/services/core/java/com/android/server/input/KeyboardBacklightController.java @@ -33,6 +33,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.os.UEventObserver; +import android.sysprop.InputProperties; import android.text.TextUtils; import android.util.IndentingPrintWriter; import android.util.Log; @@ -47,7 +48,6 @@ import java.io.PrintWriter; import java.time.Duration; import java.util.Arrays; import java.util.Objects; -import java.util.OptionalInt; import java.util.TreeSet; /** @@ -63,6 +63,10 @@ final class KeyboardBacklightController implements // 'adb shell setprop log.tag.KbdBacklightController DEBUG' (requires restart) private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + // To disable Framework controlled keyboard backlight animation run: + // adb shell setprop persist.input.keyboard.backlight_animation.enabled false (requires restart) + private final boolean mKeyboardBacklightAnimationEnabled; + private enum Direction { DIRECTION_UP, DIRECTION_DOWN } @@ -87,9 +91,6 @@ final class KeyboardBacklightController implements private final Context mContext; private final NativeInputManagerService mNative; - // The PersistentDataStore should be locked before use. - @GuardedBy("mDataStore") - private final PersistentDataStore mDataStore; private final Handler mHandler; private final AnimatorFactory mAnimatorFactory; private final UEventManager mUEventManager; @@ -123,17 +124,15 @@ final class KeyboardBacklightController implements } KeyboardBacklightController(Context context, NativeInputManagerService nativeService, - PersistentDataStore dataStore, Looper looper, UEventManager uEventManager) { - this(context, nativeService, dataStore, looper, ValueAnimator::ofInt, uEventManager); + Looper looper, UEventManager uEventManager) { + this(context, nativeService, looper, ValueAnimator::ofInt, uEventManager); } @VisibleForTesting KeyboardBacklightController(Context context, NativeInputManagerService nativeService, - PersistentDataStore dataStore, Looper looper, AnimatorFactory animatorFactory, - UEventManager uEventManager) { + Looper looper, AnimatorFactory animatorFactory, UEventManager uEventManager) { mContext = context; mNative = nativeService; - mDataStore = dataStore; mHandler = new Handler(looper, this::handleMessage); mAnimatorFactory = animatorFactory; mAmbientController = new AmbientKeyboardBacklightController(context, looper); @@ -141,6 +140,8 @@ final class KeyboardBacklightController implements Resources res = mContext.getResources(); mUserInactivityThresholdMs = res.getInteger( com.android.internal.R.integer.config_keyboardBacklightTimeoutMs); + mKeyboardBacklightAnimationEnabled = + InputProperties.enable_keyboard_backlight_animation().orElse(false); } @Override @@ -164,10 +165,8 @@ final class KeyboardBacklightController implements } }, UEVENT_KEYBOARD_BACKLIGHT_TAG); - if (InputFeatureFlagProvider.isAmbientKeyboardBacklightControlEnabled()) { - // Start ambient backlight controller - mAmbientController.systemRunning(); - } + // Start ambient backlight controller + mAmbientController.systemRunning(); } @Override @@ -229,9 +228,6 @@ final class KeyboardBacklightController implements // level through keyboard up/down button updateAmbientLightListener(); - maybeBackupBacklightBrightness(inputDevice, state.mLight, - state.mBrightnessValueForLevel[newBrightnessLevel]); - if (DEBUG) { Slog.d(TAG, "Changing state from " + state.mBrightnessLevel + " to " + newBrightnessLevel); @@ -248,47 +244,6 @@ final class KeyboardBacklightController implements } } - private void maybeBackupBacklightBrightness(InputDevice inputDevice, Light keyboardBacklight, - int brightnessValue) { - // Don't back up or restore when ALS based keyboard backlight is enabled - if (InputFeatureFlagProvider.isAmbientKeyboardBacklightControlEnabled()) { - return; - } - synchronized (mDataStore) { - try { - mDataStore.setKeyboardBacklightBrightness(inputDevice.getDescriptor(), - keyboardBacklight.getId(), - brightnessValue); - } finally { - mDataStore.saveIfNeeded(); - } - } - } - - private void maybeRestoreBacklightBrightness(InputDevice inputDevice, Light keyboardBacklight) { - // Don't back up or restore when ALS based keyboard backlight is enabled - if (InputFeatureFlagProvider.isAmbientKeyboardBacklightControlEnabled()) { - return; - } - KeyboardBacklightState state = mKeyboardBacklights.get(inputDevice.getId()); - OptionalInt brightness; - synchronized (mDataStore) { - brightness = mDataStore.getKeyboardBacklightBrightness( - inputDevice.getDescriptor(), keyboardBacklight.getId()); - } - if (state != null && brightness.isPresent()) { - int brightnessValue = Math.max(0, Math.min(MAX_BRIGHTNESS, brightness.getAsInt())); - int newLevel = Arrays.binarySearch(state.mBrightnessValueForLevel, brightnessValue); - if (newLevel < 0) { - newLevel = Math.min(state.getNumBrightnessChangeSteps(), -(newLevel + 1)); - } - state.setBrightnessLevel(newLevel); - if (DEBUG) { - Slog.d(TAG, "Restoring brightness level " + brightness.getAsInt()); - } - } - } - private void handleUserActivity() { // Ignore user activity if device is not interactive. When device becomes interactive, we // will send another user activity to turn backlight on. @@ -393,7 +348,6 @@ final class KeyboardBacklightController implements } // The keyboard backlight was added or changed. mKeyboardBacklights.put(deviceId, new KeyboardBacklightState(deviceId, keyboardBacklight)); - maybeRestoreBacklightBrightness(inputDevice, keyboardBacklight); } private InputDevice getInputDevice(int deviceId) { @@ -472,9 +426,6 @@ final class KeyboardBacklightController implements } private void updateAmbientLightListener() { - if (!InputFeatureFlagProvider.isAmbientKeyboardBacklightControlEnabled()) { - return; - } boolean needToListenAmbientLightSensor = false; for (int i = 0; i < mKeyboardBacklights.size(); i++) { needToListenAmbientLightSensor |= mKeyboardBacklights.valueAt(i).mUseAmbientController; @@ -555,8 +506,7 @@ final class KeyboardBacklightController implements private int mBrightnessLevel; private ValueAnimator mAnimator; private final int[] mBrightnessValueForLevel; - private boolean mUseAmbientController = - InputFeatureFlagProvider.isAmbientKeyboardBacklightControlEnabled(); + private boolean mUseAmbientController = true; KeyboardBacklightState(int deviceId, Light light) { mDeviceId = deviceId; @@ -565,9 +515,6 @@ final class KeyboardBacklightController implements } private int[] setupBrightnessLevels() { - if (!InputFeatureFlagProvider.isKeyboardBacklightCustomLevelsEnabled()) { - return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL; - } int[] customLevels = mLight.getPreferredBrightnessLevels(); if (customLevels == null || customLevels.length == 0) { return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL; @@ -627,7 +574,7 @@ final class KeyboardBacklightController implements if (fromValue == toValue) { return; } - if (InputFeatureFlagProvider.isKeyboardBacklightAnimationEnabled()) { + if (mKeyboardBacklightAnimationEnabled) { startAnimation(fromValue, toValue); } else { mNative.setLightColor(mDeviceId, mLight.getId(), Color.argb(toValue, 0, 0, 0)); diff --git a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt index 8bc741c86543..43844f6514e8 100644 --- a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt +++ b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt @@ -156,8 +156,7 @@ class InputManagerServiceTests { } override fun getKeyboardBacklightController( - nativeService: NativeInputManagerService?, - dataStore: PersistentDataStore? + nativeService: NativeInputManagerService? ): InputManagerService.KeyboardBacklightControllerInterface { return kbdController } diff --git a/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt b/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt index 938e2f8a3611..644d5a0679de 100644 --- a/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt +++ b/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt @@ -25,6 +25,7 @@ import android.hardware.input.IKeyboardBacklightListener import android.hardware.input.IKeyboardBacklightState import android.hardware.input.InputManager import android.hardware.lights.Light +import android.os.SystemProperties import android.os.UEventObserver import android.os.test.TestLooper import android.platform.test.annotations.Presubmit @@ -32,16 +33,13 @@ import android.view.InputDevice import android.util.TypedValue import androidx.test.annotation.UiThreadTest import androidx.test.core.app.ApplicationProvider +import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.internal.R +import com.android.modules.utils.testing.ExtendedMockitoRule import com.android.server.input.KeyboardBacklightController.DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL import com.android.server.input.KeyboardBacklightController.MAX_BRIGHTNESS_CHANGE_STEPS import com.android.test.input.MockInputManagerRule -import java.io.FileNotFoundException -import java.io.FileOutputStream -import java.io.IOException -import java.io.InputStream import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull @@ -56,7 +54,6 @@ import org.mockito.Mockito.anyInt import org.mockito.Mockito.eq import org.mockito.Mockito.spy import org.mockito.Mockito.`when` -import org.mockito.junit.MockitoJUnit private fun createKeyboard(deviceId: Int): InputDevice = InputDevice.Builder() @@ -101,7 +98,8 @@ class KeyboardBacklightControllerTests { } @get:Rule - val rule = MockitoJUnit.rule()!! + val extendedMockitoRule = + ExtendedMockitoRule.Builder(this).mockStatic(SystemProperties::class.java).build()!! @get:Rule val inputManagerRule = MockInputManagerRule() @@ -113,7 +111,6 @@ class KeyboardBacklightControllerTests { private lateinit var resources: Resources private lateinit var keyboardBacklightController: KeyboardBacklightController private lateinit var context: Context - private lateinit var dataStore: PersistentDataStore private lateinit var testLooper: TestLooper private var lightColorMap: HashMap<Int, Int> = HashMap() private var lastBacklightState: KeyboardBacklightState? = null @@ -124,21 +121,8 @@ class KeyboardBacklightControllerTests { fun setup() { context = spy(ContextWrapper(ApplicationProvider.getApplicationContext())) `when`(context.resources).thenReturn(resources) - dataStore = PersistentDataStore(object : PersistentDataStore.Injector() { - override fun openRead(): InputStream? { - throw FileNotFoundException() - } - - override fun startWrite(): FileOutputStream? { - throw IOException() - } - - override fun finishWrite(fos: FileOutputStream?, success: Boolean) {} - }) testLooper = TestLooper() setupConfig() - keyboardBacklightController = KeyboardBacklightController(context, native, dataStore, - testLooper.looper, FakeAnimatorFactory(), uEventManager) val inputManager = InputManager(context) `when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager) `when`(inputManagerRule.mock.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID)) @@ -155,6 +139,7 @@ class KeyboardBacklightControllerTests { sysfsNodeChanges++ } } + private fun setupConfig() { val brightnessValues = intArrayOf(100, 200, 0) val decreaseThresholds = intArrayOf(-1, 900, 1900) @@ -180,271 +165,166 @@ class KeyboardBacklightControllerTests { Unit } } - @Test - fun testKeyboardBacklightIncrementDecrement() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, - DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL) - } - } - @Test - fun testKeyboardWithoutBacklight() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithoutBacklight = createKeyboard(DEVICE_ID) - val keyboardInputLight = createLight(LIGHT_ID, Light.LIGHT_TYPE_INPUT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithoutBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardInputLight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - incrementKeyboardBacklight(DEVICE_ID) - assertTrue("Non Keyboard backlights should not change", lightColorMap.isEmpty()) - } + private fun setupController() { + keyboardBacklightController = KeyboardBacklightController(context, native, + testLooper.looper, FakeAnimatorFactory(), uEventManager) } @Test - fun testKeyboardWithMultipleLight() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - val keyboardInputLight = createLight(SECOND_LIGHT_ID, Light.LIGHT_TYPE_INPUT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn( - listOf( - keyboardBacklight, - keyboardInputLight - ) - ) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - incrementKeyboardBacklight(DEVICE_ID) - assertEquals("Only keyboard backlights should change", 1, lightColorMap.size) - assertNotNull("Keyboard backlight should change", lightColorMap[LIGHT_ID]) - assertNull("Input lights should not change", lightColorMap[SECOND_LIGHT_ID]) - } + fun testKeyboardBacklightIncrementDecrement() { + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, + DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL) } @Test - fun testRestoreBacklightOnInputDeviceAdded() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - - for (level in 1 until DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size) { - dataStore.setKeyboardBacklightBrightness( - keyboardWithBacklight.descriptor, - LIGHT_ID, - DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[level] - 1 - ) - - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - keyboardBacklightController.notifyUserActivity() - testLooper.dispatchNext() - assertEquals( - "Keyboard backlight level should be restored to the level saved in the " + - "data store", - Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0), - lightColorMap[LIGHT_ID] - ) - keyboardBacklightController.onInputDeviceRemoved(DEVICE_ID) - } - } + fun testKeyboardWithoutBacklight() { + setupController() + val keyboardWithoutBacklight = createKeyboard(DEVICE_ID) + val keyboardInputLight = createLight(LIGHT_ID, Light.LIGHT_TYPE_INPUT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithoutBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardInputLight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + incrementKeyboardBacklight(DEVICE_ID) + assertTrue("Non Keyboard backlights should not change", lightColorMap.isEmpty()) } @Test - fun testRestoreBacklightOnInputDeviceChanged() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - dataStore.setKeyboardBacklightBrightness( - keyboardWithBacklight.descriptor, - LIGHT_ID, - MAX_BRIGHTNESS - ) - - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - keyboardBacklightController.notifyUserActivity() - testLooper.dispatchNext() - assertTrue( - "Keyboard backlight should not be changed until its added", - lightColorMap.isEmpty() + fun testKeyboardWithMultipleLight() { + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + val keyboardInputLight = createLight(SECOND_LIGHT_ID, Light.LIGHT_TYPE_INPUT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn( + listOf( + keyboardBacklight, + keyboardInputLight ) + ) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceChanged(DEVICE_ID) - keyboardBacklightController.notifyUserActivity() - testLooper.dispatchNext() - assertEquals( - "Keyboard backlight level should be restored to the level saved in the data store", - Color.argb(MAX_BRIGHTNESS, 0, 0, 0), - lightColorMap[LIGHT_ID] - ) - } + incrementKeyboardBacklight(DEVICE_ID) + assertEquals("Only keyboard backlights should change", 1, lightColorMap.size) + assertNotNull("Keyboard backlight should change", lightColorMap[LIGHT_ID]) + assertNull("Input lights should not change", lightColorMap[SECOND_LIGHT_ID]) } @Test fun testKeyboardBacklight_registerUnregisterListener() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - val maxLevel = DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size - 1 - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - // Register backlight listener - val listener = KeyboardBacklightListener() - keyboardBacklightController.registerKeyboardBacklightListener(listener, 0) - - lastBacklightState = null - keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID) - testLooper.dispatchNext() + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + val maxLevel = DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size - 1 + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + // Register backlight listener + val listener = KeyboardBacklightListener() + keyboardBacklightController.registerKeyboardBacklightListener(listener, 0) + + lastBacklightState = null + keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID) + testLooper.dispatchNext() - assertEquals( - "Backlight state device Id should be $DEVICE_ID", - DEVICE_ID, - lastBacklightState!!.deviceId - ) - assertEquals( - "Backlight state brightnessLevel should be 1", - 1, - lastBacklightState!!.brightnessLevel - ) - assertEquals( - "Backlight state maxBrightnessLevel should be $maxLevel", - maxLevel, - lastBacklightState!!.maxBrightnessLevel - ) - assertEquals( - "Backlight state isTriggeredByKeyPress should be true", - true, - lastBacklightState!!.isTriggeredByKeyPress - ) + assertEquals( + "Backlight state device Id should be $DEVICE_ID", + DEVICE_ID, + lastBacklightState!!.deviceId + ) + assertEquals( + "Backlight state brightnessLevel should be 1", + 1, + lastBacklightState!!.brightnessLevel + ) + assertEquals( + "Backlight state maxBrightnessLevel should be $maxLevel", + maxLevel, + lastBacklightState!!.maxBrightnessLevel + ) + assertEquals( + "Backlight state isTriggeredByKeyPress should be true", + true, + lastBacklightState!!.isTriggeredByKeyPress + ) - // Unregister listener - keyboardBacklightController.unregisterKeyboardBacklightListener(listener, 0) + // Unregister listener + keyboardBacklightController.unregisterKeyboardBacklightListener(listener, 0) - lastBacklightState = null - incrementKeyboardBacklight(DEVICE_ID) + lastBacklightState = null + incrementKeyboardBacklight(DEVICE_ID) - assertNull("Listener should not receive any updates", lastBacklightState) - } + assertNull("Listener should not receive any updates", lastBacklightState) } @Test fun testKeyboardBacklight_userActivity() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - dataStore.setKeyboardBacklightBrightness( - keyboardWithBacklight.descriptor, - LIGHT_ID, - MAX_BRIGHTNESS - ) - - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - keyboardBacklightController.notifyUserActivity() - testLooper.dispatchNext() - assertEquals( - "Keyboard backlight level should be restored to the level saved in the data store", - Color.argb(MAX_BRIGHTNESS, 0, 0, 0), - lightColorMap[LIGHT_ID] - ) + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + incrementKeyboardBacklight(DEVICE_ID) + assertNotEquals( + "Keyboard backlight level should be incremented to a non-zero value", + 0, + lightColorMap[LIGHT_ID] + ) - testLooper.moveTimeForward((USER_INACTIVITY_THRESHOLD_MILLIS + 1000).toLong()) - testLooper.dispatchNext() - assertEquals( - "Keyboard backlight level should be turned off after inactivity", - 0, - lightColorMap[LIGHT_ID] - ) - } + testLooper.moveTimeForward((USER_INACTIVITY_THRESHOLD_MILLIS + 1000).toLong()) + testLooper.dispatchNext() + assertEquals( + "Keyboard backlight level should be turned off after inactivity", + 0, + lightColorMap[LIGHT_ID] + ) } @Test fun testKeyboardBacklight_displayOnOff() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - dataStore.setKeyboardBacklightBrightness( - keyboardWithBacklight.descriptor, - LIGHT_ID, - MAX_BRIGHTNESS - ) + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + incrementKeyboardBacklight(DEVICE_ID) + + val currentValue = lightColorMap[LIGHT_ID] + assertNotEquals( + "Keyboard backlight level should be incremented to a non-zero value", + 0, + lightColorMap[LIGHT_ID] + ) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - keyboardBacklightController.handleInteractiveStateChange(true /* isDisplayOn */) - assertEquals( - "Keyboard backlight level should be restored to the level saved in the data " + - "store when display turned on", - Color.argb(MAX_BRIGHTNESS, 0, 0, 0), - lightColorMap[LIGHT_ID] - ) + keyboardBacklightController.handleInteractiveStateChange(false /* isDisplayOn */) + assertEquals( + "Keyboard backlight level should be turned off after display is turned off", + 0, + lightColorMap[LIGHT_ID] + ) - keyboardBacklightController.handleInteractiveStateChange(false /* isDisplayOn */) - assertEquals( - "Keyboard backlight level should be turned off after display is turned off", - 0, - lightColorMap[LIGHT_ID] - ) - } + keyboardBacklightController.handleInteractiveStateChange(true /* isDisplayOn */) + assertEquals( + "Keyboard backlight level should be turned on after display is turned on", + currentValue, + lightColorMap[LIGHT_ID] + ) } @Test fun testKeyboardBacklightSysfsNodeAdded_AfterInputDeviceAdded() { + setupController() var counter = sysfsNodeChanges keyboardBacklightController.onKeyboardBacklightUEvent(UEventObserver.UEvent( "ACTION=add\u0000SUBSYSTEM=leds\u0000DEVPATH=/xyz/leds/abc::no_backlight\u0000" @@ -504,260 +384,160 @@ class KeyboardBacklightControllerTests { @Test @UiThreadTest fun testKeyboardBacklightAnimation_onChangeLevels() { - KeyboardBacklightFlags( - animationEnabled = true, - customLevelsEnabled = false, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - incrementKeyboardBacklight(DEVICE_ID) - assertEquals( - "Should start animation from level 0", - DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[0], - lastAnimationValues[0] - ) - assertEquals( - "Should start animation to level 1", - DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1], - lastAnimationValues[1] - ) + ExtendedMockito.doReturn("true").`when` { + SystemProperties.get(eq("persist.input.keyboard.backlight_animation.enabled")) } + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + incrementKeyboardBacklight(DEVICE_ID) + assertEquals( + "Should start animation from level 0", + DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[0], + lastAnimationValues[0] + ) + assertEquals( + "Should start animation to level 1", + DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1], + lastAnimationValues[1] + ) } @Test fun testKeyboardBacklightPreferredLevels() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = true, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val suggestedLevels = intArrayOf(0, 22, 63, 135, 196, 255) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, - suggestedLevels) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, - suggestedLevels) - } + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val suggestedLevels = intArrayOf(0, 22, 63, 135, 196, 255) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, + suggestedLevels) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, suggestedLevels) } @Test fun testKeyboardBacklightPreferredLevels_moreThanMax_shouldUseDefault() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = true, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val suggestedLevels = IntArray(MAX_BRIGHTNESS_CHANGE_STEPS + 1) { 10 * (it + 1) } - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, - suggestedLevels) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, - DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL) - } + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val suggestedLevels = IntArray(MAX_BRIGHTNESS_CHANGE_STEPS + 1) { 10 * (it + 1) } + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, + suggestedLevels) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, + DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL) } @Test fun testKeyboardBacklightPreferredLevels_mustHaveZeroAndMaxBrightnessAsBounds() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = true, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val suggestedLevels = intArrayOf(22, 63, 135, 196) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, - suggestedLevels) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - // Framework will add the lowest and maximum levels if not provided via config - assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, - intArrayOf(0, 22, 63, 135, 196, 255)) - } + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val suggestedLevels = intArrayOf(22, 63, 135, 196) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, + suggestedLevels) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + // Framework will add the lowest and maximum levels if not provided via config + assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, + intArrayOf(0, 22, 63, 135, 196, 255)) } @Test fun testKeyboardBacklightPreferredLevels_dropsOutOfBoundsLevels() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = true, - ambientControlEnabled = false - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val suggestedLevels = intArrayOf(22, 63, 135, 400, 196, 1000) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, - suggestedLevels) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)) - .thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - - // Framework will drop out of bound levels in the config - assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, - intArrayOf(0, 22, 63, 135, 196, 255)) - } - } - - @Test - fun testAmbientBacklightControl_doesntRestoreBacklightLevel() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = true - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - - dataStore.setKeyboardBacklightBrightness( - keyboardWithBacklight.descriptor, - LIGHT_ID, - DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1] - ) - - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - keyboardBacklightController.notifyUserActivity() - testLooper.dispatchNext() - assertNull( - "Keyboard backlight level should not be restored to the saved level", - lightColorMap[LIGHT_ID] - ) - } - } - - @Test - fun testAmbientBacklightControl_doesntBackupBacklightLevel() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = true - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - incrementKeyboardBacklight(DEVICE_ID) - assertFalse( - "Light value should not be backed up if ambient control is enabled", - dataStore.getKeyboardBacklightBrightness( - keyboardWithBacklight.descriptor, LIGHT_ID - ).isPresent - ) - } + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val suggestedLevels = intArrayOf(22, 63, 135, 400, 196, 1000) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT, + suggestedLevels) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + + // Framework will drop out of bound levels in the config + assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight, + intArrayOf(0, 22, 63, 135, 196, 255)) } @Test fun testAmbientBacklightControl_incrementLevel_afterAmbientChange() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = true - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - sendAmbientBacklightValue(1) - assertEquals( - "Light value should be changed to ambient provided value", - Color.argb(1, 0, 0, 0), - lightColorMap[LIGHT_ID] - ) + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + sendAmbientBacklightValue(1) + assertEquals( + "Light value should be changed to ambient provided value", + Color.argb(1, 0, 0, 0), + lightColorMap[LIGHT_ID] + ) - incrementKeyboardBacklight(DEVICE_ID) + incrementKeyboardBacklight(DEVICE_ID) - assertEquals( - "Light value for level after increment post Ambient change is mismatched", - Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1], 0, 0, 0), - lightColorMap[LIGHT_ID] - ) - } + assertEquals( + "Light value for level after increment post Ambient change is mismatched", + Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1], 0, 0, 0), + lightColorMap[LIGHT_ID] + ) } @Test fun testAmbientBacklightControl_decrementLevel_afterAmbientChange() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = true - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - sendAmbientBacklightValue(254) - assertEquals( - "Light value should be changed to ambient provided value", - Color.argb(254, 0, 0, 0), - lightColorMap[LIGHT_ID] - ) + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + sendAmbientBacklightValue(254) + assertEquals( + "Light value should be changed to ambient provided value", + Color.argb(254, 0, 0, 0), + lightColorMap[LIGHT_ID] + ) - decrementKeyboardBacklight(DEVICE_ID) + decrementKeyboardBacklight(DEVICE_ID) - val numLevels = DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size - assertEquals( - "Light value for level after decrement post Ambient change is mismatched", - Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[numLevels - 2], 0, 0, 0), - lightColorMap[LIGHT_ID] - ) - } + val numLevels = DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size + assertEquals( + "Light value for level after decrement post Ambient change is mismatched", + Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[numLevels - 2], 0, 0, 0), + lightColorMap[LIGHT_ID] + ) } @Test fun testAmbientBacklightControl_ambientChanges_afterManualChange() { - KeyboardBacklightFlags( - animationEnabled = false, - customLevelsEnabled = false, - ambientControlEnabled = true - ).use { - val keyboardWithBacklight = createKeyboard(DEVICE_ID) - val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) - `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)) - .thenReturn(keyboardWithBacklight) - `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) - keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) - incrementKeyboardBacklight(DEVICE_ID) - assertEquals( - "Light value should be changed to the first level", - Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1], 0, 0, 0), - lightColorMap[LIGHT_ID] - ) + setupController() + val keyboardWithBacklight = createKeyboard(DEVICE_ID) + val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT) + `when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight) + `when`(inputManagerRule.mock.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight)) + keyboardBacklightController.onInputDeviceAdded(DEVICE_ID) + incrementKeyboardBacklight(DEVICE_ID) + assertEquals( + "Light value should be changed to the first level", + Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1], 0, 0, 0), + lightColorMap[LIGHT_ID] + ) - sendAmbientBacklightValue(100) - assertNotEquals( - "Light value should not change based on ambient changes after manual changes", - Color.argb(100, 0, 0, 0), - lightColorMap[LIGHT_ID] - ) - } + sendAmbientBacklightValue(100) + assertNotEquals( + "Light value should not change based on ambient changes after manual changes", + Color.argb(100, 0, 0, 0), + lightColorMap[LIGHT_ID] + ) } private fun assertIncrementDecrementForLevels( @@ -774,11 +554,6 @@ class KeyboardBacklightControllerTests { Color.argb(expectedLevels[level], 0, 0, 0), lightColorMap[lightId] ) - assertEquals( - "Light value for level $level must be correctly stored in the datastore", - expectedLevels[level], - dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt - ) } // Increment above max level @@ -788,11 +563,6 @@ class KeyboardBacklightControllerTests { Color.argb(MAX_BRIGHTNESS, 0, 0, 0), lightColorMap[lightId] ) - assertEquals( - "Light value for max level must be correctly stored in the datastore", - MAX_BRIGHTNESS, - dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt - ) for (level in expectedLevels.size - 2 downTo 0) { decrementKeyboardBacklight(deviceId) @@ -801,11 +571,6 @@ class KeyboardBacklightControllerTests { Color.argb(expectedLevels[level], 0, 0, 0), lightColorMap[lightId] ) - assertEquals( - "Light value for level $level must be correctly stored in the datastore", - expectedLevels[level], - dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt - ) } // Decrement below min level @@ -815,11 +580,6 @@ class KeyboardBacklightControllerTests { Color.argb(0, 0, 0, 0), lightColorMap[lightId] ) - assertEquals( - "Light value for min level must be correctly stored in the datastore", - 0, - dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt - ) } inner class KeyboardBacklightListener : IKeyboardBacklightListener.Stub() { @@ -862,23 +622,6 @@ class KeyboardBacklightControllerTests { val isTriggeredByKeyPress: Boolean ) - private inner class KeyboardBacklightFlags constructor( - animationEnabled: Boolean, - customLevelsEnabled: Boolean, - ambientControlEnabled: Boolean - ) : AutoCloseable { - init { - InputFeatureFlagProvider.setKeyboardBacklightAnimationEnabled(animationEnabled) - InputFeatureFlagProvider.setKeyboardBacklightCustomLevelsEnabled(customLevelsEnabled) - InputFeatureFlagProvider - .setAmbientKeyboardBacklightControlEnabled(ambientControlEnabled) - } - - override fun close() { - InputFeatureFlagProvider.clearOverrides() - } - } - private inner class FakeAnimatorFactory : KeyboardBacklightController.AnimatorFactory { override fun makeIntAnimator(from: Int, to: Int): ValueAnimator { lastAnimationValues[0] = from |