summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java58
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java38
4 files changed, 96 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 89cad9c53464..6c6fbee885f2 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2098,6 +2098,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// from the client organizer, so the PIP activity can get the correct config
// from the Task, and prevent conflict with the PipTaskOrganizer.
tf.updateRequestedOverrideConfiguration(EMPTY);
+ tf.updateRelativeEmbeddedBounds();
}
});
rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 7eb9c16a25ff..454f338045d1 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -300,6 +300,14 @@ class TaskFragment extends WindowContainer<WindowContainer> {
private final IBinder mFragmentToken;
/**
+ * The bounds of the embedded TaskFragment relative to the parent Task.
+ * {@code null} if it is not {@link #mIsEmbedded}
+ * TODO(b/261785978) cleanup with legacy app transition
+ */
+ @Nullable
+ private final Rect mRelativeEmbeddedBounds;
+
+ /**
* Whether to delay the call to {@link #updateOrganizedTaskFragmentSurface()} when there is a
* configuration change.
*/
@@ -381,6 +389,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mRootWindowContainer = mAtmService.mRootWindowContainer;
mCreatedByOrganizer = createdByOrganizer;
mIsEmbedded = isEmbedded;
+ mRelativeEmbeddedBounds = isEmbedded ? new Rect() : null;
mTaskFragmentOrganizerController =
mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController;
mFragmentToken = fragmentToken;
@@ -2419,16 +2428,53 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
}
- /** Whether we should prepare a transition for this {@link TaskFragment} bounds change. */
- boolean shouldStartChangeTransition(Rect startBounds) {
+ /**
+ * Gets the relative bounds of this embedded TaskFragment. This should only be called on
+ * embedded TaskFragment.
+ */
+ @NonNull
+ Rect getRelativeEmbeddedBounds() {
+ if (mRelativeEmbeddedBounds == null) {
+ throw new IllegalStateException("The TaskFragment is not embedded");
+ }
+ return mRelativeEmbeddedBounds;
+ }
+
+ /**
+ * Updates the record of the relative bounds of this embedded TaskFragment. This should only be
+ * called when the embedded TaskFragment's override bounds are changed.
+ * Returns {@code true} if the bounds is changed.
+ */
+ void updateRelativeEmbeddedBounds() {
+ // We only record the override bounds, which means it will not be changed when it is filling
+ // Task, and resize with the parent.
+ getRequestedOverrideBounds(mTmpBounds);
+ getRelativePosition(mTmpPoint);
+ mTmpBounds.offsetTo(mTmpPoint.x, mTmpPoint.y);
+ mRelativeEmbeddedBounds.set(mTmpBounds);
+ }
+
+ /**
+ * Updates the record of relative bounds of this embedded TaskFragment, and checks whether we
+ * should prepare a transition for the bounds change.
+ */
+ boolean shouldStartChangeTransition(@NonNull Rect absStartBounds,
+ @NonNull Rect relStartBounds) {
if (mTaskFragmentOrganizer == null || !canStartChangeTransition()) {
return false;
}
- // Only take snapshot if the bounds are resized.
- final Rect endBounds = getConfiguration().windowConfiguration.getBounds();
- return endBounds.width() != startBounds.width()
- || endBounds.height() != startBounds.height();
+ if (mTransitionController.isShellTransitionsEnabled()) {
+ // For Shell transition, the change will be collected anyway, so only take snapshot when
+ // the bounds are resized.
+ final Rect endBounds = getConfiguration().windowConfiguration.getBounds();
+ return endBounds.width() != absStartBounds.width()
+ || endBounds.height() != absStartBounds.height();
+ } else {
+ // For legacy transition, we need to trigger a change transition as long as the bounds
+ // is changed, even if it is not resized.
+ return !relStartBounds.equals(mRelativeEmbeddedBounds);
+ }
}
/** Records the starting bounds of the closing organized TaskFragment. */
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index d85bd830cc11..5dacf42c176a 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -148,7 +148,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
@VisibleForTesting
final ArrayMap<IBinder, TaskFragment> mLaunchTaskFragments = new ArrayMap<>();
- private final Rect mTmpBounds = new Rect();
+ private final Rect mTmpBounds0 = new Rect();
+ private final Rect mTmpBounds1 = new Rect();
WindowOrganizerController(ActivityTaskManagerService atm) {
mService = atm;
@@ -803,14 +804,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
// When the TaskFragment is resized, we may want to create a change transition for it, for
// which we want to defer the surface update until we determine whether or not to start
// change transition.
- mTmpBounds.set(taskFragment.getBounds());
+ mTmpBounds0.set(taskFragment.getBounds());
+ mTmpBounds1.set(taskFragment.getRelativeEmbeddedBounds());
taskFragment.deferOrganizedTaskFragmentSurfaceUpdate();
final int effects = applyChanges(taskFragment, c, errorCallbackToken);
- if (taskFragment.shouldStartChangeTransition(mTmpBounds)) {
- taskFragment.initializeChangeTransition(mTmpBounds);
+ taskFragment.updateRelativeEmbeddedBounds();
+ if (taskFragment.shouldStartChangeTransition(mTmpBounds0, mTmpBounds1)) {
+ taskFragment.initializeChangeTransition(mTmpBounds0);
}
taskFragment.continueOrganizedTaskFragmentSurfaceUpdate();
- mTmpBounds.set(0, 0, 0, 0);
return effects;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 38a712ed0435..11ac929327b9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -107,18 +107,49 @@ public class TaskFragmentTest extends WindowTestsBase {
}
@Test
+ public void testShouldStartChangeTransition_relativePositionChange() {
+ mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
+ final Rect startBounds = new Rect(0, 0, 500, 1000);
+ final Rect endBounds = new Rect(500, 0, 1000, 1000);
+ mTaskFragment.setBounds(startBounds);
+ mTaskFragment.updateRelativeEmbeddedBounds();
+ doReturn(true).when(mTaskFragment).isVisible();
+ doReturn(true).when(mTaskFragment).isVisibleRequested();
+
+ // Do not resize, just change the relative position.
+ final Rect relStartBounds = new Rect(mTaskFragment.getRelativeEmbeddedBounds());
+ mTaskFragment.setBounds(endBounds);
+ mTaskFragment.updateRelativeEmbeddedBounds();
+ spyOn(mDisplayContent.mTransitionController);
+
+ // For Shell transition, we don't want to take snapshot when the bounds are not resized
+ doReturn(true).when(mDisplayContent.mTransitionController)
+ .isShellTransitionsEnabled();
+ assertFalse(mTaskFragment.shouldStartChangeTransition(startBounds, relStartBounds));
+
+ // For legacy transition, we want to request a change transition even if it is just relative
+ // bounds change.
+ doReturn(false).when(mDisplayContent.mTransitionController)
+ .isShellTransitionsEnabled();
+ assertTrue(mTaskFragment.shouldStartChangeTransition(startBounds, relStartBounds));
+ }
+
+ @Test
public void testStartChangeTransition_resetSurface() {
mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
final Rect startBounds = new Rect(0, 0, 1000, 1000);
final Rect endBounds = new Rect(500, 500, 1000, 1000);
mTaskFragment.setBounds(startBounds);
+ mTaskFragment.updateRelativeEmbeddedBounds();
doReturn(true).when(mTaskFragment).isVisible();
doReturn(true).when(mTaskFragment).isVisibleRequested();
clearInvocations(mTransaction);
+ final Rect relStartBounds = new Rect(mTaskFragment.getRelativeEmbeddedBounds());
mTaskFragment.deferOrganizedTaskFragmentSurfaceUpdate();
mTaskFragment.setBounds(endBounds);
- assertTrue(mTaskFragment.shouldStartChangeTransition(startBounds));
+ mTaskFragment.updateRelativeEmbeddedBounds();
+ assertTrue(mTaskFragment.shouldStartChangeTransition(startBounds, relStartBounds));
mTaskFragment.initializeChangeTransition(startBounds);
mTaskFragment.continueOrganizedTaskFragmentSurfaceUpdate();
@@ -157,17 +188,20 @@ public class TaskFragmentTest extends WindowTestsBase {
final Rect startBounds = new Rect(0, 0, 1000, 1000);
final Rect endBounds = new Rect(500, 500, 1000, 1000);
mTaskFragment.setBounds(startBounds);
+ mTaskFragment.updateRelativeEmbeddedBounds();
doReturn(true).when(mTaskFragment).isVisible();
doReturn(true).when(mTaskFragment).isVisibleRequested();
+ final Rect relStartBounds = new Rect(mTaskFragment.getRelativeEmbeddedBounds());
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
displayPolicy.screenTurnedOff();
assertFalse(mTaskFragment.okToAnimate());
mTaskFragment.setBounds(endBounds);
+ mTaskFragment.updateRelativeEmbeddedBounds();
- assertFalse(mTaskFragment.shouldStartChangeTransition(startBounds));
+ assertFalse(mTaskFragment.shouldStartChangeTransition(startBounds, relStartBounds));
}
/**