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

Commit 9db95e89 authored by Ats Jenk's avatar Ats Jenk
Browse files

Support desktop tasks in recents animation

Desktop tasks are using freeform windowing mode. Update recents
animation to support freeform tasks when desktop mode feature flag is
enabled.

Changes:
- set initial size for freeform tasks to be the size of the thumbnail
  instead of size of the screen
- support multiple individual remote animation targets when starting the
  recents animation

TODO:
- there are flickers when starting and ending the recents animation

Bug: 263264985
Test: swipe up when more than 1 desktop task is visible
Change-Id: I27ee02774281b3a433d779c0bb8825cdb6ea5457
parent 196569bb
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ import com.android.quickstep.util.SurfaceTransaction;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.SwipePipToHomeAnimator;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
@@ -877,7 +878,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
    public void onRecentsAnimationStart(RecentsAnimationController controller,
            RecentsAnimationTargets targets) {
        super.onRecentsAnimationStart(controller, targets);
        if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && targets.hasDesktopTasks()) {
            mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
        } else {
            mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(mContext, targets);
        }
        mRecentsAnimationController = controller;
        mRecentsAnimationTargets = targets;
        mSwipePipToHomeReleaseCheck = new RemoteAnimationTargets.ReleaseCheck();
+22 −0
Original line number Diff line number Diff line
@@ -15,11 +15,15 @@
 */
package com.android.quickstep;

import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;

import android.app.WindowConfiguration;
import android.graphics.Rect;
import android.view.RemoteAnimationTarget;

import com.android.quickstep.views.DesktopTaskView;

/**
 * Extension of {@link RemoteAnimationTargets} with additional information about swipe
 * up animation
@@ -40,4 +44,22 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
    public boolean hasTargets() {
        return unfilteredApps.length != 0;
    }

    /**
     * Check if target apps contain desktop tasks which have windowing mode set to {@link
     * WindowConfiguration#WINDOWING_MODE_FREEFORM}
     *
     * @return {@code true} if at least one target app is a desktop task
     */
    public boolean hasDesktopTasks() {
        if (!DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
            return false;
        }
        for (RemoteAnimationTarget target : apps) {
            if (target.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
                return true;
            }
        }
        return false;
    }
}
+62 −4
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.DesktopTaskView;

import java.util.ArrayList;

@@ -41,8 +42,8 @@ public class RemoteTargetGluer {
     * Use this constructor if remote targets are split-screen independent
     */
    public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy,
            RemoteAnimationTargets targets) {
        mRemoteTargetHandles = createHandles(context, sizingStrategy, targets.apps.length);
            RemoteAnimationTargets targets, boolean forDesktop) {
        init(context, sizingStrategy, targets.apps.length, forDesktop);
    }

    /**
@@ -50,15 +51,31 @@ public class RemoteTargetGluer {
     * running tasks
     */
    public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
        if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
            // TODO: binder call, only for prototyping. Creating the gluer should be postponed so
            //  we can create it when we have the remote animation targets ready.
            int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount();
            if (desktopTasks > 0) {
                init(context, sizingStrategy, desktopTasks, true /* forDesktop */);
                return;
            }
        }

        int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds();
        mRemoteTargetHandles = createHandles(context, sizingStrategy, splitIds.length == 2 ? 2 : 1);
        init(context, sizingStrategy, splitIds.length == 2 ? 2 : 1, false /* forDesktop */);
    }

    private void init(Context context, BaseActivityInterface sizingStrategy, int numHandles,
            boolean forDesktop) {
        mRemoteTargetHandles = createHandles(context, sizingStrategy, numHandles, forDesktop);
    }

    private RemoteTargetHandle[] createHandles(Context context,
            BaseActivityInterface sizingStrategy, int numHandles) {
            BaseActivityInterface sizingStrategy, int numHandles, boolean forDesktop) {
        RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
        for (int i = 0; i < numHandles; i++) {
            TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy);
            tvs.setIsDesktopTask(forDesktop);
            TransformParams transformParams = new TransformParams();
            handles[i] = new RemoteTargetHandle(tvs, transformParams);
        }
@@ -135,6 +152,20 @@ public class RemoteTargetGluer {
        return mRemoteTargetHandles;
    }

    /**
     * Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this creates distinct
     * transform params per app in {@code targets.apps} list.
     */
    public RemoteTargetHandle[] assignTargetsForDesktop(RemoteAnimationTargets targets) {
        for (int i = 0; i < mRemoteTargetHandles.length; i++) {
            RemoteAnimationTarget primaryTaskTarget = targets.apps[i];
            mRemoteTargetHandles[i].mTransformParams.setTargetSet(
                    createRemoteAnimationTargetsForTaskId(targets, primaryTaskTarget.taskId));
            mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
        }
        return mRemoteTargetHandles;
    }

    private Rect getStartBounds(RemoteAnimationTarget target) {
        return target.startBounds == null ? target.screenSpaceBounds : target.startBounds;
    }
@@ -172,6 +203,33 @@ public class RemoteTargetGluer {
                filteredApps, targets.wallpapers, targets.nonApps, targets.targetMode);
    }

    /**
     * Ensures that we only animate one specific app target. Includes ancillary targets such as
     * home/recents
     *
     * @param targets remote animation targets to filter
     * @param taskId  id for a task that we want this remote animation to apply to
     * @return {@link RemoteAnimationTargets} where app target only includes the app that has the
     * {@code taskId} that was passed in
     */
    private RemoteAnimationTargets createRemoteAnimationTargetsForTaskId(
            RemoteAnimationTargets targets, int taskId) {
        RemoteAnimationTarget[] targetApp = null;
        for (RemoteAnimationTarget targetCompat : targets.unfilteredApps) {
            if (targetCompat.taskId == taskId) {
                targetApp = new RemoteAnimationTarget[]{targetCompat};
                break;
            }
        }

        if (targetApp == null) {
            targetApp = new RemoteAnimationTarget[0];
        }

        return new RemoteAnimationTargets(targetApp, targets.wallpapers, targets.nonApps,
                targets.targetMode);
    }

    public RemoteTargetHandle[] getRemoteTargetHandles() {
        return mRemoteTargetHandles;
    }
+12 −0
Original line number Diff line number Diff line
@@ -952,4 +952,16 @@ public class SystemUiProxy implements ISystemUiProxy {
            }
        }
    }

    /** Call shell to get number of visible freeform tasks */
    public int getVisibleDesktopTaskCount() {
        if (mDesktopMode != null) {
            try {
                return mDesktopMode.getVisibleTaskCount();
            } catch (RemoteException e) {
                Log.w(TAG, "Failed call getVisibleDesktopTaskCount", e);
            }
        }
        return 0;
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -78,6 +79,7 @@ import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
@@ -182,9 +184,12 @@ public final class TaskViewUtils {
            // Re-use existing handles
            remoteTargetHandles = recentsViewHandles;
        } else {
            boolean forDesktop = DESKTOP_MODE_SUPPORTED && v instanceof DesktopTaskView;
            RemoteTargetGluer gluer = new RemoteTargetGluer(v.getContext(),
                    recentsView.getSizeStrategy(), targets);
            if (v.containsMultipleTasks()) {
                    recentsView.getSizeStrategy(), targets, forDesktop);
            if (forDesktop) {
                remoteTargetHandles = gluer.assignTargetsForDesktop(targets);
            } else if (v.containsMultipleTasks()) {
                remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets, v.getTaskIds());
            } else {
                remoteTargetHandles = gluer.assignTargets(targets);
Loading