From 460dabda46d543b6db9c963bd4f85b89575e08d8 Mon Sep 17 00:00:00 2001 From: Yunfan Chen Date: Wed, 27 May 2020 21:20:26 +0900 Subject: [PATCH] Remove IME surface when occured in multi-window mode On split-screen, IME is not controlled by the client and it's critical to remove the surface when hiding the IME. DisplayImeController doesn't have the access to the actual enabled InputMethodManager. Instead, this patch introduced a new interface in InputMethodManagerService to let system UI remove the currently enabled IME surface when needed. Bug: 155660756 Test: go/wm-smoke Test: See reproduce steps in the bug. Change-Id: I800dbab20aa90fd549ea1c07da85572311ecb7b3 --- .../internal/view/IInputMethodManager.aidl | 2 ++ .../systemui/wm/DisplayImeController.java | 24 ++++++++++++++++--- .../InputMethodManagerService.java | 16 +++++++++++++ .../MultiClientInputMethodManagerService.java | 6 +++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 3f03f2a3e7545..d22f942133380 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -71,4 +71,6 @@ interface IInputMethodManager { void reportActivityView(in IInputMethodClient parentClient, int childDisplayId, in float[] matrixValues); + + void removeImeSurface(); } diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java index 32e3a7fc032ec..7b114525adcd5 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java +++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java @@ -19,11 +19,13 @@ package com.android.systemui.wm; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Slog; import android.util.SparseArray; import android.view.IDisplayWindowInsetsController; @@ -36,6 +38,7 @@ import android.view.WindowInsets; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import com.android.internal.view.IInputMethodManager; import com.android.systemui.TransactionPool; import com.android.systemui.dagger.qualifiers.Main; @@ -352,6 +355,16 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged dispatchEndPositioning(mDisplayId, mCancelled, t); if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) { t.hide(mImeSourceControl.getLeash()); + final IInputMethodManager imms = getImms(); + if (imms != null) { + try { + // Remove the IME surface to make the insets invisible for + // non-client controlled insets. + imms.removeImeSurface(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to remove IME surface.", e); + } + } } t.apply(); mTransactionPool.release(t); @@ -382,9 +395,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged * Called when the IME position is starting to animate. * * @param hiddenTop The y position of the top of the IME surface when it is hidden. - * @param shownTop The y position of the top of the IME surface when it is shown. - * @param showing {@code true} when we are animating from hidden to shown, {@code false} - * when animating from shown to hidden. + * @param shownTop The y position of the top of the IME surface when it is shown. + * @param showing {@code true} when we are animating from hidden to shown, {@code false} + * when animating from shown to hidden. */ default void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean showing, SurfaceControl.Transaction t) {} @@ -406,4 +419,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged default void onImeEndPositioning(int displayId, boolean cancel, SurfaceControl.Transaction t) {} } + + public IInputMethodManager getImms() { + return IInputMethodManager.Stub.asInterface( + ServiceManager.getService(Context.INPUT_METHOD_SERVICE)); + } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index a498e3867c056..c604a9cf7021f 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -207,6 +207,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final int MSG_HIDE_CURRENT_INPUT_METHOD = 1035; static final int MSG_INITIALIZE_IME = 1040; static final int MSG_CREATE_SESSION = 1050; + static final int MSG_REMOVE_IME_SURFACE = 1060; static final int MSG_START_INPUT = 2000; @@ -3936,6 +3937,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + @Override + public void removeImeSurface() { + mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null); + mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); + } + @BinderThread private void notifyUserAction(@NonNull IBinder token) { if (DEBUG) { @@ -4206,6 +4213,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub args.recycle(); return true; } + case MSG_REMOVE_IME_SURFACE: { + try { + if (mEnabledSession != null && mEnabledSession.session != null) { + mEnabledSession.session.removeImeSurface(); + } + } catch (RemoteException e) { + } + return true; + } // --------------------------------------------------------- case MSG_START_INPUT: { diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 2129e9bd34f3f..d025b0f4ece5a 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1460,6 +1460,12 @@ public final class MultiClientInputMethodManagerService { return null; } + @BinderThread + @Override + public void removeImeSurface() { + reportNotSupported(); + } + @BinderThread @Override public boolean showSoftInput(