diff options
| author | 2019-05-03 22:22:36 +0800 | |
|---|---|---|
| committer | 2019-05-04 03:50:40 +0800 | |
| commit | 0e59172893e6d49b29f5efd4ce46c65fb2804b58 (patch) | |
| tree | f08a350a656254a018d0c14babe40c9b80af59bc | |
| parent | 43233b72acba8ad4554501cd4f5a7860d9a009fd (diff) | |
Fix transition animation of ResolverActivity for home
When touching navigation bar, it may trigger startRecentsActivity
to make the recents (home) activity visible to prepare recents
animation. If the final operation doesn't need the animation, the
animation will be canceled. When the condition is in the middle
of starting activity, the visibility of recents activity will be
updated after setting the transition of next activity. That leads
to the recents activity is added to closing apps so the transition
doesn't choose the animation style for translucent activity.
This change makes the recents activity invisible immediately if
it is really invisible to user, so its visibility change won't
affect the later launch transition.
Bug: 131589476
Test: atest RecentsAnimationTest#testRecentsActivityVisiblility
Change-Id: Ib8b59b9fc8dc40ea17d827a48f2b0cf2c1a1b3dd
| -rw-r--r-- | services/core/java/com/android/server/wm/RecentsAnimation.java | 14 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java | 32 |
2 files changed, 45 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index ee258cbf2de3..3092ef97a686 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -220,7 +220,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks, // Unregister for stack order changes mDefaultDisplay.unregisterStackOrderChangedListener(this); - if (mWindowManager.getRecentsAnimationController() == null) return; + final RecentsAnimationController controller = + mWindowManager.getRecentsAnimationController(); + if (controller == null) return; // Just to be sure end the launch hint in case the target activity was never launched. // However, if we're keeping the activity and making it visible, we can leave it on. @@ -292,6 +294,16 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } } } else { + // If there is no recents screenshot animation, we can update the visibility + // of target stack immediately because it is visually invisible and the + // launch-behind state is restored. That also prevents the next transition + // type being disturbed if the visibility is updated after setting the next + // transition (the target activity will be one of closing apps). + if (!controller.shouldCancelWithDeferredScreenshot() + && !targetStack.isFocusedStackOnDisplay()) { + targetStack.ensureActivitiesVisibleLocked(null /* starting */, + 0 /* starting */, false /* preserveWindows */); + } // Keep target stack in place, nothing changes, so ignore the transition // logic below return; diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index 708493be16de..8b2912cc1931 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; @@ -32,6 +33,7 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_P import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import android.content.ComponentName; @@ -71,6 +73,36 @@ public class RecentsAnimationTest extends ActivityTestsBase { } @Test + public void testRecentsActivityVisiblility() { + ActivityDisplay display = mRootActivityContainer.getDefaultDisplay(); + ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN, + ACTIVITY_TYPE_RECENTS, true /* onTop */); + ActivityRecord recentActivity = new ActivityBuilder(mService) + .setComponent(mRecentsComponent) + .setCreateTask(true) + .setStack(recentsStack) + .build(); + ActivityRecord topActivity = new ActivityBuilder(mService).setCreateTask(true).build(); + topActivity.fullscreen = true; + topActivity.getActivityStack().moveToFront("testRecentsActivityVisiblility"); + + doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */); + + RecentsAnimationCallbacks recentsAnimation = startRecentsActivity( + mRecentsComponent, true /* getRecentsAnimation */); + // The launch-behind state should make the recents activity visible. + assertTrue(recentActivity.visible); + + // Simulate the animation is cancelled without changing the stack order. + recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, true /* runSychronously */, + false /* sendUserLeaveHint */); + // The non-top recents activity should be invisible by the restored launch-behind state. + assertFalse(recentActivity.visible); + } + + @Test public void testSetLaunchTaskBehindOfTargetActivity() { ActivityDisplay display = mRootActivityContainer.getDefaultDisplay(); display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class); |