summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java28
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java52
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java7
5 files changed, 53 insertions, 42 deletions
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index dcafe80686ad..0dc6e0ff1054 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -217,6 +217,34 @@ class AsyncRotationController extends FadeAnimationController implements Consume
if (DEBUG) Slog.d(TAG, "Requested to sync draw transaction");
}
+ /**
+ * If an async window is not requested to redraw or its surface is removed, then complete its
+ * operation directly to avoid waiting until timeout.
+ */
+ void updateTargetWindows() {
+ if (mTransitionOp == OP_LEGACY || !mIsStartTransactionCommitted) return;
+ for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
+ final Operation op = mTargetWindowTokens.valueAt(i);
+ if (op.mIsCompletionPending || op.mAction == Operation.ACTION_SEAMLESS) {
+ // Skip completed target. And seamless windows use the signal from blast sync.
+ continue;
+ }
+ final WindowToken token = mTargetWindowTokens.keyAt(i);
+ int readyCount = 0;
+ final int childCount = token.getChildCount();
+ for (int j = childCount - 1; j >= 0; j--) {
+ final WindowState w = token.getChildAt(j);
+ // If the token no longer contains pending drawn windows, then it is ready.
+ if (w.isDrawn() || !w.mWinAnimator.getShown()) {
+ readyCount++;
+ }
+ }
+ if (readyCount == childCount) {
+ mDisplayContent.finishAsyncRotation(token);
+ }
+ }
+ }
+
/** Lets the window fit in new rotation naturally. */
private void finishOp(WindowToken windowToken) {
final Operation op = mTargetWindowTokens.remove(windowToken);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ade2fe7152c0..17ec9cbd7428 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4761,6 +4761,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void updateWindowsForAnimator() {
forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */);
+ if (mAsyncRotationController != null) {
+ mAsyncRotationController.updateTargetWindows();
+ }
}
boolean isInputMethodClientFocus(int uid, int pid) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a102986832fe..e8625bc3d64b 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -32,7 +32,6 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
-import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
@@ -424,7 +423,7 @@ class WindowStateAnimator {
computeShownFrameLocked();
- if (w.isParentWindowHidden() || !w.isOnScreen()) {
+ if (!w.isOnScreen()) {
hide(t, "prepareSurfaceLocked");
mWallpaperControllerLocked.hideWallpapers(w);
@@ -449,30 +448,23 @@ class WindowStateAnimator {
if (prepared && mDrawState == HAS_DRAWN) {
if (mLastHidden) {
- if (showSurfaceRobustlyLocked(t)) {
- mAnimator.requestRemovalOfReplacedWindows(w);
- mLastHidden = false;
- final DisplayContent displayContent = w.getDisplayContent();
- if (!displayContent.getLastHasContent()) {
- // This draw means the difference between unique content and mirroring.
- // Run another pass through performLayout to set mHasContent in the
- // LogicalDisplay.
- displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
- if (DEBUG_LAYOUT_REPEATS) {
- mService.mWindowPlacerLocked.debugLayoutRepeats(
- "showSurfaceRobustlyLocked " + w,
- displayContent.pendingLayoutChanges);
- }
+ mSurfaceController.showRobustly(t);
+ mAnimator.requestRemovalOfReplacedWindows(w);
+ mLastHidden = false;
+ final DisplayContent displayContent = w.getDisplayContent();
+ if (!displayContent.getLastHasContent()) {
+ // This draw means the difference between unique content and mirroring.
+ // Run another pass through performLayout to set mHasContent in the
+ // LogicalDisplay.
+ displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
+ if (DEBUG_LAYOUT_REPEATS) {
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "showSurfaceRobustlyLocked " + w,
+ displayContent.pendingLayoutChanges);
}
- } else {
- w.setOrientationChanging(false);
}
}
}
- } else {
- if (mWin.isAnimating(TRANSITION | PARENTS)) {
- ProtoLog.v(WM_DEBUG_ANIM, "prepareSurface: No changes in animation for %s", this);
- }
}
if (w.getOrientationChanging()) {
@@ -511,22 +503,6 @@ class WindowStateAnimator {
mSurfaceController.setColorSpaceAgnostic(mWin.getPendingTransaction(), agnostic);
}
- /**
- * Have the surface flinger show a surface, robustly dealing with
- * error conditions. In particular, if there is not enough memory
- * to show the surface, then we will try to get rid of other surfaces
- * in order to succeed.
- *
- * @return Returns true if the surface was successfully shown.
- */
- private boolean showSurfaceRobustlyLocked(SurfaceControl.Transaction t) {
- boolean shown = mSurfaceController.showRobustly(t);
- if (!shown)
- return false;
-
- return true;
- }
-
void applyEnterAnimationLocked() {
// If we are the new part of a window replacement transition and we have requested
// not to animate, we instead want to make it seamless, so we don't want to apply
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 607ce251c4d1..33751b9f16a0 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -245,13 +245,13 @@ class WindowSurfaceController {
t.setColorSpaceAgnostic(mSurfaceControl, agnostic);
}
- boolean showRobustly(SurfaceControl.Transaction t) {
+ void showRobustly(SurfaceControl.Transaction t) {
ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);
if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
+ " during relayout");
if (mSurfaceShown) {
- return true;
+ return;
}
setShown(true);
@@ -262,7 +262,6 @@ class WindowSurfaceController {
dc.mDisplayId, 1 /* request shown */,
String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
}
- return true;
}
boolean clearWindowContentFrameStats() {
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 05ee2f24fbaf..3f14217b7a18 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -1018,6 +1018,10 @@ public class TransitionTests extends WindowTestsBase {
@Test
public void testDisplayRotationChange() {
+ final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+ spyOn(displayPolicy);
+ // Simulate gesture navigation (non-movable) so it is not seamless.
+ doReturn(false).when(displayPolicy).navigationBarCanMove();
final Task task = createActivityRecord(mDisplayContent).getTask();
final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
@@ -1072,7 +1076,8 @@ public class TransitionTests extends WindowTestsBase {
// Navigation bar finishes drawing after the start transaction, so its fade-in animation
// can execute directly.
- asyncRotationController.handleFinishDrawing(navBar, mMockT);
+ navBar.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
+ asyncRotationController.updateTargetWindows();
assertFalse(asyncRotationController.isTargetToken(navBar.mToken));
assertNull(mDisplayContent.getAsyncRotationController());
}