diff options
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; |