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

Commit 79914dfb authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Add fallback animation for auto-enter without source rect hint" into sc-dev

parents c226a840 8aa6016b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import android.app.ActivityManager;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.SurfaceControl;
import android.graphics.GraphicBuffer;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
@@ -43,9 +44,10 @@ interface IRecentsAnimationController {
     * updated accordingly. This should be called before `finish`
     * @param taskId for which the leash should be updated
     * @param finishTransaction leash operations for the final transform.
     * @param overlay the surface control for an overlay being shown above the pip (can be null)
     */
     void setFinishTaskTransaction(int taskId,
             in PictureInPictureSurfaceTransaction finishTransaction);
             in PictureInPictureSurfaceTransaction finishTransaction, in SurfaceControl overlay);

    /**
     * Notifies to the system that the animation into Recents should end, and all leashes associated
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@
    <!-- Animation duration for resizing of PIP. -->
    <integer name="config_pipResizeAnimationDuration">425</integer>

    <!-- Animation duration for crossfading of PIP (specifically to fade out the layer on top). -->
    <integer name="config_pipCrossfadeAnimationDuration">150</integer>

    <!-- Allow dragging the PIP to a location to close it -->
    <bool name="config_pipEnableDismissDragToEdge">true</bool>

+29 −17
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {

    private final SyncTransactionQueue mSyncQueue;

    private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>();
    private final SparseArray<TaskData> mDataByTaskId = new SparseArray<>();

    public FullscreenTaskListener(SyncTransactionQueue syncQueue) {
        mSyncQueue = syncQueue;
@@ -50,14 +50,14 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {

    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        if (mLeashByTaskId.get(taskInfo.taskId) != null) {
        if (mDataByTaskId.get(taskInfo.taskId) != null) {
            throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId);
        }
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
                taskInfo.taskId);
        mLeashByTaskId.put(taskInfo.taskId, leash);
        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
        final Point positionInParent = taskInfo.positionInParent;
        mDataByTaskId.put(taskInfo.taskId, new TaskData(leash, positionInParent));
        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
        mSyncQueue.runInSync(t -> {
            // Reset several properties back to fullscreen (PiP, for example, leaves all these
            // properties in a bad state).
@@ -72,45 +72,57 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    @Override
    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
        final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
        final TaskData data = mDataByTaskId.get(taskInfo.taskId);
        final Point positionInParent = taskInfo.positionInParent;
        if (!positionInParent.equals(data.positionInParent)) {
            data.positionInParent.set(positionInParent.x, positionInParent.y);
            mSyncQueue.runInSync(t -> {
            // Reset several properties back. For instance, when an Activity enters PiP with
            // multiple activities in the same task, a new task will be created from that Activity
            // and we want reset the leash of the original task.
            t.setPosition(leash, positionInParent.x, positionInParent.y);
            t.setWindowCrop(leash, null);
                t.setPosition(data.surface, positionInParent.x, positionInParent.y);
            });
        }
    }

    @Override
    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        if (mLeashByTaskId.get(taskInfo.taskId) == null) {
        if (mDataByTaskId.get(taskInfo.taskId) == null) {
            Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
            return;
        }
        mLeashByTaskId.remove(taskInfo.taskId);
        mDataByTaskId.remove(taskInfo.taskId);
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
                taskInfo.taskId);
    }

    @Override
    public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
        if (!mLeashByTaskId.contains(taskId)) {
        if (!mDataByTaskId.contains(taskId)) {
            throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
        }
        b.setParent(mLeashByTaskId.get(taskId));
        b.setParent(mDataByTaskId.get(taskId).surface);
    }

    @Override
    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        pw.println(prefix + this);
        pw.println(innerPrefix + mLeashByTaskId.size() + " Tasks");
        pw.println(innerPrefix + mDataByTaskId.size() + " Tasks");
    }

    @Override
    public String toString() {
        return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
    }

    /**
     * Per-task data for each managed task.
     */
    private static class TaskData {
        public final SurfaceControl surface;
        public final Point positionInParent;

        public TaskData(SurfaceControl surface, Point positionInParent) {
            this.surface = surface;
            this.positionInParent = positionInParent;
        }
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.pip;

import android.app.PictureInPictureParams;
import android.view.SurfaceControl;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
@@ -48,8 +49,10 @@ interface IPip {
     *
     * @param componentName ComponentName represents the Activity
     * @param destinationBounds the destination bounds the PiP window lands into
     * @param overlay an optional overlay to fade out after entering PiP
     */
    oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds) = 2;
    oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds,
            in SurfaceControl overlay) = 2;

    /**
     * Sets listener to get pinned stack animation callbacks.
+49 −20
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    private final PipUiEventLogger mPipUiEventLoggerLogger;
    private final int mEnterAnimationDuration;
    private final int mExitAnimationDuration;
    private final int mCrossFadeAnimationDuration;
    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
    private final Optional<LegacySplitScreenController> mSplitScreenOptional;
    protected final ShellTaskOrganizer mTaskOrganizer;
@@ -257,6 +258,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
     */
    private boolean mInSwipePipToHomeTransition;

    /**
     * An optional overlay used to mask content changing between an app in/out of PiP, only set if
     * {@link #mInSwipePipToHomeTransition} is true.
     */
    private SurfaceControl mSwipePipToHomeOverlay;

    public PipTaskOrganizer(Context context,
            @NonNull SyncTransactionQueue syncTransactionQueue,
            @NonNull PipBoundsState pipBoundsState,
@@ -280,6 +287,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                .getInteger(R.integer.config_pipEnterAnimationDuration);
        mExitAnimationDuration = context.getResources()
                .getInteger(R.integer.config_pipExitAnimationDuration);
        mCrossFadeAnimationDuration = context.getResources()
                .getInteger(R.integer.config_pipCrossfadeAnimationDuration);
        mSurfaceTransactionHelper = surfaceTransactionHelper;
        mPipAnimationController = pipAnimationController;
        mPipUiEventLoggerLogger = pipUiEventLogger;
@@ -350,10 +359,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
     * Callback when launcher finishes swipe-pip-to-home operation.
     * Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
     */
    public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) {
    public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
            SurfaceControl overlay) {
        // do nothing if there is no startSwipePipToHome being called before
        if (mInSwipePipToHomeTransition) {
            mPipBoundsState.setBounds(destinationBounds);
            mSwipePipToHomeOverlay = overlay;
        }
    }

