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

Commit ac6cde62 authored by Tiger's avatar Tiger
Browse files

Re-land: Update the leash position when gaining a new control

If there is an animation playing, the leash position will be updated
after calling InsetsAnimationControlRunner#updateSurfacePosition in the
next animation frame or the end of animation.

However, if there is no animation playing. The client wouldn't update
the leash position if the surface position of the insets source window
is changed at the server side. This is fine in most of time because the
server will update the leash position. But if the client is playing the
animation while the server is updating the leash position, and then the
client finishes the animation right before receiving the new control,
the position can be overwritten by the client animation.

This CL updates the leash position when the client gains a new control
if there is no leash-animation playing, like we did to the visibility.

The previous attempt would send the control with the new surface
position while waiting for the next draw, so that it caused flickers.
This CL updates the surface position, the leash postion, and the insets
hint together as well as the time to call notifyControlChanged. In this
way, the new surface position won't be leaked to the client before it is
ready to be dispatched.

Bug: 337018949
Bug: 349601805
Flag: EXEMPT bugfix
Test: Turn screen off while the device is unfolded, fold the device,
      and then turn screen on. See if the taskbar position is expected.
Test: InsetsAnimationControlImplTest InsetsControllerTest
      InsetsSourceConsumerTest ViewTest
Change-Id: I2ebe7567f6c3d35eea23b6063718aa5499f2ed20
parent dcc2db21
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.annotation.Nullable;
import android.os.IBinder;
import android.os.Trace;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl.Transaction;
import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;
import android.view.inputmethod.InputMethodManager;
@@ -34,8 +33,6 @@ import android.view.inputmethod.InputMethodManager;
import com.android.internal.inputmethod.ImeTracing;
import com.android.internal.inputmethod.SoftInputShowHideReason;

import java.util.function.Supplier;

