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

Commit 5b9145bd authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Cleanup IME screenshot references

Some IME screenshot methods were referring to removing the IME surface,
when in reality they were removing the IME screenshot.

This also renamed the ImeVisibilityStateComputer#onInteractiveChanged to
shouldShowImeScreenshot to better reflect the actual usage, rather than
the reason for calling it. Lastly, this decouples the IME screenshot
from applyImeVisibility into applyImeScreenshotVisibility.

Flag: EXEMPT cleanup
Bug: 281029564
Test: atest DefaultImeVisibilityApplierTest ImeVisibilityStateComputerTest
  DisplayContentTests
  ZOrderingTests
  Showing the IME screenshot (switching apps, turning the screen off and
  then on)
Change-Id: I01ff035db1cddcd3158dc90d6b04f07b32e75313
parent 8d5731f0
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -2067,7 +2067,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if ((types & ime()) != 0) {
        if ((types & ime()) != 0) {
            final InsetsSourceControl imeControl = mImeSourceConsumer.getControl();
            final InsetsSourceControl imeControl = mImeSourceConsumer.getControl();
            // Skip showing animation once that made by system for some reason.
            // 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) {
            if (imeControl != null) {
                skipsAnim = imeControl.getAndClearSkipAnimationOnce() && show
                skipsAnim = imeControl.getAndClearSkipAnimationOnce() && show
                        && mImeSourceConsumer.hasViewFocusWhenWindowFocusGain();
                        && mImeSourceConsumer.hasViewFocusWhenWindowFocusGain();
+3 −3
Original line number Original line Diff line number Diff line
@@ -234,12 +234,12 @@ public class StartingSurfaceDrawerTests extends ShellTestCase {
        }) {
        }) {
            when(TaskSnapshotWindow.create(eq(windowInfo), eq(mBinder), eq(snapshot), any(),
            when(TaskSnapshotWindow.create(eq(windowInfo), eq(mBinder), eq(snapshot), any(),
                    any())).thenReturn(mockSnapshotWindow);
                    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);
            mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, snapshot);
            waitHandlerIdle(mTestHandler);
            waitHandlerIdle(mTestHandler);


            // Verify the task snapshot with IME snapshot will be removed when received the real IME
            // Verify the task snapshot with hasImeSurface will be removed when receiving the
            // drawn callback.
            // callback that the real IME was drawn.
            // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new
            // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new
            // StartingWindowRecord for the task.
            // StartingWindowRecord for the task.
            mStartingSurfaceDrawer.onImeDrawnOnTask(1);
            mStartingSurfaceDrawer.onImeDrawnOnTask(1);
+40 −29
Original line number Original line 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 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_HIDE_IME;
import static com.android.server.EventLogTags.IMF_SHOW_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.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;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_EXPLICIT;
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_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;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME_IMPLICIT;
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.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.os.IBinder;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.os.ResultReceiver;
@@ -44,6 +39,7 @@ import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodManager;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.protolog.ProtoLog;
@@ -164,7 +160,7 @@ final class DefaultImeVisibilityApplier {
     * @param userId      the target user when applying the IME visibility state
     * @param userId      the target user when applying the IME visibility state
     */
     */
    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
    void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
            @ImeVisibilityStateComputer.VisibilityState int state,
            @ImeVisibilityStateComputer.VisibilityState int state,
            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
        final var userData = mService.getUserData(userId);
        final var userData = mService.getUserData(userId);
@@ -224,50 +220,65 @@ final class DefaultImeVisibilityApplier {
                            null /* resultReceiver */, reason, userId);
                            null /* resultReceiver */, reason, userId);
                }
                }
                break;
                break;
            case STATE_SHOW_IME_SNAPSHOT:
                showImeScreenshot(windowToken, displayIdToShowIme, userId);
                break;
            case STATE_REMOVE_IME_SNAPSHOT:
                removeImeScreenshot(displayIdToShowIme, userId);
                break;
            default:
            default:
                throw new IllegalArgumentException("Invalid IME visibility state: " + state);
                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 imeTarget the token of the IME target window.
     * @param displayId   the unique id to identify the display
     * @param show      whether to show or remove the screenshot.
     * @param userId      the target user when when showing the IME screenshot
     * @param userId    the ID of the user to apply the screenshot visibility for.
     * @return {@code true} if success, {@code false} otherwise
     */
     */
    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
    void applyImeScreenshotVisibility(IBinder imeTarget, boolean show, @UserIdInt int userId) {
            @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)) {
        if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) {
            mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
            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 true;
        }
        }
        return false;
        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 imeTarget the token of the IME target window.
     * @param userId    the target user of showing IME screenshot
     * @param displayId the ID of the display to remove the screenshot from.
     * @return {@code true} if success, {@code false} otherwise
     * @param userId    the ID of the user to remove the screenshot for.
     * @return {@code true} if successful, {@code false} otherwise.
     */
     */
    @VisibleForTesting
    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    boolean removeImeScreenshot(int displayId, @UserIdInt int userId) {
    boolean removeImeScreenshot(IBinder imeTarget, int displayId, @UserIdInt int userId) {
        final var userData = mService.getUserData(userId);
        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
            mService.onShowHideSoftInputRequested(false /* show */,
            mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
                    userData.mImeBindingState.mFocusedWindow,
                    SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */,
                    REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId);
                    userId);
            return true;
            return true;
        }
        }
        return false;
        return false;
