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

Commit 0a8ef45e authored by Arthur Hung's avatar Arthur Hung Committed by Android (Google) Code Review
Browse files

Merge "Use IS_U_ANIMATION_ENABLED to enable animators for U"

parents ede188f7 104cb594
Loading
Loading
Loading
Loading
+50 −43
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    private final TouchTracker mTouchTracker = new TouchTracker();

    private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>();

    @Nullable
    private IOnBackInvokedCallback mActiveCallback;

    @VisibleForTesting
@@ -180,6 +180,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    }

    private void initBackAnimationRunners() {
        if (!IS_U_ANIMATION_ENABLED) {
            return;
        }

        final CrossTaskBackAnimation crossTaskAnimation = new CrossTaskBackAnimation(mContext);
        mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_TASK,
                new BackAnimationRunner(crossTaskAnimation.mCallback, crossTaskAnimation.mRunner));
@@ -207,7 +211,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    private void updateEnableAnimationFromSetting() {
        int settingValue = Global.getInt(mContext.getContentResolver(),
                Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_OFF);
        boolean isEnabled = settingValue == SETTING_VALUE_ON && IS_U_ANIMATION_ENABLED;
        boolean isEnabled = settingValue == SETTING_VALUE_ON;
        mEnableAnimations.set(isEnabled);
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Back animation enabled=%s", isEnabled);
    }
