From 53f6e83df0da99bcaae64eec9a6708bfea257261 Mon Sep 17 00:00:00 2001 From: Joshua Tsuji Date: Sun, 21 Jun 2020 22:21:15 -0400 Subject: [PATCH] Hide the IME using InputMethodManagerInternal, because doing it that way actually works. This technique is also used by the Recents animation to hide the IME. It replaces the AV back press workaround entirely, which fixes the IME hanging around issue (and by extension, the weirdness around the insets). Test: open a bubble (go/use-bubbles), focus an input field, then tap outside the bubbles UI to close the stack, observe that the IME hides Test: open a bubble, focus an input field, switch to another bubble, observe IME hides Test: open bubble, focus input field, switch to another bubble, focus input field, switch to the original bubble, focus input field, collapse stack, observe IME hides (previously the IME would remain visible) Bug: 159369847 Bug: 159561847 Change-Id: I09f27b3c187a7bcfbef663cd3101a74ad8ab95ab --- .../inputmethod/SoftInputShowHideReason.java | 9 ++++- .../internal/statusbar/IStatusBarService.aidl | 1 + .../systemui/bubbles/BubbleController.java | 21 ++++++----- .../systemui/bubbles/BubbleExpandedView.java | 1 - .../systemui/bubbles/BubbleStackView.java | 36 ++++++++++--------- .../statusbar/StatusBarManagerService.java | 13 +++++++ 6 files changed, 54 insertions(+), 27 deletions(-) diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java index 79397b81ace7d..4b968b45f1224 100644 --- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java +++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java @@ -46,7 +46,8 @@ import java.lang.annotation.Retention; SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE, SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED, - SoftInputShowHideReason.HIDE_RECENTS_ANIMATION}) + SoftInputShowHideReason.HIDE_RECENTS_ANIMATION, + SoftInputShowHideReason.HIDE_BUBBLES}) public @interface SoftInputShowHideReason { /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */ int SHOW_SOFT_INPUT = 0; @@ -140,4 +141,10 @@ public @interface SoftInputShowHideReason { * intercept touch from app window. */ int HIDE_RECENTS_ANIMATION = 18; + + /** + * Hide soft input when {@link com.android.systemui.bubbles.BubbleController} is expanding, + * switching, or collapsing Bubbles. + */ + int HIDE_BUBBLES = 19; } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index c32082418bc59..4999ec0556087 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -79,6 +79,7 @@ interface IStatusBarService void onNotificationSettingsViewed(String key); void onNotificationBubbleChanged(String key, boolean isBubble, int flags); void onBubbleNotificationSuppressionChanged(String key, boolean isSuppressed); + void hideCurrentInputMethodForBubbles(); void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName); void clearInlineReplyUriPermissions(String key); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index aa417191b2042..ccfbd8f57df19 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -483,12 +483,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } /** - * Dispatches a back press into the expanded Bubble's ActivityView if its IME is visible, - * causing it to hide. + * Hides the current input method, wherever it may be focused, via InputMethodManagerInternal. */ - public void hideImeFromExpandedBubble() { - if (mStackView != null) { - mStackView.hideImeFromExpandedBubble(); + public void hideCurrentInputMethod() { + try { + mBarService.hideCurrentInputMethodForBubbles(); + } catch (RemoteException e) { + e.printStackTrace(); } } @@ -693,8 +694,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (mStackView == null) { mStackView = new BubbleStackView( mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator, - mSysUiState, this::onAllBubblesAnimatedOut, - this::onImeVisibilityChanged); + mSysUiState, this::onAllBubblesAnimatedOut, this::onImeVisibilityChanged, + this::hideCurrentInputMethod); mStackView.addView(mBubbleScrim); if (mExpandListener != null) { mStackView.setExpandListener(mExpandListener); @@ -1589,7 +1590,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi @Override public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { if (mStackView != null && taskInfo.displayId == getExpandedDisplayId(mContext)) { - mBubbleData.setExpanded(false); + if (mImeVisible) { + hideCurrentInputMethod(); + } else { + mBubbleData.setExpanded(false); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 7c3e027e2e655..551c1a61cc7b5 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -465,7 +465,6 @@ public class BubbleExpandedView extends LinearLayout { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - hideImeIfVisible(); mKeyboardVisible = false; mNeedsNewHeight = false; if (mActivityView != null) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index c985b083f9a9e..356ee94a69370 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -383,6 +383,11 @@ public class BubbleStackView extends FrameLayout */ public final Consumer mOnImeVisibilityChanged; + /** + * Callback to run to ask BubbleController to hide the current IME. + */ + private final Runnable mHideCurrentInputMethodCallback; + /** * The currently magnetized object, which is being dragged and will be attracted to the magnetic * dismiss target. @@ -560,7 +565,7 @@ public class BubbleStackView extends FrameLayout mMagneticTarget, mIndividualBubbleMagnetListener); - hideImeFromExpandedBubble(); + hideCurrentInputMethod(); // Save the magnetized individual bubble so we can dispatch touch events to it. mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut(); @@ -732,7 +737,8 @@ public class BubbleStackView extends FrameLayout FloatingContentCoordinator floatingContentCoordinator, SysUiState sysUiState, Runnable allBubblesAnimatedOutAction, - Consumer onImeVisibilityChanged) { + Consumer onImeVisibilityChanged, + Runnable hideCurrentInputMethodCallback) { super(context); mBubbleData = data; @@ -868,6 +874,7 @@ public class BubbleStackView extends FrameLayout setUpOverflow(); mOnImeVisibilityChanged = onImeVisibilityChanged; + mHideCurrentInputMethodCallback = hideCurrentInputMethodCallback; setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> { onImeVisibilityChanged.accept(insets.getInsets(WindowInsets.Type.ime()).bottom > 0); @@ -1584,6 +1591,8 @@ public class BubbleStackView extends FrameLayout updatePointerPosition(); if (mIsExpanded) { + hideCurrentInputMethod(); + // Make the container of the expanded view transparent before removing the expanded view // from it. Otherwise a punch hole created by {@link android.view.SurfaceView} in the // expanded view becomes visible on the screen. See b/126856255 @@ -1592,11 +1601,6 @@ public class BubbleStackView extends FrameLayout if (previouslySelected != null) { previouslySelected.setContentVisibility(false); } - if (previouslySelected != null && previouslySelected.getExpandedView() != null) { - // Hide the currently expanded bubble's IME if it's visible before switching - // to a new bubble. - previouslySelected.getExpandedView().hideImeIfVisible(); - } updateExpandedBubble(); requestUpdate(); @@ -1624,6 +1628,8 @@ public class BubbleStackView extends FrameLayout return; } + hideCurrentInputMethod(); + mSysUiState .setFlag(QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED, shouldExpand) .commitUpdate(mContext.getDisplayId()); @@ -1807,12 +1813,12 @@ public class BubbleStackView extends FrameLayout } } - void hideImeFromExpandedBubble() { - if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { - // Hide the currently expanded bubble's IME if it's visible before switching to a new - // bubble. - mExpandedBubble.getExpandedView().hideImeIfVisible(); - } + /** + * Asks the BubbleController to hide the IME from anywhere, whether it's focused on Bubbles or + * not. + */ + void hideCurrentInputMethod() { + mHideCurrentInputMethodCallback.run(); } private void beforeExpandedViewAnimation() { @@ -1927,10 +1933,6 @@ public class BubbleStackView extends FrameLayout mAnimatingOutSurfaceContainer.setScaleX(0f); mAnimatingOutSurfaceContainer.setScaleY(0f); - if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { - mExpandedBubble.getExpandedView().hideImeIfVisible(); - } - // Let the expanded animation controller know that it shouldn't animate child adds/reorders // since we're about to animate collapsed. mExpandedAnimationController.notifyPreparingToCollapse(); diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 4ba58bd259fcd..39e839dfc7e4c 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -52,6 +52,7 @@ import android.view.WindowInsetsController.Appearance; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; @@ -61,6 +62,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.view.AppearanceRegion; import com.android.server.LocalServices; import com.android.server.UiThread; +import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.notification.NotificationDelegate; import com.android.server.policy.GlobalActionsProvider; import com.android.server.power.ShutdownThread; @@ -1401,6 +1403,17 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } } + @Override + public void hideCurrentInputMethodForBubbles() { + final long token = Binder.clearCallingIdentity(); + try { + InputMethodManagerInternal.get().hideCurrentInputMethod( + SoftInputShowHideReason.HIDE_BUBBLES); + } finally { + Binder.restoreCallingIdentity(token); + } + } + @Override public void grantInlineReplyUriPermission(String key, Uri uri, UserHandle user, String packageName) {