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

Commit 94457298 authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge changes Id3953904,I2ef286d6 into rvc-dev

* changes:
  Implement PIP Leash resizing.
  Track current resized bounds for resized PIP.
parents 5e28e529 7d6b8e74
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -225,8 +225,8 @@ public class PipBoundsHandler {
     */
    Rect getDestinationBounds(float aspectRatio, Rect bounds) {
        final Rect destinationBounds;
        final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
        if (bounds == null) {
            final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
            destinationBounds = new Rect(defaultBounds);
        } else {
            destinationBounds = new Rect(bounds);
+91 −46
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.systemui.pip;

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.DURATION_NONE;
import static com.android.systemui.pip.PipAnimationController.DURATION_DEFAULT_MS;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -87,19 +87,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
                }
            });
            final Rect destinationBounds = animator.getDestinationBounds();
            mLastReportedBounds.set(destinationBounds);
            try {
                final WindowContainerTransaction wct = new WindowContainerTransaction();
                if (animator.shouldScheduleFinishPip()) {
                    wct.scheduleFinishEnterPip(wc, destinationBounds);
                } else {
                    wct.setBounds(wc, destinationBounds);
                }
                wct.setBoundsChangeTransaction(wc, tx);
                mTaskOrganizerController.applyContainerTransaction(wct, null /* ITaskOrganizer */);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to apply container transaction", e);
            }
            finishResizeInternal(destinationBounds, wc, tx, animator.shouldScheduleFinishPip());
        }

        @Override
@@ -124,15 +112,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        mPipAnimationController = new PipAnimationController(context);
    }

    /**
     * Resize the PiP window, animate if the given duration is not {@link #DURATION_NONE}
     */
    public void resizePinnedStack(Rect destinationBounds, int durationMs) {
        Objects.requireNonNull(mTaskInfo, "Requires valid IWindowContainer");
        resizePinnedStackInternal(mTaskInfo.token, false /* scheduleFinishPip */,
                mLastReportedBounds, destinationBounds, durationMs);
    }

    /**
     * Offset the PiP window, animate if the given duration is not {@link #DURATION_NONE}
     */
@@ -143,7 +122,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        }
        final Rect destinationBounds = new Rect(originalBounds);
        destinationBounds.offset(xOffset, yOffset);
        resizePinnedStackInternal(mTaskInfo.token, false /* scheduleFinishPip*/,
        animateResizePipInternal(mTaskInfo.token, false /* scheduleFinishPip*/,
                originalBounds, destinationBounds, durationMs);
    }

@@ -208,15 +187,14 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        mTaskInfo = info;
        if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
            final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
            resizePinnedStackInternal(mTaskInfo.token, true /* scheduleFinishPip */,
                    currentBounds, destinationBounds,
                    PipAnimationController.DURATION_DEFAULT_MS);
            animateResizePipInternal(mTaskInfo.token, true /* scheduleFinishPip */,
                    currentBounds, destinationBounds, DURATION_DEFAULT_MS);
        } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
            mMainHandler.post(() -> mPipAnimationController
                    .getAnimator(mTaskInfo.token, true /* scheduleFinishPip */,
                            destinationBounds, 0f, 1f)
                    .setPipAnimationCallback(mPipAnimationCallback)
                    .setDuration(PipAnimationController.DURATION_DEFAULT_MS)
                    .setDuration(DURATION_DEFAULT_MS)
                    .start());
            mOneShotAnimationType = ANIM_TYPE_BOUNDS;
        } else {
@@ -231,9 +209,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            Log.wtf(TAG, "Unrecognized token: " + token);
            return;
        }
        resizePinnedStackInternal(token, false /* scheduleFinishPip */,
                mLastReportedBounds, mDisplayBounds,
                PipAnimationController.DURATION_DEFAULT_MS);
        animateResizePipInternal(token, false /* scheduleFinishPip */,
                mLastReportedBounds, mDisplayBounds, DURATION_DEFAULT_MS);
    }

    @Override
