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

Commit e1b00c0f authored by Ming-Shin Lu's avatar Ming-Shin Lu Committed by Automerger Merge Worker
Browse files

Merge changes from topic "cherrypick-ime-target-policy-to-applier-0l2tbz7bqd"...

Merge changes from topic "cherrypick-ime-target-policy-to-applier-0l2tbz7bqd" into udc-dev am: 70898897

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21873740



Change-Id: Ifd3ba0351ec9d07a27e77344f6edce12681b548b
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 338fa70d 70898897
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -255,6 +255,12 @@ public final class InputMethodDebug {
                return "HIDE_SOFT_INPUT_IMM_DEPRECATION";
            case SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR:
                return "HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR";
            case SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS:
                return "SHOW_IME_SCREENSHOT_FROM_IMMS";
            case SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS:
                return "REMOVE_IME_SCREENSHOT_FROM_IMMS";
            case SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE:
                return "HIDE_WHEN_INPUT_TARGET_INVISIBLE";
            default:
                return "Unknown=" + reason;
        }
+20 −1
Original line number Diff line number Diff line
@@ -65,7 +65,10 @@ import java.lang.annotation.Retention;
        SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT,
        SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED,
        SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION,
        SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR
        SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR,
        SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS,
        SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS,
        SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE,
})
public @interface SoftInputShowHideReason {
    /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
@@ -259,4 +262,20 @@ public @interface SoftInputShowHideReason {
     */
    int HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR =
            ImeProtoEnums.REASON_HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR;

    /**
     * Shows ime screenshot by {@link com.android.server.inputmethod.InputMethodManagerService}.
     */
    int SHOW_IME_SCREENSHOT_FROM_IMMS = ImeProtoEnums.REASON_SHOW_IME_SCREENSHOT_FROM_IMMS;

    /**
     * Removes ime screenshot by {@link com.android.server.inputmethod.InputMethodManagerService}.
     */
    int REMOVE_IME_SCREENSHOT_FROM_IMMS = ImeProtoEnums.REASON_REMOVE_IME_SCREENSHOT_FROM_IMMS;

    /**
     * Hide soft input when the input target being removed or being obscured by an non-IME
     * focusable overlay window.
     */
    int HIDE_WHEN_INPUT_TARGET_INVISIBLE = ImeProtoEnums.REASON_HIDE_WHEN_INPUT_TARGET_INVISIBLE;
}
+39 −0
Original line number Diff line number Diff line
@@ -18,14 +18,19 @@ package com.android.server.inputmethod;

import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;

import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS;
import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS;
import static com.android.server.EventLogTags.IMF_HIDE_IME;
import static com.android.server.EventLogTags.IMF_SHOW_IME;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_EXPLICIT;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_NOT_ALWAYS;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_REMOVE_IME_SNAPSHOT;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME_IMPLICIT;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME_SNAPSHOT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IBinder;
import android.os.ResultReceiver;
@@ -38,6 +43,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.server.LocalServices;
import com.android.server.wm.ImeTargetVisibilityPolicy;
import com.android.server.wm.WindowManagerInternal;

import java.util.Objects;
@@ -56,10 +62,14 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {

    private final WindowManagerInternal mWindowManagerInternal;

    @NonNull
    private final ImeTargetVisibilityPolicy mImeTargetVisibilityPolicy;


    DefaultImeVisibilityApplier(InputMethodManagerService service) {
        mService = service;
        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
        mImeTargetVisibilityPolicy = LocalServices.getService(ImeTargetVisibilityPolicy.class);
    }

    @GuardedBy("ImfLock.class")
@@ -162,8 +172,37 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
                mService.showCurrentInputLocked(windowToken, statsToken,
                        InputMethodManager.SHOW_IMPLICIT, null, reason);
                break;
            case STATE_SHOW_IME_SNAPSHOT:
                showImeScreenshot(windowToken, mService.getDisplayIdToShowImeLocked(), null);
                break;
            case STATE_REMOVE_IME_SNAPSHOT:
                removeImeScreenshot(mService.getDisplayIdToShowImeLocked());
                break;
            default:
                throw new IllegalArgumentException("Invalid IME visibility state: " + state);
        }
    }

    @GuardedBy("ImfLock.class")
    @Override
    public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
            @Nullable ImeTracker.Token statsToken) {
        if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) {
            mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
                    SHOW_IME_SCREENSHOT_FROM_IMMS, statsToken);
            return true;
        }
        return false;
    }

    @GuardedBy("ImfLock.class")
    @Override
    public boolean removeImeScreenshot(int displayId) {
        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
            mService.onShowHideSoftInputRequested(false /* show */, mService.mCurFocusedWindow,
                    REMOVE_IME_SCREENSHOT_FROM_IMMS, null);
            return true;
        }
        return false;
    }
}
+24 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.inputmethod;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IBinder;
import android.os.ResultReceiver;
@@ -76,4 +77,27 @@ interface ImeVisibilityApplier {
        // TODO: add a method in WindowManagerInternal to call DC#updateImeInputAndControlTarget
        //  here to end up updating IME layering after IMMS#attachNewInputLocked called.
    }

    /**
     * Shows the IME screenshot and attach it to the given IME target window.
     *
     * @param windowToken The token of a window to show the IME screenshot.
     * @param displayId The unique id to identify the display
     * @param statsToken  A token that tracks the progress of an IME request.
     * @return {@code true} if success, {@code false} otherwise.
     */
    default boolean showImeScreenshot(@NonNull IBinder windowToken, int displayId,
            @Nullable ImeTracker.Token statsToken) {
        return false;
    }

    /**
     * Removes the IME screenshot on the given display.
     *
     * @param displayId The target display of showing IME screenshot.
     * @return {@code true} if success, {@code false} otherwise.
     */
    default boolean removeImeScreenshot(int displayId) {
        return false;
    }
}
+53 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFI
import static android.view.WindowManager.LayoutParams.SoftInputModeFlags;

