From 95ebce09e6c5efc64c2cbea5a0d3116fb864a3c9 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Tue, 20 Jul 2021 17:41:35 -0700 Subject: [PATCH] Hook up custom activity-level animation callbacks to shell Activity->activity transition animations can be customized by the client app. The animation part was already hooked up to shell transitions, but the start/finish callbacks were not. This hooks them up. Bug: 194233756 Test: atest WindowUntrustedTouchTest Change-Id: I2ee6f6e54bf1ebd0f1cbb73cdf79bc25eb0247db --- .../server/wm/ActivityClientController.java | 3 ++- .../com/android/server/wm/ActivityRecord.java | 9 ++++++- .../com/android/server/wm/Transition.java | 26 ++++++++++++++++++- .../server/wm/TransitionController.java | 6 +++-- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 8a76e3e586e01..0ebdb1d6133b5 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -1020,7 +1020,8 @@ class ActivityClientController extends IActivityClientController.Stub { r.mOverrideTaskTransition); mService.getTransitionController().setOverrideAnimation( TransitionInfo.AnimationOptions.makeCustomAnimOptions(packageName, - enterAnim, exitAnim, r.mOverrideTaskTransition)); + enterAnim, exitAnim, r.mOverrideTaskTransition), + null /* startCallback */, null /* finishCallback */); } } Binder.restoreCallingIdentity(origId); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 0d439456c3acb..d9d18bc56f7fa 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -272,6 +272,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; @@ -4317,6 +4318,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int animationType = pendingOptions.getAnimationType(); final DisplayContent displayContent = getDisplayContent(); AnimationOptions options = null; + IRemoteCallback startCallback = null; + IRemoteCallback finishCallback = null; switch (animationType) { case ANIM_CUSTOM: displayContent.mAppTransition.overridePendingAppTransition( @@ -4329,6 +4332,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A options = AnimationOptions.makeCustomAnimOptions(pendingOptions.getPackageName(), pendingOptions.getCustomEnterResId(), pendingOptions.getCustomExitResId(), pendingOptions.getOverrideTaskTransition()); + startCallback = pendingOptions.getAnimationStartedListener(); + finishCallback = pendingOptions.getAnimationFinishedListener(); break; case ANIM_CLIP_REVEAL: displayContent.mAppTransition.overridePendingAppTransitionClipReveal( @@ -4368,6 +4373,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A scaleUp); options = AnimationOptions.makeThumnbnailAnimOptions(buffer, pendingOptions.getStartX(), pendingOptions.getStartY(), scaleUp); + startCallback = pendingOptions.getAnimationStartedListener(); if (intent.getSourceBounds() == null && buffer != null) { intent.setSourceBounds(new Rect(pendingOptions.getStartX(), pendingOptions.getStartY(), @@ -4418,7 +4424,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } if (options != null) { - mAtmService.getTransitionController().setOverrideAnimation(options); + mAtmService.getTransitionController().setOverrideAnimation(options, + startCallback, finishCallback); } } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 1ac16664244fa..7c1a189c911aa 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -46,11 +46,13 @@ import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_W import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.RemoteException; import android.os.SystemClock; import android.util.ArrayMap; @@ -65,6 +67,7 @@ import android.window.TransitionInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; +import com.android.internal.util.function.pooled.PooledLambda; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -130,7 +133,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe /** The final animation targets derived from participants after promotion. */ private ArraySet mTargets = null; + /** Custom activity-level animation options and callbacks. */ private TransitionInfo.AnimationOptions mOverrideOptions; + private IRemoteCallback mClientAnimationStartCallback = null; + private IRemoteCallback mClientAnimationFinishCallback = null; private @TransitionState int mState = STATE_COLLECTING; private final ReadyTracker mReadyTracker = new ReadyTracker(); @@ -226,13 +232,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mChanges.get(wc).mExistenceChanged = true; } + private void sendRemoteCallback(@Nullable IRemoteCallback callback) { + if (callback == null) return; + mController.mAtm.mH.sendMessage(PooledLambda.obtainMessage(cb -> { + try { + cb.sendResult(null); + } catch (RemoteException e) { } + }, callback)); + } + /** * Set animation options for collecting transition by ActivityRecord. * @param options AnimationOptions captured from ActivityOptions */ - void setOverrideAnimation(TransitionInfo.AnimationOptions options) { + void setOverrideAnimation(TransitionInfo.AnimationOptions options, + @Nullable IRemoteCallback startCallback, @Nullable IRemoteCallback finishCallback) { if (mSyncId < 0) return; mOverrideOptions = options; + sendRemoteCallback(mClientAnimationStartCallback); + mClientAnimationStartCallback = startCallback; + mClientAnimationFinishCallback = finishCallback; } /** @@ -363,6 +382,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe .scheduleProcessStoppingAndFinishingActivitiesIfNeeded(); } + sendRemoteCallback(mClientAnimationFinishCallback); + legacyRestoreNavigationBarFromApp(); } @@ -426,6 +447,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe reportStartReasonsToLogger(); + // The callback is only populated for custom activity-level client animations + sendRemoteCallback(mClientAnimationStartCallback); + // Manually show any activities that are visibleRequested. This is needed to properly // support simultaneous animation queueing/merging. Specifically, if transition A makes // an activity invisible, it's finishTransaction (which is applied *after* the animation) diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 16d22787500c0..44dee4d85dc52 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -30,6 +30,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.RemoteException; import android.os.SystemClock; import android.util.Slog; @@ -277,9 +278,10 @@ class TransitionController { } /** @see Transition#setOverrideAnimation */ - void setOverrideAnimation(TransitionInfo.AnimationOptions options) { + void setOverrideAnimation(TransitionInfo.AnimationOptions options, + @Nullable IRemoteCallback startCallback, @Nullable IRemoteCallback finishCallback) { if (mCollectingTransition == null) return; - mCollectingTransition.setOverrideAnimation(options); + mCollectingTransition.setOverrideAnimation(options, startCallback, finishCallback); } /** @see Transition#setReady */