diff options
| author | 2023-08-21 10:30:44 +0000 | |
|---|---|---|
| committer | 2023-08-21 10:30:44 +0000 | |
| commit | 098b09348254a81accd34aa0e7f9f202fa50cd8f (patch) | |
| tree | 33908d258729d7d18d0cc53f8b5cd6a6d20466d3 | |
| parent | 8fe4e9d9da8369ce05f183fe28c94989d020b1cf (diff) | |
| parent | d23210577f1b8b6a5e68cff4e7def8b6dcb1c68a (diff) | |
Merge "Polish navbar while quick switching apps with different orientation" into udc-qpr-dev am: 5358fcde1c am: d23210577f
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/24465727
Change-Id: I5184a22472ff70611b45e0a169c86494d811c706
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
4 files changed, 49 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java index 2eceeccd9d8f..025047588ea5 100644 --- a/services/core/java/com/android/server/wm/AsyncRotationController.java +++ b/services/core/java/com/android/server/wm/AsyncRotationController.java @@ -172,10 +172,9 @@ class AsyncRotationController extends FadeAnimationController implements Consume if (recents != null && recents.isNavigationBarAttachedToApp()) { return; } - } else if (navigationBarCanMove || mTransitionOp == OP_CHANGE_MAY_SEAMLESS) { + } else if (navigationBarCanMove || mTransitionOp == OP_CHANGE_MAY_SEAMLESS + || mDisplayContent.mTransitionController.mNavigationBarAttachedToApp) { action = Operation.ACTION_SEAMLESS; - } else if (mDisplayContent.mTransitionController.mNavigationBarAttachedToApp) { - return; } mTargetWindowTokens.put(w.mToken, new Operation(action)); return; @@ -294,6 +293,11 @@ class AsyncRotationController extends FadeAnimationController implements Consume finishOp(mTargetWindowTokens.keyAt(i)); } mTargetWindowTokens.clear(); + onAllCompleted(); + } + + private void onAllCompleted() { + if (DEBUG) Slog.d(TAG, "onAllCompleted"); if (mTimeoutRunnable != null) { mService.mH.removeCallbacks(mTimeoutRunnable); } @@ -333,7 +337,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume if (DEBUG) Slog.d(TAG, "Complete directly " + token.getTopChild()); finishOp(token); if (mTargetWindowTokens.isEmpty()) { - if (mTimeoutRunnable != null) mService.mH.removeCallbacks(mTimeoutRunnable); + onAllCompleted(); return true; } } @@ -411,14 +415,18 @@ class AsyncRotationController extends FadeAnimationController implements Consume if (mDisplayContent.mInputMethodWindow == null) return; final WindowToken imeWindowToken = mDisplayContent.mInputMethodWindow.mToken; if (isTargetToken(imeWindowToken)) return; + hideImmediately(imeWindowToken, Operation.ACTION_TOGGLE_IME); + if (DEBUG) Slog.d(TAG, "hideImeImmediately " + imeWindowToken.getTopChild()); + } + + private void hideImmediately(WindowToken token, @Operation.Action int action) { final boolean original = mHideImmediately; mHideImmediately = true; - final Operation op = new Operation(Operation.ACTION_TOGGLE_IME); - mTargetWindowTokens.put(imeWindowToken, op); - fadeWindowToken(false /* show */, imeWindowToken, ANIMATION_TYPE_TOKEN_TRANSFORM); - op.mLeash = imeWindowToken.getAnimationLeash(); + final Operation op = new Operation(action); + mTargetWindowTokens.put(token, op); + fadeWindowToken(false /* show */, token, ANIMATION_TYPE_TOKEN_TRANSFORM); + op.mLeash = token.getAnimationLeash(); mHideImmediately = original; - if (DEBUG) Slog.d(TAG, "hideImeImmediately " + imeWindowToken.getTopChild()); } /** Returns {@code true} if the window will rotate independently. */ @@ -428,11 +436,20 @@ class AsyncRotationController extends FadeAnimationController implements Consume || isTargetToken(w.mToken); } - /** Returns {@code true} if the controller will run fade animations on the window. */ + /** + * Returns {@code true} if the rotation transition appearance of the window is currently + * managed by this controller. + */ boolean isTargetToken(WindowToken token) { return mTargetWindowTokens.containsKey(token); } + /** Returns {@code true} if the controller will run fade animations on the window. */ + boolean hasFadeOperation(WindowToken token) { + final Operation op = mTargetWindowTokens.get(token); + return op != null && op.mAction == Operation.ACTION_FADE; + } + /** * Whether the insets animation leash should use previous position when running fade animation * or seamless transformation in a rotated display. @@ -564,7 +581,18 @@ class AsyncRotationController extends FadeAnimationController implements Consume return false; } final Operation op = mTargetWindowTokens.get(w.mToken); - if (op == null) return false; + if (op == null) { + // If a window becomes visible after the rotation transition is requested but before + // the transition is ready, hide it by an animation leash so it won't be flickering + // by drawing the rotated content before applying projection transaction of display. + // And it will fade in after the display transition is finished. + if (mTransitionOp == OP_APP_SWITCH && !mIsStartTransactionCommitted + && canBeAsync(w.mToken)) { + hideImmediately(w.mToken, Operation.ACTION_FADE); + if (DEBUG) Slog.d(TAG, "Hide on finishDrawing " + w.mToken.getTopChild()); + } + return false; + } if (DEBUG) Slog.d(TAG, "handleFinishDrawing " + w); if (postDrawTransaction == null || !mIsSyncDrawRequested || canDrawBeforeStartTransaction(op)) { diff --git a/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java b/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java index 2e5474e5e415..79b26d2ee994 100644 --- a/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java +++ b/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java @@ -86,7 +86,7 @@ public class NavBarFadeAnimationController extends FadeAnimationController{ ANIMATION_TYPE_TOKEN_TRANSFORM); if (controller == null) { fadeAnim.run(); - } else if (!controller.isTargetToken(mNavigationBar.mToken)) { + } else if (!controller.hasFadeOperation(mNavigationBar.mToken)) { // If fade rotation animation is running and the nav bar is not controlled by it: // - For fade-in animation, defer the animation until fade rotation animation finishes. // - For fade-out animation, just play the animation. diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 1566bb2c8610..e9af42bb7b90 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -1930,11 +1930,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { break; } - final AsyncRotationController asyncRotationController = dc.getAsyncRotationController(); - if (asyncRotationController != null) { - asyncRotationController.accept(navWindow); - } - if (animate) { final NavBarFadeAnimationController controller = new NavBarFadeAnimationController(dc); 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 9b6d4e216744..873d09b42c83 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -1191,6 +1191,7 @@ public class TransitionTests extends WindowTestsBase { final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar"); makeWindowVisible(statusBar); mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs); + final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar"); final ActivityRecord app = createActivityRecord(mDisplayContent); final Transition transition = app.mTransitionController.createTransition(TRANSIT_OPEN); app.mTransitionController.requestStartTransition(transition, app.getTask(), @@ -1220,9 +1221,17 @@ public class TransitionTests extends WindowTestsBase { mDisplayContent.mTransitionController.dispatchLegacyAppTransitionFinished(app); assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp()); + // The bar was invisible so it is not handled by the controller. But if it becomes visible + // and drawn before the transition starts, + assertFalse(asyncRotationController.isTargetToken(navBar.mToken)); + navBar.finishDrawing(null /* postDrawTransaction */, Integer.MAX_VALUE); + assertTrue(asyncRotationController.isTargetToken(navBar.mToken)); + player.startTransition(); // Non-app windows should not be collected. assertFalse(mDisplayContent.mTransitionController.isCollecting(statusBar.mToken)); + // Avoid DeviceStateController disturbing the test by triggering another rotation change. + doReturn(false).when(mDisplayContent).updateRotationUnchecked(); onRotationTransactionReady(player, mWm.mTransactionFactory.get()).onTransactionCommitted(); assertEquals(ROTATION_ANIMATION_SEAMLESS, player.mLastReady.getChange( |