Merge "Fix app requested animation for ActivityEmbedding remote animation" into tm-qpr-dev

This commit is contained in:
Chris Li
2022-11-19 03:12:11 +00:00
committed by Android (Google) Code Review
3 changed files with 121 additions and 13 deletions

View File

@@ -169,7 +169,8 @@ public class AppTransition implements Dump {
private final WindowManagerService mService; private final WindowManagerService mService;
private final DisplayContent mDisplayContent; private final DisplayContent mDisplayContent;
private final TransitionAnimation mTransitionAnimation; @VisibleForTesting
final TransitionAnimation mTransitionAnimation;
private @TransitionFlags int mNextAppTransitionFlags = 0; private @TransitionFlags int mNextAppTransitionFlags = 0;
private final ArrayList<Integer> mNextAppTransitionRequests = new ArrayList<>(); private final ArrayList<Integer> mNextAppTransitionRequests = new ArrayList<>();
@@ -315,10 +316,33 @@ public class AppTransition implements Dump {
setAppTransitionState(APP_STATE_TIMEOUT); setAppTransitionState(APP_STATE_TIMEOUT);
} }
/**
* Gets the animation overridden by app via {@link #overridePendingAppTransition}.
*/
@Nullable
Animation getNextAppRequestedAnimation(boolean enter) {
final Animation a = mTransitionAnimation.loadAppTransitionAnimation(
mNextAppTransitionPackage,
enter ? mNextAppTransitionEnter : mNextAppTransitionExit);
if (mNextAppTransitionBackgroundColor != 0 && a != null) {
a.setBackdropColor(mNextAppTransitionBackgroundColor);
}
return a;
}
/**
* Gets the animation background color overridden by app via
* {@link #overridePendingAppTransition}.
*/
@ColorInt int getNextAppTransitionBackgroundColor() { @ColorInt int getNextAppTransitionBackgroundColor() {
return mNextAppTransitionBackgroundColor; return mNextAppTransitionBackgroundColor;
} }
@VisibleForTesting
boolean isNextAppTransitionOverrideRequested() {
return mNextAppTransitionOverrideRequested;
}
HardwareBuffer getAppTransitionThumbnailHeader(WindowContainer container) { HardwareBuffer getAppTransitionThumbnailHeader(WindowContainer container) {
AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get( AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
container.hashCode()); container.hashCode());
@@ -411,9 +435,12 @@ public class AppTransition implements Dump {
} }
void clear() { void clear() {
clear(true /* clearAppOverride */);
}
private void clear(boolean clearAppOverride) {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE; mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
mNextAppTransitionOverrideRequested = false; mNextAppTransitionOverrideRequested = false;
mNextAppTransitionPackage = null;
mNextAppTransitionAnimationsSpecs.clear(); mNextAppTransitionAnimationsSpecs.clear();
mRemoteAnimationController = null; mRemoteAnimationController = null;
mNextAppTransitionAnimationsSpecsFuture = null; mNextAppTransitionAnimationsSpecsFuture = null;
@@ -421,6 +448,12 @@ public class AppTransition implements Dump {
mAnimationFinishedCallback = null; mAnimationFinishedCallback = null;
mOverrideTaskTransition = false; mOverrideTaskTransition = false;
mNextAppTransitionIsSync = false; mNextAppTransitionIsSync = false;
if (clearAppOverride) {
mNextAppTransitionPackage = null;
mNextAppTransitionEnter = 0;
mNextAppTransitionExit = 0;
mNextAppTransitionBackgroundColor = 0;
}
} }
void freeze() { void freeze() {
@@ -528,7 +561,7 @@ public class AppTransition implements Dump {
return TransitionAnimation.loadAnimationSafely(context, resId, TAG); return TransitionAnimation.loadAnimationSafely(context, resId, TAG);
} }
static int mapOpenCloseTransitTypes(int transit, boolean enter) { private static int mapOpenCloseTransitTypes(int transit, boolean enter) {
int animAttr = 0; int animAttr = 0;
switch (transit) { switch (transit) {
case TRANSIT_OLD_ACTIVITY_OPEN: case TRANSIT_OLD_ACTIVITY_OPEN:
@@ -788,11 +821,7 @@ public class AppTransition implements Dump {
"applyAnimation: anim=%s transit=%s Callers=%s", a, "applyAnimation: anim=%s transit=%s Callers=%s", a,
appTransitionOldToString(transit), Debug.getCallers(3)); appTransitionOldToString(transit), Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
a = mTransitionAnimation.loadAppTransitionAnimation(mNextAppTransitionPackage, a = getNextAppRequestedAnimation(enter);
enter ? mNextAppTransitionEnter : mNextAppTransitionExit);
if (mNextAppTransitionBackgroundColor != 0) {
a.setBackdropColor(mNextAppTransitionBackgroundColor);
}
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s " "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
+ "isEntrance=%b Callers=%s", + "isEntrance=%b Callers=%s",
@@ -1032,7 +1061,9 @@ public class AppTransition implements Dump {
ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s", ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s",
isTransitionSet(), remoteAnimationAdapter); isTransitionSet(), remoteAnimationAdapter);
if (isTransitionSet() && !mNextAppTransitionIsSync) { if (isTransitionSet() && !mNextAppTransitionIsSync) {
clear(); // ActivityEmbedding animation will run by the app process for which we want to respect
// the app override for whether or not to show background color.
clear(!isActivityEmbedding /* clearAppOverride */);
mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE; mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent, mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent,
remoteAnimationAdapter, mHandler, isActivityEmbedding); remoteAnimationAdapter, mHandler, isActivityEmbedding);

View File

@@ -2995,10 +2995,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// screen empty. Show background color to cover that. // screen empty. Show background color to cover that.
showBackdrop = getDisplayContent().mChangingContainers.size() > 1; showBackdrop = getDisplayContent().mChangingContainers.size() > 1;
} else { } else {
// Check whether or not to show backdrop for open/close transition. // Check whether the app has requested to show backdrop for open/close
final int animAttr = AppTransition.mapOpenCloseTransitTypes(transit, enter); // transition.
final Animation a = animAttr != 0 final Animation a = appTransition.getNextAppRequestedAnimation(enter);
? appTransition.loadAnimationAttr(lp, animAttr, transit) : null;
showBackdrop = a != null && a.getShowBackdrop(); showBackdrop = a != null && a.getShowBackdrop();
} }
backdropColor = appTransition.getNextAppTransitionBackgroundColor(); backdropColor = appTransition.getNextAppTransitionBackgroundColor();

View File

@@ -49,6 +49,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@@ -67,11 +68,14 @@ import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget; import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.animation.Animation;
import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizer;
import android.window.TaskFragmentOrganizer; import android.window.TaskFragmentOrganizer;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.internal.policy.TransitionAnimation;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -495,6 +499,80 @@ public class AppTransitionTests extends WindowTestsBase {
assertEquals(startBounds, taskFragment.mSurfaceFreezer.mFreezeBounds); assertEquals(startBounds, taskFragment.mSurfaceFreezer.mFreezeBounds);
} }
@Test
public void testGetNextAppTransitionBackgroundColor() {
assumeFalse(WindowManagerService.sEnableShellTransitions);
// No override by default.
assertEquals(0, mDc.mAppTransition.getNextAppTransitionBackgroundColor());
// Override with a custom color.
mDc.mAppTransition.prepareAppTransition(TRANSIT_OPEN, 0);
final int testColor = 123;
mDc.mAppTransition.overridePendingAppTransition("testPackage", 0 /* enterAnim */,
0 /* exitAnim */, testColor, null /* startedCallback */, null /* endedCallback */,
false /* overrideTaskTransaction */);
assertEquals(testColor, mDc.mAppTransition.getNextAppTransitionBackgroundColor());
assertTrue(mDc.mAppTransition.isNextAppTransitionOverrideRequested());
// Override with ActivityEmbedding remote animation. Background color should be kept.
mDc.mAppTransition.overridePendingAppTransitionRemote(mock(RemoteAnimationAdapter.class),
false /* sync */, true /* isActivityEmbedding */);
assertEquals(testColor, mDc.mAppTransition.getNextAppTransitionBackgroundColor());
assertFalse(mDc.mAppTransition.isNextAppTransitionOverrideRequested());
// Background color should not be cleared anymore after #clear().
mDc.mAppTransition.clear();
assertEquals(0, mDc.mAppTransition.getNextAppTransitionBackgroundColor());
assertFalse(mDc.mAppTransition.isNextAppTransitionOverrideRequested());
}
@Test
public void testGetNextAppRequestedAnimation() {
assumeFalse(WindowManagerService.sEnableShellTransitions);
final String packageName = "testPackage";
final int enterAnimResId = 1;
final int exitAnimResId = 2;
final int testColor = 123;
final Animation enterAnim = mock(Animation.class);
final Animation exitAnim = mock(Animation.class);
final TransitionAnimation transitionAnimation = mDc.mAppTransition.mTransitionAnimation;
spyOn(transitionAnimation);
doReturn(enterAnim).when(transitionAnimation)
.loadAppTransitionAnimation(packageName, enterAnimResId);
doReturn(exitAnim).when(transitionAnimation)
.loadAppTransitionAnimation(packageName, exitAnimResId);
// No override by default.
assertNull(mDc.mAppTransition.getNextAppRequestedAnimation(true /* enter */));
assertNull(mDc.mAppTransition.getNextAppRequestedAnimation(false /* enter */));
// Override with a custom animation.
mDc.mAppTransition.prepareAppTransition(TRANSIT_OPEN, 0);
mDc.mAppTransition.overridePendingAppTransition(packageName, enterAnimResId, exitAnimResId,
testColor, null /* startedCallback */, null /* endedCallback */,
false /* overrideTaskTransaction */);
assertEquals(enterAnim, mDc.mAppTransition.getNextAppRequestedAnimation(true /* enter */));
assertEquals(exitAnim, mDc.mAppTransition.getNextAppRequestedAnimation(false /* enter */));
assertTrue(mDc.mAppTransition.isNextAppTransitionOverrideRequested());
// Override with ActivityEmbedding remote animation. Custom animation should be kept.
mDc.mAppTransition.overridePendingAppTransitionRemote(mock(RemoteAnimationAdapter.class),
false /* sync */, true /* isActivityEmbedding */);
assertEquals(enterAnim, mDc.mAppTransition.getNextAppRequestedAnimation(true /* enter */));
assertEquals(exitAnim, mDc.mAppTransition.getNextAppRequestedAnimation(false /* enter */));
assertFalse(mDc.mAppTransition.isNextAppTransitionOverrideRequested());
// Custom animation should not be cleared anymore after #clear().
mDc.mAppTransition.clear();
assertNull(mDc.mAppTransition.getNextAppRequestedAnimation(true /* enter */));
assertNull(mDc.mAppTransition.getNextAppRequestedAnimation(false /* enter */));
}
private class TestRemoteAnimationRunner implements IRemoteAnimationRunner { private class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
boolean mCancelled = false; boolean mCancelled = false;
@Override @Override