+17 −19
Original line number Original line 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 android.view.WindowManager.LayoutParams.SoftInputModeFlags;


import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString;
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.ImeProtoLogGroup.IME_VIS_STATE_COMPUTER_DEBUG;
import static com.android.server.inputmethod.InputMethodManagerService.computeImeDisplayIdForTarget;
import static com.android.server.inputmethod.InputMethodManagerService.computeImeDisplayIdForTarget;


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


    /**
    /**
     * Set if we called
     * Set if we called {@link com.android.server.wm.ImeTargetVisibilityPolicy#showImeScreenshot}.
     * {@link com.android.server.wm.ImeTargetVisibilityPolicy#showImeScreenshot(IBinder, int)}.
     */
     */
    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    private boolean mRequestedImeScreenshot;
    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.  */
    /** State to handle showing the IME window with making the overlay window behind it.  */
    public static final int STATE_SHOW_IME_BEHIND_OVERLAY = 3;
    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_HIDE_IME_EXPLICIT = 4;
    public static final int STATE_SHOW_IME_SNAPSHOT = 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 = 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({
    @IntDef({
            STATE_INVALID,
            STATE_INVALID,
@@ -175,11 +166,9 @@ public final class ImeVisibilityStateComputer {
            STATE_SHOW_IME,
            STATE_SHOW_IME,
            STATE_SHOW_IME_ABOVE_OVERLAY,
            STATE_SHOW_IME_ABOVE_OVERLAY,
            STATE_SHOW_IME_BEHIND_OVERLAY,
            STATE_SHOW_IME_BEHIND_OVERLAY,
            STATE_SHOW_IME_SNAPSHOT,
            STATE_HIDE_IME_EXPLICIT,
            STATE_HIDE_IME_EXPLICIT,
            STATE_HIDE_IME_NOT_ALWAYS,
            STATE_HIDE_IME_NOT_ALWAYS,
            STATE_SHOW_IME_IMPLICIT,
            STATE_SHOW_IME_IMPLICIT,
            STATE_REMOVE_IME_SNAPSHOT,
    })
    })
    @interface VisibilityState {}
    @interface VisibilityState {}


@@ -613,17 +602,26 @@ public final class ImeVisibilityStateComputer {
        return null;
        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")
    @GuardedBy("ImfLock.class")
    ImeVisibilityResult onInteractiveChanged(IBinder windowToken, boolean interactive) {
    Boolean shouldShowImeScreenshot(IBinder windowToken, boolean interactive) {
        final ImeTargetWindowState state = getWindowStateOrNull(windowToken);
        final ImeTargetWindowState state = getWindowStateOrNull(windowToken);
        if (state != null && state.isRequestedImeVisible() && mInputShown && !interactive) {
        if (state != null && state.isRequestedImeVisible() && mInputShown && !interactive) {
            mRequestedImeScreenshot = true;
            mRequestedImeScreenshot = true;
            return new ImeVisibilityResult(STATE_SHOW_IME_SNAPSHOT, SHOW_IME_SCREENSHOT_FROM_IMMS);
            return true;
        }
        }
        if (interactive && mRequestedImeScreenshot) {
        if (interactive && mRequestedImeScreenshot) {
            mRequestedImeScreenshot = false;
            mRequestedImeScreenshot = false;
            return new ImeVisibilityResult(STATE_REMOVE_IME_SNAPSHOT,
            return false;
                    REMOVE_IME_SCREENSHOT_FROM_IMMS);
        }
        }
        return null;
        return null;
    }
    }
+6 −8
Original line number Original line Diff line number Diff line
@@ -5189,16 +5189,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            }
            }
            if (mImePlatformCompatUtils.shouldUseSetInteractiveProtocol(
            if (mImePlatformCompatUtils.shouldUseSetInteractiveProtocol(
                    bindingController.getCurMethodUid())) {
                    bindingController.getCurMethodUid())) {
                // Handle IME visibility when interactive changed before finishing the input to
                // Apply IME screenshot visibility before notifying the client, as it could dismiss
                // ensure we preserve the last state as possible.
                // the IME.
                final var visibilityStateComputer = userData.mVisibilityStateComputer;
                final var visibilityStateComputer = userData.mVisibilityStateComputer;
                final ImeVisibilityResult imeVisRes = visibilityStateComputer.onInteractiveChanged(
                final Boolean showScreenshot = visibilityStateComputer.shouldShowImeScreenshot(
                        userData.mImeBindingState.mFocusedWindow, interactive);
                        userData.mImeBindingState.mFocusedWindow, interactive);
                if (imeVisRes != null) {
                if (showScreenshot != null) {
                    // Pass in a null statsToken as the IME snapshot is not tracked by ImeTracker.
                    mVisibilityApplier.applyImeScreenshotVisibility(
                    mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
                            userData.mImeBindingState.mFocusedWindow, showScreenshot, userId);
                            null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason(),
                            userId);
                }
                }
                // Eligible IME processes use new "setInteractive" protocol.
                // Eligible IME processes use new "setInteractive" protocol.
                userData.mCurClient.mClient.setInteractive(mIsInteractive,
                userData.mCurClient.mClient.setInteractive(mIsInteractive,
Loading