diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 5 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java | 35 |
2 files changed, 35 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5110c999ac36..b3f9ddb2eef8 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7081,6 +7081,11 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG, "startPositioningLocked: Bad window " + win); return false; } + if (win.mInputChannel == null) { + Slog.wtf(TAG, "startPositioningLocked: " + win + " has no input channel, " + + " probably being removed"); + return false; + } final DisplayContent displayContent = win.getDisplayContent(); if (displayContent == null) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 2b686b2ea750..3b0fc4f186a4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -70,6 +70,8 @@ import android.view.Gravity; import android.view.IApplicationToken; import android.view.IWindow; import android.view.InputChannel; +import android.view.InputEvent; +import android.view.InputEventReceiver; import android.view.View; import android.view.ViewTreeObserver; import android.view.WindowManager; @@ -1282,6 +1284,20 @@ final class WindowState implements WindowManagerPolicy.WindowState { mConfigHasChanged = false; } + private final class DeadWindowEventReceiver extends InputEventReceiver { + DeadWindowEventReceiver(InputChannel inputChannel) { + super(inputChannel, mService.mH.getLooper()); + } + @Override + public void onInputEvent(InputEvent event) { + finishInputEvent(event, true); + } + } + /** + * Dummy event receiver for windows that died visible. + */ + private DeadWindowEventReceiver mDeadWindowEventReceiver; + void openInputChannel(InputChannel outInputChannel) { if (mInputChannel != null) { throw new IllegalStateException("Window already has an input channel."); @@ -1295,22 +1311,31 @@ final class WindowState implements WindowManagerPolicy.WindowState { mClientChannel.transferTo(outInputChannel); mClientChannel.dispose(); mClientChannel = null; + } else { + // If the window died visible, we setup a dummy input channel, so that taps + // can still detected by input monitor channel, and we can relaunch the app. + // Create dummy event receiver that simply reports all events as handled. + mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); } mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle); } void disposeInputChannel() { - if (mClientChannel != null) { - mClientChannel.dispose(); - mClientChannel = null; + if (mDeadWindowEventReceiver != null) { + mDeadWindowEventReceiver.dispose(); + mDeadWindowEventReceiver = null; } + + // unregister server channel first otherwise it complains about broken channel if (mInputChannel != null) { mService.mInputManager.unregisterInputChannel(mInputChannel); - mInputChannel.dispose(); mInputChannel = null; } - + if (mClientChannel != null) { + mClientChannel.dispose(); + mClientChannel = null; + } mInputWindowHandle.inputChannel = null; } |