diff options
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()); } |