Add test APIs for makeCustomAnimation
For CTS to verify activity custom transition duration
with onAnimationStartedListener / onAnimationFinishedListener
in ActivityOptions
Bug: 150443017
Test: build, atest ActivityTransitionTests
Change-Id: I603ab60a65343f3f336b311064ad55b01ead4929
diff --git a/api/test-current.txt b/api/test-current.txt
index 0ca8b2d..08f662c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -107,6 +107,7 @@
}
public class ActivityOptions {
+ method @NonNull public static android.app.ActivityOptions makeCustomAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
method public static void setExitTransitionTimeout(long);
method public void setLaunchActivityType(int);
method public void setLaunchTaskId(int);
@@ -115,6 +116,14 @@
method public void setTaskOverlay(boolean, boolean);
}
+ public static interface ActivityOptions.OnAnimationFinishedListener {
+ method public void onAnimationFinished();
+ }
+
+ public static interface ActivityOptions.OnAnimationStartedListener {
+ method public void onAnimationStarted();
+ }
+
public class ActivityTaskManager {
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void clearLaunchParamsForPackages(java.util.List<java.lang.String>);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public String listAllStacks();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 7fd02112..9833536 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -22,6 +22,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
@@ -369,7 +370,7 @@
*/
public static ActivityOptions makeCustomAnimation(Context context,
int enterResId, int exitResId) {
- return makeCustomAnimation(context, enterResId, exitResId, null, null);
+ return makeCustomAnimation(context, enterResId, exitResId, null, null, null);
}
/**
@@ -404,6 +405,38 @@
}
/**
+ * Create an ActivityOptions specifying a custom animation to run when
+ * the activity is displayed.
+ *
+ * @param context Who is defining this. This is the application that the
+ * animation resources will be loaded from.
+ * @param enterResId A resource ID of the animation resource to use for
+ * the incoming activity. Use 0 for no animation.
+ * @param exitResId A resource ID of the animation resource to use for
+ * the outgoing activity. Use 0 for no animation.
+ * @param handler If <var>listener</var> is non-null this must be a valid
+ * Handler on which to dispatch the callback; otherwise it should be null.
+ * @param startedListener Optional OnAnimationStartedListener to find out when the
+ * requested animation has started running. If for some reason the animation
+ * is not executed, the callback will happen immediately.
+ * @param finishedListener Optional OnAnimationFinishedListener when the animation
+ * has finished running.
+ * @return Returns a new ActivityOptions object that you can use to
+ * supply these options as the options Bundle when starting an activity.
+ * @hide
+ */
+ @TestApi
+ public static @NonNull ActivityOptions makeCustomAnimation(@NonNull Context context,
+ int enterResId, int exitResId, @Nullable Handler handler,
+ @Nullable OnAnimationStartedListener startedListener,
+ @Nullable OnAnimationFinishedListener finishedListener) {
+ ActivityOptions opts = makeCustomAnimation(context, enterResId, exitResId, handler,
+ startedListener);
+ opts.setOnAnimationFinishedListener(handler, finishedListener);
+ return opts;
+ }
+
+ /**
* Creates an ActivityOptions specifying a custom animation to run in place on an existing
* activity.
*
@@ -448,6 +481,7 @@
* to find out when the given animation has started running.
* @hide
*/
+ @TestApi
public interface OnAnimationStartedListener {
void onAnimationStarted();
}
@@ -474,6 +508,7 @@
* to find out when the given animation has drawn its last frame.
* @hide
*/
+ @TestApi
public interface OnAnimationFinishedListener {
void onAnimationFinished();
}
@@ -1089,7 +1124,7 @@
}
/** @hide */
- public IRemoteCallback getOnAnimationStartListener() {
+ public IRemoteCallback getAnimationStartedListener() {
return mAnimationStartedListener;
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
index 7b39ba3..345a649 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
@@ -76,7 +76,7 @@
callbackHandler.post(callback);
}
}
- });
+ }, null /* finishedListener */);
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c1c8440..e338715 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3739,7 +3739,8 @@
pendingOptions.getPackageName(),
pendingOptions.getCustomEnterResId(),
pendingOptions.getCustomExitResId(),
- pendingOptions.getOnAnimationStartListener());
+ pendingOptions.getAnimationStartedListener(),
+ pendingOptions.getAnimationFinishedListener());
break;
case ANIM_CLIP_REVEAL:
displayContent.mAppTransition.overridePendingAppTransitionClipReveal(
@@ -3769,7 +3770,7 @@
final GraphicBuffer buffer = pendingOptions.getThumbnail();
displayContent.mAppTransition.overridePendingAppTransitionThumb(buffer,
pendingOptions.getStartX(), pendingOptions.getStartY(),
- pendingOptions.getOnAnimationStartListener(),
+ pendingOptions.getAnimationStartedListener(),
scaleUp);
if (intent.getSourceBounds() == null && buffer != null) {
intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
@@ -3785,19 +3786,19 @@
pendingOptions.getSpecsFuture();
if (specsFuture != null) {
displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
- specsFuture, pendingOptions.getOnAnimationStartListener(),
+ specsFuture, pendingOptions.getAnimationStartedListener(),
animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
} else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
&& specs != null) {
displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
- specs, pendingOptions.getOnAnimationStartListener(),
+ specs, pendingOptions.getAnimationStartedListener(),
pendingOptions.getAnimationFinishedListener(), false);
} else {
displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
pendingOptions.getThumbnail(),
pendingOptions.getStartX(), pendingOptions.getStartY(),
pendingOptions.getWidth(), pendingOptions.getHeight(),
- pendingOptions.getOnAnimationStartListener(),
+ pendingOptions.getAnimationStartedListener(),
(animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
if (intent.getSourceBounds() == null) {
intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 682e991..44ab1e3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2003,7 +2003,7 @@
if (self.isState(
ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
self.getDisplay().mDisplayContent.mAppTransition.overridePendingAppTransition(
- packageName, enterAnim, exitAnim, null);
+ packageName, enterAnim, exitAnim, null, null);
}
Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index f86aeb2..755bc9a 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1411,23 +1411,7 @@
: new TranslateAnimation(0, fromX, 0, fromY);
set.addAnimation(scale);
set.addAnimation(translation);
-
- final IRemoteCallback callback = mAnimationFinishedCallback;
- if (callback != null) {
- set.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) { }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- mHandler.sendMessage(PooledLambda.obtainMessage(
- AppTransition::doAnimationCallback, callback));
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) { }
- });
- }
+ setAppTransitionFinishedCallbackIfNeeded(set);
return set;
}
@@ -1665,6 +1649,7 @@
"applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
+ "isEntrance=%b Callers=%s",
a, appTransitionToString(transit), enter, Debug.getCallers(3));
+ setAppTransitionFinishedCallbackIfNeeded(a);
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
@@ -1833,7 +1818,7 @@
}
void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
- IRemoteCallback startedCallback) {
+ IRemoteCallback startedCallback, IRemoteCallback endedCallback) {
if (canOverridePendingAppTransition()) {
clear();
mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
@@ -1842,6 +1827,7 @@
mNextAppTransitionExit = exitAnim;
postAnimationCallback();
mNextAppTransitionCallback = startedCallback;
+ mAnimationFinishedCallback = endedCallback;
}
}
@@ -2329,6 +2315,25 @@
}
}
+ private void setAppTransitionFinishedCallbackIfNeeded(Animation anim) {
+ final IRemoteCallback callback = mAnimationFinishedCallback;
+ if (callback != null && anim != null) {
+ anim.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) { }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ AppTransition::doAnimationCallback, callback));
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) { }
+ });
+ }
+ }
+
void removeAppTransitionTimeoutCallbacks() {
mHandler.removeCallbacks(mHandleAppTransitionTimeoutRunnable);
}