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

Commit 37c91d5e authored by Hongwei Wang's avatar Hongwei Wang Committed by Android (Google) Code Review
Browse files

Merge "Start PiP dismiss from SysUI via TaskOrganizer" into rvc-dev

parents 6745b6c7 d39583af
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -298,13 +298,6 @@ interface IActivityTaskManager {
    void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);

    /**
     * Dismisses PiP
     * @param animate True if the dismissal should be animated.
     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
     *                          default animation duration should be used.
     */
    void dismissPip(boolean animate, int animationDuration);
    void suppressResizeConfigChanges(boolean suppress);
    void moveTasksToFullscreenStack(int fromStackId, boolean onTop);
    boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds);
+51 −11
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.systemui.pip;

import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;

import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA;
import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_BOUNDS;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_NONE;
@@ -26,8 +29,6 @@ import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTI
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.window.ITaskOrganizerController;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -38,9 +39,9 @@ import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.IWindowContainer;
import android.view.SurfaceControl;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;

@@ -216,6 +217,29 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        mOneShotAnimationType = animationType;
    }

    /**
     * Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction}
     * - setActivityWindowingMode to fullscreen at beginning of the transaction. without changing
     *   the windowing mode of the Task itself. This makes sure the activity render it's fullscreen
     *   configuration while the Task is still in PiP.
     * - setWindowingMode to fullscreen at the end of transition
     * @param animationDurationMs duration in millisecond for the exiting PiP transition
     */
    public void dismissPip(int animationDurationMs) {
        try {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
            WindowOrganizer.applyTransaction(wct);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to apply container transaction", e);
        }
        final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
        scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
                TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs,
                null /* updateBoundsCallback */);
        mInPip = false;
    }

    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo info) {
        Objects.requireNonNull(info, "Requires RunningTaskInfo");
@@ -235,7 +259,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        mBoundsToRestore.put(mToken.asBinder(), currentBounds);
        if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
            scheduleAnimateResizePip(currentBounds, destinationBounds,
                    TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null);
                    TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
                    null /* updateBoundsCallback */);
        } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
            mUpdateHandler.post(() -> mPipAnimationController
                    .getAnimator(mLeash, destinationBounds, 0f, 1f)
@@ -249,6 +274,12 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        }
    }

    /**
     * Note that dismissing PiP is now originated from SystemUI, see {@link #dismissPip(int)}.
     * Meanwhile this callback is invoked whenever the task is removed. For instance:
     *   - as a result of removeStacksInWindowingModes from WM
     *   - activity itself is died
     */
    @Override
    public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
        IWindowContainer token = info.token;
@@ -259,7 +290,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        }
        final Rect boundsToRestore = mBoundsToRestore.remove(token.asBinder());
        scheduleAnimateResizePip(mLastReportedBounds, boundsToRestore,
                TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, null);
                TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration,
                null /* updateBoundsCallback */);
        mInPip = false;
    }

@@ -274,7 +306,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
                getAspectRatioOrDefault(newParams),
                null /* bounds */, getMinimalSize(info.topActivityInfo));
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, null);
        scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration,
                null /* updateBoundsCallback */);
    }

    /**
@@ -434,12 +467,19 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        }
        mLastReportedBounds.set(destinationBounds);
        try {
            // If we are animating to fullscreen, then we need to reset the override bounds on the
            // task to ensure that the task "matches" the parent's bounds
            Rect taskBounds = direction == TRANSITION_DIRECTION_TO_FULLSCREEN
                    ? null
                    : destinationBounds;
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            final Rect taskBounds;
            if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
                // If we are animating to fullscreen, then we need to reset the override bounds
                // on the task to ensure that the task "matches" the parent's bounds, this applies
                // also to the final windowing mode, which should be reset to undefined rather than
                // fullscreen.
                taskBounds = null;
                wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
                        .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
            } else {
                taskBounds = destinationBounds;
            }
            if (direction == TRANSITION_DIRECTION_TO_PIP) {
                wct.scheduleFinishEnterPip(mToken, taskBounds);
            } else {
+1 −5
Original line number Diff line number Diff line
@@ -219,11 +219,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        cancelAnimations();
        mMenuController.hideMenuWithoutResize();
        mPipTaskOrganizer.getUpdateHandler().post(() -> {
            try {
                mActivityTaskManager.dismissPip(!skipAnimation, EXPAND_STACK_TO_FULLSCREEN_DURATION);
            } catch (RemoteException e) {
                Log.e(TAG, "Error expanding PiP activity", e);
            }
            mPipTaskOrganizer.dismissPip(skipAnimation ? 0 : EXPAND_STACK_TO_FULLSCREEN_DURATION);
        });
    }

+0 −29
Original line number Diff line number Diff line
@@ -3986,35 +3986,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
    }

    /**
     * Dismisses Pip
     * @param animate True if the dismissal should be animated.
     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
     *                          default animation duration should be used.
     */
    @Override
    public void dismissPip(boolean animate, int animationDuration) {
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final ActivityStack stack =
                        mRootWindowContainer.getDefaultDisplay().getRootPinnedTask();
                if (stack == null) {
                    Slog.w(TAG, "dismissPip: pinned stack not found.");
                    return;
                }
                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
                    throw new IllegalArgumentException("Stack: " + stack
                            + " doesn't support animated resize.");
                }
                stack.dismissPip();
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    @Override
    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
+0 −1
Original line number Diff line number Diff line
@@ -1113,7 +1113,6 @@ public class RecentTasksTest extends ActivityTestsBase {
                () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true));
        assertSecurityException(expectCallable,
                () -> mService.setTaskWindowingModeSplitScreenPrimary(0, true));
        assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0));
        assertSecurityException(expectCallable,
                () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
        assertSecurityException(expectCallable, () -> mService.getAllStackInfos());