@@ -599,6 +610,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,

    private void onEndOfSwipePipToHomeTransition() {
        final Rect destinationBounds = mPipBoundsState.getBounds();
        final SurfaceControl swipeToHomeOverlay = mSwipePipToHomeOverlay;
        final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
        mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds);
        mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds);
@@ -607,8 +619,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            // Ensure menu's settled in its final bounds first.
            finishResizeForMenu(destinationBounds);
            sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);

            // Remove the swipe to home overlay
            if (swipeToHomeOverlay != null) {
                fadeOutAndRemoveOverlay(swipeToHomeOverlay);
            }
        }, tx);
        mInSwipePipToHomeTransition = false;
        mSwipePipToHomeOverlay = null;
    }

    private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable,
@@ -1139,25 +1157,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                mSurfaceTransactionHelper.scale(t, snapshotSurface, snapshotSrc, snapshotDest);

                // Start animation to fade out the snapshot.
                final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
                animator.setDuration(mEnterAnimationDuration);
                animator.addUpdateListener(animation -> {
                    final float alpha = (float) animation.getAnimatedValue();
                    final SurfaceControl.Transaction transaction =
                            mSurfaceControlTransactionFactory.getTransaction();
                    transaction.setAlpha(snapshotSurface, alpha);
                    transaction.apply();
                });
                animator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        final SurfaceControl.Transaction tx =
                                mSurfaceControlTransactionFactory.getTransaction();
                        tx.remove(snapshotSurface);
                        tx.apply();
                    }
                });
                animator.start();
                fadeOutAndRemoveOverlay(snapshotSurface);
            });
        } else {
            applyFinishBoundsResize(wct, direction);
@@ -1300,6 +1300,35 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        return true;
    }

    /**
     * Fades out and removes an overlay surface.
     */
    private void fadeOutAndRemoveOverlay(SurfaceControl surface) {
        if (surface == null) {
            return;
        }

        final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
        animator.setDuration(mCrossFadeAnimationDuration);
        animator.addUpdateListener(animation -> {
            final float alpha = (float) animation.getAnimatedValue();
            final SurfaceControl.Transaction transaction =
                    mSurfaceControlTransactionFactory.getTransaction();
            transaction.setAlpha(surface, alpha);
            transaction.apply();
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                final SurfaceControl.Transaction tx =
                        mSurfaceControlTransactionFactory.getTransaction();
                tx.remove(surface);
                tx.apply();
            }
        });
        animator.start();
    }

    /**
     * Dumps internal states.
     */
Loading