summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Rosky <erosky@google.com> 2022-03-18 15:33:36 -0700
committer Evan Rosky <erosky@google.com> 2022-03-18 15:33:36 -0700
commit433c5eae073416d7b30536b0335f91018443985c (patch)
tree3252a6d2a73b95654ac2b0d2c823c8698a020bc6
parentcde55d305f5b7d43f5b026812ba0b149bac6d5cf (diff)
Sync PiP WM bounds to rotation immediately for fade-in
When pip is fading-in, it should be reconfigured at the start of the animation. This means that if the display rotates, we want to immediately update the pip bounds to match otherwise the window content will be relayout-ed in the wrong place on screen -- usually resulting in unwanted insets. In this case, keep track of when we are expecting to start a fade-in and, in that situation, recalculate the bounds. Additionally, fix a non-deterministic ordering situation where some legacy per-activity callbacks would make global changes. This meant that the order of activities in mParticipants could effect which transition was actually requested. This CL moves all the legacy callbacks after the other per-activity logic in finishTransition. Bug: 222033492 Test: Open landscape auto-pip app. Open recents, tap on edge watch pip fade-in without content-flicker Change-Id: Iea3dc3ac4ddda02e1b464baedd11fb1cc9cbe930
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java3
-rw-r--r--services/core/java/com/android/server/wm/Transition.java10
4 files changed, 47 insertions, 1 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index be713a59a816..f3af9594dcbd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -89,6 +89,8 @@ public class PipTransition extends PipTransitionController {
private final Rect mExitDestinationBounds = new Rect();
@Nullable
private IBinder mExitTransition;
+ private IBinder mRequestedEnterTransition;
+ private WindowContainerToken mRequestedEnterTask;
/** The Task window that is currently in PIP windowing mode. */
@Nullable
private WindowContainerToken mCurrentPipTaskToken;
@@ -202,6 +204,9 @@ public class PipTransition extends PipTransitionController {
}
mCurrentPipTaskToken = null;
return true;
+ } else if (transition == mRequestedEnterTransition) {
+ mRequestedEnterTransition = null;
+ mRequestedEnterTask = null;
}
// The previous PIP Task is no longer in PIP, but this is not an exit transition (This can
@@ -239,6 +244,8 @@ public class PipTransition extends PipTransitionController {
if (request.getType() == TRANSIT_PIP) {
WindowContainerTransaction wct = new WindowContainerTransaction();
if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+ mRequestedEnterTransition = transition;
+ mRequestedEnterTask = request.getTriggerTask().token;
wct.setActivityWindowingMode(request.getTriggerTask().token,
WINDOWING_MODE_UNDEFINED);
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
@@ -251,6 +258,23 @@ public class PipTransition extends PipTransitionController {
}
@Override
+ public boolean handleRotateDisplay(int startRotation, int endRotation,
+ WindowContainerTransaction wct) {
+ if (mRequestedEnterTransition != null && mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+ // A fade-in was requested but not-yet started. In this case, just recalculate the
+ // initial state under the new rotation.
+ int rotationDelta = deltaRotation(startRotation, endRotation);
+ if (rotationDelta != Surface.ROTATION_0) {
+ mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), endRotation);
+ final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
+ wct.setBounds(mRequestedEnterTask, destinationBounds);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
public void onTransitionMerged(@NonNull IBinder transition) {
if (transition != mExitTransition) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 02e713d2eaa3..24993c621e3c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -196,6 +196,17 @@ public abstract class PipTransitionController implements Transitions.TransitionH
}
/**
+ * Called when the display is going to rotate.
+ *
+ * @return {@code true} if it was handled, otherwise the existing pip logic
+ * will deal with rotation.
+ */
+ public boolean handleRotateDisplay(int startRotation, int endRotation,
+ WindowContainerTransaction wct) {
+ return false;
+ }
+
+ /**
* Callback interface for PiP transitions (both from and to PiP mode)
*/
public interface PipTransitionCallback {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index e7a1c4cca07e..f13153ac90ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -143,6 +143,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
*/
private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
+ if (mPipTransitionController.handleRotateDisplay(fromRotation, toRotation, t)) {
+ return;
+ }
if (mPipBoundsState.getDisplayLayout().rotation() == toRotation) {
// The same rotation may have been set by auto PiP-able or fixed rotation. So notify
// the change with fromRotation=false to apply the rotated destination bounds from
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 21ca4bb6038b..557ca4c97838 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -520,7 +520,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// Legacy dispatch relies on this (for now).
ar.mEnteringAnimation = visibleAtTransitionEnd;
}
- mController.dispatchLegacyAppTransitionFinished(ar);
}
final WallpaperWindowToken wt = mParticipants.valueAt(i).asWallpaperToken();
if (wt != null) {
@@ -532,6 +531,15 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
}
}
}
+ // dispatch legacy callback in a different loop. This is because multiple legacy handlers
+ // (fixed-rotation/displaycontent) make global changes, so we want to ensure that we've
+ // processed all the participants first (in particular, we want to trigger pip-enter first)
+ for (int i = 0; i < mParticipants.size(); ++i) {
+ final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
+ if (ar != null) {
+ mController.dispatchLegacyAppTransitionFinished(ar);
+ }
+ }
if (activitiesWentInvisible) {
// Always schedule stop processing when transition finishes because activities don't
// stop while they are in a transition thus their stop could still be pending.