diff options
| author | 2024-01-31 13:12:49 +0000 | |
|---|---|---|
| committer | 2024-02-02 17:29:57 +0000 | |
| commit | 228bc6c034d3e289d55caef9af2a187483b1162f (patch) | |
| tree | cadb2da3dc996053100fc09f5ca8a7f3ebd63758 | |
| parent | 0505c36312e4f1a2d36576c95adf43822b65c605 (diff) | |
Make Letterbox.InputInterceptor thread safe
InputEventReceiver#finishInputEvent is invoked every time
a double-tap event occurs on the ui thread and so it cannot
be guarded by the mWmService.mGlobalLock.
To avoid race conditions the common practice is to invoke
the InputEventReceiver#dispose() on the same thread dispatching
input events.
Fix: 317428610
Test: atest WmTests:LetterboxTest
Change-Id: I4cbaa9ede668a4434dd59d6a7758bec961cc1eeb
| -rw-r--r-- | services/core/java/com/android/server/wm/Letterbox.java | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index f6aad4c86220..e66321ae8219 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -23,6 +23,7 @@ import static android.window.TaskConstants.TASK_CHILD_LAYER_LETTERBOX_BACKGROUND import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; +import android.os.Handler; import android.os.IBinder; import android.os.InputConfig; import android.view.GestureDetector; @@ -258,11 +259,12 @@ public class Letterbox { private final GestureDetector mDoubleTapDetector; private final DoubleTapListener mDoubleTapListener; - TapEventReceiver(InputChannel inputChannel, WindowManagerService wmService) { - super(inputChannel, UiThread.getHandler().getLooper()); + TapEventReceiver(InputChannel inputChannel, WindowManagerService wmService, + Handler uiHandler) { + super(inputChannel, uiHandler.getLooper()); mDoubleTapListener = new DoubleTapListener(wmService); - mDoubleTapDetector = new GestureDetector( - wmService.mContext, mDoubleTapListener, UiThread.getHandler()); + mDoubleTapDetector = new GestureDetector(wmService.mContext, mDoubleTapListener, + uiHandler); } @Override @@ -294,19 +296,21 @@ public class Letterbox { } } - private final class InputInterceptor { + private final class InputInterceptor implements Runnable { private final InputChannel mClientChannel; private final InputWindowHandle mWindowHandle; private final InputEventReceiver mInputEventReceiver; private final WindowManagerService mWmService; private final IBinder mToken; + private final Handler mHandler; InputInterceptor(String namePrefix, WindowState win) { mWmService = win.mWmService; + mHandler = UiThread.getHandler(); final String name = namePrefix + (win.mActivityRecord != null ? win.mActivityRecord : win); mClientChannel = mWmService.mInputManager.createInputChannel(name); - mInputEventReceiver = new TapEventReceiver(mClientChannel, mWmService); + mInputEventReceiver = new TapEventReceiver(mClientChannel, mWmService, mHandler); mToken = mClientChannel.getToken(); @@ -335,11 +339,17 @@ public class Letterbox { mWindowHandle.touchableRegion.translate(-frame.left, -frame.top); } - void dispose() { - mWmService.mInputManager.removeInputChannel(mToken); + @Override + public void run() { mInputEventReceiver.dispose(); mClientChannel.dispose(); } + + void dispose() { + mWmService.mInputManager.removeInputChannel(mToken); + // Perform dispose on the same thread that dispatches input event + mHandler.post(this); + } } private class LetterboxSurface { |