Loading services/core/java/com/android/server/wm/AsyncRotationController.java +28 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/wm/DisplayContent.java +3 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading services/core/java/com/android/server/wm/WindowStateAnimator.java +14 −38 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -424,7 +423,7 @@ class WindowStateAnimator { computeShownFrameLocked(); if (w.isParentWindowHidden() || !w.isOnScreen()) { if (!w.isOnScreen()) { hide(t, "prepareSurfaceLocked"); mWallpaperControllerLocked.hideWallpapers(w); Loading @@ -449,7 +448,7 @@ class WindowStateAnimator { if (prepared && mDrawState == HAS_DRAWN) { if (mLastHidden) { if (showSurfaceRobustlyLocked(t)) { mSurfaceController.showRobustly(t); mAnimator.requestRemovalOfReplacedWindows(w); mLastHidden = false; final DisplayContent displayContent = w.getDisplayContent(); Loading @@ -464,16 +463,9 @@ class WindowStateAnimator { 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()) { if (!w.isDrawn()) { Loading Loading @@ -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 Loading services/core/java/com/android/server/wm/WindowSurfaceController.java +2 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -262,7 +262,6 @@ class WindowSurfaceController { dc.mDisplayId, 1 /* request shown */, String.valueOf(dc.mWallpaperController.getWallpaperTarget())); } return true; } boolean clearWindowContentFrameStats() { Loading services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +6 −1 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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()); } Loading Loading
services/core/java/com/android/server/wm/AsyncRotationController.java +28 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/wm/DisplayContent.java +3 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading
services/core/java/com/android/server/wm/WindowStateAnimator.java +14 −38 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -424,7 +423,7 @@ class WindowStateAnimator { computeShownFrameLocked(); if (w.isParentWindowHidden() || !w.isOnScreen()) { if (!w.isOnScreen()) { hide(t, "prepareSurfaceLocked"); mWallpaperControllerLocked.hideWallpapers(w); Loading @@ -449,7 +448,7 @@ class WindowStateAnimator { if (prepared && mDrawState == HAS_DRAWN) { if (mLastHidden) { if (showSurfaceRobustlyLocked(t)) { mSurfaceController.showRobustly(t); mAnimator.requestRemovalOfReplacedWindows(w); mLastHidden = false; final DisplayContent displayContent = w.getDisplayContent(); Loading @@ -464,16 +463,9 @@ class WindowStateAnimator { 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()) { if (!w.isDrawn()) { Loading Loading @@ -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 Loading
services/core/java/com/android/server/wm/WindowSurfaceController.java +2 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -262,7 +262,6 @@ class WindowSurfaceController { dc.mDisplayId, 1 /* request shown */, String.valueOf(dc.mWallpaperController.getWallpaperTarget())); } return true; } boolean clearWindowContentFrameStats() { Loading
services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +6 −1 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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()); } Loading