Request change transition for layout direction change for legacy
Before, we check if the bounds are resized to start a change transition to avoid unnecessary screenshot. However, when the layout direction is changed, we also want to have a change transition when the bounds are not resized. Bug: 241043533 Fix: 258130319 Test: atest WmTests:TaskFragmentTest Change-Id: I413febe18c2288600066e9f8d641d6ab4ec5f126
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -299,6 +299,14 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
@Nullable
|
||||
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. */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,19 +106,50 @@ public class TaskFragmentTest extends WindowTestsBase {
|
||||
verify(mTransaction).setWindowCrop(mLeash, 1000, 1000);
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user