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

Commit 9639fcc3 authored by Luca Zuccarini's avatar Luca Zuccarini Committed by Android (Google) Code Review
Browse files

Merge "Hand off gesture nav animations to registered remotes." into main

parents afd0d288 33dfe5e7
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -56,9 +56,11 @@ import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_CANCELE
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.TaskViewUtils.extractTargetsAndStates;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -77,6 +79,7 @@ import android.graphics.RectF;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -90,6 +93,7 @@ import android.view.animation.Interpolator;
import android.widget.Toast;
import android.window.DesktopModeFlags;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.WindowAnimationState;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -143,6 +147,7 @@ import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
import com.android.quickstep.views.TaskContainer;
import com.android.quickstep.views.TaskView;
import com.android.systemui.animation.TransitionAnimator;
import com.android.systemui.contextualeducation.GestureType;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -156,6 +161,8 @@ import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.shared.startingsurface.SplashScreenExitAnimationUtils;

import kotlin.Unit;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -165,8 +172,6 @@ import java.util.Optional;
import java.util.OptionalInt;
import java.util.function.Consumer;

import kotlin.Unit;

/**
 * Handles the navigation gestures when Launcher is the default home activity.
 */
@@ -347,6 +352,9 @@ public abstract class AbsSwipeUpHandler<
    // Indicates whether the divider is shown, only used when split screen is activated.
    private boolean mIsDividerShown = true;
    private boolean mStartMovingTasks;
    // Whether the animation to home should be handed off to another handler once the gesture is
    // committed.
    protected boolean mHandOffAnimationToHome = false;

    @Nullable
    private RemoteAnimationTargets.ReleaseCheck mSwipePipToHomeReleaseCheck = null;
@@ -945,6 +953,10 @@ public abstract class AbsSwipeUpHandler<
        mSwipePipToHomeReleaseCheck = new RemoteAnimationTargets.ReleaseCheck();
        mSwipePipToHomeReleaseCheck.setCanRelease(true);
        mRecentsAnimationTargets.addReleaseCheck(mSwipePipToHomeReleaseCheck);
        if (TransitionAnimator.Companion.longLivedReturnAnimationsEnabled()) {
            mHandOffAnimationToHome =
                    targets.extras.getBoolean(KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION, false);
        }

        // Only initialize the device profile, if it has not been initialized before, as in some
        // configurations targets.homeContentInsets may not be correct.
