Loading quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +31 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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) { Loading Loading @@ -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) { Loading quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +4 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading quickstep/src/com/android/quickstep/RecentsAnimationController.java +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 */); Loading quickstep/src/com/android/quickstep/TaskViewUtils.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } quickstep/src_protolog/com/android/quickstep/util/ActiveGestureProtoLogProxy.java +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +31 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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) { Loading Loading @@ -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) { Loading
quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +4 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading
quickstep/src/com/android/quickstep/RecentsAnimationController.java +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 */); Loading
quickstep/src/com/android/quickstep/TaskViewUtils.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }
quickstep/src_protolog/com/android/quickstep/util/ActiveGestureProtoLogProxy.java +6 −0 Original line number Diff line number Diff line Loading @@ -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