summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java47
1 files changed, 32 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 70e493d26d16..2e4200c1f7d9 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -222,7 +222,12 @@ public class InputManagerService extends IInputManager.Stub
private int mNextVibratorTokenValue;
// State for lid switch
+ // Lock for the lid switch state. Held when triggering callbacks to guarantee lid switch events
+ // are delivered in order. For ex, when a new lid switch callback is registered the lock is held
+ // while the callback is processing the initial lid switch event which guarantees that any
+ // events that occur at the same time are delivered after the callback has returned.
private final Object mLidSwitchLock = new Object();
+ @GuardedBy("mLidSwitchLock")
private List<LidSwitchCallback> mLidSwitchCallbacks = new ArrayList<>();
// State for the currently installed input filter.
@@ -370,9 +375,6 @@ public class InputManagerService extends IInputManager.Stub
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;
@@ -408,13 +410,18 @@ public class InputManagerService extends IInputManager.Stub
}
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;
+
+ // Skip triggering the initial callback if the system is not yet ready as the switch
+ // state will be reported as KEY_STATE_UNKNOWN. The callback will be triggered in
+ // systemRunning().
+ if (mSystemReady) {
+ boolean lidOpen = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID)
+ == KEY_STATE_UP;
+ callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen);
+ }
}
- callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen);
}
void unregisterLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) {
@@ -462,7 +469,18 @@ public class InputManagerService extends IInputManager.Stub
}
mNotificationManager = (NotificationManager)mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
- mSystemReady = true;
+
+ synchronized (mLidSwitchLock) {
+ mSystemReady = true;
+
+ // Send the initial lid switch state to any callback registered before the system was
+ // ready.
+ int switchState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID);
+ for (int i = 0; i < mLidSwitchCallbacks.size(); i++) {
+ LidSwitchCallback callback = mLidSwitchCallbacks.get(i);
+ callback.notifyLidSwitchChanged(0 /* whenNanos */, switchState == KEY_STATE_UP);
+ }
+ }
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
@@ -2233,14 +2251,13 @@ public class InputManagerService extends IInputManager.Stub
if ((switchMask & SW_LID_BIT) != 0) {
final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0);
-
- 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 (mSystemReady) {
+ for (int i = 0; i < mLidSwitchCallbacks.size(); i++) {
+ LidSwitchCallback callbacks = mLidSwitchCallbacks.get(i);
+ callbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
+ }
+ }
}
}