diff options
5 files changed, 103 insertions, 55 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 665146e6ba0d..1566877c7204 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -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 @@ -125,15 +113,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } /** - * 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} */ public void offsetPinnedStack(Rect originalBounds, int xOffset, int yOffset, int durationMs) { @@ -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); + } + + + /** + * 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 resizePinnedStackInternal(IWindowContainer wc, boolean scheduleFinishPip, - Rect currentBounds, Rect destinationBounds, int animationDurationMs) { + 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(); + 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 { - mMainHandler.post(() -> mPipAnimationController - .getAnimator(wc, scheduleFinishPip, currentBounds, destinationBounds) - .setPipAnimationCallback(mPipAnimationCallback) - .setDuration(animationDurationMs) - .start()); + 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(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() diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index 980d18b6a7e0..dece8503cc3a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index e3d3df6358b1..5926b8922173 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -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; @@ -75,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(); @@ -88,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); @@ -205,12 +208,13 @@ public class PipResizeGestureHandler { mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x, mMinSize.y, mMaxSize, true, true)); mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds); - //TODO: Actually do resize here. + mPipTaskOrganizer.resizePip(mLastResizeBounds); + break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: + mPipTaskOrganizer.finishResize(mLastResizeBounds); mLastResizeBounds.setEmpty(); - //TODO: Finish resize operation here. mCtrlType = CTRL_NONE; mAllowGesture = false; break; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 558b3c696df8..bd224800e858 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -191,7 +191,7 @@ public class PipTouchHandler { mMenuController, mSnapAlgorithm, mFlingAnimationUtils, floatingContentCoordinator); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsHandler, this, mMotionHelper, - deviceConfig); + deviceConfig, pipTaskOrganizer); mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler, () -> mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), mMovementBounds, true /* allowMenuTimeout */, willResizeMenu())); diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index cb1a218af954..f28c3f6e71ec 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -433,8 +433,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mCurrentPipBounds = mPipBounds; break; } - mPipTaskOrganizer.resizePinnedStack( - mCurrentPipBounds, PipAnimationController.DURATION_DEFAULT_MS); + mPipTaskOrganizer.animateResizePip(mCurrentPipBounds, + PipAnimationController.DURATION_DEFAULT_MS); } /** |