Collect changes for transition right before updating config
Otherwise if display configuration is updated first, the later collect() may not detect change. Such as if an activity with ROTATION_ANIMATION_SEAMLESS is not included in TransitionInfo, the animation will still be screenshot based style. Bug: 240238575 Test: SeamlessAppRotationTest Change-Id: I53f4212dad210cacdc4c243475ab1ab6355fe53b
This commit is contained in:
@@ -504,6 +504,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newParentConfig) {
|
||||
mTransitionController.collectForDisplayAreaChange(this);
|
||||
mTmpConfiguration.setTo(getConfiguration());
|
||||
super.onConfigurationChanged(newParentConfig);
|
||||
|
||||
|
||||
@@ -5935,6 +5935,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
if (changes != 0) {
|
||||
Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
|
||||
+ mTempConfig + " for displayId=" + mDisplayId);
|
||||
if (isReady() && mTransitionController.isShellTransitionsEnabled()) {
|
||||
requestChangeTransitionIfNeeded(changes, null /* displayChange */);
|
||||
}
|
||||
onRequestedOverrideConfigurationChanged(mTempConfig);
|
||||
|
||||
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
|
||||
@@ -5951,9 +5954,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
}
|
||||
mWmService.mDisplayNotificationController.dispatchDisplayChanged(
|
||||
this, getConfiguration());
|
||||
if (isReady() && mTransitionController.isShellTransitionsEnabled()) {
|
||||
requestChangeTransitionIfNeeded(changes, null /* displayChange */);
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
@@ -513,19 +513,6 @@ public class DisplayRotation {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get a rotating displaycontent from a Transition.
|
||||
* @return null if the transition doesn't contain a rotating display.
|
||||
*/
|
||||
static DisplayContent getDisplayFromTransition(Transition transition) {
|
||||
for (int i = transition.mParticipants.size() - 1; i >= 0; --i) {
|
||||
final WindowContainer wc = transition.mParticipants.valueAt(i);
|
||||
if (!(wc instanceof DisplayContent)) continue;
|
||||
return (DisplayContent) wc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void startRemoteRotation(int fromRotation, int toRotation) {
|
||||
mDisplayContent.mRemoteDisplayChangeController.performRemoteDisplayChange(
|
||||
fromRotation, toRotation, null /* newDisplayAreaInfo */,
|
||||
@@ -545,11 +532,6 @@ public class DisplayRotation {
|
||||
throw new IllegalStateException("Trying to rotate outside a transition");
|
||||
}
|
||||
mDisplayContent.mTransitionController.collect(mDisplayContent);
|
||||
// Go through all tasks and collect them before the rotation
|
||||
// TODO(shell-transitions): move collect() to onConfigurationChange once wallpaper
|
||||
// handling is synchronized.
|
||||
mDisplayContent.mTransitionController.collectForDisplayAreaChange(mDisplayContent,
|
||||
null /* use collecting transition */);
|
||||
}
|
||||
mService.mAtmService.deferWindowLayout();
|
||||
try {
|
||||
|
||||
@@ -101,7 +101,6 @@ public class PhysicalDisplaySwitchTransitionLauncher {
|
||||
|
||||
if (t != null) {
|
||||
mDisplayContent.mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
|
||||
mTransitionController.collectForDisplayAreaChange(mDisplayContent, t);
|
||||
mTransition = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1634,6 +1634,19 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
return mainWin.getAttrs().rotationAnimation;
|
||||
}
|
||||
|
||||
/** Applies the new configuration and returns {@code true} if there is a display change. */
|
||||
boolean applyDisplayChangeIfNeeded() {
|
||||
boolean changed = false;
|
||||
for (int i = mParticipants.size() - 1; i >= 0; --i) {
|
||||
final WindowContainer<?> wc = mParticipants.valueAt(i);
|
||||
final DisplayContent dc = wc.asDisplayContent();
|
||||
if (dc == null || !mChanges.get(dc).hasChanged(dc)) continue;
|
||||
dc.sendNewConfiguration();
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
boolean getLegacyIsReady() {
|
||||
return isCollecting() && mSyncId >= 0;
|
||||
}
|
||||
|
||||
@@ -463,13 +463,12 @@ class TransitionController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the window containers which need to be synced with the changing display (e.g.
|
||||
* rotating) to the given transition or the current collecting transition.
|
||||
* Collects the window containers which need to be synced with the changing display area into
|
||||
* the current collecting transition.
|
||||
*/
|
||||
void collectForDisplayAreaChange(@NonNull DisplayArea<?> wc, @Nullable Transition incoming) {
|
||||
if (incoming == null) incoming = mCollectingTransition;
|
||||
if (incoming == null) return;
|
||||
final Transition transition = incoming;
|
||||
void collectForDisplayAreaChange(@NonNull DisplayArea<?> wc) {
|
||||
final Transition transition = mCollectingTransition;
|
||||
if (transition == null || !transition.mParticipants.contains(wc)) return;
|
||||
// Collect all visible tasks.
|
||||
wc.forAllLeafTasks(task -> {
|
||||
if (task.isVisible()) {
|
||||
|
||||
@@ -397,17 +397,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
mService.deferWindowLayout();
|
||||
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
|
||||
try {
|
||||
if (transition != null) {
|
||||
// First check if we have a display rotation transition and if so, update it.
|
||||
final DisplayContent dc = DisplayRotation.getDisplayFromTransition(transition);
|
||||
if (dc != null && transition.mChanges.get(dc).hasChanged(dc)) {
|
||||
// Go through all tasks and collect them before the rotation
|
||||
// TODO(shell-transitions): move collect() to onConfigurationChange once
|
||||
// wallpaper handling is synchronized.
|
||||
dc.mTransitionController.collectForDisplayAreaChange(dc, transition);
|
||||
dc.sendNewConfiguration();
|
||||
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
||||
}
|
||||
if (transition != null && transition.applyDisplayChangeIfNeeded()) {
|
||||
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
||||
}
|
||||
final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
|
||||
final int hopSize = hops.size();
|
||||
@@ -428,15 +419,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
addToSyncSet(syncId, wc);
|
||||
}
|
||||
if (transition != null) transition.collect(wc);
|
||||
final DisplayArea da = wc.asDisplayArea();
|
||||
// Only check DisplayArea here as a similar thing is done for DisplayContent above.
|
||||
if (da != null && wc.asDisplayContent() == null
|
||||
&& entry.getValue().getWindowingMode() != da.getWindowingMode()) {
|
||||
// Go through all tasks and collect them before changing the windowing mode of a
|
||||
// display-level container.
|
||||
// TODO(shell-transitions): handle this more elegantly.
|
||||
da.mTransitionController.collectForDisplayAreaChange(da, transition);
|
||||
}
|
||||
|
||||
if ((entry.getValue().getChangeMask()
|
||||
& WindowContainerTransaction.Change.CHANGE_FORCE_NO_PIP) != 0) {
|
||||
|
||||
@@ -1904,10 +1904,10 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
testPlayer.start();
|
||||
assertNotEquals(origRot, dc.getConfiguration().windowConfiguration.getRotation());
|
||||
assertNotNull(testPlayer.mLastReady);
|
||||
assertEquals(dc, DisplayRotation.getDisplayFromTransition(testPlayer.mLastTransit));
|
||||
WindowContainerToken dcToken = dc.mRemoteToken.toWindowContainerToken();
|
||||
assertNotEquals(testPlayer.mLastReady.getChange(dcToken).getEndRotation(),
|
||||
testPlayer.mLastReady.getChange(dcToken).getStartRotation());
|
||||
assertTrue(testPlayer.mLastTransit.applyDisplayChangeIfNeeded());
|
||||
testPlayer.finish();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user