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

Commit a61b3ca0 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Polish IME insets not provided for non-IME target in split-screen

As in CL[1] we introduced AR#mImeInsetsFrozenUntilStartInput in
InsetsPolicy#adjustVisibilityForIme to temporary freeze the IME insets
visibility with the requested IME visiblity to deliver to the client
until the next input started.

The reason is when app transitioning, the next true IME visiblity
requires the next focused app to start the input connection and
updates the IME input target to WM.

We also made CL[2] to improve the IME flicker when quick-switching
from the fullscreen app to the split-screen task. However, we are
not aware mImeInsetsFrozenUntilStartInput only unfreezes the IME
insets when the target window is input target, this breaks when in
split-screen landscape mode, the adjecent non-IME target task
will not get the latest IME insets and the app size will not be
resized by ADJECENT_RESIZE if IME was visible.

Also, during switching to split-screen task from an IME shown task in
the overview screen in landscape, mImeInsetsFrozenUntilStartInput will
set to false when AR#onResize called during reparenting to split-screen
task, that will seeing a flicker by dispatching IME visible insets to
the next client too early.

To fix those problems with

1) In ImeInsetsSourceProvider#updateClientVisiblity ensure setting
   mImeInsetsFrozenUntilStartInput as false for all
   activities when they are going to visible after the new target
   updated the IME client visiblity. In case non-IME target window
   still freezes the IME insets.

2) Remove unset mImeInsetsFrozenUntilStartInput to false logic in
   AR#onResize and AR#onParentChanged, since these logic may happen
   before the new input started to make IME insets unfrozen
   unexpectedly.
3) Remove InputTarget#unfreezeInsetsAfterStartInput since it's useless
   after 1)'s change.

[1]: Id8a56c68a06a774ef12ba444fd9a368148ea4539
[2]: I332c0e4fff62df5d7b793eda2767bb58fe85a938

Fix: 257351983
Test: atest ActivityRecordTests#\
       testImeInsetsFrozenFlag_multiWindowActivities
Change-Id: I9fe8440ea111be59bd36dea4637a486c0f9f233f
parent e09d61ca
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -726,6 +726,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    /**
     * When set to true, the IME insets will be frozen until the next app becomes IME input target.
     * @see InsetsPolicy#adjustVisibilityForIme
     * @see ImeInsetsSourceProvider#updateClientVisibility
     */
    boolean mImeInsetsFrozenUntilStartInput;

@@ -1576,7 +1577,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (newParent != null) {
            if (isState(RESUMED)) {
                newParent.setResumedActivity(this, "onParentChanged");
                mImeInsetsFrozenUntilStartInput = false;
            }
            mLetterboxUiController.onActivityParentChanged(newParent);
        }
@@ -8848,13 +8848,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    @Override
    void onResize() {
        // Reset freezing IME insets flag when the activity resized.
        mImeInsetsFrozenUntilStartInput = false;
        super.onResize();
    }

    private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
            Rect containingBounds) {
        return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
+28 −4
Original line number Diff line number Diff line
@@ -4510,11 +4510,35 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                            mImeWindowsContainer.getParent().mSurfaceControl));
            updateImeControlTarget(forceUpdateImeParent);
        }
        // Unfreeze IME insets after the new target updated, in case updateAboveInsetsState may
        // deliver unrelated IME insets change to the non-IME requester.
        if (target != null) {
            target.unfreezeInsetsAfterStartInput();
    }

    /**
     * Callback from {@link ImeInsetsSourceProvider#updateClientVisibility} for the system to
     * judge whether or not to notify the IME insets provider to dispatch this reported IME client
     * visibility state to the app clients when needed.
     */
    boolean onImeInsetsClientVisibilityUpdate() {
        boolean[] changed = new boolean[1];

        // Unlike the IME layering target or the control target can be updated during the layout
        // change, the IME input target requires to be changed after gaining the input focus.
        // In case unfreezing IME insets state may too early during IME focus switching, we unfreeze
        // when activities going to be visible until the input target changed, or the
        // activity was the current input target that has to unfreeze after updating the IME
        // client visibility.
        final ActivityRecord inputTargetActivity =
                mImeInputTarget != null ? mImeInputTarget.getActivityRecord() : null;
        final boolean targetChanged = mImeInputTarget != mLastImeInputTarget;
        if (targetChanged || inputTargetActivity != null && inputTargetActivity.isVisibleRequested()
                && inputTargetActivity.mImeInsetsFrozenUntilStartInput) {
            forAllActivities(r -> {
                if (r.mImeInsetsFrozenUntilStartInput && r.isVisibleRequested()) {
                    r.mImeInsetsFrozenUntilStartInput = false;
                    changed[0] = true;
                }
            });
        }
        return changed[0];
    }

    void updateImeControlTarget() {
+0 −4
Original line number Diff line number Diff line
@@ -334,10 +334,6 @@ class EmbeddedWindowController {
            return true;
        }

        @Override
        public void unfreezeInsetsAfterStartInput() {
        }

        @Override
        public InsetsControlTarget getImeControlTarget() {
            return mWmService.getDefaultDisplayContentLocked().mRemoteInsetsControlTarget;
+4 −0
Original line number Diff line number Diff line
@@ -140,10 +140,14 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider

    @Override
    protected boolean updateClientVisibility(InsetsControlTarget caller) {
        if (caller != getControlTarget()) {
            return false;
        }
        boolean changed = super.updateClientVisibility(caller);
        if (changed && caller.isRequestedVisible(mSource.getType())) {
            reportImeDrawnForOrganizer(caller);
        }
        changed |= mDisplayContent.onImeInsetsClientVisibilityUpdate();
        return changed;
    }

+1 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.server.wm;

import android.view.IWindow;
import android.util.proto.ProtoOutputStream;
import android.view.IWindow;

/**
 * Common interface between focusable objects.
@@ -58,7 +58,6 @@ interface InputTarget {
    boolean canScreenshotIme();

    ActivityRecord getActivityRecord();
    void unfreezeInsetsAfterStartInput();

    boolean isInputMethodClientFocus(int uid, int pid);

Loading