Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f24351f authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

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
parent 9ce13dd2
Loading
Loading
Loading
Loading
+47 −33
Original line number Diff line number Diff line
@@ -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() {
+3 −6
Original line number Diff line number Diff line
@@ -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;
+9 −4
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -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()
Loading