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

Commit 183c8252 authored by Simranjit Kohli's avatar Simranjit Kohli
Browse files

[Improve fill dialog] Get IME updates to autofill

Autofill Fill Dialog (aka Bottomsheet dialog) should show up after
IME animation finishes.  Currently, the bottomsheet may start
popping up simultaneously as the IME is animating. This change lays
the foundation to provide autofill service the information about the
start and end of IME animation. This will help autofill to make
informed results to hold up animating Bottomsheet till the IME
animation completes.

This change only handles insets generated on the client side.

Test: atest WmTests:WindowManagerServiceTests
      Manually verify autofill logs on recieving animation updates.
Flag: android.service.autofill.improve_fill_dialog_aconfig
Bug: 390528373
Change-Id: I00965976cd4fd62faf95de4720584273a18faea3
parent 84319ceb
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1146,6 +1146,14 @@ interface IWindowManager
     */
    KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId);

    /*
     * Notifies about IME insets animation.
     *
     * @param running Indicates the insets animation state.
     * @param animationType Indicates the {@link InsetsController.AnimationType}
     */
     oneway void notifyImeInsetsAnimationStateChanged(boolean running, int animationType);

    /**
     * Returns whether the display with {@code displayId} ignores orientation request.
     */
+12 −11
Original line number Diff line number Diff line
@@ -214,9 +214,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
         * Notifies when the state of running animation is changed. The state is either "running" or
         * "idle".
         *
         * @param running {@code true} if there is any animation running; {@code false} otherwise.
         * @param running       {@code true} if the given insets types start running
         *                      {@code false} otherwise.
         * @param animationType {@link AnimationType}
         * @param insetsTypes   {@link Type}.
         */
        default void notifyAnimationRunningStateChanged(boolean running) {}
        default void notifyAnimationRunningStateChanged(boolean running,
                @AnimationType int animationType, @InsetsType int insetsTypes) {
        }

        /** @see ViewRootImpl#isHandlingPointerEvent */
        default boolean isHandlingPointerEvent() {
@@ -744,9 +749,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
                            mFrame, mFromState, mToState, RESIZE_INTERPOLATOR,
                            ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
                    if (mRunningAnimations.isEmpty()) {
                        mHost.notifyAnimationRunningStateChanged(true);
                    }
                    mHost.notifyAnimationRunningStateChanged(true,
                            runner.getAnimationType(), mTypes);
                    mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType()));
                }
            };
@@ -1560,9 +1564,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            }
        }
        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
        if (mRunningAnimations.isEmpty()) {
            mHost.notifyAnimationRunningStateChanged(true);
        }
        mHost.notifyAnimationRunningStateChanged(true, animationType, types);
        mRunningAnimations.add(new RunningAnimation(runner, animationType));
        if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
                + useInsetsAnimationThread);
@@ -1842,9 +1844,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                break;
            }
        }
        if (mRunningAnimations.isEmpty()) {
            mHost.notifyAnimationRunningStateChanged(false);
        }
        mHost.notifyAnimationRunningStateChanged(
                false, control.getAnimationType(), removedTypes);
        onAnimationStateChanged(removedTypes, false /* running */);
    }

+44 −9
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
import static android.os.Trace.TRACE_TAG_VIEW;
import static android.service.autofill.Flags.improveFillDialogAconfig;
import static android.util.SequenceUtils.getInitSeq;
import static android.util.SequenceUtils.isIncomingSeqStale;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -922,6 +923,8 @@ public final class ViewRootImpl implements ViewParent,
    private boolean mInsetsAnimationRunning;
    private int mInsetsAnimatingTypes = 0;
    private long mPreviousFrameDrawnTime = -1;
    // The largest view size percentage to the display size. Used on trace to collect metric.
    private float mLargestChildPercentage = 0.0f;
@@ -2520,20 +2523,52 @@ public final class ViewRootImpl implements ViewParent,
     * Notify the when the running state of a insets animation changed.
     */
    @VisibleForTesting
    public void notifyInsetsAnimationRunningStateChanged(boolean running) {
    public void notifyInsetsAnimationRunningStateChanged(boolean running,
            @InsetsController.AnimationType int animationType,
            @InsetsType int insetsTypes) {
        @InsetsType int previousInsetsType = mInsetsAnimatingTypes;
        // If improveFillDialogAconfig is disabled, we notify WindowSession of all the updates we
        // receive here
        boolean notifyWindowSession = !improveFillDialogAconfig();
        if (running) {
            mInsetsAnimatingTypes |= insetsTypes;
        } else {
            mInsetsAnimatingTypes &= ~insetsTypes;
        }
        if (sToolkitSetFrameRateReadOnlyFlagValue) {
            mInsetsAnimationRunning = running;
            // If improveFillDialogAconfig is enabled, we need to confirm other animations aren't
            // running to maintain the existing behavior. System server were notified previously
            // only when animation started running or stopped when there were no running animations.
            if (improveFillDialogAconfig()) {
                if ((previousInsetsType == 0 && mInsetsAnimatingTypes != 0)
                        || (previousInsetsType != 0 && mInsetsAnimatingTypes == 0)) {
                    notifyWindowSession = true;
                }
            }
            if (notifyWindowSession) {
                if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                    Trace.instant(Trace.TRACE_TAG_VIEW,
                            TextUtils.formatSimple("notifyInsetsAnimationRunningStateChanged(%s)",
                                    Boolean.toString(running)));
                }
            mInsetsAnimationRunning = running;
                try {
                    mWindowSession.notifyInsetsAnimationRunningStateChanged(mWindow, running);
                } catch (RemoteException e) {
                }
            }
        }
        if (improveFillDialogAconfig()) {
            // Update WindowManager for ImeAnimation
            if ((insetsTypes & WindowInsets.Type.ime()) != 0) {
                try {
                    WindowManagerGlobal.getWindowManagerService()
                            .notifyImeInsetsAnimationStateChanged(running, animationType);
                } catch (RemoteException e) {
                }
            }
        }
    }
    @Override
    public void requestLayout() {
+5 −2
Original line number Diff line number Diff line
@@ -275,9 +275,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
    }

    @Override
    public void notifyAnimationRunningStateChanged(boolean running) {
    public void notifyAnimationRunningStateChanged(boolean running,
            @InsetsController.AnimationType int animationType,
            @WindowInsets.Type.InsetsType int insetsTypes) {
        if (mViewRoot != null) {
            mViewRoot.notifyInsetsAnimationRunningStateChanged(running);
            mViewRoot.notifyInsetsAnimationRunningStateChanged(
                    running, animationType, insetsTypes);
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -1054,7 +1054,8 @@ public class ViewRootImplTest {
        ViewRootImpl viewRootImpl = mView.getViewRootImpl();
        sInstrumentation.runOnMainSync(() -> {
            mView.invalidate();
            viewRootImpl.notifyInsetsAnimationRunningStateChanged(true);
            viewRootImpl.notifyInsetsAnimationRunningStateChanged(true, 0 /* animationType */,
                    0 /* insetsTypes */  /* areOtherAnimationsRunning */);
            mView.invalidate();
        });
        sInstrumentation.waitForIdleSync();
Loading