Add per-display RemoteAnimation overrides and flag to disable snapshots
This CL adds a display-level fallback for remoteanimation overrides
and a property to RemoteAnimationAdapter specifying whether it needs
a snapshot for change transitions or not.
During a mode-change, this check for an override and then asks it
whether it needs a snapshot before creating one.
Bug: 113252739
Test: Added AppChangeTransitionTests
Change-Id: I47c933bd08fe512dc6cf029607819e2c908ab4cd
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ea6f4cc..0ce71fd 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4399,6 +4399,27 @@
}
}
+ @Override
+ public void registerRemoteAnimationsForDisplay(int displayId,
+ RemoteAnimationDefinition definition) {
+ mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+ "registerRemoteAnimations");
+ definition.setCallingPid(Binder.getCallingPid());
+ synchronized (mGlobalLock) {
+ final ActivityDisplay display = mRootActivityContainer.getActivityDisplay(displayId);
+ if (display == null) {
+ Slog.e(TAG, "Couldn't find display with id: " + displayId);
+ return;
+ }
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ display.mDisplayContent.registerRemoteAnimations(definition);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
/** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
@Override
public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 49308b8..8f0a7c0 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -76,6 +76,7 @@
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
private final WallpaperController mWallpaperControllerLocked;
+ private RemoteAnimationDefinition mRemoteAnimationDefinition = null;
private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
@@ -85,6 +86,10 @@
mWallpaperControllerLocked = mDisplayContent.mWallpaperController;
}
+ void registerRemoteAnimations(RemoteAnimationDefinition definition) {
+ mRemoteAnimationDefinition = definition;
+ }
+
/**
* Handle application transition for given display.
*/
@@ -216,6 +221,21 @@
return mainWindow != null ? mainWindow.mAttrs : null;
}
+ RemoteAnimationAdapter getRemoteAnimationOverride(AppWindowToken animLpToken, int transit,
+ ArraySet<Integer> activityTypes) {
+ final RemoteAnimationDefinition definition = animLpToken.getRemoteAnimationDefinition();
+ if (definition != null) {
+ final RemoteAnimationAdapter adapter = definition.getAdapter(transit, activityTypes);
+ if (adapter != null) {
+ return adapter;
+ }
+ }
+ if (mRemoteAnimationDefinition == null) {
+ return null;
+ }
+ return mRemoteAnimationDefinition.getAdapter(transit, activityTypes);
+ }
+
/**
* Overrides the pending transition with the remote animation defined for the transition in the
* set of defined remote animations in the app window token.
@@ -229,11 +249,8 @@
if (animLpToken == null) {
return;
}
- final RemoteAnimationDefinition definition = animLpToken.getRemoteAnimationDefinition();
- if (definition == null) {
- return;
- }
- final RemoteAnimationAdapter adapter = definition.getAdapter(transit, activityTypes);
+ final RemoteAnimationAdapter adapter =
+ getRemoteAnimationOverride(animLpToken, transit, activityTypes);
if (adapter != null) {
animLpToken.getDisplayContent().mAppTransition.overridePendingAppTransitionRemote(
adapter);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 65b36a0..d915e10 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -105,6 +105,7 @@
import android.view.DisplayInfo;
import android.view.IApplicationToken;
import android.view.InputApplicationHandle;
+import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -1621,6 +1622,17 @@
t.reparent(getSurfaceControl(), mTransitChangeLeash);
onAnimationLeashCreated(t, mTransitChangeLeash);
+ // Skip creating snapshot if this transition is controlled by a remote animator which
+ // doesn't need it.
+ ArraySet<Integer> activityTypes = new ArraySet<>();
+ activityTypes.add(getActivityType());
+ RemoteAnimationAdapter adapter =
+ mDisplayContent.mAppTransitionController.getRemoteAnimationOverride(
+ this, TRANSIT_TASK_CHANGE_WINDOWING_MODE, activityTypes);
+ if (adapter != null && !adapter.getChangeNeedsSnapshot()) {
+ return;
+ }
+
if (mThumbnail == null && getTask() != null) {
final TaskSnapshotController snapshotCtrl = mWmService.mTaskSnapshotController;
final ArraySet<Task> tasks = new ArraySet<>();
@@ -1639,6 +1651,11 @@
return mTransitChangeLeash != null || isChangeTransition(mTransit);
}
+ @VisibleForTesting
+ AppWindowThumbnail getThumbnail() {
+ return mThumbnail;
+ }
+
@Override
void checkAppWindowsReadyToShow() {
if (allDrawn == mLastAllDrawn) {
@@ -2349,7 +2366,7 @@
AnimationAdapter thumbnailAdapter = null;
getAnimationBounds(mTmpPoint, mTmpRect);
- boolean isChanging = isChangeTransition(transit) && mThumbnail != null;
+ boolean isChanging = isChangeTransition(transit) && enter;
// Delaying animation start isn't compatible with remote animations at all.
if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
@@ -2368,11 +2385,13 @@
getDisplayContent().getDisplayInfo(), duration,
true /* isAppAnimation */, false /* isThumbnail */),
mWmService.mSurfaceAnimationRunner);
- thumbnailAdapter = new LocalAnimationAdapter(
- new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect,
- getDisplayContent().getDisplayInfo(), duration,
- true /* isAppAnimation */, true /* isThumbnail */),
- mWmService.mSurfaceAnimationRunner);
+ if (mThumbnail != null) {
+ thumbnailAdapter = new LocalAnimationAdapter(
+ new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect,
+ getDisplayContent().getDisplayInfo(), duration,
+ true /* isAppAnimation */, true /* isThumbnail */),
+ mWmService.mSurfaceAnimationRunner);
+ }
mTransit = transit;
mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
} else {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8f976e7..4ddecfb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -162,6 +162,7 @@
import android.view.InputDevice;
import android.view.InsetsState.InternalInsetType;
import android.view.MagnificationSpec;
+import android.view.RemoteAnimationDefinition;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -1091,6 +1092,10 @@
return mLastWindowForcedOrientation;
}
+ void registerRemoteAnimations(RemoteAnimationDefinition definition) {
+ mAppTransitionController.registerRemoteAnimations(definition);
+ }
+
/**
* Temporarily pauses rotation changes until resumed.
*
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index f760b39..5f95691 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -322,8 +322,10 @@
mStartBounds = new Rect(startBounds);
mTmpRect.set(startBounds);
mTmpRect.offsetTo(0, 0);
- mThumbnailAdapter =
- new RemoteAnimationAdapterWrapper(this, new Point(0, 0), mTmpRect);
+ if (mRemoteAnimationAdapter.getChangeNeedsSnapshot()) {
+ mThumbnailAdapter =
+ new RemoteAnimationAdapterWrapper(this, new Point(0, 0), mTmpRect);
+ }
} else {
mStartBounds = null;
}