@@ -245,11 +222,22 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                getAspectRatioOrDefault(info.pictureInPictureParams), null /* bounds */);
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        resizePinnedStack(destinationBounds, PipAnimationController.DURATION_DEFAULT_MS);
        animateResizePip(destinationBounds, DURATION_DEFAULT_MS);
    }

    private void resizePinnedStackInternal(IWindowContainer wc, boolean scheduleFinishPip,
            Rect currentBounds, Rect destinationBounds, int animationDurationMs) {

    /**
     * Directly perform manipulation/resize on the leash. This will not perform any
     * {@link WindowContainerTransaction} until {@link #finishResize} is called.
     */
    public void resizePip(Rect destinationBounds) {
        Objects.requireNonNull(mTaskInfo, "Requires valid IWindowContainer");
        resizePipInternal(mTaskInfo.token, destinationBounds);
    }

    private void resizePipInternal(IWindowContainer wc,
            Rect destinationBounds) {
        Objects.requireNonNull(mTaskInfo, "Requires valid IWindowContainer");
        try {
            // Could happen when dismissPip
            if (wc == null || wc.getLeash() == null) {
@@ -257,20 +245,76 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
                return;
            }
            final SurfaceControl leash = wc.getLeash();
            if (animationDurationMs == DURATION_NONE) {
                // Directly resize if no animation duration is set. When fling, wait for final
                // callback to issue the proper WindowContainerTransaction with destination bounds.
            new SurfaceControl.Transaction()
                    .setPosition(leash, destinationBounds.left, destinationBounds.top)
                    .setWindowCrop(leash, destinationBounds.width(), destinationBounds.height())
                    .apply();
        } catch (RemoteException e) {
            Log.w(TAG, "Abort animation, invalid window container", e);
        } catch (Exception e) {
            Log.e(TAG, "Should not reach here, terrible thing happened", e);
        }
    }

    /**
     * Finish a intermediate resize operation. This is expected to be called after
     * {@link #resizePip}.
     */
    public void finishResize(Rect destinationBounds) {
        try {
            final IWindowContainer wc = mTaskInfo.token;
            SurfaceControl.Transaction tx = new SurfaceControl.Transaction()
                    .setPosition(wc.getLeash(), destinationBounds.left,
                            destinationBounds.top)
                    .setWindowCrop(wc.getLeash(), destinationBounds.width(),
                            destinationBounds.height());
            finishResizeInternal(destinationBounds, wc, tx, false);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to obtain leash");
        }
    }

    private void finishResizeInternal(Rect destinationBounds, IWindowContainer wc,
            SurfaceControl.Transaction tx, boolean shouldScheduleFinishPip) {
        mLastReportedBounds.set(destinationBounds);
        try {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            if (shouldScheduleFinishPip) {
                wct.scheduleFinishEnterPip(wc, destinationBounds);
            } else {
                wct.setBounds(wc, destinationBounds);
            }
            wct.setBoundsChangeTransaction(mTaskInfo.token, tx);
            mTaskOrganizerController.applyContainerTransaction(wct, null /* ITaskOrganizer */);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to apply container transaction", e);
        }
    }

    /**
     * Animates resizing of the pinned stack given the duration.
     */
    public void animateResizePip(Rect destinationBounds, int durationMs) {
        Objects.requireNonNull(mTaskInfo, "Requires valid IWindowContainer");
        animateResizePipInternal(mTaskInfo.token, false, mLastReportedBounds,
                destinationBounds, durationMs);
    }

    private void animateResizePipInternal(IWindowContainer wc, boolean scheduleFinishPip,
            Rect currentBounds, Rect destinationBounds, int durationMs) {
        try {
            // Could happen when dismissPip
            if (wc == null || wc.getLeash() == null) {
                Log.w(TAG, "Abort animation, invalid leash");
                return;
            }
            final SurfaceControl leash = wc.getLeash();

            mMainHandler.post(() -> mPipAnimationController
                    .getAnimator(wc, scheduleFinishPip, currentBounds, destinationBounds)
                    .setPipAnimationCallback(mPipAnimationCallback)
                        .setDuration(animationDurationMs)
                    .setDuration(durationMs)
                    .start());
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Abort animation, invalid window container", e);
        } catch (Exception e) {
@@ -278,6 +322,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        }
    }


    private float getAspectRatioOrDefault(@Nullable PictureInPictureParams params) {
        return params == null
                ? mPipBoundsHandler.getDefaultAspectRatio()
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
                // bounds. We want to restore to the unexpanded bounds when re-entering pip,
                // so we save the bounds before expansion (normal) instead of the current
                // bounds.
                mReentryBounds.set(mTouchHandler.getNormalBounds());
                mReentryBounds.set(mTouchHandler.getMinBounds());
                // Apply the snap fraction of the current bounds to the normal bounds.
                float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
                mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction);
+2 −3
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import androidx.dynamicanimation.animation.SpringForce;

import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.internal.os.SomeArgs;
import com.android.systemui.pip.PipAnimationController;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -546,7 +545,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call
            case MSG_RESIZE_IMMEDIATE: {
                SomeArgs args = (SomeArgs) msg.obj;
                Rect toBounds = (Rect) args.arg1;
                mPipTaskOrganizer.resizePinnedStack(toBounds, PipAnimationController.DURATION_NONE);
                mPipTaskOrganizer.resizePip(toBounds);
                mBounds.set(toBounds);
                return true;
            }
@@ -564,7 +563,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call
                        return true;
                    }

                    mPipTaskOrganizer.resizePinnedStack(toBounds, duration);
                    mPipTaskOrganizer.animateResizePip(toBounds, duration);
                    mBounds.set(toBounds);
                } catch (RemoteException e) {
                    Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e);
