summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java50
-rw-r--r--services/core/java/com/android/server/wm/NavBarFadeAnimationController.java2
-rw-r--r--services/core/java/com/android/server/wm/Transition.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java9
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(