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

Commit 6d0d7695 authored by Tiger's avatar Tiger
Browse files

Prevent changing mFromState during insets resize animation

This CL uses a new InsetsState as the mFromState, instead of using
mLastDispatchedState. So when mLastDispatchedState is chaged, the
mFromState in InsetsResizeAnimationRunner won't be affected.

The change can also improve the efficiency when iterating the sources in
InsetsResizeAnimationRunner#applyChangeInsets, because the mFromState
only contains necessary insets sources now.

Fix: 343412265
Test: atest InsetsControllerTest
Change-Id: Ib9217ad5cdfc912bc7a7cfaf772d585e3f249649
parent 2767bf3c
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -706,11 +706,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            new InsetsState.OnTraverseCallbacks() {
            new InsetsState.OnTraverseCallbacks() {


                private @InsetsType int mTypes;
                private @InsetsType int mTypes;
                private InsetsState mFromState;
                private InsetsState mToState;
                private InsetsState mToState;


                @Override
                @Override
                public void onStart(InsetsState state1, InsetsState state2) {
                public void onStart(InsetsState state1, InsetsState state2) {
                    mTypes = 0;
                    mTypes = 0;
                    mFromState = null;
                    mToState = null;
                    mToState = null;
                }
                }


@@ -727,9 +729,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        return;
                        return;
                    }
                    }
                    mTypes |= source1.getType();
                    mTypes |= source1.getType();
                    if (mFromState == null) {
                        mFromState = new InsetsState();
                    }
                    if (mToState == null) {
                    if (mToState == null) {
                        mToState = new InsetsState();
                        mToState = new InsetsState();
                    }
                    }
                    mFromState.addSource(new InsetsSource(source1));
                    mToState.addSource(new InsetsSource(source2));
                    mToState.addSource(new InsetsSource(source2));
                }
                }


@@ -740,7 +746,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    }
                    }
                    cancelExistingControllers(mTypes);
                    cancelExistingControllers(mTypes);
                    final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
                    final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
                            mFrame, state1, mToState, RESIZE_INTERPOLATOR,
                            mFrame, mFromState, mToState, RESIZE_INTERPOLATOR,
                            ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
                            ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
                    if (mRunningAnimations.isEmpty()) {
                    if (mRunningAnimations.isEmpty()) {
                        mHost.notifyAnimationRunningStateChanged(true);
                        mHost.notifyAnimationRunningStateChanged(true);
+39 −5
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@ import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;


@@ -52,6 +53,9 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;


import static java.util.concurrent.TimeUnit.SECONDS;

import android.annotation.NonNull;
import android.content.Context;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Point;
@@ -80,6 +84,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.InOrder;
import org.mockito.Mockito;
import org.mockito.Mockito;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;


/**
/**
@@ -668,30 +674,58 @@ public class InsetsControllerTest {
    }
    }


    @Test
    @Test
    public void testResizeAnimation_withFlagAnimateResizing() {
    public void testResizeAnimation_withFlagAnimateResizing() throws InterruptedException {
        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
        final int id = ID_NAVIGATION_BAR;
        final int id = ID_NAVIGATION_BAR;
        final @InsetsType int type = navigationBars();
        final @InsetsType int type = navigationBars();
        final int fromInsetsHeight = 50;
        final int toInsetsHeight = 60;
        final ArrayList<WindowInsets> progressList = new ArrayList<>();
        final CountDownLatch animationEndLatch = new CountDownLatch(1);
        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            final InsetsState state1 = new InsetsState();
            final InsetsState state1 = new InsetsState();
            state1.getOrCreateSource(id, type)
            state1.getOrCreateSource(id, type)
                    .setVisible(true)
                    .setVisible(true)
                    .setFrame(0, 0, 500, 50)
                    .setFrame(0, 0, 500, fromInsetsHeight)
                    .setFlags(FLAG_ANIMATE_RESIZING, FLAG_ANIMATE_RESIZING);
                    .setFlags(FLAG_ANIMATE_RESIZING, FLAG_ANIMATE_RESIZING);
            final InsetsState state2 = new InsetsState(state1, true /* copySources */);
            final InsetsState state2 = new InsetsState(state1, true /* copySources */);
            state2.peekSource(id).setFrame(0, 0, 500, 60);
            state2.peekSource(id).setFrame(0, 0, 500, toInsetsHeight);


            // New insets source won't cause the resize animation.
            // New insets source won't cause the resize animation.
            mController.onStateChanged(state1);
            mController.onStateChanged(state1);
            assertEquals("There must not be resize animation.", ANIMATION_TYPE_NONE,
            assertEquals("There must not be resize animation.", ANIMATION_TYPE_NONE,
                    mController.getAnimationType(type));
                    mController.getAnimationType(type));


            mViewRoot.getView().setWindowInsetsAnimationCallback(
                    new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
                        @Override
                        public WindowInsets onProgress(
                                @NonNull WindowInsets insets,
                                @NonNull List<WindowInsetsAnimation> runningAnimations) {
                            progressList.add(insets);
                            return insets;
                        }

                        @Override
                        public void onEnd(@NonNull WindowInsetsAnimation animation) {
                            animationEndLatch.countDown();
                        }
                    });

            // Changing frame of the source with FLAG_ANIMATE_RESIZING will cause the resize
            // Changing frame of the source with FLAG_ANIMATE_RESIZING will cause the resize
            // animation.
            // animation.
            mController.onStateChanged(state2);
            mController.onStateChanged(state2);
            assertEquals("There must be resize animation.", ANIMATION_TYPE_RESIZE,
            assertEquals("There must be resize animation.", ANIMATION_TYPE_RESIZE,
                    mController.getAnimationType(type));
                    mController.getAnimationType(type));

            mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
        });
        });
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        assertTrue("Animation must be ended.", animationEndLatch.await(3, SECONDS));
        assertEquals("The first insets height must be the same as `fromInsetsHeight`",
                fromInsetsHeight, progressList.get(0).getInsets(type).top);
        assertEquals("The last insets height must be the same as `toInsetsHeight`",
                toInsetsHeight, progressList.get(progressList.size() - 1).getInsets(type).top);
    }
    }


    @Test
    @Test