diff options
| author | 2023-03-06 12:35:49 +0100 | |
|---|---|---|
| committer | 2023-06-14 17:17:42 +0200 | |
| commit | 9f24351f4affb52bdc94fe865d851d0ab6f5a260 (patch) | |
| tree | 74a512e2714906dd7c3135277e581b0a95f1185e | |
| parent | 9ce13dd292932c89c09a0931aec865c4353508f8 (diff) | |
Cleanup IME window visibility flag logic
Cache last reported imeWindowVisibility value in IME to avoid sending
duplicate IPC calls
Remove updates to imeWindowVisibility that were not needed
Handle imeWindowVisibility updates when a service disconnects (e.g. when
the currently shown IME is being updated/uninstalled)
Test: observe navigation bar behaviour when showing/hiding IME in
different apps, when rotating the screen with IME shown,
when in split screen, when switching between IMEs, and when
updating/uninstalling the IME that is currently visible
Bug: 271816203
Change-Id: I7980a68bca22009c364a635e557214da2ccf7fa9
15 files changed, 152 insertions, 110 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index a9c4818393a8..2f9c2073cd38 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -52,8 +52,6 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; -import static java.lang.annotation.RetentionPolicy.SOURCE; - import android.annotation.AnyThread; import android.annotation.CallSuper; import android.annotation.DrawableRes; @@ -160,6 +158,7 @@ import com.android.internal.inputmethod.InputMethodNavButtonFlags; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry; import com.android.internal.inputmethod.SoftInputShowHideReason; +import com.android.internal.util.Preconditions; import com.android.internal.util.RingBuffer; import org.xmlpull.v1.XmlPullParserException; @@ -482,43 +481,53 @@ public class InputMethodService extends AbstractInputMethodService { public static final int BACK_DISPOSITION_ADJUST_NOTHING = 3; /** - * Enum flag to be used for {@link #setBackDisposition(int)}. + * Enum values to be used for {@link #setBackDisposition(int)}. * * @hide */ - @Retention(SOURCE) - @IntDef(value = {BACK_DISPOSITION_DEFAULT, BACK_DISPOSITION_WILL_NOT_DISMISS, - BACK_DISPOSITION_WILL_DISMISS, BACK_DISPOSITION_ADJUST_NOTHING}, - prefix = "BACK_DISPOSITION_") + @IntDef(prefix = { "BACK_DISPOSITION_" }, value = { + BACK_DISPOSITION_DEFAULT, + BACK_DISPOSITION_WILL_NOT_DISMISS, + BACK_DISPOSITION_WILL_DISMISS, + BACK_DISPOSITION_ADJUST_NOTHING, + }) + @Retention(RetentionPolicy.SOURCE) public @interface BackDispositionMode {} /** + * Enum flags to be used for {@link #setImeWindowStatus}, representing the current state of the + * IME window visibility. + * * @hide - * The IME is active. It may or may not be visible. */ - public static final int IME_ACTIVE = 0x1; + @IntDef(flag = true, prefix = { "IME_" }, value = { + IME_ACTIVE, + IME_VISIBLE, + IME_VISIBLE_IMPERCEPTIBLE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImeWindowVisibility {} /** + * The IME is active. It may or may not be visible. * @hide - * The IME is perceptibly visible to the user. */ - public static final int IME_VISIBLE = 0x2; + public static final int IME_ACTIVE = 0x1; /** + * The IME is perceptibly visible to the user. * @hide - * The IME is active and ready with views but set invisible. - * This flag cannot be combined with {@link #IME_VISIBLE}. */ - public static final int IME_INVISIBLE = 0x4; + public static final int IME_VISIBLE = 0x2; /** - * @hide * The IME is visible, but not yet perceptible to the user (e.g. fading in) * by {@link android.view.WindowInsetsController}. * * @see InputMethodManager#reportPerceptible + * @hide */ - public static final int IME_VISIBLE_IMPERCEPTIBLE = 0x8; + public static final int IME_VISIBLE_IMPERCEPTIBLE = 0x4; // Min and max values for back disposition. private static final int BACK_DISPOSITION_MIN = BACK_DISPOSITION_DEFAULT; @@ -631,9 +640,18 @@ public class InputMethodService extends AbstractInputMethodService { int mStatusIcon; + /** + * Latest value reported of back disposition mode. + */ @BackDispositionMode int mBackDisposition; + /** + * Latest value reported of IME window visibility flags. + */ + @ImeWindowVisibility + private int mImeWindowVisibility; + private Object mLock = new Object(); @GuardedBy("mLock") private boolean mNotifyUserActionSent; @@ -1210,8 +1228,14 @@ public class InputMethodService extends AbstractInputMethodService { mImeSurfaceRemoverRunnable = null; } - private void setImeWindowStatus(int visibilityFlags, int backDisposition) { - mPrivOps.setImeWindowStatusAsync(visibilityFlags, backDisposition); + private void setImeWindowStatus(@ImeWindowVisibility int vis, + @BackDispositionMode int backDisposition) { + if (vis == mImeWindowVisibility && backDisposition == mBackDisposition) { + return; + } + mImeWindowVisibility = Preconditions.checkFlagsArgument(vis, IME_ACTIVE | IME_VISIBLE); + mBackDisposition = backDisposition; + mPrivOps.setImeWindowStatusAsync(mImeWindowVisibility, mBackDisposition); } /** Set region of the keyboard to be avoided from back gesture */ @@ -1885,15 +1909,11 @@ public class InputMethodService extends AbstractInputMethodService { * @param disposition disposition mode to be set */ public void setBackDisposition(@BackDispositionMode int disposition) { - if (disposition == mBackDisposition) { - return; - } - if (disposition > BACK_DISPOSITION_MAX || disposition < BACK_DISPOSITION_MIN) { + if (disposition < BACK_DISPOSITION_MIN || disposition > BACK_DISPOSITION_MAX) { Log.e(TAG, "Invalid back disposition value (" + disposition + ") specified."); return; } - mBackDisposition = disposition; - setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); + setImeWindowStatus(mImeWindowVisibility, disposition); } /** @@ -2867,14 +2887,8 @@ public class InputMethodService extends AbstractInputMethodService { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow"); mDecorViewWasVisible = mDecorViewVisible; mInShowWindow = true; - final int previousImeWindowStatus = - (mDecorViewVisible ? IME_ACTIVE : 0) | (isInputViewShown() - ? (!mWindowVisible ? IME_INVISIBLE : IME_VISIBLE) : 0); startViews(prepareWindow(showInput)); - final int nextImeWindowStatus = mapToImeWindowStatus(); - if (previousImeWindowStatus != nextImeWindowStatus) { - setImeWindowStatus(nextImeWindowStatus, mBackDisposition); - } + setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); mNavigationBarController.onWindowShown(); // compute visibility @@ -4085,9 +4099,9 @@ public class InputMethodService extends AbstractInputMethodService { }; } + @ImeWindowVisibility private int mapToImeWindowStatus() { - return IME_ACTIVE - | (isInputViewShown() ? IME_VISIBLE : 0); + return IME_ACTIVE | (mDecorViewVisible ? IME_VISIBLE : 0); } private boolean isAutomotive() { diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java index 66e3333acf7c..1a3804900665 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java @@ -20,6 +20,7 @@ import android.annotation.AnyThread; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; +import android.inputmethodservice.InputMethodService; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; @@ -105,14 +106,10 @@ public final class InputMethodPrivilegedOperations { * * @param vis visibility flags * @param backDisposition disposition flags - * @see android.inputmethodservice.InputMethodService#IME_ACTIVE - * @see android.inputmethodservice.InputMethodService#IME_VISIBLE - * @see android.inputmethodservice.InputMethodService#IME_INVISIBLE - * @see android.inputmethodservice.InputMethodService#BACK_DISPOSITION_DEFAULT - * @see android.inputmethodservice.InputMethodService#BACK_DISPOSITION_ADJUST_NOTHING */ @AnyThread - public void setImeWindowStatusAsync(int vis, int backDisposition) { + public void setImeWindowStatusAsync(@InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition) { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java index 4f827cda6afa..8b9a9913183d 100644 --- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java @@ -16,6 +16,7 @@ package com.android.internal.statusbar; +import android.inputmethodservice.InputMethodService; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -31,7 +32,9 @@ public final class RegisterStatusBarResult implements Parcelable { public final int mDisabledFlags1; // switch[0] public final int mAppearance; // switch[1] public final AppearanceRegion[] mAppearanceRegions; // switch[2] + @InputMethodService.ImeWindowVisibility public final int mImeWindowVis; // switch[3] + @InputMethodService.BackDispositionMode public final int mImeBackDisposition; // switch[4] public final boolean mShowImeSwitcher; // switch[5] public final int mDisabledFlags2; // switch[6] @@ -44,10 +47,12 @@ public final class RegisterStatusBarResult implements Parcelable { public final LetterboxDetails[] mLetterboxDetails; public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1, - int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis, - int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, IBinder imeToken, - boolean navbarColorManagedByIme, int behavior, int requestedVisibleTypes, - String packageName, int transientBarTypes, LetterboxDetails[] letterboxDetails) { + int appearance, AppearanceRegion[] appearanceRegions, + @InputMethodService.ImeWindowVisibility int imeWindowVis, + @InputMethodService.BackDispositionMode int imeBackDisposition, boolean showImeSwitcher, + int disabledFlags2, IBinder imeToken, boolean navbarColorManagedByIme, int behavior, + int requestedVisibleTypes, String packageName, int transientBarTypes, + LetterboxDetails[] letterboxDetails) { mIcons = new ArrayMap<>(icons); mDisabledFlags1 = disabledFlags1; mAppearance = appearance; diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java index 751a3f8458bd..2e6c485336f3 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java @@ -104,7 +104,8 @@ public class Utilities { * @return updated set of flags from InputMethodService based off {@param oldHints} * Leaves original hints unmodified */ - public static int calculateBackDispositionHints(int oldHints, int backDisposition, + public static int calculateBackDispositionHints(int oldHints, + @InputMethodService.BackDispositionMode int backDisposition, boolean imeShown, boolean showImeSwitcher) { int hints = oldHints; switch (backDisposition) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 8225c47d904b..99c591f25edb 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -462,7 +462,7 @@ public final class NavBarHelper implements * @return Whether the IME is shown on top of the screen given the {@code vis} flag of * {@link InputMethodService} and the keyguard states. */ - public boolean isImeShown(int vis) { + public boolean isImeShown(@InputMethodService.ImeWindowVisibility int vis) { View shadeWindowView = mNotificationShadeWindowController.getWindowRootView(); boolean isKeyguardShowing = mKeyguardStateController.isShowing(); boolean imeVisibleOnShade = shadeWindowView != null && shadeWindowView.isAttachedToWindow() diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 682335e0b419..5bae1cba4ac4 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -66,6 +66,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.inputmethodservice.InputMethodService; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -1047,8 +1048,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements // ----- CommandQueue Callbacks ----- @Override - public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, boolean showImeSwitcher) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index b96ca7ac2961..e6fab1b1eb44 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -339,8 +339,9 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, } @Override - public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, - boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, boolean showImeSwitcher) { boolean imeShown = mNavBarHelper.isImeShown(vis); if (!imeShown) { // Count imperceptible changes as visible so we transition taskbar out quickly. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index a532195c5b9f..6c2c0cf12aad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar; import static android.app.StatusBarManager.DISABLE2_NONE; import static android.app.StatusBarManager.DISABLE_NONE; import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; -import static android.inputmethodservice.InputMethodService.IME_INVISIBLE; import static android.view.Display.INVALID_DISPLAY; import android.annotation.Nullable; @@ -37,7 +36,7 @@ import android.hardware.biometrics.IBiometricContextListener; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; -import android.inputmethodservice.InputMethodService.BackDispositionMode; +import android.inputmethodservice.InputMethodService; import android.media.INearbyMediaDevicesProvider; import android.media.MediaRoute2Info; import android.os.Binder; @@ -226,8 +225,10 @@ public class CommandQueue extends IStatusBar.Stub implements * @param backDisposition Disposition mode of back button. It should be one of below flags: * @param showImeSwitcher {@code true} to show IME switch button. */ - default void setImeWindowStatus(int displayId, IBinder token, int vis, - @BackDispositionMode int backDisposition, boolean showImeSwitcher) { } + default void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, + boolean showImeSwitcher) { } default void showRecentApps(boolean triggeredFromAltTab) { } default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } default void toggleTaskbar() { } @@ -678,7 +679,9 @@ public class CommandQueue extends IStatusBar.Stub implements } @Override - public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, + public void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, boolean showImeSwitcher) { synchronized (mLock) { mHandler.removeMessages(MSG_SHOW_IME_BUTTON); @@ -1092,7 +1095,9 @@ public class CommandQueue extends IStatusBar.Stub implements } } - private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, + private void handleShowImeButton(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, boolean showImeSwitcher) { if (displayId == INVALID_DISPLAY) return; @@ -1112,7 +1117,7 @@ public class CommandQueue extends IStatusBar.Stub implements private void sendImeInvisibleStatusForPrevNavBar() { for (int i = 0; i < mCallbacks.size(); i++) { mCallbacks.get(i).setImeWindowStatus(mLastUpdatedImeDisplayId, - null /* token */, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, + null /* token */, 0 /* vis */, BACK_DISPOSITION_DEFAULT, false /* showImeSwitcher */); } } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 5144d1966222..4c7e6b007f38 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -334,8 +334,10 @@ public final class WMShell implements } @Override - public void setImeWindowStatus(int displayId, IBinder token, int vis, - int backDisposition, boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, + boolean showImeSwitcher) { if (displayId == mDisplayTracker.getDefaultDisplayId() && (vis & InputMethodService.IME_VISIBLE) != 0) { oneHanded.stopOneHanded( diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 25d494cee5e8..697d1a3b775c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -20,7 +20,6 @@ import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT; import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN; import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN; import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; -import static android.inputmethodservice.InputMethodService.IME_INVISIBLE; import static android.inputmethodservice.InputMethodService.IME_VISIBLE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; @@ -364,7 +363,7 @@ public class NavigationBarTest extends SysuiTestCase { externalNavBar.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null, IME_VISIBLE, BACK_DISPOSITION_DEFAULT, true); defaultNavBar.setImeWindowStatus( - DEFAULT_DISPLAY, null, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, false); + DEFAULT_DISPLAY, null, 0 /* vis */, BACK_DISPOSITION_DEFAULT, false); // Verify IME window state will be updated in external NavBar & default NavBar state reset. assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN | NAVIGATION_HINT_IME_SWITCHER_SHOWN, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index 1643e174ee13..385d556092a6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; -import static android.inputmethodservice.InputMethodService.IME_INVISIBLE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT; @@ -201,7 +200,7 @@ public class CommandQueueTest extends SysuiTestCase { mCommandQueue.setImeWindowStatus(SECONDARY_DISPLAY, null, 1, 2, true); waitForIdleSync(); - verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(null), eq(IME_INVISIBLE), + verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(null), eq(0), eq(BACK_DISPOSITION_DEFAULT), eq(false)); verify(mCallbacks).setImeWindowStatus( eq(SECONDARY_DISPLAY), eq(null), eq(1), eq(2), eq(true)); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java index ba9e280be49d..b0b1d676bc4b 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java @@ -352,6 +352,7 @@ final class InputMethodBindingController { clearCurMethodAndSessions(); mService.clearInputShownLocked(); mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME); + mService.resetSystemUiLocked(); } } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 57f8d1478905..8c137e2eb44c 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -633,8 +633,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private InputMethodSubtype mCurrentSubtype; /** - * {@code true} if the IME has not been mostly hidden via {@link android.view.InsetsController} + * {@code true} if the IME has not been mostly hidden via {@link android.view.InsetsController}. */ + @GuardedBy("ImfLock.class") private boolean mCurPerceptible; /** @@ -748,33 +749,26 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub SparseArray<AccessibilitySessionState> mEnabledAccessibilitySessions = new SparseArray<>(); /** - * True if the device is currently interactive with user. The value is true initially. + * {@code true} if the device is currently interactive with the user, initially true. + * + * @see #handleSetInteractive */ + @GuardedBy("ImfLock.class") boolean mIsInteractive = true; + @GuardedBy("ImfLock.class") + @InputMethodService.BackDispositionMode int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; /** - * A set of status bits regarding the active IME. + * The {@link InputMethodService.ImeWindowVisibility} of the currently bound IME, + * or {@code 0} if no IME is bound. * - * <p>This value is a combination of following two bits:</p> - * <dl> - * <dt>{@link InputMethodService#IME_ACTIVE}</dt> - * <dd> - * If this bit is ON, connected IME is ready to accept touch/key events. - * </dd> - * <dt>{@link InputMethodService#IME_VISIBLE}</dt> - * <dd> - * If this bit is ON, some of IME view, e.g. software input, candidate view, is visible. - * </dd> - * <dt>{@link InputMethodService#IME_INVISIBLE}</dt> - * <dd> If this bit is ON, IME is ready with views from last EditorInfo but is - * currently invisible. - * </dd> - * </dl> - * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and + * <p><em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and * {@link InputMethodBindingController#unbindCurrentMethod()}.</em> */ + @GuardedBy("ImfLock.class") + @InputMethodService.ImeWindowVisibility int mImeWindowVis; private LocaleList mLastSystemLocales; @@ -1535,7 +1529,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Uh oh, current input method is no longer around! // Pick another one... Slog.i(TAG, "Current input method removed: " + curInputMethodId); - updateSystemUiLocked(0 /* vis */, mBackDisposition); if (!chooseNewDefaultIMELocked()) { changed = true; curIm = null; @@ -2938,7 +2931,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub sessionState.mSession.finishSession(); } catch (RemoteException e) { Slog.w(TAG, "Session failed to close due to remote exception", e); - updateSystemUiLocked(0 /* vis */, mBackDisposition); } sessionState.mSession = null; } @@ -3048,15 +3040,15 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("ImfLock.class") - private boolean shouldShowImeSwitcherLocked(int visibility) { + private boolean shouldShowImeSwitcherLocked( + @InputMethodService.ImeWindowVisibility int visibility) { if (!mShowOngoingImeSwitcherForPhones) return false; if (mMenuController.getSwitchingDialogLocked() != null) return false; if (mWindowManagerInternal.isKeyguardShowingAndNotOccluded() && mWindowManagerInternal.isKeyguardSecure(mSettings.getCurrentUserId())) { return false; } - if ((visibility & InputMethodService.IME_ACTIVE) == 0 - || (visibility & InputMethodService.IME_INVISIBLE) != 0) { + if ((visibility & InputMethodService.IME_ACTIVE) == 0) { return false; } if (mWindowManagerInternal.isHardKeyboardAvailable()) { @@ -3115,7 +3107,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @SuppressWarnings("deprecation") - private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition) { + private void setImeWindowStatus(@NonNull IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition) { final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId(); synchronized (ImfLock.class) { @@ -3132,7 +3126,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } mImeWindowVis = vis; mBackDisposition = backDisposition; - updateSystemUiLocked(vis, backDisposition); + updateSystemUiLocked(mImeWindowVis, mBackDisposition); } final boolean dismissImeOnBackKeyPressed; @@ -3167,37 +3161,46 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private void updateImeWindowStatus(boolean disableImeIcon) { synchronized (ImfLock.class) { - if (disableImeIcon) { - updateSystemUiLocked(0, mBackDisposition); - } else { - updateSystemUiLocked(); - } + // TODO(b/285109020): disableImeIcon should be stored in a property like + // mIsSwitcherIconDisabled, but it is currently not reliably cleared. + updateSystemUiLocked(disableImeIcon ? 0 : mImeWindowVis, mBackDisposition); } } @GuardedBy("ImfLock.class") void updateSystemUiLocked() { + // This is only used by InputMethodMenuController to trigger the IME switcher icon + // visibility, by having {@code shouldShowImeSwitcherLocked} called, which depends on the + // visibility of the IME switcher dialog. updateSystemUiLocked(mImeWindowVis, mBackDisposition); } // Caution! This method is called in this class. Handle multi-user carefully @GuardedBy("ImfLock.class") - private void updateSystemUiLocked(int vis, int backDisposition) { + private void updateSystemUiLocked(@InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition) { if (getCurTokenLocked() == null) { return; } if (DEBUG) { Slog.d(TAG, "IME window vis: " + vis - + " active: " + (vis & InputMethodService.IME_ACTIVE) - + " inv: " + (vis & InputMethodService.IME_INVISIBLE) + + " active: " + ((vis & InputMethodService.IME_ACTIVE) != 0) + + " visible: " + ((vis & InputMethodService.IME_VISIBLE) != 0) + + " backDisposition: " + backDisposition + + " isInteractive: " + mIsInteractive + + " curPerceptible: " + mCurPerceptible + " displayId: " + mCurTokenDisplayId); } // TODO: Move this clearing calling identity block to setImeWindowStatus after making sure - // all updateSystemUi happens on system privilege. + // all updateSystemUi happens on system privilege. final long ident = Binder.clearCallingIdentity(); try { - if (!mCurPerceptible) { + if (!mIsInteractive) { + // When we are not interactive, + // the visibility should be 0 (no IME icons should be shown). + vis = 0; + } else if (!mCurPerceptible) { if ((vis & InputMethodService.IME_VISIBLE) != 0) { vis &= ~InputMethodService.IME_VISIBLE; vis |= InputMethodService.IME_VISIBLE_IMPERCEPTIBLE; @@ -3527,7 +3530,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub return; } mCurPerceptible = perceptible; - updateSystemUiLocked(); + updateSystemUiLocked(mImeWindowVis, mBackDisposition); } }); } @@ -5089,8 +5092,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private void handleSetInteractive(final boolean interactive) { synchronized (ImfLock.class) { + if (mIsInteractive == interactive) { + return; + } mIsInteractive = interactive; - updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition); + updateSystemUiLocked(mImeWindowVis, mBackDisposition); // Inform the current client of the change in active status if (mCurClient == null || mCurClient.mClient == null) { @@ -6725,7 +6731,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @Override - public void setImeWindowStatusAsync(int vis, int backDisposition) { + public void setImeWindowStatusAsync(@InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition) { mImms.setImeWindowStatus(mToken, vis, backDisposition); } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index efd8b6d9a943..6e9a22c7872b 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -19,6 +19,7 @@ package com.android.server.statusbar; import android.annotation.Nullable; import android.app.ITransientNotificationCallback; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; +import android.inputmethodservice.InputMethodService; import android.os.Bundle; import android.os.IBinder; import android.view.WindowInsets.Type.InsetsType; @@ -54,13 +55,13 @@ public interface StatusBarManagerInternal { * @param displayId The display to which the IME is bound to. * @param token The IME token. * @param vis Bit flags about the IME visibility. - * (e.g. {@link android.inputmethodservice.InputMethodService#IME_ACTIVE}) * @param backDisposition Bit flags about the IME back disposition. - * (e.g. {@link android.inputmethodservice.InputMethodService#BACK_DISPOSITION_DEFAULT}) * @param showImeSwitcher {@code true} when the IME switcher button should be shown. */ - void setImeWindowStatus(int displayId, IBinder token, int vis, - int backDisposition, boolean showImeSwitcher); + void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, + boolean showImeSwitcher); /** * See {@link android.app.StatusBarManager#setIcon(String, int, int, String)}. diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 044d30b368da..719b2d2f0355 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -59,6 +59,7 @@ import android.hardware.biometrics.PromptInfo; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; +import android.inputmethodservice.InputMethodService; import android.media.INearbyMediaDevicesProvider; import android.media.MediaRoute2Info; import android.net.Uri; @@ -516,7 +517,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, + public void setImeWindowStatus(int displayId, IBinder token, + @InputMethodService.ImeWindowVisibility int vis, + @InputMethodService.BackDispositionMode int backDisposition, boolean showImeSwitcher) { StatusBarManagerService.this.setImeWindowStatus(displayId, token, vis, backDisposition, showImeSwitcher); @@ -1221,12 +1224,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void setImeWindowStatus(int displayId, final IBinder token, final int vis, - final int backDisposition, final boolean showImeSwitcher) { + public void setImeWindowStatus(int displayId, final IBinder token, + @InputMethodService.ImeWindowVisibility final int vis, + @InputMethodService.BackDispositionMode final int backDisposition, + final boolean showImeSwitcher) { enforceStatusBar(); if (SPEW) { - Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition); + Slog.d(TAG, "setImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition); } synchronized(mLock) { @@ -1289,7 +1294,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D private String mPackageName = "none"; private int mDisabled1 = 0; private int mDisabled2 = 0; + @InputMethodService.ImeWindowVisibility private int mImeWindowVis = 0; + @InputMethodService.BackDispositionMode private int mImeBackDisposition = 0; private boolean mShowImeSwitcher = false; private IBinder mImeToken = null; @@ -1334,7 +1341,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D return mDisabled1 == disabled1 && mDisabled2 == disabled2; } - private void setImeWindowState(final int vis, final int backDisposition, + private void setImeWindowState(@InputMethodService.ImeWindowVisibility final int vis, + @InputMethodService.BackDispositionMode final int backDisposition, final boolean showImeSwitcher, final IBinder token) { mImeWindowVis = vis; mImeBackDisposition = backDisposition; |