summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2022-08-10 23:49:53 +0800
committer Riddle Hsu <riddlehsu@google.com> 2022-08-12 19:11:28 +0800
commit213fab27f67e23ba86fcf41aa29c3ad36a4deeeb (patch)
treeb710d97958e6f8f5cbb3000c6b6af4c381cc4cdc
parent9de781b8a4549ed0a2477959bf8c60ae47325a74 (diff)
Defer rotation change while running display change transition
This aligns the behavior of shell transition with legacy transition. The rotation change will be skipped if there is a display change transition. And then after the transition is finished, check again if there is still a change to send. The benefits: 1. If the new transition will cancel previous transition (current behavior), it can avoid jump cut that the display transition will go to the end state directly. 2. If the new transition will be queued, it may avoid unnecessary temporal states change from preempting CPU with animation. 3. It may make some tests stabler that the sync state and async rotation controller won't need to worry about crossing transition if the tests request changing various rotations in a short time. Also optimize WMS#updateRotationUnchecked a bit, which eliminates an unnecessary surface placement if nothing is changed. Bug: 234585256 Bug: 209920544 Test: AppConfigurationTests Change-Id: I6a0e9ae7449dc361998e1f8066a76dd4647ae0b0
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java5
-rw-r--r--services/core/java/com/android/server/wm/Transition.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java15
5 files changed, 28 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 3d91921e3ab7..8dd58506ef0b 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -399,9 +399,8 @@ public class DisplayRotation {
return false;
}
- final ScreenRotationAnimation screenRotationAnimation =
- mDisplayContent.getRotationAnimation();
- if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
+ if (mDisplayContent.inTransition()
+ && !mDisplayContent.mTransitionController.useShellTransitionsRotation()) {
// Rotation updates cannot be performed while the previous rotation change animation
// is still in progress. Skip this update. We will try updating again after the
// animation is finished and the display is unfrozen.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index bbc95a1dd70f..584a40e04700 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -622,9 +622,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
throw new IllegalStateException("Can't finish a non-playing transition " + mSyncId);
}
+ boolean hasParticipatedDisplay = false;
// Commit all going-invisible containers
for (int i = 0; i < mParticipants.size(); ++i) {
- final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
+ final WindowContainer<?> participant = mParticipants.valueAt(i);
+ final ActivityRecord ar = participant.asActivityRecord();
if (ar != null) {
boolean visibleAtTransitionEnd = mVisibleAtTransitionEndTokens.contains(ar);
// We need both the expected visibility AND current requested-visibility to be
@@ -656,8 +658,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// Legacy dispatch relies on this (for now).
ar.mEnteringAnimation = visibleAtTransitionEnd;
}
+ continue;
}
- final WallpaperWindowToken wt = mParticipants.valueAt(i).asWallpaperToken();
+ if (participant.asDisplayContent() != null) {
+ hasParticipatedDisplay = true;
+ continue;
+ }
+ final WallpaperWindowToken wt = participant.asWallpaperToken();
if (wt != null) {
final boolean visibleAtTransitionEnd = mVisibleAtTransitionEndTokens.contains(wt);
if (!visibleAtTransitionEnd && !wt.isVisibleRequested()) {
@@ -737,6 +744,12 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
mState = STATE_FINISHED;
mController.mTransitionTracer.logState(this);
+ // Rotation change may be deferred while there is a display change transition, so check
+ // again in case there is a new pending change.
+ if (hasParticipatedDisplay && !mController.useShellTransitionsRotation()) {
+ mController.mAtm.mWindowManager.updateRotation(false /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }
}
void abort() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 296390a57bcc..bb0a1bc6b5c0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4290,7 +4290,9 @@ public class WindowManagerService extends IWindowManager.Stub
// Even if alwaysSend, we are waiting for a transition or remote to provide
// updated configuration, so we can't update configuration yet.
if (!pendingRemoteDisplayChange) {
- if (!rotationChanged || forceRelayout) {
+ // The layout-needed flag will be set if there is a rotation change, so
+ // only set it if the caller requests to force relayout.
+ if (forceRelayout) {
displayContent.setLayoutNeeded();
layoutNeeded = true;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 7c46fd61a834..5aaffbec7903 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2464,6 +2464,7 @@ public class ActivityRecordTests extends WindowTestsBase {
activity.addWindow(appWindow);
spyOn(appWindow);
doNothing().when(appWindow).onStartFreezingScreen();
+ doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
// Set initial orientation and update.
performRotation(displayRotation, Surface.ROTATION_90);
@@ -2472,8 +2473,6 @@ public class ActivityRecordTests extends WindowTestsBase {
// Update the rotation to perform 180 degree rotation and check that resize was reported.
performRotation(displayRotation, Surface.ROTATION_270);
assertTrue(appWindow.mResizeReported);
-
- appWindow.removeImmediately();
}
private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index d6b807fc223e..600881ea955c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1820,19 +1820,18 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testRemoteRotation() {
- DisplayContent dc = createNewDisplay();
-
+ final DisplayContent dc = mDisplayContent;
final DisplayRotation dr = dc.getDisplayRotation();
- doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
+ spyOn(dr);
// Rotate 180 degree so the display doesn't have configuration change. This condition is
// used for the later verification of stop-freezing (without setting mWaitingForConfig).
doReturn((dr.getRotation() + 2) % 4).when(dr).rotationForOrientation(anyInt(), anyInt());
final boolean[] continued = new boolean[1];
- doAnswer(
- invocation -> {
- continued[0] = true;
- return true;
- }).when(dc).updateDisplayOverrideConfigurationLocked();
+ doAnswer(invocation -> {
+ continued[0] = true;
+ mAtm.addWindowLayoutReasons(ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED);
+ return true;
+ }).when(dc).updateDisplayOverrideConfigurationLocked();
final boolean[] called = new boolean[1];
mWm.mDisplayChangeController =
new IDisplayChangeWindowController.Stub() {