@@ -350,10 +354,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            return;
        }
        final int backType = backNavigationInfo.getType();
        final boolean shouldDispatchToAnimator = shouldDispatchToAnimator(backType);
        final boolean shouldDispatchToAnimator = shouldDispatchToAnimator();
        if (shouldDispatchToAnimator) {
            if (mAnimationDefinition.contains(backType)) {
                mActiveCallback = mAnimationDefinition.get(backType).getCallback();
                mAnimationDefinition.get(backType).startGesture();
            } else {
                mActiveCallback = null;
            }
        } else {
            mActiveCallback = mBackNavigationInfo.getOnBackInvokedCallback();
            dispatchOnBackStarted(mActiveCallback, mTouchTracker.createStartEvent(null));
@@ -361,9 +369,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    }

    private void onMove() {
        if (!mBackGestureStarted || mBackNavigationInfo == null || !mEnableAnimations.get()) {
        if (!mBackGestureStarted || mBackNavigationInfo == null || !mEnableAnimations.get()
                || mActiveCallback == null) {
            return;
        }

        final BackEvent backEvent = mTouchTracker.createProgressEvent();
        dispatchOnBackProgressed(mActiveCallback, backEvent);
    }
@@ -387,11 +397,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }
    }

    private boolean shouldDispatchToAnimator(int backType) {
    private boolean shouldDispatchToAnimator() {
        return mEnableAnimations.get()
                && mBackNavigationInfo != null
                && mBackNavigationInfo.isPrepareRemoteAnimation()
                && mAnimationDefinition.contains(backType);
                && mBackNavigationInfo.isPrepareRemoteAnimation();
    }

    private void dispatchOnBackStarted(IOnBackInvokedCallback callback,
@@ -461,6 +470,30 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        mTouchTracker.setProgressThreshold(progressThreshold);
    }

    private void invokeOrCancelBack() {
        // Make a synchronized call to core before dispatch back event to client side.
        // If the close transition happens before the core receives onAnimationFinished, there will
        // play a second close animation for that transition.
        if (mBackAnimationFinishedCallback != null) {
            try {
                mBackAnimationFinishedCallback.onAnimationFinished(mTriggerBack);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed call IBackAnimationFinishedCallback", e);
            }
            mBackAnimationFinishedCallback = null;
        }

        if (mBackNavigationInfo != null) {
            final IOnBackInvokedCallback callback = mBackNavigationInfo.getOnBackInvokedCallback();
            if (mTriggerBack) {
                dispatchOnBackInvoked(callback);
            } else {
                dispatchOnBackCancelled(callback);
            }
        }
        finishBackNavigation();
    }

    /**
     * Called when the gesture is released, then it could start the post commit animation.
     */
@@ -493,15 +526,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }

        final int backType = mBackNavigationInfo.getType();
        // Directly finish back navigation if no animator defined.
        if (!shouldDispatchToAnimator(backType)) {
            if (mTriggerBack) {
                dispatchOnBackInvoked(mActiveCallback);
            } else {
                dispatchOnBackCancelled(mActiveCallback);
            }
            // Animation missing. Simply finish back navigation.
            finishBackNavigation();
        // Simply trigger and finish back navigation when no animator defined.
        if (!shouldDispatchToAnimator() || mActiveCallback == null) {
            invokeOrCancelBack();
            return;
        }

@@ -549,16 +576,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: onBackAnimationFinished()");

        // Trigger the real back.
        if (mBackNavigationInfo != null) {
            IOnBackInvokedCallback callback = mBackNavigationInfo.getOnBackInvokedCallback();
            if (mTriggerBack) {
                dispatchOnBackInvoked(callback);
            } else {
                dispatchOnBackCancelled(callback);
            }
        }

        finishBackNavigation();
        invokeOrCancelBack();
    }

    /**
@@ -567,25 +585,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    @VisibleForTesting
    void finishBackNavigation() {
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: finishBackNavigation()");
        BackNavigationInfo backNavigationInfo = mBackNavigationInfo;
        boolean triggerBack = mTriggerBack;
        mBackNavigationInfo = null;
        mTriggerBack = false;
        mShouldStartOnNextMoveEvent = false;
        mTouchTracker.reset();
        mActiveCallback = null;
        if (backNavigationInfo == null) {
            return;
        }
        if (mBackAnimationFinishedCallback != null) {
            try {
                mBackAnimationFinishedCallback.onAnimationFinished(triggerBack);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed call IBackAnimationFinishedCallback", e);
            }
            mBackAnimationFinishedCallback = null;
        if (mBackNavigationInfo != null) {
            mBackNavigationInfo.onBackNavigationFinished(mTriggerBack);
            mBackNavigationInfo = null;
        }
        backNavigationInfo.onBackNavigationFinished(triggerBack);
        mTriggerBack = false;
    }

    private void createAdapter() {
+75 −12
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.app.WindowConfiguration;
import android.content.pm.ApplicationInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
@@ -56,6 +57,7 @@ import android.window.BackNavigationInfo;
import android.window.IBackAnimationFinishedCallback;
import android.window.IOnBackInvokedCallback;

import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;

@@ -189,31 +191,23 @@ public class BackAnimationControllerTest extends ShellTestCase {
        }

        for (int type: testTypes) {
            boolean[] backNavigationDone = new boolean[]{false};
            boolean[] triggerBack = new boolean[]{false};

            final ResultListener result  = new ResultListener();
            createNavigationInfo(new BackNavigationInfo.Builder()
                    .setType(type)
                    .setOnBackInvokedCallback(mAppCallback)
                    .setPrepareRemoteAnimation(true)
                    .setOnBackNavigationDone(
                            new RemoteCallback(result -> {
                                backNavigationDone[0] = true;
                                triggerBack[0] = result.getBoolean(KEY_TRIGGER_BACK);
                            })));
                    .setOnBackNavigationDone(new RemoteCallback(result)));
            triggerBackGesture();
            simulateRemoteAnimationStart(type);
            simulateRemoteAnimationFinished();
            mShellExecutor.flushAll();

            assertTrue("Navigation Done callback not called for "
                    + BackNavigationInfo.typeToString(type), backNavigationDone[0]);
            assertTrue("TriggerBack should have been true", triggerBack[0]);
                    + BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
            assertTrue("TriggerBack should have been true", result.mTriggerBack);
        }
    }



    @Test
    public void backToHome_dispatchesEvents() throws RemoteException {
        registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
@@ -351,6 +345,65 @@ public class BackAnimationControllerTest extends ShellTestCase {
        verify(mAnimatorCallback, never()).onBackInvoked();
    }

    @Test
    public void animationNotDefined() throws RemoteException {
        final int[] testTypes = new int[] {
                BackNavigationInfo.TYPE_RETURN_TO_HOME,
                BackNavigationInfo.TYPE_CROSS_TASK,
                BackNavigationInfo.TYPE_CROSS_ACTIVITY,
                BackNavigationInfo.TYPE_DIALOG_CLOSE};

        for (int type: testTypes) {
            final ResultListener result = new ResultListener();
            createNavigationInfo(new BackNavigationInfo.Builder()
                    .setType(type)
                    .setOnBackInvokedCallback(mAppCallback)
                    .setPrepareRemoteAnimation(true)
                    .setOnBackNavigationDone(new RemoteCallback(result)));
            triggerBackGesture();
            simulateRemoteAnimationStart(type);
            mShellExecutor.flushAll();

            assertTrue("Navigation Done callback not called for "
                    + BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
            assertTrue("TriggerBack should have been true", result.mTriggerBack);
        }

        verify(mAppCallback, never()).onBackStarted(any());
        verify(mAppCallback, never()).onBackProgressed(any());
        verify(mAppCallback, times(testTypes.length)).onBackInvoked();

        verify(mAnimatorCallback, never()).onBackStarted(any());
        verify(mAnimatorCallback, never()).onBackProgressed(any());
        verify(mAnimatorCallback, never()).onBackInvoked();
    }

    @Test
    public void callbackShouldDeliverProgress() throws RemoteException {
        registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);

        final int type = BackNavigationInfo.TYPE_CALLBACK;
        final ResultListener result = new ResultListener();
        createNavigationInfo(new BackNavigationInfo.Builder()
                .setType(type)
                .setOnBackInvokedCallback(mAppCallback)
                .setOnBackNavigationDone(new RemoteCallback(result)));
        triggerBackGesture();
        mShellExecutor.flushAll();

        assertTrue("Navigation Done callback not called for "
                + BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
        assertTrue("TriggerBack should have been true", result.mTriggerBack);

        verify(mAppCallback, times(1)).onBackStarted(any());
        verify(mAppCallback, times(1)).onBackProgressed(any());
        verify(mAppCallback, times(1)).onBackInvoked();

        verify(mAnimatorCallback, never()).onBackStarted(any());
        verify(mAnimatorCallback, never()).onBackProgressed(any());
        verify(mAnimatorCallback, never()).onBackInvoked();
    }

    private void doMotionEvent(int actionDown, int coordinate) {
        mController.onMotionEvent(
                coordinate, coordinate,
@@ -377,4 +430,14 @@ public class BackAnimationControllerTest extends ShellTestCase {
        mController.registerAnimation(type,
                new BackAnimationRunner(mAnimatorCallback, mBackAnimationRunner));
    }

    private static class ResultListener implements RemoteCallback.OnResultListener {
        boolean mBackNavigationDone = false;
        boolean mTriggerBack = false;
        @Override
        public void onResult(@Nullable Bundle result) {
            mBackNavigationDone = true;
            mTriggerBack = result.getBoolean(KEY_TRIGGER_BACK);
        }
    };
}