Add support to InputManagerService for listening to lid switch events.
This extracts the notifyLidSwitchChanged() method from
WindowManagerCallbacks to allow services other than window manager to
receive lid switch notifications
Test: Manual, register callback and trigger lid switch
Bug: 159401801
Change-Id: I8967d4f2f5a9c56c2b7e0822224d1c0ea0f1bc06
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
index f6cd726..1173c31 100644
--- a/core/java/android/hardware/input/InputManagerInternal.java
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -78,4 +78,26 @@
*/
public abstract boolean transferTouchFocus(@NonNull IBinder fromChannelToken,
@NonNull IBinder toChannelToken);
+
+ /** Registers the {@link LidSwitchCallback} to begin receiving notifications. */
+ public abstract void registerLidSwitchCallback(@NonNull LidSwitchCallback callbacks);
+
+ /**
+ * Unregisters a {@link LidSwitchCallback callback} previously registered with
+ * {@link #registerLidSwitchCallback(LidSwitchCallback)}.
+ */
+ public abstract void unregisterLidSwitchCallback(@NonNull LidSwitchCallback callbacks);
+
+ /** Callback interface for notifications relating to the lid switch. */
+ public interface LidSwitchCallback {
+ /**
+ * This callback is invoked when the lid switch changes state. Will be triggered once on
+ * registration of the callback with a {@code whenNanos} of 0 and then on every subsequent
+ * change in lid switch state.
+ *
+ * @param whenNanos the time when the change occurred
+ * @param lidOpen true if the lid is open
+ */
+ void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
+ }
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 7c98c6c..fa50bac0 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -46,6 +46,7 @@
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
+import android.hardware.input.InputManagerInternal.LidSwitchCallback;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.TouchCalibration;
import android.media.AudioManager;
@@ -189,6 +190,10 @@
private Map<IBinder, VibratorToken> mVibratorTokens = new ArrayMap<IBinder, VibratorToken>();
private int mNextVibratorTokenValue;
+ // State for lid switch
+ private final Object mLidSwitchLock = new Object();
+ private List<LidSwitchCallback> mLidSwitchCallbacks = new ArrayList<>();
+
// State for the currently installed input filter.
final Object mInputFilterLock = new Object();
IInputFilter mInputFilter; // guarded by mInputFilterLock
@@ -330,6 +335,9 @@
public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER;
public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE;
+ /** Indicates an open state for the lid switch. */
+ public static final int SW_STATE_LID_OPEN = 0;
+
/** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
final boolean mUseDevInputEventForAudioJack;
@@ -353,13 +361,33 @@
}
public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
+ if (mWindowManagerCallbacks != null) {
+ unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks);
+ }
mWindowManagerCallbacks = callbacks;
+ registerLidSwitchCallbackInternal(mWindowManagerCallbacks);
}
public void setWiredAccessoryCallbacks(WiredAccessoryCallbacks callbacks) {
mWiredAccessoryCallbacks = callbacks;
}
+ void registerLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) {
+ boolean lidOpen;
+ synchronized (mLidSwitchLock) {
+ mLidSwitchCallbacks.add(callback);
+ lidOpen = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID)
+ == SW_STATE_LID_OPEN;
+ }
+ callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen);
+ }
+
+ void unregisterLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) {
+ synchronized (mLidSwitchLock) {
+ mLidSwitchCallbacks.remove(callback);
+ }
+ }
+
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
@@ -1934,6 +1962,7 @@
synchronized (mInputFilterLock) { }
synchronized (mAssociationsLock) { /* Test if blocked by associations lock. */}
synchronized (mGestureMonitorPidsLock) { /* Test if blocked by gesture monitor pids lock */}
+ synchronized (mLidSwitchLock) { /* Test if blocked by lid switch lock. */ }
nativeMonitor(mPtr);
}
@@ -1964,7 +1993,15 @@
if ((switchMask & SW_LID_BIT) != 0) {
final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0);
- mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
+
+ ArrayList<LidSwitchCallback> callbacksCopy;
+ synchronized (mLidSwitchLock) {
+ callbacksCopy = new ArrayList<>(mLidSwitchCallbacks);
+ }
+ for (int i = 0; i < callbacksCopy.size(); i++) {
+ LidSwitchCallback callbacks = callbacksCopy.get(i);
+ callbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
+ }
}
if ((switchMask & SW_CAMERA_LENS_COVER_BIT) != 0) {
@@ -2263,20 +2300,13 @@
/**
* Callback interface implemented by the Window Manager.
*/
- public interface WindowManagerCallbacks {
+ public interface WindowManagerCallbacks extends LidSwitchCallback {
/**
* This callback is invoked when the confuguration changes.
*/
public void notifyConfigurationChanged();
/**
- * This callback is invoked when the lid switch changes state.
- * @param whenNanos the time when the change occurred
- * @param lidOpen true if the lid is open
- */
- public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
-
- /**
* This callback is invoked when the camera lens cover switch changes state.
* @param whenNanos the time when the change occurred
* @param lensCovered true is the lens is covered
@@ -2603,6 +2633,16 @@
@NonNull IBinder toChannelToken) {
return InputManagerService.this.transferTouchFocus(fromChannelToken, toChannelToken);
}
+
+ @Override
+ public void registerLidSwitchCallback(LidSwitchCallback callbacks) {
+ registerLidSwitchCallbackInternal(callbacks);
+ }
+
+ @Override
+ public void unregisterLidSwitchCallback(LidSwitchCallback callbacks) {
+ unregisterLidSwitchCallbackInternal(callbacks);
+ }
}
@Override