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

Commit 6ef6e744 authored by Vadim Caen's avatar Vadim Caen Committed by Automerger Merge Worker
Browse files

Merge "Ensure no animation is run except for HOME" into tm-dev am: 87a1c2dd am: 3c3c58c3

parents d0612658 3c3c58c3
Loading
Loading
Loading
Loading
+6 −70
Original line number Diff line number Diff line
@@ -19,9 +19,6 @@ package com.android.wm.shell.back;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
@@ -223,14 +220,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont

    private void initAnimation(MotionEvent event) {
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "initAnimation mMotionStarted=%b", mBackGestureStarted);
        if (mBackGestureStarted) {
        if (mBackGestureStarted || mBackNavigationInfo != null) {
            Log.e(TAG, "Animation is being initialized but is already started.");
            return;
        }

        if (mBackNavigationInfo != null) {
            finishAnimation();
        }

        mInitTouchLocation.set(event.getX(), event.getY());
        mBackGestureStarted = true;

@@ -304,8 +298,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            return;
        }
        int deltaX = Math.round(event.getX() - mInitTouchLocation.x);
        int deltaY = Math.round(event.getY() - mInitTouchLocation.y);
        ProtoLog.v(WM_SHELL_BACK_PREVIEW, "Runner move: %d %d", deltaX, deltaY);
        float progressThreshold = PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
        float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
        int backType = mBackNavigationInfo.getType();
@@ -317,11 +309,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            targetCallback = mBackToLauncherCallback;
        } else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
                || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
            if (animationTarget != null) {
                mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
                mTouchEventDelta.set(deltaX, deltaY);
                mTransaction.apply();
            }
            // TODO(208427216) Run the actual animation
        } else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
            targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
        }
@@ -343,19 +331,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        } else {
            dispatchOnBackCancelled(targetCallback);
        }
        if (backType == BackNavigationInfo.TYPE_CALLBACK) {
            finishAnimation();
        } else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
                && !shouldDispatchToLauncher) {
        if (backType != BackNavigationInfo.TYPE_RETURN_TO_HOME || !shouldDispatchToLauncher) {
            // Launcher callback missing. Simply finish animation.
            finishAnimation();
        } else if (backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY
                || backType == BackNavigationInfo.TYPE_CROSS_TASK) {
            if (mTriggerBack) {
                prepareTransition();
            } else {
                resetPositionAnimated();
            }
        }
    }

@@ -403,8 +381,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }
    }

    private static void dispatchOnBackProgressed(
            IOnBackInvokedCallback callback, BackEvent backEvent) {
    private static void dispatchOnBackProgressed(IOnBackInvokedCallback callback,
            BackEvent backEvent) {
        if (callback == null) {
            return;
        }
@@ -415,48 +393,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }
    }

    /**
     * Animate the top window leash to its initial position.
     */
    private void resetPositionAnimated() {
        mBackGestureStarted = false;
        // TODO(208786853) Handle overlap with a new coming gesture.
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Runner: Back not triggered, cancelling animation "
                + "mLastPos=%s mInitTouch=%s", mTouchEventDelta, mInitTouchLocation);

        // TODO(208427216) : Replace placeholder animation with an actual one.
        ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f).setDuration(200);
        animation.addUpdateListener(animation1 -> {
            if (mBackNavigationInfo == null) {
                return;
            }
            float fraction = animation1.getAnimatedFraction();
            int deltaX = Math.round(mTouchEventDelta.x - (mTouchEventDelta.x * fraction));
            int deltaY = Math.round(mTouchEventDelta.y - (mTouchEventDelta.y * fraction));
            RemoteAnimationTarget animationTarget =
                    mBackNavigationInfo.getDepartingAnimationTarget();
            if (animationTarget != null) {
                mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
                mTransaction.apply();
            }
        });

        animation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: onAnimationEnd");
                finishAnimation();
            }
        });
        animation.start();
    }

    private void prepareTransition() {
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "prepareTransition()");
        mTriggerBack = false;
        mBackGestureStarted = false;
    }

    /**
     * Sets to true when the back gesture has passed the triggering threshold, false otherwise.
     */
+48 −1
Original line number Diff line number Diff line
@@ -16,10 +16,16 @@

package com.android.wm.shell.back;

import static android.window.BackNavigationInfo.KEY_TRIGGER_BACK;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.app.IActivityTaskManager;
@@ -101,6 +107,14 @@ public class BackAnimationControllerTest {
        }
    }

    private void createNavigationInfo(BackNavigationInfo.Builder builder) {
        try {
            doReturn(builder.build()).when(mActivityTaskManager).startBackNavigation();
        } catch (RemoteException ex) {
            ex.rethrowFromSystemServer();
        }
    }

    RemoteAnimationTarget createAnimationTarget() {
        SurfaceControl topWindowLeash = new SurfaceControl();
        return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
@@ -109,6 +123,18 @@ public class BackAnimationControllerTest {
                true, null, null, null, false, -1);
    }

    private void triggerBackGesture() {
        MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
        mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);

        event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0);
        mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);

        mController.setTriggerBack(true);
        event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_UP, 100, 100, 0);
        mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
    }

    @Test
    @Ignore("b/207481538")
    public void crossActivity_screenshotAttachedAndVisible() {
@@ -140,10 +166,31 @@ public class BackAnimationControllerTest {
                MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
                MotionEvent.ACTION_MOVE,
                BackEvent.EDGE_LEFT);
        verify(mTransaction).setPosition(animationTarget.leash, 100, 100);
        // b/207481538, we check that the surface is not moved for now, we can re-enable this once
        // we implement the animation
        verify(mTransaction, never()).setScale(eq(screenshotSurface), anyInt(), anyInt());
        verify(mTransaction, never()).setPosition(animationTarget.leash, 100, 100);
        verify(mTransaction, atLeastOnce()).apply();
    }

    @Test
    public void verifyAnimationFinishes() {
        RemoteAnimationTarget animationTarget = createAnimationTarget();
        boolean[] backNavigationDone = new boolean[]{false};
        boolean[] triggerBack = new boolean[]{false};
        createNavigationInfo(new BackNavigationInfo.Builder()
                .setDepartingAnimationTarget(animationTarget)
                .setType(BackNavigationInfo.TYPE_CROSS_ACTIVITY)
                .setOnBackNavigationDone(
                        new RemoteCallback(result -> {
                            backNavigationDone[0] = true;
                            triggerBack[0] = result.getBoolean(KEY_TRIGGER_BACK);
                        })));
        triggerBackGesture();
        assertTrue("Navigation Done callback not called", backNavigationDone[0]);
        assertTrue("TriggerBack should have been true", triggerBack[0]);
    }

    @Test
    public void backToHome_dispatchesEvents() throws RemoteException {
        mController.setBackToLauncherCallback(mIOnBackInvokedCallback);