Merge "Prevent cross-activity animation if scene transition is set"
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6abd3d7..90d25ee 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -932,6 +932,8 @@
// task and directly above this ActivityRecord. This field is updated whenever a new activity
// is launched from this ActivityRecord. Touches are always allowed within the same uid.
int mAllowedTouchUid;
+ // Whether client has requested a scene transition when exiting.
+ final boolean mHasSceneTransition;
// Whether the ActivityEmbedding is enabled on the app.
private final boolean mAppActivityEmbeddingSplitsEnabled;
@@ -2091,6 +2093,10 @@
if (options != null) {
setOptions(options);
+ // The result receiver is the transition receiver, which will handle the shared element
+ // exit transition.
+ mHasSceneTransition = options.getAnimationType() == ANIM_SCENE_TRANSITION
+ && options.getResultReceiver() != null;
final PendingIntent usageReport = options.getUsageTimeReport();
if (usageReport != null) {
appTimeTracker = new AppTimeTracker(usageReport);
@@ -2103,6 +2109,8 @@
mHandoverLaunchDisplayId = options.getLaunchDisplayId();
mLaunchCookie = options.getLaunchCookie();
mLaunchRootTask = options.getLaunchRootTask();
+ } else {
+ mHasSceneTransition = false;
}
mPersistentState = persistentState;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 14131e6..cc71155 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -218,17 +218,19 @@
// - We don't have any ActivityRecord or Task to animate.
// - The IME is opened, and we just need to close it.
// - The home activity is the focused activity.
+ // - The current activity will do shared element transition when exiting.
if (backType == BackNavigationInfo.TYPE_CALLBACK
|| currentActivity == null
|| currentTask == null
- || currentActivity.isActivityTypeHome()) {
+ || currentActivity.isActivityTypeHome()
+ || currentActivity.mHasSceneTransition) {
infoBuilder.setType(BackNavigationInfo.TYPE_CALLBACK);
final WindowState finalFocusedWindow = window;
infoBuilder.setOnBackNavigationDone(new RemoteCallback(result ->
onBackNavigationDone(result, finalFocusedWindow,
BackNavigationInfo.TYPE_CALLBACK)));
- mLastBackType = backType;
- return infoBuilder.setType(backType).build();
+ mLastBackType = BackNavigationInfo.TYPE_CALLBACK;
+ return infoBuilder.build();
}
mBackAnimationInProgress = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index e02863e..e663245 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2315,7 +2315,7 @@
.build();
final ActivityOptions opts = ActivityOptions.makeLaunchIntoPip(params);
final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setLaunchIntoPipActivityOptions(opts)
+ .setActivityOptions(opts)
.build();
// Verify the pictureInPictureArgs is set on the new Activity
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index ca28558..caaf934 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -1507,7 +1507,7 @@
.build();
final ActivityOptions opts = ActivityOptions.makeLaunchIntoPip(params);
ActivityRecord targetRecord = new ActivityBuilder(mAtm)
- .setLaunchIntoPipActivityOptions(opts)
+ .setActivityOptions(opts)
.build();
// Start the target launch-into-pip activity from a source
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index 9a786d4..ee8a988 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -16,8 +16,10 @@
package com.android.server.wm;
+import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.window.BackNavigationInfo.typeToString;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -37,8 +39,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityOptions;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.WindowManager;
@@ -219,6 +223,35 @@
assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(appCallback);
}
+ // TODO (b/259427810) Remove this test when we figure out new API
+ @Test
+ public void backAnimationSkipSharedElementTransition() {
+ // Simulate ActivityOptions#makeSceneTransitionAnimation
+ final Bundle myBundle = new Bundle();
+ myBundle.putInt(ActivityOptions.KEY_ANIM_TYPE, ANIM_SCENE_TRANSITION);
+ myBundle.putParcelable("android:activity.transitionCompleteListener",
+ mock(android.os.ResultReceiver.class));
+ final ActivityOptions options = new ActivityOptions(myBundle);
+
+ final ActivityRecord testActivity = new ActivityBuilder(mAtm)
+ .setCreateTask(true)
+ .setActivityOptions(options)
+ .build();
+ testActivity.info.applicationInfo.privateFlagsExt |=
+ PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK;
+ final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, testActivity,
+ "window");
+ addToWindowMap(window, true);
+ makeWindowVisibleAndDrawn(window);
+ IOnBackInvokedCallback callback = withSystemCallback(testActivity.getTask());
+
+ BackNavigationInfo backNavigationInfo = startBackNavigation();
+ assertTrue(testActivity.mHasSceneTransition);
+ assertThat(typeToString(backNavigationInfo.getType()))
+ .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK));
+ assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(callback);
+ }
+
@Test
public void testUnregisterCallbacksWithSystemCallback()
throws InterruptedException, RemoteException {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 4d31414..bbdf621 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -1016,8 +1016,8 @@
private boolean mOnTop = false;
private ActivityInfo.WindowLayout mWindowLayout;
private boolean mVisible = true;
- private ActivityOptions mLaunchIntoPipOpts;
private String mRequiredDisplayCategory;
+ private ActivityOptions mActivityOpts;
ActivityBuilder(ActivityTaskManagerService service) {
mService = service;
@@ -1153,8 +1153,8 @@
return this;
}
- ActivityBuilder setLaunchIntoPipActivityOptions(ActivityOptions opts) {
- mLaunchIntoPipOpts = opts;
+ ActivityBuilder setActivityOptions(ActivityOptions opts) {
+ mActivityOpts = opts;
return this;
}
@@ -1225,8 +1225,8 @@
}
ActivityOptions options = null;
- if (mLaunchIntoPipOpts != null) {
- options = mLaunchIntoPipOpts;
+ if (mActivityOpts != null) {
+ options = mActivityOpts;
} else if (mLaunchTaskBehind) {
options = ActivityOptions.makeTaskLaunchBehind();
}