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

Commit f36e0727 authored by Cosmin Băieș's avatar Cosmin Băieș Committed by Android (Google) Code Review
Browse files

Merge "Cleanup IME screenshot references" into main

parents e2e8ecbf 5b9145bd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2065,7 +2065,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if ((types & ime()) != 0) {
            final InsetsSourceControl imeControl = mImeSourceConsumer.getControl();
            // Skip showing animation once that made by system for some reason.
            // (e.g. starting window with IME snapshot)
            // (e.g. starting window with hasImeSurface)
            if (imeControl != null) {
                skipsAnim = imeControl.getAndClearSkipAnimationOnce() && show
                        && mImeSourceConsumer.hasViewFocusWhenWindowFocusGain();
+3 −3
Original line number Diff line number Diff line
@@ -234,12 +234,12 @@ public class StartingSurfaceDrawerTests extends ShellTestCase {
        }) {
            when(TaskSnapshotWindow.create(eq(windowInfo), eq(mBinder), eq(snapshot), any(),
                    any())).thenReturn(mockSnapshotWindow);
            // Simulate a task snapshot window created with IME snapshot shown.
            // Simulate a task snapshot window created with hasImeSurface.
            mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, snapshot);
            waitHandlerIdle(mTestHandler);

            // Verify the task snapshot with IME snapshot will be removed when received the real IME
            // drawn callback.
            // Verify the task snapshot with hasImeSurface will be removed when receiving the
            // callback that the real IME was drawn.
            // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new
            // StartingWindowRecord for the task.
            mStartingSurfaceDrawer.onImeDrawnOnTask(1);
+40 −29
Original line number Diff line number Diff line
@@ -18,21 +18,16 @@ 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.ImeProtoLogGroup.IME_VISIBILITY_APPLIER_DEBUG;
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.annotation.UserIdInt;
import android.os.IBinder;
import android.os.ResultReceiver;
@@ -44,6 +39,7 @@ import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodManager;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.protolog.ProtoLog;
@@ -164,7 +160,7 @@ final class DefaultImeVisibilityApplier {
     * @param userId      the target user when applying the IME visibility state
     */
    @GuardedBy("ImfLock.class")
    void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
    void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
            @ImeVisibilityStateComputer.VisibilityState int state,
            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
        final var userData = mService.getUserData(userId);
@@ -224,50 +220,65 @@ final class DefaultImeVisibilityApplier {
                            null /* resultReceiver */, reason, userId);
                }
                break;
            case STATE_SHOW_IME_SNAPSHOT:
                showImeScreenshot(windowToken, displayIdToShowIme, userId);
                break;
            case STATE_REMOVE_IME_SNAPSHOT:
                removeImeScreenshot(displayIdToShowIme, userId);
                break;
            default:
                throw new IllegalArgumentException("Invalid IME visibility state: " + state);
        }
    }

    /**
     * Shows the IME screenshot and attach it to the given IME target window.
     * Applies the IME screenshot visibility on the given IME target window.
     *
     * @param imeTarget   the token of a window to show the IME screenshot
     * @param displayId   the unique id to identify the display
     * @param userId      the target user when when showing the IME screenshot
     * @return {@code true} if success, {@code false} otherwise
     * @param imeTarget the token of the IME target window.
     * @param show      whether to show or remove the screenshot.
     * @param userId    the ID of the user to apply the screenshot visibility for.
     */
    @GuardedBy("ImfLock.class")
    boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
            @UserIdInt int userId) {
    void applyImeScreenshotVisibility(IBinder imeTarget, boolean show, @UserIdInt int userId) {
        final var userData = mService.getUserData(userId);
        final var bindingController = userData.mBindingController;
        final int displayId = bindingController.getDisplayIdToShowIme();
        if (show) {
            showImeScreenshot(imeTarget, displayId, userId);
        } else {
            removeImeScreenshot(imeTarget, displayId, userId);
        }
    }

    /**
     * Shows the IME screenshot and attaches it to the given IME target window.
     *
     * @param imeTarget the token of the IME target window.
     * @param displayId the ID of the display to show the screenshot on.
     * @param userId    the ID of the user to show the screenshot for.
     * @return {@code true} if successful, {@code false} otherwise.
     */
    @VisibleForTesting
    @GuardedBy("ImfLock.class")
    boolean showImeScreenshot(IBinder imeTarget, int displayId, @UserIdInt int userId) {
        if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) {
            mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
                    SHOW_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId);
                    SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */,
                    userId);
            return true;
        }
        return false;
    }

    /**
     * Removes the IME screenshot on the given display.
     * Removes the IME screenshot from the given display.
     *
     * @param displayId the target display of showing IME screenshot
     * @param userId    the target user of showing IME screenshot
     * @return {@code true} if success, {@code false} otherwise
     * @param imeTarget the token of the IME target window.
     * @param displayId the ID of the display to remove the screenshot from.
     * @param userId    the ID of the user to remove the screenshot for.
     * @return {@code true} if successful, {@code false} otherwise.
     */
    @VisibleForTesting
    @GuardedBy("ImfLock.class")
    boolean removeImeScreenshot(int displayId, @UserIdInt int userId) {
        final var userData = mService.getUserData(userId);
    boolean removeImeScreenshot(IBinder imeTarget, int displayId, @UserIdInt int userId) {
        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
            mService.onShowHideSoftInputRequested(false /* show */,
                    userData.mImeBindingState.mFocusedWindow,
                    REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId);
            mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
                    SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */,
                    userId);
            return true;
        }
        return false;
