summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/Transition.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java35
2 files changed, 54 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index bbc95a1dd70f..471319e956a1 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1192,7 +1192,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
return false;
}
- final @TransitionInfo.TransitionMode int mode = changes.get(target).getTransitMode(target);
+ final ChangeInfo change = changes.get(target);
+ if (change.mStartParent != null && target.getParent() != change.mStartParent) {
+ // When a window is reparented, the state change won't fit into any of the parents.
+ // Don't promote such change so that we can animate the reparent if needed.
+ return false;
+ }
+
+ final @TransitionInfo.TransitionMode int mode = change.getTransitMode(target);
for (int i = parent.getChildCount() - 1; i >= 0; --i) {
final WindowContainer<?> sibling = parent.getChildAt(i);
if (target == sibling) continue;
@@ -1332,14 +1339,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// Intermediate parents must be those that has window to be managed by Shell.
continue;
}
- if (parentChange.mParent != null && !skipIntermediateReports) {
- changes.get(wc).mParent = p;
+ if (parentChange.mEndParent != null && !skipIntermediateReports) {
+ changes.get(wc).mEndParent = p;
// The chain above the parent was processed.
break;
}
if (targetList.contains(p)) {
if (skipIntermediateReports) {
- changes.get(wc).mParent = p;
+ changes.get(wc).mEndParent = p;
} else {
intermediates.add(p);
}
@@ -1351,10 +1358,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
}
if (!foundParentInTargets || intermediates.isEmpty()) continue;
// Add any always-report parents along the way.
- changes.get(wc).mParent = intermediates.get(0);
+ changes.get(wc).mEndParent = intermediates.get(0);
for (int j = 0; j < intermediates.size() - 1; j++) {
final WindowContainer<?> intermediate = intermediates.get(j);
- changes.get(intermediate).mParent = intermediates.get(j + 1);
+ changes.get(intermediate).mEndParent = intermediates.get(j + 1);
targets.add(intermediate);
}
}
@@ -1467,8 +1474,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken()
: null, getLeashSurface(target, startT));
// TODO(shell-transitions): Use leash for non-organized windows.
- if (info.mParent != null) {
- change.setParent(info.mParent.mRemoteToken.toWindowContainerToken());
+ if (info.mEndParent != null) {
+ change.setParent(info.mEndParent.mRemoteToken.toWindowContainerToken());
}
change.setMode(info.getTransitMode(target));
change.setStartAbsBounds(info.mAbsoluteBounds);
@@ -1651,7 +1658,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
@interface Flag {}
// Usually "post" change state.
- WindowContainer mParent;
+ WindowContainer mEndParent;
+ // Parent before change state.
+ WindowContainer mStartParent;
// State tracking
boolean mExistenceChanged = false;
@@ -1672,6 +1681,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
mAbsoluteBounds.set(origState.getBounds());
mShowWallpaper = origState.showWallpaper();
mRotation = origState.getWindowConfiguration().getRotation();
+ mStartParent = origState.getParent();
}
@VisibleForTesting
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index a1ad07adbafb..0f13fb20a06e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -36,8 +36,10 @@ import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static android.window.TransitionInfo.isIndependent;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -1079,6 +1081,39 @@ public class TransitionTests extends WindowTestsBase {
assertTrue((info.getChanges().get(1).getFlags() & FLAG_IS_EMBEDDED) != 0);
}
+ @Test
+ public void testIncludeEmbeddedActivityReparent() {
+ final Transition transition = createTestTransition(TRANSIT_OPEN);
+ final Task task = createTask(mDisplayContent);
+ task.setBounds(new Rect(0, 0, 2000, 1000));
+ final ActivityRecord activity = createActivityRecord(task);
+ activity.mVisibleRequested = true;
+ // Skip manipulate the SurfaceControl.
+ doNothing().when(activity).setDropInputMode(anyInt());
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ mAtm.mTaskFragmentOrganizerController.registerOrganizer(
+ ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder()));
+ final TaskFragment embeddedTf = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .setOrganizer(organizer)
+ .build();
+ // TaskFragment with different bounds from Task.
+ embeddedTf.setBounds(new Rect(0, 0, 1000, 1000));
+
+ // Start states.
+ transition.collect(activity);
+ transition.collectExistenceChange(embeddedTf);
+
+ // End states.
+ activity.reparent(embeddedTf, POSITION_TOP);
+
+ // Verify that both activity and TaskFragment are included.
+ final ArrayList<WindowContainer> targets = Transition.calculateTargets(
+ transition.mParticipants, transition.mChanges);
+ assertTrue(targets.contains(embeddedTf));
+ assertTrue(targets.contains(activity));
+ }
+
private static void makeTaskOrganized(Task... tasks) {
final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
for (Task t : tasks) {