From 31c9c8d96bd76520defb09d2d09e39e791673228 Mon Sep 17 00:00:00 2001 From: Darryl L Johnson Date: Mon, 30 Nov 2020 10:38:37 -0800 Subject: [PATCH] Defer triggering notifyLidSwitchChanged() until the system is ready. Before the system is ready getSwitchState() returns KEY_STATE_UNKNOWN for the lid switch causing the initial lidOpen value to be false on boot even if the lid is currently open. This defers the triggering of any callbacks registered before the system is ready to ensure that the initial callback value is correct. Bug: 159401801 Test: Manual - ensure first callback value matches lid state on boot. Change-Id: I9351312e5ecf8b1984ae11a47ed9b89dab1aa07f --- .../server/input/InputManagerService.java | 47 +++++++++++++------ 1 file 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 42aad7d7ad5cb..e9fe90f5b8bbc 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -203,7 +203,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 mLidSwitchCallbacks = new ArrayList<>(); // State for the currently installed input filter. @@ -343,9 +348,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; @@ -381,13 +383,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) { @@ -435,7 +442,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); @@ -2045,14 +2063,13 @@ public class InputManagerService extends IInputManager.Stub if ((switchMask & SW_LID_BIT) != 0) { final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0); - - ArrayList 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); + } + } } }