+17 −19
Original line number Diff line number Diff line
@@ -30,8 +30,6 @@ 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.ImeProtoLogGroup.IME_VIS_STATE_COMPUTER_DEBUG;
import static com.android.server.inputmethod.InputMethodManagerService.computeImeDisplayIdForTarget;

@@ -119,8 +117,7 @@ public final class ImeVisibilityStateComputer {
    private boolean mInputShown;

    /**
     * Set if we called
     * {@link com.android.server.wm.ImeTargetVisibilityPolicy#showImeScreenshot(IBinder, int)}.
     * Set if we called {@link com.android.server.wm.ImeTargetVisibilityPolicy#showImeScreenshot}.
     */
    @GuardedBy("ImfLock.class")
    private boolean mRequestedImeScreenshot;
@@ -157,17 +154,11 @@ public final class ImeVisibilityStateComputer {
    /** State to handle showing the IME window with making the overlay window behind it.  */
    public static final int STATE_SHOW_IME_BEHIND_OVERLAY = 3;

    /** State to handle showing an IME preview surface during the app was loosing the IME focus */
    public static final int STATE_SHOW_IME_SNAPSHOT = 4;
    public static final int STATE_HIDE_IME_EXPLICIT = 4;

    public static final int STATE_HIDE_IME_EXPLICIT = 5;
    public static final int STATE_HIDE_IME_NOT_ALWAYS = 5;

    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;
    public static final int STATE_SHOW_IME_IMPLICIT = 6;

    @IntDef({
            STATE_INVALID,
@@ -175,11 +166,9 @@ public final class ImeVisibilityStateComputer {
            STATE_SHOW_IME,
            STATE_SHOW_IME_ABOVE_OVERLAY,
            STATE_SHOW_IME_BEHIND_OVERLAY,
            STATE_SHOW_IME_SNAPSHOT,
            STATE_HIDE_IME_EXPLICIT,
            STATE_HIDE_IME_NOT_ALWAYS,
            STATE_SHOW_IME_IMPLICIT,
            STATE_REMOVE_IME_SNAPSHOT,
    })
    @interface VisibilityState {}

@@ -613,17 +602,26 @@ public final class ImeVisibilityStateComputer {
        return null;
    }

    /**
     * Checks if we should show or hide the IME screenshot, based on the given IME target window and
     * the interactive state.
     *
     * @param windowToken the token of the {@link ImeTargetWindowState} to check.
     * @param interactive whether the system is currently interactive.
     * @return {@code true} if the screenshot should be shown, {@code false} if it should be hidden,
     * or {@code null} if it should remain unchanged.
     */
    @Nullable
    @GuardedBy("ImfLock.class")
    ImeVisibilityResult onInteractiveChanged(IBinder windowToken, boolean interactive) {
    Boolean shouldShowImeScreenshot(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);
            return true;
        }
        if (interactive && mRequestedImeScreenshot) {
            mRequestedImeScreenshot = false;
            return new ImeVisibilityResult(STATE_REMOVE_IME_SNAPSHOT,
                    REMOVE_IME_SCREENSHOT_FROM_IMMS);
            return false;
        }
        return null;
    }
+6 −8
Original line number Diff line number Diff line
@@ -5177,16 +5177,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            }
            if (mImePlatformCompatUtils.shouldUseSetInteractiveProtocol(
                    bindingController.getCurMethodUid())) {
                // Handle IME visibility when interactive changed before finishing the input to
                // ensure we preserve the last state as possible.
                // Apply IME screenshot visibility before notifying the client, as it could dismiss
                // the IME.
                final var visibilityStateComputer = userData.mVisibilityStateComputer;
                final ImeVisibilityResult imeVisRes = visibilityStateComputer.onInteractiveChanged(
                final Boolean showScreenshot = visibilityStateComputer.shouldShowImeScreenshot(
                        userData.mImeBindingState.mFocusedWindow, interactive);
                if (imeVisRes != null) {
                    // Pass in a null statsToken as the IME snapshot is not tracked by ImeTracker.
                    mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
                            null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason(),
                            userId);
                if (showScreenshot != null) {
                    mVisibilityApplier.applyImeScreenshotVisibility(
                            userData.mImeBindingState.mFocusedWindow, showScreenshot, userId);
                }
                // Eligible IME processes use new "setInteractive" protocol.
                userData.mCurClient.mClient.setInteractive(mIsInteractive,
Loading