Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +2 −1 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, @NonNull PipTransitionState pipTransitionState, @NonNull PipScheduler pipScheduler, @NonNull SizeSpecSource sizeSpecSource, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, Loading @@ -140,7 +141,7 @@ public abstract class Pip2Module { @ShellMainThread ShellExecutor mainExecutor, Optional<PipPerfHintController> pipPerfHintControllerOptional) { return new PipTouchHandler(context, shellInit, menuPhoneController, pipBoundsAlgorithm, pipBoundsState, pipTransitionState, sizeSpecSource, pipMotionHelper, pipBoundsState, pipTransitionState, pipScheduler, sizeSpecSource, pipMotionHelper, floatingContentCoordinator, pipUiEventLogger, mainExecutor, pipPerfHintControllerOptional); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +5 −3 Original line number Diff line number Diff line Loading @@ -58,7 +58,8 @@ import java.util.function.Consumer; * A helper to animate and manipulate the PiP. */ public class PipMotionHelper implements PipAppOpsListener.Callback, FloatingContentCoordinator.FloatingContent { FloatingContentCoordinator.FloatingContent, PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PipMotionHelper"; private static final String FLING_BOUNDS_CHANGE = "fling_bounds_change"; private static final boolean DEBUG = false; Loading Loading @@ -181,7 +182,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, } }; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mPipTransitionState.addPipTransitionStateChangedListener(this); } void init() { Loading Loading @@ -687,7 +688,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, // setAnimatingToBounds(toBounds); } private void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { switch (newState) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java +100 −67 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.Looper; import android.view.BatchedInputEventReceiver; import android.view.Choreographer; Loading @@ -32,6 +33,7 @@ import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.InputMonitor; import android.view.MotionEvent; import android.view.SurfaceControl; import android.view.ViewConfiguration; import androidx.annotation.VisibleForTesting; Loading @@ -51,16 +53,20 @@ import java.util.function.Consumer; * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to * trigger dynamic resize. */ public class PipResizeGestureHandler { public class PipResizeGestureHandler implements PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PipResizeGestureHandler"; private static final int PINCH_RESIZE_SNAP_DURATION = 250; private static final float PINCH_RESIZE_AUTO_MAX_RATIO = 0.9f; private static final String RESIZE_BOUNDS_CHANGE = "resize_bounds_change"; private final Context mContext; private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final PipBoundsState mPipBoundsState; private final PipTouchState mPipTouchState; private final PipScheduler mPipScheduler; private final PipTransitionState mPipTransitionState; private final PhonePipMenuController mPhonePipMenuController; private final PipUiEventLogger mPipUiEventLogger; private final PipPinchResizingAlgorithm mPinchResizingAlgorithm; Loading Loading @@ -88,6 +94,7 @@ public class PipResizeGestureHandler { private boolean mIsSysUiStateValid; private boolean mThresholdCrossed; private boolean mOngoingPinchToResize = false; private boolean mWaitingForBoundsChangeTransition = false; private float mAngle = 0; int mFirstIndex = -1; int mSecondIndex = -1; Loading @@ -104,11 +111,17 @@ public class PipResizeGestureHandler { private int mCtrlType; private int mOhmOffset; public PipResizeGestureHandler(Context context, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipTouchState pipTouchState, public PipResizeGestureHandler(Context context, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipTouchState pipTouchState, PipScheduler pipScheduler, PipTransitionState pipTransitionState, Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, ShellExecutor mainExecutor, @Nullable PipPerfHintController pipPerfHintController) { PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, ShellExecutor mainExecutor, @Nullable PipPerfHintController pipPerfHintController) { mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = mainExecutor; Loading @@ -116,6 +129,11 @@ public class PipResizeGestureHandler { mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; mPipTouchState = pipTouchState; mPipScheduler = pipScheduler; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; mPhonePipMenuController = menuActivityController; mPipUiEventLogger = pipUiEventLogger; Loading @@ -125,6 +143,7 @@ public class PipResizeGestureHandler { mUserResizeBounds.set(rect); // mMotionHelper.synchronizePinnedStackBounds(); mUpdateMovementBoundsRunnable.run(); mPipBoundsState.setBounds(rect); resetState(); }; } Loading Loading @@ -202,7 +221,7 @@ public class PipResizeGestureHandler { @VisibleForTesting void onInputEvent(InputEvent ev) { if (!mEnablePinchResize) { // No need to handle anything if neither form of resizing is enabled. // No need to handle anything if resizing isn't enabled. return; } Loading @@ -227,7 +246,7 @@ public class PipResizeGestureHandler { } } if (mEnablePinchResize && mOngoingPinchToResize) { if (mOngoingPinchToResize) { onPinchResize(mv); } } Loading @@ -249,7 +268,6 @@ public class PipResizeGestureHandler { } boolean willStartResizeGesture(MotionEvent ev) { if (isInValidSysUiState()) { if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { if (mEnablePinchResize && ev.getPointerCount() == 2) { onPinchResize(ev); Loading @@ -257,7 +275,6 @@ public class PipResizeGestureHandler { return mAllowGesture; } } } return false; } Loading @@ -284,7 +301,6 @@ public class PipResizeGestureHandler { mSecondIndex = -1; mAllowGesture = false; finishResize(); cleanUpHighPerfSessionMaybe(); } if (ev.getPointerCount() != 2) { Loading Loading @@ -347,10 +363,7 @@ public class PipResizeGestureHandler { mDownSecondPoint, mLastPoint, mLastSecondPoint, mMinSize, mMaxSize, mDownBounds, mLastResizeBounds); /* mPipTaskOrganizer.scheduleUserResizePip(mDownBounds, mLastResizeBounds, mAngle, null); */ mPipScheduler.scheduleUserResizePip(mLastResizeBounds, mAngle); mPipBoundsState.setHasUserResizedPip(true); } } Loading Loading @@ -399,11 +412,14 @@ public class PipResizeGestureHandler { } private void finishResize() { if (!mLastResizeBounds.isEmpty()) { // Pinch-to-resize needs to re-calculate snap fraction and animate to the snapped // position correctly. Drag-resize does not need to move, so just finalize resize. if (mOngoingPinchToResize) { if (mLastResizeBounds.isEmpty()) { resetState(); } if (!mOngoingPinchToResize) { return; } final Rect startBounds = new Rect(mLastResizeBounds); // If user resize is pretty close to max size, just auto resize to max. if (mLastResizeBounds.width() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.x || mLastResizeBounds.height() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.y) { Loading @@ -427,29 +443,12 @@ public class PipResizeGestureHandler { mLastResizeBounds, movementBounds); mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds, snapFraction); // disable any touch events beyond resizing too mPipTouchState.setAllowInputEvents(false); // Update the transition state to schedule a resize transition. Bundle extra = new Bundle(); extra.putBoolean(RESIZE_BOUNDS_CHANGE, true); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); /* mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds, PINCH_RESIZE_SNAP_DURATION, mAngle, mUpdateResizeBoundsCallback, () -> { // enable touch events mPipTouchState.setAllowInputEvents(true); }); */ } else { /* mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, TRANSITION_DIRECTION_USER_RESIZE, mUpdateResizeBoundsCallback); */ } final float magnetRadiusPercent = (float) mLastResizeBounds.width() / mMinSize.x / 2.f; mPipUiEventLogger.log( PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE); } else { resetState(); } mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE); } private void resetState() { Loading Loading @@ -509,6 +508,40 @@ public class PipResizeGestureHandler { rect.set(l, t, r, b); } @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { switch (newState) { case PipTransitionState.SCHEDULED_BOUNDS_CHANGE: if (!extra.getBoolean(RESIZE_BOUNDS_CHANGE)) break; mWaitingForBoundsChangeTransition = true; mPipScheduler.scheduleAnimateResizePip(mLastResizeBounds); break; case PipTransitionState.CHANGING_PIP_BOUNDS: if (!mWaitingForBoundsChangeTransition) break; // If bounds change transition was scheduled from this class, handle leash updates. mWaitingForBoundsChangeTransition = false; SurfaceControl.Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); Rect destinationBounds = extra.getParcelable( PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); startTx.setPosition(mPipTransitionState.mPinnedTaskLeash, destinationBounds.left, destinationBounds.top); startTx.apply(); // All motion operations have actually finished, so make bounds cache updates. cleanUpHighPerfSessionMaybe(); // Setting state to CHANGED_PIP_BOUNDS applies finishTx and notifies Core. mPipTransitionState.setState(PipTransitionState.CHANGED_PIP_BOUNDS); mUpdateResizeBoundsCallback.accept(destinationBounds); break; } } /** * Dumps the {@link PipResizeGestureHandler} state. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +21 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Matrix; import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; Loading Loading @@ -165,6 +166,16 @@ public class PipScheduler { * {@link WindowContainerTransaction}. */ public void scheduleUserResizePip(Rect toBounds) { scheduleUserResizePip(toBounds, 0f /* degrees */); } /** * Directly perform a scaled matrix transformation on the leash. This will not perform any * {@link WindowContainerTransaction}. * * @param degrees the angle to rotate the bounds to. */ public void scheduleUserResizePip(Rect toBounds, float degrees) { if (toBounds.isEmpty()) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: Attempted to user resize PIP to empty bounds, aborting.", TAG); Loading @@ -172,7 +183,16 @@ public class PipScheduler { } SurfaceControl leash = mPipTransitionState.mPinnedTaskLeash; final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); tx.setPosition(leash, toBounds.left, toBounds.top); Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; final float scale = (float) toBounds.width() / mPipBoundsState.getBounds().width(); transformTensor.setScale(scale, scale); transformTensor.postTranslate(toBounds.left, toBounds.top); transformTensor.postRotate(degrees, toBounds.centerX(), toBounds.centerY()); tx.setMatrix(leash, transformTensor, mMatrixTmp); tx.apply(); } } libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +10 −6 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ import java.util.Optional; * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding * the PIP. */ public class PipTouchHandler { public class PipTouchHandler implements PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PipTouchHandler"; private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f; Loading @@ -84,6 +84,7 @@ public class PipTouchHandler { private final PipBoundsAlgorithm mPipBoundsAlgorithm; @NonNull private final PipBoundsState mPipBoundsState; @NonNull private final PipTransitionState mPipTransitionState; @NonNull private final PipScheduler mPipScheduler; @NonNull private final SizeSpecSource mSizeSpecSource; private final PipUiEventLogger mPipUiEventLogger; private final PipDismissTargetHandler mPipDismissTargetHandler; Loading Loading @@ -173,6 +174,7 @@ public class PipTouchHandler { PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, @NonNull PipTransitionState pipTransitionState, @NonNull PipScheduler pipScheduler, @NonNull SizeSpecSource sizeSpecSource, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, Loading @@ -188,6 +190,7 @@ public class PipTouchHandler { mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mPipScheduler = pipScheduler; mSizeSpecSource = sizeSpecSource; mMenuController = menuController; mPipUiEventLogger = pipUiEventLogger; Loading @@ -213,10 +216,10 @@ public class PipTouchHandler { }, menuController::hideMenu, mainExecutor); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState, mTouchState, this::updateMovementBounds, pipUiEventLogger, menuController, mainExecutor, mPipPerfHintController); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState, mTouchState, mPipScheduler, mPipTransitionState, this::updateMovementBounds, pipUiEventLogger, menuController, mainExecutor, mPipPerfHintController); mPipBoundsState.addOnAspectRatioChangedCallback(this::updateMinMaxSize); if (PipUtils.isPip2ExperimentEnabled()) { Loading Loading @@ -1075,7 +1078,8 @@ public class PipTouchHandler { mPipResizeGestureHandler.setOhmOffset(offset); } private void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { switch (newState) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +2 −1 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, @NonNull PipTransitionState pipTransitionState, @NonNull PipScheduler pipScheduler, @NonNull SizeSpecSource sizeSpecSource, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, Loading @@ -140,7 +141,7 @@ public abstract class Pip2Module { @ShellMainThread ShellExecutor mainExecutor, Optional<PipPerfHintController> pipPerfHintControllerOptional) { return new PipTouchHandler(context, shellInit, menuPhoneController, pipBoundsAlgorithm, pipBoundsState, pipTransitionState, sizeSpecSource, pipMotionHelper, pipBoundsState, pipTransitionState, pipScheduler, sizeSpecSource, pipMotionHelper, floatingContentCoordinator, pipUiEventLogger, mainExecutor, pipPerfHintControllerOptional); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +5 −3 Original line number Diff line number Diff line Loading @@ -58,7 +58,8 @@ import java.util.function.Consumer; * A helper to animate and manipulate the PiP. */ public class PipMotionHelper implements PipAppOpsListener.Callback, FloatingContentCoordinator.FloatingContent { FloatingContentCoordinator.FloatingContent, PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PipMotionHelper"; private static final String FLING_BOUNDS_CHANGE = "fling_bounds_change"; private static final boolean DEBUG = false; Loading Loading @@ -181,7 +182,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, } }; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mPipTransitionState.addPipTransitionStateChangedListener(this); } void init() { Loading Loading @@ -687,7 +688,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, // setAnimatingToBounds(toBounds); } private void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { switch (newState) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java +100 −67 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.Looper; import android.view.BatchedInputEventReceiver; import android.view.Choreographer; Loading @@ -32,6 +33,7 @@ import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.InputMonitor; import android.view.MotionEvent; import android.view.SurfaceControl; import android.view.ViewConfiguration; import androidx.annotation.VisibleForTesting; Loading @@ -51,16 +53,20 @@ import java.util.function.Consumer; * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to * trigger dynamic resize. */ public class PipResizeGestureHandler { public class PipResizeGestureHandler implements PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PipResizeGestureHandler"; private static final int PINCH_RESIZE_SNAP_DURATION = 250; private static final float PINCH_RESIZE_AUTO_MAX_RATIO = 0.9f; private static final String RESIZE_BOUNDS_CHANGE = "resize_bounds_change"; private final Context mContext; private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final PipBoundsState mPipBoundsState; private final PipTouchState mPipTouchState; private final PipScheduler mPipScheduler; private final PipTransitionState mPipTransitionState; private final PhonePipMenuController mPhonePipMenuController; private final PipUiEventLogger mPipUiEventLogger; private final PipPinchResizingAlgorithm mPinchResizingAlgorithm; Loading Loading @@ -88,6 +94,7 @@ public class PipResizeGestureHandler { private boolean mIsSysUiStateValid; private boolean mThresholdCrossed; private boolean mOngoingPinchToResize = false; private boolean mWaitingForBoundsChangeTransition = false; private float mAngle = 0; int mFirstIndex = -1; int mSecondIndex = -1; Loading @@ -104,11 +111,17 @@ public class PipResizeGestureHandler { private int mCtrlType; private int mOhmOffset; public PipResizeGestureHandler(Context context, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipTouchState pipTouchState, public PipResizeGestureHandler(Context context, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipTouchState pipTouchState, PipScheduler pipScheduler, PipTransitionState pipTransitionState, Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, ShellExecutor mainExecutor, @Nullable PipPerfHintController pipPerfHintController) { PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, ShellExecutor mainExecutor, @Nullable PipPerfHintController pipPerfHintController) { mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = mainExecutor; Loading @@ -116,6 +129,11 @@ public class PipResizeGestureHandler { mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; mPipTouchState = pipTouchState; mPipScheduler = pipScheduler; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; mPhonePipMenuController = menuActivityController; mPipUiEventLogger = pipUiEventLogger; Loading @@ -125,6 +143,7 @@ public class PipResizeGestureHandler { mUserResizeBounds.set(rect); // mMotionHelper.synchronizePinnedStackBounds(); mUpdateMovementBoundsRunnable.run(); mPipBoundsState.setBounds(rect); resetState(); }; } Loading Loading @@ -202,7 +221,7 @@ public class PipResizeGestureHandler { @VisibleForTesting void onInputEvent(InputEvent ev) { if (!mEnablePinchResize) { // No need to handle anything if neither form of resizing is enabled. // No need to handle anything if resizing isn't enabled. return; } Loading @@ -227,7 +246,7 @@ public class PipResizeGestureHandler { } } if (mEnablePinchResize && mOngoingPinchToResize) { if (mOngoingPinchToResize) { onPinchResize(mv); } } Loading @@ -249,7 +268,6 @@ public class PipResizeGestureHandler { } boolean willStartResizeGesture(MotionEvent ev) { if (isInValidSysUiState()) { if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { if (mEnablePinchResize && ev.getPointerCount() == 2) { onPinchResize(ev); Loading @@ -257,7 +275,6 @@ public class PipResizeGestureHandler { return mAllowGesture; } } } return false; } Loading @@ -284,7 +301,6 @@ public class PipResizeGestureHandler { mSecondIndex = -1; mAllowGesture = false; finishResize(); cleanUpHighPerfSessionMaybe(); } if (ev.getPointerCount() != 2) { Loading Loading @@ -347,10 +363,7 @@ public class PipResizeGestureHandler { mDownSecondPoint, mLastPoint, mLastSecondPoint, mMinSize, mMaxSize, mDownBounds, mLastResizeBounds); /* mPipTaskOrganizer.scheduleUserResizePip(mDownBounds, mLastResizeBounds, mAngle, null); */ mPipScheduler.scheduleUserResizePip(mLastResizeBounds, mAngle); mPipBoundsState.setHasUserResizedPip(true); } } Loading Loading @@ -399,11 +412,14 @@ public class PipResizeGestureHandler { } private void finishResize() { if (!mLastResizeBounds.isEmpty()) { // Pinch-to-resize needs to re-calculate snap fraction and animate to the snapped // position correctly. Drag-resize does not need to move, so just finalize resize. if (mOngoingPinchToResize) { if (mLastResizeBounds.isEmpty()) { resetState(); } if (!mOngoingPinchToResize) { return; } final Rect startBounds = new Rect(mLastResizeBounds); // If user resize is pretty close to max size, just auto resize to max. if (mLastResizeBounds.width() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.x || mLastResizeBounds.height() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.y) { Loading @@ -427,29 +443,12 @@ public class PipResizeGestureHandler { mLastResizeBounds, movementBounds); mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds, snapFraction); // disable any touch events beyond resizing too mPipTouchState.setAllowInputEvents(false); // Update the transition state to schedule a resize transition. Bundle extra = new Bundle(); extra.putBoolean(RESIZE_BOUNDS_CHANGE, true); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); /* mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds, PINCH_RESIZE_SNAP_DURATION, mAngle, mUpdateResizeBoundsCallback, () -> { // enable touch events mPipTouchState.setAllowInputEvents(true); }); */ } else { /* mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, TRANSITION_DIRECTION_USER_RESIZE, mUpdateResizeBoundsCallback); */ } final float magnetRadiusPercent = (float) mLastResizeBounds.width() / mMinSize.x / 2.f; mPipUiEventLogger.log( PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE); } else { resetState(); } mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE); } private void resetState() { Loading Loading @@ -509,6 +508,40 @@ public class PipResizeGestureHandler { rect.set(l, t, r, b); } @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { switch (newState) { case PipTransitionState.SCHEDULED_BOUNDS_CHANGE: if (!extra.getBoolean(RESIZE_BOUNDS_CHANGE)) break; mWaitingForBoundsChangeTransition = true; mPipScheduler.scheduleAnimateResizePip(mLastResizeBounds); break; case PipTransitionState.CHANGING_PIP_BOUNDS: if (!mWaitingForBoundsChangeTransition) break; // If bounds change transition was scheduled from this class, handle leash updates. mWaitingForBoundsChangeTransition = false; SurfaceControl.Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); Rect destinationBounds = extra.getParcelable( PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); startTx.setPosition(mPipTransitionState.mPinnedTaskLeash, destinationBounds.left, destinationBounds.top); startTx.apply(); // All motion operations have actually finished, so make bounds cache updates. cleanUpHighPerfSessionMaybe(); // Setting state to CHANGED_PIP_BOUNDS applies finishTx and notifies Core. mPipTransitionState.setState(PipTransitionState.CHANGED_PIP_BOUNDS); mUpdateResizeBoundsCallback.accept(destinationBounds); break; } } /** * Dumps the {@link PipResizeGestureHandler} state. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +21 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Matrix; import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; Loading Loading @@ -165,6 +166,16 @@ public class PipScheduler { * {@link WindowContainerTransaction}. */ public void scheduleUserResizePip(Rect toBounds) { scheduleUserResizePip(toBounds, 0f /* degrees */); } /** * Directly perform a scaled matrix transformation on the leash. This will not perform any * {@link WindowContainerTransaction}. * * @param degrees the angle to rotate the bounds to. */ public void scheduleUserResizePip(Rect toBounds, float degrees) { if (toBounds.isEmpty()) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: Attempted to user resize PIP to empty bounds, aborting.", TAG); Loading @@ -172,7 +183,16 @@ public class PipScheduler { } SurfaceControl leash = mPipTransitionState.mPinnedTaskLeash; final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); tx.setPosition(leash, toBounds.left, toBounds.top); Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; final float scale = (float) toBounds.width() / mPipBoundsState.getBounds().width(); transformTensor.setScale(scale, scale); transformTensor.postTranslate(toBounds.left, toBounds.top); transformTensor.postRotate(degrees, toBounds.centerX(), toBounds.centerY()); tx.setMatrix(leash, transformTensor, mMatrixTmp); tx.apply(); } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +10 −6 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ import java.util.Optional; * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding * the PIP. */ public class PipTouchHandler { public class PipTouchHandler implements PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PipTouchHandler"; private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f; Loading @@ -84,6 +84,7 @@ public class PipTouchHandler { private final PipBoundsAlgorithm mPipBoundsAlgorithm; @NonNull private final PipBoundsState mPipBoundsState; @NonNull private final PipTransitionState mPipTransitionState; @NonNull private final PipScheduler mPipScheduler; @NonNull private final SizeSpecSource mSizeSpecSource; private final PipUiEventLogger mPipUiEventLogger; private final PipDismissTargetHandler mPipDismissTargetHandler; Loading Loading @@ -173,6 +174,7 @@ public class PipTouchHandler { PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, @NonNull PipTransitionState pipTransitionState, @NonNull PipScheduler pipScheduler, @NonNull SizeSpecSource sizeSpecSource, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, Loading @@ -188,6 +190,7 @@ public class PipTouchHandler { mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mPipScheduler = pipScheduler; mSizeSpecSource = sizeSpecSource; mMenuController = menuController; mPipUiEventLogger = pipUiEventLogger; Loading @@ -213,10 +216,10 @@ public class PipTouchHandler { }, menuController::hideMenu, mainExecutor); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState, mTouchState, this::updateMovementBounds, pipUiEventLogger, menuController, mainExecutor, mPipPerfHintController); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState, mTouchState, mPipScheduler, mPipTransitionState, this::updateMovementBounds, pipUiEventLogger, menuController, mainExecutor, mPipPerfHintController); mPipBoundsState.addOnAspectRatioChangedCallback(this::updateMinMaxSize); if (PipUtils.isPip2ExperimentEnabled()) { Loading Loading @@ -1075,7 +1078,8 @@ public class PipTouchHandler { mPipResizeGestureHandler.setOhmOffset(offset); } private void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { switch (newState) { Loading