Merge "Add inactivity timer to turn off keyboard backlight"
diff --git a/services/core/java/com/android/server/input/InputManagerInternal.java b/services/core/java/com/android/server/input/InputManagerInternal.java
index ca42614..4d03e44 100644
--- a/services/core/java/com/android/server/input/InputManagerInternal.java
+++ b/services/core/java/com/android/server/input/InputManagerInternal.java
@@ -213,4 +213,10 @@
* @param enabled When true, stylus buttons will not be reported through motion events.
*/
public abstract void setStylusButtonMotionEventsEnabled(boolean enabled);
+
+ /**
+ * Notify whether any user activity occurred. This includes any input activity on any
+ * display, external peripherals, fingerprint sensor, etc.
+ */
+ public abstract void notifyUserActivity();
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e86632c..be4373a 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -3271,6 +3271,7 @@
public void setInteractive(boolean interactive) {
mNative.setInteractive(interactive);
mBatteryController.onInteractiveChanged(interactive);
+ mKeyboardBacklightController.onInteractiveChanged(interactive);
}
@Override
@@ -3358,6 +3359,11 @@
}
@Override
+ public void notifyUserActivity() {
+ mKeyboardBacklightController.notifyUserActivity();
+ }
+
+ @Override
public void incrementKeyboardBacklight(int deviceId) {
mKeyboardBacklightController.incrementKeyboardBacklight(deviceId);
}
@@ -3489,6 +3495,8 @@
default void decrementKeyboardBacklight(int deviceId) {}
default void registerKeyboardBacklightListener(IKeyboardBacklightListener l, int pid) {}
default void unregisterKeyboardBacklightListener(IKeyboardBacklightListener l, int pid) {}
+ default void onInteractiveChanged(boolean isInteractive) {}
+ default void notifyUserActivity() {}
default void systemRunning() {}
default void dump(PrintWriter pw) {}
}
diff --git a/services/core/java/com/android/server/input/KeyboardBacklightController.java b/services/core/java/com/android/server/input/KeyboardBacklightController.java
index 653a821..e1e3dd9 100644
--- a/services/core/java/com/android/server/input/KeyboardBacklightController.java
+++ b/services/core/java/com/android/server/input/KeyboardBacklightController.java
@@ -17,7 +17,6 @@
package com.android.server.input;
import android.annotation.BinderThread;
-import android.annotation.ColorInt;
import android.content.Context;
import android.graphics.Color;
import android.hardware.input.IKeyboardBacklightListener;
@@ -29,6 +28,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
@@ -39,9 +39,10 @@
import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
+import java.time.Duration;
+import java.util.Arrays;
import java.util.Objects;
import java.util.OptionalInt;
-import java.util.TreeSet;
/**
* A thread-safe component of {@link InputManagerService} responsible for managing the keyboard
@@ -59,12 +60,20 @@
private enum Direction {
DIRECTION_UP, DIRECTION_DOWN
}
- private static final int MSG_INCREMENT_KEYBOARD_BACKLIGHT = 1;
- private static final int MSG_DECREMENT_KEYBOARD_BACKLIGHT = 2;
+ private static final int MSG_UPDATE_EXISTING_DEVICES = 1;
+ private static final int MSG_INCREMENT_KEYBOARD_BACKLIGHT = 2;
+ private static final int MSG_DECREMENT_KEYBOARD_BACKLIGHT = 3;
+ private static final int MSG_NOTIFY_USER_ACTIVITY = 4;
+ private static final int MSG_NOTIFY_USER_INACTIVITY = 5;
+ private static final int MSG_INTERACTIVE_STATE_CHANGED = 6;
private static final int MAX_BRIGHTNESS = 255;
private static final int NUM_BRIGHTNESS_CHANGE_STEPS = 10;
+
@VisibleForTesting
- static final TreeSet<Integer> BRIGHTNESS_LEVELS = new TreeSet<>();
+ static final long USER_INACTIVITY_THRESHOLD_MILLIS = Duration.ofSeconds(30).toMillis();
+
+ @VisibleForTesting
+ static final int[] BRIGHTNESS_VALUE_FOR_LEVEL = new int[NUM_BRIGHTNESS_CHANGE_STEPS + 1];
private final Context mContext;
private final NativeInputManagerService mNative;
@@ -72,7 +81,12 @@
@GuardedBy("mDataStore")
private final PersistentDataStore mDataStore;
private final Handler mHandler;
- private final SparseArray<Light> mKeyboardBacklights = new SparseArray<>();
+ // Always access on handler thread or need to lock this for synchronization.
+ private final SparseArray<KeyboardBacklightState> mKeyboardBacklights = new SparseArray<>(1);
+ // Maintains state if all backlights should be on or turned off
+ private boolean mIsBacklightOn = false;
+ // Maintains state if currently the device is interactive or not
+ private boolean mIsInteractive = true;
// List of currently registered keyboard backlight listeners
@GuardedBy("mKeyboardBacklightListenerRecords")
@@ -84,8 +98,8 @@
// device brightness range to [0-255]
// Levels are: 0, 25, 51, ..., 255
for (int i = 0; i <= NUM_BRIGHTNESS_CHANGE_STEPS; i++) {
- BRIGHTNESS_LEVELS.add(
- (int) Math.floor(((float) i * MAX_BRIGHTNESS) / NUM_BRIGHTNESS_CHANGE_STEPS));
+ BRIGHTNESS_VALUE_FOR_LEVEL[i] = (int) Math.floor(
+ ((float) i * MAX_BRIGHTNESS) / NUM_BRIGHTNESS_CHANGE_STEPS);
}
}
@@ -102,10 +116,10 @@
InputManager inputManager = Objects.requireNonNull(
mContext.getSystemService(InputManager.class));
inputManager.registerInputDeviceListener(this, mHandler);
- // Circle through all the already added input devices
- for (int deviceId : inputManager.getInputDeviceIds()) {
- onInputDeviceAdded(deviceId);
- }
+
+ Message msg = Message.obtain(mHandler, MSG_UPDATE_EXISTING_DEVICES,
+ inputManager.getInputDeviceIds());
+ mHandler.sendMessage(msg);
}
@Override
@@ -120,37 +134,41 @@
mHandler.sendMessage(msg);
}
+ @Override
+ public void notifyUserActivity() {
+ Message msg = Message.obtain(mHandler, MSG_NOTIFY_USER_ACTIVITY);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onInteractiveChanged(boolean isInteractive) {
+ Message msg = Message.obtain(mHandler, MSG_INTERACTIVE_STATE_CHANGED, isInteractive);
+ mHandler.sendMessage(msg);
+ }
+
private void updateKeyboardBacklight(int deviceId, Direction direction) {
InputDevice inputDevice = getInputDevice(deviceId);
- Light keyboardBacklight = mKeyboardBacklights.get(deviceId);
- if (inputDevice == null || keyboardBacklight == null) {
+ KeyboardBacklightState state = mKeyboardBacklights.get(deviceId);
+ if (inputDevice == null || state == null) {
return;
}
+ Light keyboardBacklight = state.mLight;
// Follow preset levels of brightness defined in BRIGHTNESS_LEVELS
- int currBrightness = BRIGHTNESS_LEVELS.floor(Color.alpha(
- mNative.getLightColor(deviceId, keyboardBacklight.getId())));
- int newBrightness;
+ final int currBrightnessLevel = state.mBrightnessLevel;
+ final int newBrightnessLevel;
if (direction == Direction.DIRECTION_UP) {
- newBrightness = currBrightness != MAX_BRIGHTNESS ? BRIGHTNESS_LEVELS.higher(
- currBrightness) : currBrightness;
+ newBrightnessLevel = Math.min(currBrightnessLevel + 1, NUM_BRIGHTNESS_CHANGE_STEPS);
} else {
- newBrightness = currBrightness != 0 ? BRIGHTNESS_LEVELS.lower(currBrightness)
- : currBrightness;
+ newBrightnessLevel = Math.max(currBrightnessLevel - 1, 0);
}
- @ColorInt int newColor = Color.argb(newBrightness, 0, 0, 0);
- mNative.setLightColor(deviceId, keyboardBacklight.getId(), newColor);
- if (DEBUG) {
- Slog.d(TAG, "Changing brightness from " + currBrightness + " to " + newBrightness);
- }
-
- notifyKeyboardBacklightChanged(deviceId, BRIGHTNESS_LEVELS.headSet(newBrightness).size(),
- true/* isTriggeredByKeyPress */);
+ updateBacklightState(deviceId, keyboardBacklight, newBrightnessLevel,
+ true /* isTriggeredByKeyPress */);
synchronized (mDataStore) {
try {
mDataStore.setKeyboardBacklightBrightness(inputDevice.getDescriptor(),
keyboardBacklight.getId(),
- newBrightness);
+ BRIGHTNESS_VALUE_FOR_LEVEL[newBrightnessLevel]);
} finally {
mDataStore.saveIfNeeded();
}
@@ -163,23 +181,83 @@
brightness = mDataStore.getKeyboardBacklightBrightness(
inputDevice.getDescriptor(), keyboardBacklight.getId());
}
- if (!brightness.isEmpty()) {
- mNative.setLightColor(inputDevice.getId(), keyboardBacklight.getId(),
- Color.argb(brightness.getAsInt(), 0, 0, 0));
+ if (brightness.isPresent()) {
+ int brightnessValue = Math.max(0, Math.min(MAX_BRIGHTNESS, brightness.getAsInt()));
+ int brightnessLevel = Arrays.binarySearch(BRIGHTNESS_VALUE_FOR_LEVEL, brightnessValue);
+ updateBacklightState(inputDevice.getId(), keyboardBacklight, brightnessLevel,
+ false /* isTriggeredByKeyPress */);
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.
+ if (!mIsInteractive) {
+ return;
+ }
+ if (!mIsBacklightOn) {
+ mIsBacklightOn = true;
+ for (int i = 0; i < mKeyboardBacklights.size(); i++) {
+ int deviceId = mKeyboardBacklights.keyAt(i);
+ KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
+ updateBacklightState(deviceId, state.mLight, state.mBrightnessLevel,
+ false /* isTriggeredByKeyPress */);
+ }
+ }
+ mHandler.removeMessages(MSG_NOTIFY_USER_INACTIVITY);
+ mHandler.sendEmptyMessageAtTime(MSG_NOTIFY_USER_INACTIVITY,
+ SystemClock.uptimeMillis() + USER_INACTIVITY_THRESHOLD_MILLIS);
+ }
+
+ private void handleUserInactivity() {
+ if (mIsBacklightOn) {
+ mIsBacklightOn = false;
+ for (int i = 0; i < mKeyboardBacklights.size(); i++) {
+ int deviceId = mKeyboardBacklights.keyAt(i);
+ KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
+ updateBacklightState(deviceId, state.mLight, state.mBrightnessLevel,
+ false /* isTriggeredByKeyPress */);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ public void handleInteractiveStateChange(boolean isInteractive) {
+ // Interactive state changes should force the keyboard to turn on/off irrespective of
+ // whether time out occurred or not.
+ mIsInteractive = isInteractive;
+ if (isInteractive) {
+ handleUserActivity();
+ } else {
+ handleUserInactivity();
+ }
+ }
+
private boolean handleMessage(Message msg) {
switch (msg.what) {
+ case MSG_UPDATE_EXISTING_DEVICES:
+ for (int deviceId : (int[]) msg.obj) {
+ onInputDeviceAdded(deviceId);
+ }
+ return true;
case MSG_INCREMENT_KEYBOARD_BACKLIGHT:
updateKeyboardBacklight((int) msg.obj, Direction.DIRECTION_UP);
return true;
case MSG_DECREMENT_KEYBOARD_BACKLIGHT:
updateKeyboardBacklight((int) msg.obj, Direction.DIRECTION_DOWN);
return true;
+ case MSG_NOTIFY_USER_ACTIVITY:
+ handleUserActivity();
+ return true;
+ case MSG_NOTIFY_USER_INACTIVITY:
+ handleUserInactivity();
+ return true;
+ case MSG_INTERACTIVE_STATE_CHANGED:
+ handleInteractiveStateChange((boolean) msg.obj);
+ return true;
}
return false;
}
@@ -208,12 +286,12 @@
mKeyboardBacklights.remove(deviceId);
return;
}
- final Light oldBacklight = mKeyboardBacklights.get(deviceId);
- if (oldBacklight != null && oldBacklight.getId() == keyboardBacklight.getId()) {
+ KeyboardBacklightState state = mKeyboardBacklights.get(deviceId);
+ if (state != null && state.mLight.getId() == keyboardBacklight.getId()) {
return;
}
// The keyboard backlight was added or changed.
- mKeyboardBacklights.put(deviceId, keyboardBacklight);
+ mKeyboardBacklights.put(deviceId, new KeyboardBacklightState(keyboardBacklight));
restoreBacklightBrightness(inputDevice, keyboardBacklight);
}
@@ -275,13 +353,29 @@
}
}
- private void notifyKeyboardBacklightChanged(int deviceId, int currentBacklightLevel,
+ private void updateBacklightState(int deviceId, Light light, int brightnessLevel,
boolean isTriggeredByKeyPress) {
+ KeyboardBacklightState state = mKeyboardBacklights.get(deviceId);
+ if (state == null) {
+ return;
+ }
+
+ mNative.setLightColor(deviceId, light.getId(),
+ mIsBacklightOn ? Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[brightnessLevel], 0, 0, 0)
+ : 0);
+ if (DEBUG) {
+ Slog.d(TAG, "Changing state from " + state.mBrightnessLevel + " to " + brightnessLevel
+ + "(isBacklightOn = " + mIsBacklightOn + ")");
+ }
+ state.mBrightnessLevel = brightnessLevel;
+
synchronized (mKeyboardBacklightListenerRecords) {
for (int i = 0; i < mKeyboardBacklightListenerRecords.size(); i++) {
+ IKeyboardBacklightState callbackState = new IKeyboardBacklightState();
+ callbackState.brightnessLevel = brightnessLevel;
+ callbackState.maxBrightnessLevel = NUM_BRIGHTNESS_CHANGE_STEPS;
mKeyboardBacklightListenerRecords.valueAt(i).notifyKeyboardBacklightChanged(
- deviceId, new KeyboardBacklightState(currentBacklightLevel),
- isTriggeredByKeyPress);
+ deviceId, callbackState, isTriggeredByKeyPress);
}
}
}
@@ -295,11 +389,14 @@
@Override
public void dump(PrintWriter pw) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
- ipw.println(TAG + ": " + mKeyboardBacklights.size() + " keyboard backlights");
+ ipw.println(
+ TAG + ": " + mKeyboardBacklights.size() + " keyboard backlights, isBacklightOn = "
+ + mIsBacklightOn);
+
ipw.increaseIndent();
for (int i = 0; i < mKeyboardBacklights.size(); i++) {
- Light light = mKeyboardBacklights.get(i);
- ipw.println(i + ": { id: " + light.getId() + ", name: " + light.getName() + " }");
+ KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
+ ipw.println(i + ": " + state.toString());
}
ipw.decreaseIndent();
}
@@ -334,17 +431,18 @@
}
}
- private static class KeyboardBacklightState extends IKeyboardBacklightState {
+ private static class KeyboardBacklightState {
+ private final Light mLight;
+ private int mBrightnessLevel;
- KeyboardBacklightState(int brightnessLevel) {
- this.brightnessLevel = brightnessLevel;
- this.maxBrightnessLevel = NUM_BRIGHTNESS_CHANGE_STEPS;
+ KeyboardBacklightState(Light light) {
+ mLight = light;
}
@Override
public String toString() {
- return "KeyboardBacklightState{brightnessLevel=" + brightnessLevel
- + ", maxBrightnessLevel=" + maxBrightnessLevel
+ return "KeyboardBacklightState{Light=" + mLight.getId()
+ + ", BrightnessLevel=" + mBrightnessLevel
+ "}";
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 326d709..ed6a46f 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -737,6 +737,7 @@
}
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
tm.notifyUserActivity();
+ mInputManagerInternal.notifyUserActivity();
mPolicy.userActivity(displayGroupId, event);
mFaceDownDetector.userActivity(event);
mScreenUndimDetector.userActivity(displayGroupId);
diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
index b5dad94..1d23e12 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
@@ -28,7 +28,8 @@
import android.platform.test.annotations.Presubmit
import android.view.InputDevice
import androidx.test.core.app.ApplicationProvider
-import com.android.server.input.KeyboardBacklightController.BRIGHTNESS_LEVELS
+import com.android.server.input.KeyboardBacklightController.BRIGHTNESS_VALUE_FOR_LEVEL
+import com.android.server.input.KeyboardBacklightController.USER_INACTIVITY_THRESHOLD_MILLIS
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
@@ -78,6 +79,7 @@
const val DEVICE_ID = 1
const val LIGHT_ID = 2
const val SECOND_LIGHT_ID = 3
+ const val MAX_BRIGHTNESS = 255
}
@get:Rule
@@ -118,10 +120,6 @@
val args = it.arguments
lightColorMap.put(args[1] as Int, args[2] as Int)
}
- `when`(native.getLightColor(anyInt(), anyInt())).then {
- val args = it.arguments
- lightColorMap.getOrDefault(args[1] as Int, -1)
- }
lightColorMap.clear()
}
@@ -137,21 +135,17 @@
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
`when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- // Initially backlight is at min
- lightColorMap[LIGHT_ID] = Color.argb(BRIGHTNESS_LEVELS.first(), 0, 0, 0)
- val brightnessLevelsArray = BRIGHTNESS_LEVELS.toTypedArray()
- for (level in 1 until brightnessLevelsArray.size) {
- keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
+ for (level in 1 until BRIGHTNESS_VALUE_FOR_LEVEL.size) {
+ incrementKeyboardBacklight(DEVICE_ID)
assertEquals(
"Light value for level $level mismatched",
- Color.argb(brightnessLevelsArray[level], 0, 0, 0),
+ Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
lightColorMap[LIGHT_ID]
)
assertEquals(
"Light value for level $level must be correctly stored in the datastore",
- brightnessLevelsArray[level],
+ BRIGHTNESS_VALUE_FOR_LEVEL[level],
dataStore.getKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID
@@ -159,72 +153,49 @@
)
}
- for (level in brightnessLevelsArray.size - 2 downTo 0) {
- keyboardBacklightController.decrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
- assertEquals(
- "Light value for level $level mismatched",
- Color.argb(brightnessLevelsArray[level], 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for level $level must be correctly stored in the datastore",
- brightnessLevelsArray[level],
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
- }
- }
-
- @Test
- fun testKeyboardBacklightIncrementAboveMaxLevel() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- // Initially backlight is at max
- lightColorMap[LIGHT_ID] = Color.argb(BRIGHTNESS_LEVELS.last(), 0, 0, 0)
-
- keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
+ // Increment above max level
+ incrementKeyboardBacklight(DEVICE_ID)
assertEquals(
"Light value for max level mismatched",
- Color.argb(BRIGHTNESS_LEVELS.last(), 0, 0, 0),
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
lightColorMap[LIGHT_ID]
)
assertEquals(
"Light value for max level must be correctly stored in the datastore",
- BRIGHTNESS_LEVELS.last(),
+ MAX_BRIGHTNESS,
dataStore.getKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID
).asInt
)
- }
- @Test
- fun testKeyboardBacklightDecrementBelowMin() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- // Initially backlight is at min
- lightColorMap[LIGHT_ID] = Color.argb(BRIGHTNESS_LEVELS.first(), 0, 0, 0)
+ for (level in BRIGHTNESS_VALUE_FOR_LEVEL.size - 2 downTo 0) {
+ decrementKeyboardBacklight(DEVICE_ID)
+ assertEquals(
+ "Light value for level $level mismatched",
+ Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ lightColorMap[LIGHT_ID]
+ )
+ assertEquals(
+ "Light value for level $level must be correctly stored in the datastore",
+ BRIGHTNESS_VALUE_FOR_LEVEL[level],
+ dataStore.getKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID
+ ).asInt
+ )
+ }
- keyboardBacklightController.decrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
+ // Decrement below min level
+ decrementKeyboardBacklight(DEVICE_ID)
assertEquals(
"Light value for min level mismatched",
- Color.argb(BRIGHTNESS_LEVELS.first(), 0, 0, 0),
+ Color.argb(0, 0, 0, 0),
lightColorMap[LIGHT_ID]
)
assertEquals(
"Light value for min level must be correctly stored in the datastore",
- BRIGHTNESS_LEVELS.first(),
+ 0,
dataStore.getKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID
@@ -240,7 +211,7 @@
`when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardInputLight))
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
+ incrementKeyboardBacklight(DEVICE_ID)
assertTrue("Non Keyboard backlights should not change", lightColorMap.isEmpty())
}
@@ -258,8 +229,7 @@
)
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
+ 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])
@@ -275,14 +245,15 @@
dataStore.setKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID,
- BRIGHTNESS_LEVELS.last()
+ MAX_BRIGHTNESS
)
- lightColorMap.clear()
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(BRIGHTNESS_LEVELS.last(), 0, 0, 0),
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
lightColorMap[LIGHT_ID]
)
}
@@ -295,11 +266,12 @@
dataStore.setKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID,
- BRIGHTNESS_LEVELS.last()
+ MAX_BRIGHTNESS
)
- lightColorMap.clear()
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ keyboardBacklightController.notifyUserActivity()
+ testLooper.dispatchNext()
assertTrue(
"Keyboard backlight should not be changed until its added",
lightColorMap.isEmpty()
@@ -307,22 +279,22 @@
`when`(iInputManager.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(BRIGHTNESS_LEVELS.last(), 0, 0, 0),
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
lightColorMap[LIGHT_ID]
)
}
@Test
- fun testKeyboardBacklightT_registerUnregisterListener() {
+ fun testKeyboardBacklight_registerUnregisterListener() {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
`when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- // Initially backlight is at min
- lightColorMap[LIGHT_ID] = Color.argb(BRIGHTNESS_LEVELS.first(), 0, 0, 0)
// Register backlight listener
val listener = KeyboardBacklightListener()
@@ -343,8 +315,8 @@
lastBacklightState!!.brightnessLevel
)
assertEquals(
- "Backlight state maxBrightnessLevel should be " + (BRIGHTNESS_LEVELS.size - 1),
- (BRIGHTNESS_LEVELS.size - 1),
+ "Backlight state maxBrightnessLevel should be " + (BRIGHTNESS_VALUE_FOR_LEVEL.size - 1),
+ (BRIGHTNESS_VALUE_FOR_LEVEL.size - 1),
lastBacklightState!!.maxBrightnessLevel
)
assertEquals(
@@ -357,12 +329,70 @@
keyboardBacklightController.unregisterKeyboardBacklightListener(listener, 0)
lastBacklightState = null
- keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
+ incrementKeyboardBacklight(DEVICE_ID)
assertNull("Listener should not receive any updates", lastBacklightState)
}
+ @Test
+ fun testKeyboardBacklight_userActivity() {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.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]
+ )
+
+ testLooper.moveTimeForward(USER_INACTIVITY_THRESHOLD_MILLIS + 1000)
+ testLooper.dispatchNext()
+ assertEquals(
+ "Keyboard backlight level should be turned off after inactivity",
+ 0,
+ lightColorMap[LIGHT_ID]
+ )
+ }
+
+ @Test
+ fun testKeyboardBacklight_displayOnOff() {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ dataStore.setKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID,
+ MAX_BRIGHTNESS
+ )
+
+ 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]
+ )
+ }
+
inner class KeyboardBacklightListener : IKeyboardBacklightListener.Stub() {
override fun onBrightnessChanged(
deviceId: Int,
@@ -378,6 +408,18 @@
}
}
+ private fun incrementKeyboardBacklight(deviceId: Int) {
+ keyboardBacklightController.incrementKeyboardBacklight(deviceId)
+ keyboardBacklightController.notifyUserActivity()
+ testLooper.dispatchAll()
+ }
+
+ private fun decrementKeyboardBacklight(deviceId: Int) {
+ keyboardBacklightController.decrementKeyboardBacklight(deviceId)
+ keyboardBacklightController.notifyUserActivity()
+ testLooper.dispatchAll()
+ }
+
class KeyboardBacklightState(
val deviceId: Int,
val brightnessLevel: Int,