Update config ordering when entering/leaving pip
- Always set the activity windowing mode to the previous windowing mode
prior to pip until SysUI has a chance to update
- When entering with bounds animation, do the bounds animation before
resetting the activity windowing mode and setting final bounds
- When entering with alpha animation, immediately reset the activity
windowing mode and final bounds
- When exiting, set the activity windowing mode to fullscreen along with
the task bounds and do an inverse scale animation from the previous
size up to fullscreen
- Skip the animation when exiting to fullscreen in another orientation
- Dumping pip task org state
Bug: 149946388
Test: Enter/exit pip
Test: atest PinnedStackTests
Change-Id: Ia5a50a5e2ce7621c2c678d0ded3d8c02b1932302
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
index f72de11..13516a9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
@@ -65,6 +65,10 @@
@Retention(RetentionPolicy.SOURCE)
public @interface TransitionDirection {}
+ public static boolean isInPipDirection(@TransitionDirection int direction) {
+ return direction == TRANSITION_DIRECTION_TO_PIP;
+ }
+
public static boolean isOutPipDirection(@TransitionDirection int direction) {
return direction == TRANSITION_DIRECTION_TO_FULLSCREEN
|| direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
@@ -104,6 +108,12 @@
if (mCurrentAnimator == null) {
mCurrentAnimator = setupPipTransitionAnimator(
PipTransitionAnimator.ofBounds(leash, startBounds, endBounds));
+ } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA
+ && mCurrentAnimator.isRunning()) {
+ // If we are still animating the fade into pip, then just move the surface and ensure
+ // we update with the new destination bounds, but don't interrupt the existing animation
+ // with a new bounds
+ mCurrentAnimator.setDestinationBounds(endBounds);
} else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_BOUNDS
&& mCurrentAnimator.isRunning()) {
mCurrentAnimator.setDestinationBounds(endBounds);
@@ -265,8 +275,7 @@
boolean inScaleTransition() {
if (mAnimationType != ANIM_TYPE_BOUNDS) return false;
- final int direction = getTransitionDirection();
- return !isOutPipDirection(direction) && direction != TRANSITION_DIRECTION_TO_PIP;
+ return !isInPipDirection(getTransitionDirection());
}
/**
@@ -354,7 +363,11 @@
getCastedFractionValue(start.bottom, end.bottom, fraction));
setCurrentValue(mTmpRect);
if (inScaleTransition()) {
- getSurfaceTransactionHelper().scale(tx, leash, start, mTmpRect);
+ if (isOutPipDirection(getTransitionDirection())) {
+ getSurfaceTransactionHelper().scale(tx, leash, end, mTmpRect);
+ } else {
+ getSurfaceTransactionHelper().scale(tx, leash, start, mTmpRect);
+ }
} else {
getSurfaceTransactionHelper().crop(tx, leash, mTmpRect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 3eeadc3..394f997 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -209,6 +209,10 @@
return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
+ public int getDisplayRotation() {
+ return mDisplayInfo.rotation;
+ }
+
/**
* Responds to IPinnedStackListener on {@link DisplayInfo} change.
* It will normally follow up with a
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 7e2efc0..fd13890 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -16,6 +16,9 @@
package com.android.systemui.pip;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA;
@@ -25,25 +28,30 @@
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
+import static com.android.systemui.pip.PipAnimationController.isInPipDirection;
import static com.android.systemui.pip.PipAnimationController.isOutPipDirection;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.RemoteException;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceControl;
import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
+import android.window.WindowContainerTransactionCallback;
import android.window.WindowOrganizer;
import com.android.internal.os.SomeArgs;
@@ -51,6 +59,7 @@
import com.android.systemui.pip.phone.PipUpdateThread;
import com.android.systemui.stackdivider.Divider;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -90,7 +99,7 @@
private final Rect mLastReportedBounds = new Rect();
private final int mEnterExitAnimationDuration;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
- private final Map<IBinder, Rect> mBoundsToRestore = new HashMap<>();
+ private final Map<IBinder, Configuration> mInitialState = new HashMap<>();
private final Divider mSplitDivider;
// These callbacks are called on the update thread
@@ -110,7 +119,8 @@
@Override
public void onPipAnimationEnd(SurfaceControl.Transaction tx,
PipAnimationController.PipTransitionAnimator animator) {
- finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection());
+ finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection(),
+ animator.getAnimationType());
mMainHandler.post(() -> {
for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
@@ -170,7 +180,7 @@
case MSG_FINISH_RESIZE: {
SurfaceControl.Transaction tx = (SurfaceControl.Transaction) args.arg2;
Rect toBounds = (Rect) args.arg3;
- finishResize(tx, toBounds, args.argi1 /* direction */);
+ finishResize(tx, toBounds, args.argi1 /* direction */, -1);
if (updateBoundsCallback != null) {
updateBoundsCallback.accept(toBounds);
}
@@ -240,28 +250,76 @@
}
/**
- * Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction}
- * - setActivityWindowingMode to undefined at beginning of the transaction. without changing
- * the windowing mode of the Task itself. This makes sure the activity render it's final
- * configuration while the Task is still in PiP.
+ * Expands PiP to the previous bounds, this is done in two phases using
+ * {@link WindowContainerTransaction}
+ * - setActivityWindowingMode to either fullscreen or split-secondary at beginning of the
+ * transaction. without changing the windowing mode of the Task itself. This makes sure the
+ * activity render it's final configuration while the Task is still in PiP.
* - setWindowingMode to undefined at the end of transition
* @param animationDurationMs duration in millisecond for the exiting PiP transition
*/
- public void dismissPip(int animationDurationMs) {
+ public void exitPip(int animationDurationMs) {
if (!mInPip || mToken == null) {
- Log.wtf(TAG, "Not allowed to dismissPip in current state"
+ Log.wtf(TAG, "Not allowed to exitPip in current state"
+ " mInPip=" + mInPip + " mToken=" + mToken);
return;
}
+
+ final Configuration initialConfig = mInitialState.remove(mToken.asBinder());
+ final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation()
+ != mPipBoundsHandler.getDisplayRotation();
final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- WindowOrganizer.applyTransaction(wct);
- final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
- final int direction = syncWithSplitScreenBounds(destinationBounds)
- ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN;
- scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
- direction, animationDurationMs, null /* updateBoundsCallback */);
- mInPip = false;
+ if (orientationDiffers) {
+ // Don't bother doing an animation if the display rotation differs or if it's in
+ // a non-supported windowing mode
+ wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ WindowOrganizer.applyTransaction(wct);
+ mInPip = false;
+ } else {
+ final Rect destinationBounds = initialConfig.windowConfiguration.getBounds();
+ final int direction = syncWithSplitScreenBounds(destinationBounds)
+ ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
+ : TRANSITION_DIRECTION_TO_FULLSCREEN;
+ final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+ mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
+ mLastReportedBounds);
+ tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
+ wct.setActivityWindowingMode(mToken, direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN
+ ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+ : WINDOWING_MODE_FULLSCREEN);
+ wct.setBounds(mToken, destinationBounds);
+ wct.setBoundsChangeTransaction(mToken, tx);
+ applySyncTransaction(wct, new WindowContainerTransactionCallback() {
+ @Override
+ public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+ t.apply();
+ scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
+ direction, animationDurationMs, null /* updateBoundsCallback */);
+ mInPip = false;
+ }
+ });
+ }
+ }
+
+ /**
+ * Removes PiP immediately.
+ */
+ public void removePip() {
+ if (!mInPip || mToken == null) {
+ Log.wtf(TAG, "Not allowed to removePip in current state"
+ + " mInPip=" + mInPip + " mToken=" + mToken);
+ return;
+ }
+ getUpdateHandler().post(() -> {
+ try {
+ ActivityTaskManager.getService().removeStacksInWindowingModes(
+ new int[]{ WINDOWING_MODE_PINNED });
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to remove PiP", e);
+ }
+ });
+ mInitialState.remove(mToken.asBinder());
}
@Override
@@ -277,19 +335,37 @@
mInPip = true;
mLeash = leash;
+ // TODO: Skip enter animation when entering pip from another orientation
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
- mBoundsToRestore.put(mToken.asBinder(), currentBounds);
+ mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
+
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
scheduleAnimateResizePip(currentBounds, destinationBounds,
TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
null /* updateBoundsCallback */);
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
- mUpdateHandler.post(() -> mPipAnimationController
- .getAnimator(mLeash, destinationBounds, 0f, 1f)
- .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
- .setPipAnimationCallback(mPipAnimationCallback)
- .setDuration(mEnterExitAnimationDuration)
- .start());
+ // If we are fading the PIP in, then we should move the pip to the final location as
+ // soon as possible, but set the alpha immediately since the transaction can take a
+ // while to process
+ final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+ tx.setAlpha(mLeash, 0f);
+ tx.apply();
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ wct.setBounds(mToken, destinationBounds);
+ wct.scheduleFinishEnterPip(mToken, destinationBounds);
+ applySyncTransaction(wct, new WindowContainerTransactionCallback() {
+ @Override
+ public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+ t.apply();
+ mUpdateHandler.post(() -> mPipAnimationController
+ .getAnimator(mLeash, destinationBounds, 0f, 1f)
+ .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
+ .setPipAnimationCallback(mPipAnimationCallback)
+ .setDuration(mEnterExitAnimationDuration)
+ .start());
+ }
+ });
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
} else {
throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
@@ -297,7 +373,7 @@
}
/**
- * Note that dismissing PiP is now originated from SystemUI, see {@link #dismissPip(int)}.
+ * Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int)}.
* Meanwhile this callback is invoked whenever the task is removed. For instance:
* - as a result of removeStacksInWindowingModes from WM
* - activity itself is died
@@ -411,6 +487,7 @@
// can be initiated in other component, ignore if we are no longer in PIP
return;
}
+
SomeArgs args = SomeArgs.obtain();
args.arg1 = updateBoundsCallback;
args.arg2 = currentBounds;
@@ -509,7 +586,7 @@
throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
+ "directly");
}
- // Could happen when dismissPip
+ // Could happen when exitPip
if (mToken == null || mLeash == null) {
Log.w(TAG, "Abort animation, invalid leash");
return;
@@ -526,7 +603,7 @@
throw new RuntimeException("Callers should call scheduleUserResizePip() instead of "
+ "this directly");
}
- // Could happen when dismissPip
+ // Could happen when exitPip
if (mToken == null || mLeash == null) {
Log.w(TAG, "Abort animation, invalid leash");
return;
@@ -537,32 +614,43 @@
}
private void finishResize(SurfaceControl.Transaction tx, Rect destinationBounds,
- @PipAnimationController.TransitionDirection int direction) {
+ @PipAnimationController.TransitionDirection int direction,
+ @PipAnimationController.AnimationType int type) {
if (Looper.myLooper() != mUpdateHandler.getLooper()) {
throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
+ "directly");
}
mLastReportedBounds.set(destinationBounds);
+ if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
+ return;
+ }
+
final WindowContainerTransaction wct = new WindowContainerTransaction();
final Rect taskBounds;
- if (isOutPipDirection(direction)) {
+ if (isInPipDirection(direction)) {
+ // If we are animating from fullscreen using a bounds animation, then reset the
+ // activity windowing mode set by WM, and set the task bounds to the final bounds
+ taskBounds = destinationBounds;
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ wct.scheduleFinishEnterPip(mToken, destinationBounds);
+ } else if (isOutPipDirection(direction)) {
// 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.
taskBounds = (direction == TRANSITION_DIRECTION_TO_FULLSCREEN)
? null : destinationBounds;
- // As for the final windowing mode, simply reset it to undefined.
+ // As for the final windowing mode, simply reset it to undefined and reset the activity
+ // mode set prior to the animation running
wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
if (mSplitDivider != null && direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN) {
wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */);
}
} else {
+ // Just a resize in PIP
taskBounds = destinationBounds;
}
- if (direction == TRANSITION_DIRECTION_TO_PIP) {
- wct.scheduleFinishEnterPip(mToken, taskBounds);
- } else {
- wct.setBounds(mToken, taskBounds);
- }
+
+ wct.setBounds(mToken, taskBounds);
wct.setBoundsChangeTransaction(mToken, tx);
WindowOrganizer.applyTransaction(wct);
}
@@ -573,17 +661,17 @@
throw new RuntimeException("Callers should call scheduleAnimateResizePip() instead of "
+ "this directly");
}
- // Could happen when dismissPip
+ // Could happen when exitPip
if (mToken == null || mLeash == null) {
Log.w(TAG, "Abort animation, invalid leash");
return;
}
- mUpdateHandler.post(() -> mPipAnimationController
+ mPipAnimationController
.getAnimator(mLeash, currentBounds, destinationBounds)
.setTransitionDirection(direction)
.setPipAnimationCallback(mPipAnimationCallback)
.setDuration(durationMs)
- .start());
+ .start();
}
private Size getMinimalSize(ActivityInfo activityInfo) {
@@ -624,6 +712,27 @@
}
/**
+ * Dumps internal states.
+ */
+ public void dump(PrintWriter pw, String prefix) {
+ final String innerPrefix = prefix + " ";
+ pw.println(prefix + TAG);
+ pw.println(innerPrefix + "mTaskInfo=" + mTaskInfo);
+ pw.println(innerPrefix + "mToken=" + mToken
+ + " binder=" + (mToken != null ? mToken.asBinder() : null));
+ pw.println(innerPrefix + "mLeash=" + mLeash);
+ pw.println(innerPrefix + "mInPip=" + mInPip);
+ pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
+ pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
+ pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds);
+ pw.println(innerPrefix + "mInitialState:");
+ for (Map.Entry<IBinder, Configuration> e : mInitialState.entrySet()) {
+ pw.println(innerPrefix + " binder=" + e.getKey()
+ + " winConfig=" + e.getValue().windowConfiguration);
+ }
+ }
+
+ /**
* Callback interface for PiP transitions (both from and to PiP mode)
*/
public interface PipTransitionCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
index 84f7e89..f1eef43 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
@@ -101,7 +101,7 @@
result = true;
break;
case AccessibilityNodeInfo.ACTION_EXPAND:
- mMotionHelper.expandPip();
+ mMotionHelper.expandPipToFullscreen();
result = true;
break;
default:
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 0841bb7..30d6cd9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -25,7 +25,6 @@
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IActivityManager;
-import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ParceledListSlice;
@@ -140,7 +139,7 @@
!= WINDOWING_MODE_PINNED) {
return;
}
- mTouchHandler.getMotionHelper().expandPip(clearedTask /* skipAnimation */);
+ mTouchHandler.getMotionHelper().expandPipToFullscreen(clearedTask /* skipAnimation */);
}
};
@@ -214,7 +213,6 @@
}
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
- final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
mPipBoundsHandler = pipBoundsHandler;
mPipTaskOrganizer = pipTaskOrganizer;
mPipTaskOrganizer.registerPipTransitionCallback(this);
@@ -222,7 +220,7 @@
mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
mMenuController = new PipMenuActivityController(context, mMediaController,
mInputConsumerController);
- mTouchHandler = new PipTouchHandler(context, mActivityManager, activityTaskManager,
+ mTouchHandler = new PipTouchHandler(context, mActivityManager,
mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
floatingContentCoordinator, deviceConfig, pipSnapAlgorithm);
mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
@@ -237,7 +235,7 @@
try {
mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
- ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo(
+ ActivityManager.StackInfo stackInfo = ActivityTaskManager.getService().getStackInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (stackInfo != null) {
// If SystemUI restart, and it already existed a pinned stack,
@@ -261,7 +259,7 @@
*/
@Override
public void expandPip() {
- mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
+ mTouchHandler.getMotionHelper().expandPipToFullscreen(false /* skipAnimation */);
}
/**
@@ -378,5 +376,6 @@
mMenuController.dump(pw, innerPrefix);
mTouchHandler.dump(pw, innerPrefix);
mPipBoundsHandler.dump(pw, innerPrefix);
+ mPipTaskOrganizer.dump(pw, innerPrefix);
}
}
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 08d4222..d099597 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -16,16 +16,12 @@
package com.android.systemui.pip.phone;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Rect;
import android.os.Debug;
-import android.os.RemoteException;
import android.util.Log;
import androidx.dynamicanimation.animation.SpringForce;
@@ -33,7 +29,6 @@
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.util.FloatingContentCoordinator;
import com.android.systemui.util.animation.FloatProperties;
import com.android.systemui.util.animation.PhysicsAnimator;
@@ -60,12 +55,10 @@
private static final float DEFAULT_FRICTION = 2f;
private final Context mContext;
- private final IActivityTaskManager mActivityTaskManager;
private final PipTaskOrganizer mPipTaskOrganizer;
private PipMenuActivityController mMenuController;
private PipSnapAlgorithm mSnapAlgorithm;
- private FlingAnimationUtils mFlingAnimationUtils;
private final Rect mStableInsets = new Rect();
@@ -147,16 +140,13 @@
public void onPipTransitionCanceled(ComponentName activity, int direction) {}
};
- public PipMotionHelper(Context context, IActivityTaskManager activityTaskManager,
- PipTaskOrganizer pipTaskOrganizer, PipMenuActivityController menuController,
- PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils,
+ public PipMotionHelper(Context context, PipTaskOrganizer pipTaskOrganizer,
+ PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm,
FloatingContentCoordinator floatingContentCoordinator) {
mContext = context;
- mActivityTaskManager = activityTaskManager;
mPipTaskOrganizer = pipTaskOrganizer;
mMenuController = menuController;
mSnapAlgorithm = snapAlgorithm;
- mFlingAnimationUtils = flingAnimationUtils;
mFloatingContentCoordinator = floatingContentCoordinator;
onConfigurationChanged();
mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
@@ -267,22 +257,24 @@
/**
* Resizes the pinned stack back to fullscreen.
*/
- void expandPip() {
- expandPip(false /* skipAnimation */);
+ void expandPipToFullscreen() {
+ expandPipToFullscreen(false /* skipAnimation */);
}
/**
* Resizes the pinned stack back to fullscreen.
*/
- void expandPip(boolean skipAnimation) {
+ void expandPipToFullscreen(boolean skipAnimation) {
if (DEBUG) {
- Log.d(TAG, "expandPip: skipAnimation=" + skipAnimation
+ Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
+ " callers=\n" + Debug.getCallers(5, " "));
}
cancelAnimations();
mMenuController.hideMenuWithoutResize();
mPipTaskOrganizer.getUpdateHandler().post(() -> {
- mPipTaskOrganizer.dismissPip(skipAnimation ? 0 : EXPAND_STACK_TO_FULLSCREEN_DURATION);
+ mPipTaskOrganizer.exitPip(skipAnimation
+ ? 0
+ : EXPAND_STACK_TO_FULLSCREEN_DURATION);
});
}
@@ -292,18 +284,11 @@
@Override
public void dismissPip() {
if (DEBUG) {
- Log.d(TAG, "dismissPip: callers=\n" + Debug.getCallers(5, " "));
+ Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, " "));
}
cancelAnimations();
mMenuController.hideMenuWithoutResize();
- mPipTaskOrganizer.getUpdateHandler().post(() -> {
- try {
- mActivityTaskManager.removeStacksInWindowingModes(
- new int[]{ WINDOWING_MODE_PINNED });
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to remove PiP", e);
- }
- });
+ mPipTaskOrganizer.removePip();
}
/** Sets the movement bounds to use to constrain PIP position animations. */
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 b70fb3f..ca73a6c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -23,7 +23,6 @@
import android.annotation.SuppressLint;
import android.app.IActivityManager;
-import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
@@ -188,7 +187,7 @@
@Override
public void onPipExpand() {
- mMotionHelper.expandPip();
+ mMotionHelper.expandPipToFullscreen();
}
@Override
@@ -210,7 +209,7 @@
@SuppressLint("InflateParams")
public PipTouchHandler(Context context, IActivityManager activityManager,
- IActivityTaskManager activityTaskManager, PipMenuActivityController menuController,
+ PipMenuActivityController menuController,
InputConsumerController inputConsumerController,
PipBoundsHandler pipBoundsHandler,
PipTaskOrganizer pipTaskOrganizer,
@@ -228,8 +227,8 @@
mFlingAnimationUtils = new FlingAnimationUtils(context.getResources().getDisplayMetrics(),
2.5f);
mGesture = new DefaultPipTouchGesture();
- mMotionHelper = new PipMotionHelper(mContext, activityTaskManager, pipTaskOrganizer,
- mMenuController, mSnapAlgorithm, mFlingAnimationUtils, floatingContentCoordinator);
+ mMotionHelper = new PipMotionHelper(mContext, pipTaskOrganizer, mMenuController,
+ mSnapAlgorithm, floatingContentCoordinator);
mPipResizeGestureHandler =
new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper,
deviceConfig, pipTaskOrganizer);
@@ -905,7 +904,7 @@
// Expand to fullscreen if this is a double tap
// the PiP should be frozen until the transition ends
setTouchEnabled(false);
- mMotionHelper.expandPip();
+ mMotionHelper.expandPipToFullscreen();
} else if (mMenuState != MENU_STATE_FULL) {
if (!mTouchState.isWaitingForDoubleTap()) {
// User has stalled long enough for this not to be a drag or a double tap, just
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 f49732d..6282236 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -468,7 +468,7 @@
mPipTaskOrganizer.scheduleAnimateResizePip(mCurrentPipBounds, mResizeAnimationDuration,
null);
} else {
- mPipTaskOrganizer.dismissPip(mResizeAnimationDuration);
+ mPipTaskOrganizer.exitPip(mResizeAnimationDuration);
}
}