/**
 * Controls the visibility and animations of IME window insets source.
 * @hide
@@ -54,10 +51,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
     */
    private boolean mIsRequestedVisibleAwaitingLeash;

    public ImeInsetsSourceConsumer(
            int id, InsetsState state, Supplier<Transaction> transactionSupplier,
            InsetsController controller) {
        super(id, WindowInsets.Type.ime(), state, transactionSupplier, controller);
    public ImeInsetsSourceConsumer(int id, InsetsState state, InsetsController controller) {
        super(id, WindowInsets.Type.ime(), state, controller);
    }

    @Override
+0 −7
Original line number Diff line number Diff line
@@ -53,13 +53,6 @@ public interface InsetsAnimationControlCallbacks {
     */
    void notifyFinished(InsetsAnimationControlRunner runner, boolean shown);

    /**
     * Apply the new params to the surface.
     * @param params The {@link android.view.SyncRtSurfaceTransactionApplier.SurfaceParams} to
     *               apply.
     */
    void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params);

    /**
     * Post a message to release the Surface, guaranteed to happen after all
     * previous calls to applySurfaceParams.
+9 −1
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
    private final @InsetsType int mTypes;
    private @InsetsType int mControllingTypes;
    private final InsetsAnimationControlCallbacks mController;
    private final SurfaceParamsApplier mSurfaceParamsApplier;
    private final WindowInsetsAnimation mAnimation;
    private final long mDurationMs;
    private final Interpolator mInterpolator;
@@ -123,6 +124,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
    public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls,
            @Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
            @InsetsType int types, InsetsAnimationControlCallbacks controller,
            SurfaceParamsApplier surfaceParamsApplier,
            InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            CompatibilityInfo.Translator translator, @Nullable ImeTracker.Token statsToken) {
@@ -131,6 +133,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        mTypes = types;
        mControllingTypes = types;
        mController = controller;
        mSurfaceParamsApplier = surfaceParamsApplier;
        mInitialInsetsState = new InsetsState(state, true /* copySources */);
        if (frame != null) {
            final SparseIntArray idSideMap = new SparseIntArray();
@@ -257,6 +260,11 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        return mAnimationType;
    }

    @Override
    public SurfaceParamsApplier getSurfaceParamsApplier() {
        return mSurfaceParamsApplier;
    }

    @Override
    @Nullable
    public ImeTracker.Token getStatsToken() {
@@ -305,7 +313,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        updateLeashesForSide(SIDE_RIGHT, offset.right, params, outState, mPendingAlpha);
        updateLeashesForSide(SIDE_BOTTOM, offset.bottom, params, outState, mPendingAlpha);

        mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
        mSurfaceParamsApplier.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
        mCurrentInsets = mPendingInsets;
        mAnimation.setFraction(mPendingFraction);
        mCurrentAlpha = mPendingAlpha;
+28 −0
Original line number Diff line number Diff line
@@ -76,6 +76,11 @@ public interface InsetsAnimationControlRunner {
     */
    @AnimationType int getAnimationType();

    /**
     * @return The {@link SurfaceParamsApplier} this runner is using.
     */
    SurfaceParamsApplier getSurfaceParamsApplier();

    /**
     * @return The token tracking the current IME request or {@code null} otherwise.
     */
@@ -99,4 +104,27 @@ public interface InsetsAnimationControlRunner {
     * @param fieldId FieldId of the implementation class
     */
    void dumpDebug(ProtoOutputStream proto, long fieldId);

    /**
     * Interface applying given surface operations.
     */
    interface SurfaceParamsApplier {

        SurfaceParamsApplier DEFAULT = params -> {
            final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            for (int i = params.length - 1; i >= 0; i--) {
                SyncRtSurfaceTransactionApplier.applyParams(t, params[i], new float[9]);
            }
            t.apply();
            t.close();
        };

        /**
         * Apply the new params to the surface.
         *
         * @param params The {@link SyncRtSurfaceTransactionApplier.SurfaceParams} to apply.
         */
        void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params);

    }
}
+23 −19
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.view;

import static android.view.InsetsController.DEBUG;
import static android.view.SyncRtSurfaceTransactionApplier.applyParams;

import android.annotation.Nullable;
import android.annotation.UiThread;
@@ -30,7 +29,6 @@ import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsController.AnimationType;
import android.view.InsetsController.LayoutInsetsDuringAnimation;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;
import android.view.inputmethod.ImeTracker;
@@ -50,8 +48,6 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
    private final InsetsAnimationControlCallbacks mCallbacks =
            new InsetsAnimationControlCallbacks() {

        private final float[] mTmpFloat9 = new float[9];

        @Override
        @UiThread
        public <T extends InsetsAnimationControlRunner & InternalInsetsAnimationController>
@@ -80,19 +76,6 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
                    mOuterCallbacks.notifyFinished(InsetsAnimationThreadControlRunner.this, shown));
        }

        @Override
        public void applySurfaceParams(SurfaceParams... params) {
            if (DEBUG) Log.d(TAG, "applySurfaceParams");
            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            for (int i = params.length - 1; i >= 0; i--) {
                SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i];
                applyParams(t, surfaceParams, mTmpFloat9);
            }
            t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
            t.apply();
            t.close();
        }

        @Override
        public void releaseSurfaceControlFromRt(SurfaceControl sc) {
            if (DEBUG) Log.d(TAG, "releaseSurfaceControlFromRt");
@@ -106,6 +89,22 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
        }
    };

    private SurfaceParamsApplier mSurfaceParamsApplier = new SurfaceParamsApplier() {

        private final float[] mTmpFloat9 = new float[9];

        @Override
        public void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
            final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            for (int i = params.length - 1; i >= 0; i--) {
                SyncRtSurfaceTransactionApplier.applyParams(t, params[i], mTmpFloat9);
            }
            t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
            t.apply();
            t.close();
        }
    };

    @UiThread
    public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls,
            @Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
@@ -117,8 +116,8 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
        mMainThreadHandler = mainThreadHandler;
        mOuterCallbacks = controller;
        mControl = new InsetsAnimationControlImpl(controls, frame, state, listener, types,
                mCallbacks, insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
                translator, statsToken);
                mCallbacks, mSurfaceParamsApplier, insetsAnimationSpec, animationType,
                layoutInsetsDuringAnimation, translator, statsToken);
        InsetsAnimationThread.getHandler().post(() -> {
            if (mControl.isCancelled()) {
                return;
@@ -186,6 +185,11 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
        return mControl.getAnimationType();
    }

    @Override
    public SurfaceParamsApplier getSurfaceParamsApplier() {
        return mSurfaceParamsApplier;
    }

    @Override
    public void updateLayoutInsetsDuringAnimation(
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
Loading