import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString;
import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS;
import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS;
import static com.android.server.inputmethod.InputMethodManagerService.computeImeDisplayIdForTarget;

import android.accessibilityservice.AccessibilityService;
@@ -49,6 +51,7 @@ import android.view.inputmethod.InputMethodManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.server.LocalServices;
import com.android.server.wm.ImeTargetChangeListener;
import com.android.server.wm.WindowManagerInternal;

import java.io.PrintWriter;
@@ -99,6 +102,18 @@ public final class ImeVisibilityStateComputer {
     */
    private boolean mInputShown;

    /**
     * Set if we called
     * {@link com.android.server.wm.ImeTargetVisibilityPolicy#showImeScreenshot(IBinder, int)}.
     */
    private boolean mRequestedImeScreenshot;

    /** The window token of the current visible IME layering target overlay. */
    private IBinder mCurVisibleImeLayeringOverlay;

    /** The window token of the current visible IME input target. */
    private IBinder mCurVisibleImeInputTarget;

    /** Represent the invalid IME visibility state */
    public static final int STATE_INVALID = -1;

@@ -122,6 +137,10 @@ public final class ImeVisibilityStateComputer {
    public static final int STATE_HIDE_IME_NOT_ALWAYS = 6;

    public static final int STATE_SHOW_IME_IMPLICIT = 7;

    /** State to handle removing an IME preview surface when necessary. */
    public static final int STATE_REMOVE_IME_SNAPSHOT = 8;

    @IntDef({
            STATE_INVALID,
            STATE_HIDE_IME,
@@ -132,6 +151,7 @@ public final class ImeVisibilityStateComputer {
            STATE_HIDE_IME_EXPLICIT,
            STATE_HIDE_IME_NOT_ALWAYS,
            STATE_SHOW_IME_IMPLICIT,
            STATE_REMOVE_IME_SNAPSHOT,
    })
    @interface VisibilityState {}

@@ -172,6 +192,24 @@ public final class ImeVisibilityStateComputer {
        mWindowManagerInternal = wmService;
        mImeDisplayValidator = imeDisplayValidator;
        mPolicy = imePolicy;
        mWindowManagerInternal.setInputMethodTargetChangeListener(new ImeTargetChangeListener() {
            @Override
            public void onImeTargetOverlayVisibilityChanged(IBinder overlayWindowToken,
                    boolean visible, boolean removed) {
                mCurVisibleImeLayeringOverlay = (visible && !removed) ? overlayWindowToken : null;
            }

            @Override
            public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
                    boolean visibleRequested, boolean removed) {
                mCurVisibleImeInputTarget = (visibleRequested && !removed) ? imeInputTarget : null;
                if (mCurVisibleImeInputTarget == null && mCurVisibleImeLayeringOverlay != null) {
                    mService.onApplyImeVisibilityFromComputer(imeInputTarget,
                            new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT,
                                    SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE));
                }
            }
        });
    }

    /**
@@ -453,6 +491,21 @@ public final class ImeVisibilityStateComputer {
        return null;
    }

    @VisibleForTesting
    ImeVisibilityResult onInteractiveChanged(IBinder windowToken, boolean interactive) {
        final ImeTargetWindowState state = getWindowStateOrNull(windowToken);
        if (state != null && state.isRequestedImeVisible() && mInputShown && !interactive) {
            mRequestedImeScreenshot = true;
            return new ImeVisibilityResult(STATE_SHOW_IME_SNAPSHOT, SHOW_IME_SCREENSHOT_FROM_IMMS);
        }
        if (interactive && mRequestedImeScreenshot) {
            mRequestedImeScreenshot = false;
            return new ImeVisibilityResult(STATE_REMOVE_IME_SNAPSHOT,
                    REMOVE_IME_SCREENSHOT_FROM_IMMS);
        }
        return null;
    }

    IBinder getWindowTokenFrom(IBinder requestImeToken) {
        for (IBinder windowToken : mRequestWindowStateMap.keySet()) {
            final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
Loading