Allow apply animation to ActivityRecord after transfer starting window.

If there are two activities be start continuous, it might have a chance
that opening transition cannot be applied becuase the starting window
just been transferred to secondary activity.
To fix this, only set mUseTransferredAnimation to true when the first
ActivityRecord is animating.

Bug: 155030898
Test: atest TaskSnapshotControllerTest AppWindowTokenTests
Test: atest AppWindowTokenTests#testTransferStartingWindowCanAnimate
Change-Id: I09166094514a5867e24e8421e0c829dd7446b123
This commit is contained in:
wilsonshih
2020-05-05 17:32:21 +08:00
parent 4942963c5e
commit ca274ed006
2 changed files with 36 additions and 6 deletions

View File

@@ -571,7 +571,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
new WindowState.UpdateReportedVisibilityResults();
boolean mUseTransferredAnimation;
private boolean mUseTransferredAnimation;
/**
* @see #currentLaunchCanTurnScreenOn()
@@ -3373,12 +3373,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
setClientVisible(fromActivity.mClientVisible);
transferAnimation(fromActivity);
if (fromActivity.isAnimating()) {
transferAnimation(fromActivity);
// When transferring an animation, we no longer need to apply an animation to the
// the token we transfer the animation over. Thus, set this flag to indicate we've
// transferred the animation.
mUseTransferredAnimation = true;
// When transferring an animation, we no longer need to apply an animation to
// the token we transfer the animation over. Thus, set this flag to indicate
// we've transferred the animation.
mUseTransferredAnimation = true;
}
mWmService.updateFocusedWindowLocked(
UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);

View File

@@ -31,10 +31,12 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
@@ -59,6 +61,8 @@ import android.view.WindowManager;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -365,6 +369,30 @@ public class AppWindowTokenTests extends WindowTestsBase {
assertHasStartingWindow(activity2);
}
@Test
public void testTransferStartingWindowCanAnimate() {
final ActivityRecord activity1 = createIsolatedTestActivityRecord();
final ActivityRecord activity2 = createIsolatedTestActivityRecord();
activity1.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
waitUntilHandlersIdle();
activity2.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
true, true, false, true, false, false);
waitUntilHandlersIdle();
assertNoStartingWindow(activity1);
assertHasStartingWindow(activity2);
// Assert that bottom activity is allowed to do animation.
doReturn(true).when(activity2).okToAnimate();
doReturn(true).when(activity2).isAnimating();
final OnAnimationFinishedCallback onAnimationFinishedCallback =
mock(OnAnimationFinishedCallback.class);
assertTrue(activity2.applyAnimation(null, TRANSIT_ACTIVITY_OPEN, true, false,
onAnimationFinishedCallback));
}
private ActivityRecord createIsolatedTestActivityRecord() {
final ActivityStack taskStack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(taskStack, 0 /* userId */);