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

Commit 3c3c58c3 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

parents 4ac61af3 87a1c2dd
Loading
Loading
Loading
Loading
+6 −70
Original line number Original line 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.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
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.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager;
@@ -223,14 +220,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont


    private void initAnimation(MotionEvent event) {
    private void initAnimation(MotionEvent event) {
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "initAnimation mMotionStarted=%b", mBackGestureStarted);
        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.");
            Log.e(TAG, "Animation is being initialized but is already started.");
            return;
        }

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

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


@@ -304,8 +298,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            return;
            return;
        }
        }
        int deltaX = Math.round(event.getX() - mInitTouchLocation.x);
        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 progressThreshold = PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
        float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
        float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
        int backType = mBackNavigationInfo.getType();
        int backType = mBackNavigationInfo.getType();
@@ -317,11 +309,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            targetCallback = mBackToLauncherCallback;
            targetCallback = mBackToLauncherCallback;
        } else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
        } else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
                || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
                || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
            if (animationTarget != null) {
            // TODO(208427216) Run the actual animation
                mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
                mTouchEventDelta.set(deltaX, deltaY);
                mTransaction.apply();
            }
        } else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
        } else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
            targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
            targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
        }
        }
@@ -343,19 +331,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        } else {
        } else {
            dispatchOnBackCancelled(targetCallback);
            dispatchOnBackCancelled(targetCallback);
        }
        }
        if (backType == BackNavigationInfo.TYPE_CALLBACK) {
        if (backType != BackNavigationInfo.TYPE_RETURN_TO_HOME || !shouldDispatchToLauncher) {
            finishAnimation();
        } else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
                && !shouldDispatchToLauncher) {
            // Launcher callback missing. Simply finish animation.
            // Launcher callback missing. Simply finish animation.
            finishAnimation();
            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(
    private static void dispatchOnBackProgressed(IOnBackInvokedCallback callback,
            IOnBackInvokedCallback callback, BackEvent backEvent) {
            BackEvent backEvent) {
        if (callback == null) {
        if (callback == null) {
            return;
            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.
     * Sets to true when the back gesture has passed the triggering threshold, false otherwise.
     */
     */
+48 −1
Original line number Original line Diff line number Diff line
@@ -16,10 +16,16 @@


package com.android.wm.shell.back;
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.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.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;


import android.app.IActivityTaskManager;
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() {
    RemoteAnimationTarget createAnimationTarget() {
        SurfaceControl topWindowLeash = new SurfaceControl();
        SurfaceControl topWindowLeash = new SurfaceControl();
        return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
        return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
@@ -109,6 +123,18 @@ public class BackAnimationControllerTest {
                true, null, null, null, false, -1);
                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
    @Test
    @Ignore("b/207481538")
    @Ignore("b/207481538")
    public void crossActivity_screenshotAttachedAndVisible() {
    public void crossActivity_screenshotAttachedAndVisible() {
@@ -140,10 +166,31 @@ public class BackAnimationControllerTest {
                MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
                MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
                MotionEvent.ACTION_MOVE,
                MotionEvent.ACTION_MOVE,
                BackEvent.EDGE_LEFT);
                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();
        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
    @Test
    public void backToHome_dispatchesEvents() throws RemoteException {
    public void backToHome_dispatchesEvents() throws RemoteException {
        mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
        mController.setBackToLauncherCallback(mIOnBackInvokedCallback);