+16 −10
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.view.MotionEvent;
import com.android.internal.policy.TaskResizingAlgorithm;
import com.android.systemui.R;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.util.DeviceConfigProxy;

import java.util.concurrent.Executor;
@@ -64,6 +65,7 @@ public class PipResizeGestureHandler {
    private final PointF mDownPoint = new PointF();
    private final Point mMaxSize = new Point();
    private final Point mMinSize = new Point();
    private final Rect mLastResizeBounds = new Rect();
    private final Rect mTmpBounds = new Rect();
    private final int mDelta;

@@ -74,12 +76,13 @@ public class PipResizeGestureHandler {

    private InputMonitor mInputMonitor;
    private InputEventReceiver mInputEventReceiver;
    private PipTaskOrganizer mPipTaskOrganizer;

    private int mCtrlType;

    public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
            PipTouchHandler pipTouchHandler, PipMotionHelper motionHelper,
            DeviceConfigProxy deviceConfig) {
            DeviceConfigProxy deviceConfig, PipTaskOrganizer pipTaskOrganizer) {
        final Resources res = context.getResources();
        context.getDisplay().getMetrics(mDisplayMetrics);
        mDisplayId = context.getDisplayId();
@@ -87,6 +90,7 @@ public class PipResizeGestureHandler {
        mPipBoundsHandler = pipBoundsHandler;
        mPipTouchHandler = pipTouchHandler;
        mMotionHelper = motionHelper;
        mPipTaskOrganizer = pipTaskOrganizer;

        context.getDisplay().getRealSize(mMaxSize);
        mDelta = res.getDimensionPixelSize(R.dimen.pip_resize_edge_size);
@@ -190,11 +194,7 @@ public class PipResizeGestureHandler {
            }

        } else if (mAllowGesture) {
            final Rect currentPipBounds = mMotionHelper.getBounds();
            Rect newSize = TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(), mDownPoint.x,
                    mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x, mMinSize.y, mMaxSize,
                    true, true);
            mPipBoundsHandler.transformBoundsToAspectRatio(newSize);

            switch (action) {
                case MotionEvent.ACTION_POINTER_DOWN:
                    // We do not support multi touch for resizing via drag
@@ -203,12 +203,18 @@ public class PipResizeGestureHandler {
                case MotionEvent.ACTION_MOVE:
                    // Capture inputs
                    mInputMonitor.pilferPointers();
                    //TODO: Actually do resize here.
                    final Rect currentPipBounds = mMotionHelper.getBounds();
                    mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(),
                            mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
                            mMinSize.y, mMaxSize, true, true));
                    mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
                    mPipTaskOrganizer.resizePip(mLastResizeBounds);

                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    //TODO: Finish resize operation here.
                    mMotionHelper.synchronizePinnedStackBounds();
                    mPipTaskOrganizer.finishResize(mLastResizeBounds);
                    mLastResizeBounds.setEmpty();
                    mCtrlType = CTRL_NONE;
                    mAllowGesture = false;
                    break;
@@ -220,7 +226,7 @@ public class PipResizeGestureHandler {
        mMaxSize.set(maxX, maxY);
    }

    void updateMiniSize(int minX, int minY) {
    void updateMinSize(int minX, int minY) {
        mMinSize.set(minX, minY);
    }

Loading