@@ -1629,6 +1641,10 @@ public abstract class AbsSwipeUpHandler<
                }
                windowAnim = createWindowAnimationToHome(start, homeAnimFactory);

                if (mHandOffAnimationToHome) {
                    handOffAnimation(velocityPxPerMs);
                }

                windowAnim[0].addAnimatorListener(new AnimationSuccessListener() {
                    @Override
                    public void onAnimationSuccess(Animator animator) {
@@ -1711,6 +1727,19 @@ public abstract class AbsSwipeUpHandler<
        }
    }

    private void handOffAnimation(PointF velocityPxPerMs) {
        if (!TransitionAnimator.Companion.longLivedReturnAnimationsEnabled()
                || mRecentsAnimationController == null) {
            return;
        }

        Pair<RemoteAnimationTarget[], WindowAnimationState[]> targetsAndStates =
                extractTargetsAndStates(mRemoteTargetHandles, velocityPxPerMs);
        mRecentsAnimationController.handOffAnimation(
                targetsAndStates.first, targetsAndStates.second);
        ActiveGestureProtoLogProxy.logHandOffAnimation();
    }

    private int calculateWindowRotation(RemoteAnimationTarget runningTaskTarget,
            RecentsOrientedState orientationState) {
        if (runningTaskTarget.rotationChange != 0) {
+4 −2
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import com.android.launcher3.views.ClipIconView;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.ScalingWorkspaceRevealAnim;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
@@ -54,6 +53,7 @@ import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.views.FloatingWidgetView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.animation.TransitionAnimator;
import com.android.systemui.shared.system.InputConsumerController;

import java.util.Collections;
@@ -108,7 +108,9 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<

        mContainer.getRootView().setForceHideBackArrow(true);

        if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForSplit) {
        boolean handOffAnimation = TransitionAnimator.Companion.longLivedReturnAnimationsEnabled()
                && mHandOffAnimationToHome;
        if (handOffAnimation || !canUseWorkspaceView || appCanEnterPip || mIsSwipeForSplit) {
            return new LauncherHomeAnimationFactory() {

                @Nullable
+13 −0
Original line number Diff line number Diff line
@@ -21,9 +21,11 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.WindowManagerGlobal;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.WindowAnimationState;

import androidx.annotation.UiThread;

@@ -32,6 +34,7 @@ import com.android.internal.os.IResultReceiver;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.systemui.animation.TransitionAnimator;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -89,6 +92,16 @@ public class RecentsAnimationController {
        }
    }

    @UiThread
    public void handOffAnimation(RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
        if (TransitionAnimator.Companion.longLivedReturnAnimationsEnabled()) {
            UI_HELPER_EXECUTOR.execute(() -> mController.handOffAnimation(targets, states));
        } else {
            Log.e(TAG, "Tried to hand off the animation, but the feature is disabled",
                    new Exception());
        }
    }

    @UiThread
    public void finishAnimationToHome() {
        finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
+42 −0
Original line number Diff line number Diff line
@@ -47,12 +47,15 @@ import android.content.ComponentName;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Matrix.ScaleToFit;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Pair;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.View;
import android.window.TransitionInfo;
import android.window.WindowAnimationState;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -784,4 +787,43 @@ public final class TaskViewUtils {
        animatorHandler.accept(dockFadeAnimator);
        return dockFadeAnimator;
    }

    /**
     * Creates an array of {@link RemoteAnimationTarget}s and a matching array of
     * {@link WindowAnimationState}s from the provided handles.
     * Important: the ordering of the two arrays is the same, so the state at each index of the
     * second applies to the target in the same index of the first.
     *
     * @param handles The handles wrapping each target.
     * @param velocityPxPerMs The current velocity of the target animations.
     */
    @NonNull
    public static Pair<RemoteAnimationTarget[], WindowAnimationState[]> extractTargetsAndStates(
            @NonNull RemoteTargetHandle[] handles, @NonNull PointF velocityPxPerMs) {
        RemoteAnimationTarget[] targets = new RemoteAnimationTarget[handles.length];
        WindowAnimationState[] animationStates = new WindowAnimationState[handles.length];
        long timestamp = System.currentTimeMillis();

        for (int i = 0; i < handles.length; i++) {
            targets[i] = handles[i].getTransformParams().getTargetSet().apps[i];

            TaskViewSimulator taskViewSimulator = handles[i].getTaskViewSimulator();
            RectF startRect = taskViewSimulator.getCurrentRect();
            float cornerRadius = taskViewSimulator.getCurrentCornerRadius();

            WindowAnimationState state = new WindowAnimationState();
            state.timestamp = timestamp;
            state.bounds = new RectF(
                    startRect.left, startRect.top, startRect.right, startRect.bottom);
            state.topLeftRadius = cornerRadius;
            state.topRightRadius = cornerRadius;
            state.bottomRightRadius = cornerRadius;
            state.bottomLeftRadius = cornerRadius;
            state.velocityPxPerMs = velocityPxPerMs;

            animationStates[i] = state;
        }

        return new Pair<>(targets, animationStates);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -96,6 +96,12 @@ public class ActiveGestureProtoLogProxy {
                + "force finish recents animation complete; clearing state callback.");
    }

    public static void logHandOffAnimation() {
        ActiveGestureLog.INSTANCE.addLog("AbsSwipeUpHandler.handOffAnimation");
        if (!enableActiveGestureProtoLog()) return;
        ProtoLog.d(ACTIVE_GESTURE_LOG, "AbsSwipeUpHandler.handOffAnimation");
    }

    public static void logFinishRecentsAnimationOnTasksAppeared() {
        ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimationOnTasksAppeared");
        if (!enableActiveGestureProtoLog()) return;
Loading