summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/ITaskFragmentOrganizerController.aidl4
-rw-r--r--core/java/android/window/TaskFragmentOrganizer.java13
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java19
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java44
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java5
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java31
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java4
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java28
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java35
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java35
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java26
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java40
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java93
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java8
14 files changed, 194 insertions, 191 deletions
diff --git a/core/java/android/window/ITaskFragmentOrganizerController.aidl b/core/java/android/window/ITaskFragmentOrganizerController.aidl
index 3250dd8f7308..d25c8a834c7b 100644
--- a/core/java/android/window/ITaskFragmentOrganizerController.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizerController.aidl
@@ -39,13 +39,13 @@ interface ITaskFragmentOrganizerController {
* animations if the transition only contains windows that belong to the organized
* TaskFragments in the given Task.
*/
- void registerRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId,
+ void registerRemoteAnimations(in ITaskFragmentOrganizer organizer,
in RemoteAnimationDefinition definition);
/**
* Unregisters remote animations per transition type for the organizer.
*/
- void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId);
+ void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer);
/**
* Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 8df6541aed9e..ef19c55019dc 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -122,16 +122,13 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
/**
* Registers remote animations per transition type for the organizer. It will override the
* animations if the transition only contains windows that belong to the organized
- * TaskFragments in the given Task.
- *
- * @param taskId overrides if the transition only contains windows belonging to this Task.
+ * TaskFragments, and at least one of the transition window is embedded (not filling the Task).
* @hide
*/
@CallSuper
- public void registerRemoteAnimations(int taskId,
- @NonNull RemoteAnimationDefinition definition) {
+ public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) {
try {
- getController().registerRemoteAnimations(mInterface, taskId, definition);
+ getController().registerRemoteAnimations(mInterface, definition);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -142,9 +139,9 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* @hide
*/
@CallSuper
- public void unregisterRemoteAnimations(int taskId) {
+ public void unregisterRemoteAnimations() {
try {
- getController().unregisterRemoteAnimations(mInterface, taskId);
+ getController().unregisterRemoteAnimations(mInterface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 9d841ea2e55d..d7d43aa19757 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -37,7 +37,6 @@ import android.window.TaskFragmentOrganizer;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;
-import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -85,26 +84,20 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
@Override
public void unregisterOrganizer() {
if (mAnimationController != null) {
- mAnimationController.unregisterAllRemoteAnimations();
+ mAnimationController.unregisterRemoteAnimations();
mAnimationController = null;
}
super.unregisterOrganizer();
}
- /** Overrides the animation if the transition is on the given Task. */
- void startOverrideSplitAnimation(int taskId) {
+ /**
+ * Overrides the animation for transitions of embedded activities organized by this organizer.
+ */
+ void overrideSplitAnimation() {
if (mAnimationController == null) {
mAnimationController = new TaskFragmentAnimationController(this);
}
- mAnimationController.registerRemoteAnimations(taskId);
- }
-
- /** No longer overrides the animation if the transition is on the given Task. */
- @GuardedBy("mLock")
- void stopOverrideSplitAnimation(int taskId) {
- if (mAnimationController != null) {
- mAnimationController.unregisterRemoteAnimations(taskId);
- }
+ mAnimationController.registerRemoteAnimations();
}
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index d52caaf4c3e8..c06548ad81a1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -193,7 +193,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
continue;
}
updateContainersInTask(wct, taskContainer);
- updateAnimationOverride(taskContainer);
}
// The WCT should be applied and merged to the device state change transition if
// there is one.
@@ -208,9 +207,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
synchronized (mLock) {
mSplitRules.clear();
mSplitRules.addAll(rules);
- for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
- updateAnimationOverride(mTaskContainers.valueAt(i));
- }
}
}
@@ -612,7 +608,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
if (taskContainer.isEmpty()) {
// Cleanup the TaskContainer if it becomes empty.
- mPresenter.stopOverrideSplitAnimation(taskContainer.getTaskId());
mTaskContainers.remove(taskContainer.getTaskId());
}
return;
@@ -622,43 +617,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@GuardedBy("mLock")
private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer,
@NonNull Configuration config) {
- final boolean wasInPip = taskContainer.isInPictureInPicture();
- final boolean isInPIp = isInPictureInPicture(config);
-
- // We need to check the animation override when enter/exit PIP or has bounds changed.
- boolean shouldUpdateAnimationOverride = wasInPip != isInPIp;
- if (taskContainer.setTaskBounds(config.windowConfiguration.getBounds())
- && !isInPIp) {
- // We don't care the bounds change when it has already entered PIP.
- shouldUpdateAnimationOverride = true;
- }
- if (shouldUpdateAnimationOverride) {
- updateAnimationOverride(taskContainer);
- }
- }
-
- /**
- * Updates if we should override transition animation. We only want to override if the Task
- * bounds is large enough for at least one split rule.
- */
- @GuardedBy("mLock")
- private void updateAnimationOverride(@NonNull TaskContainer taskContainer) {
- if (ENABLE_SHELL_TRANSITIONS) {
- // TODO(b/207070762): cleanup with legacy app transition
- // Animation will be handled by WM Shell with Shell transition enabled.
- return;
- }
- if (!taskContainer.isTaskBoundsInitialized()) {
- // We don't know about the Task bounds/windowingMode yet.
- return;
- }
-
- // We only want to override if the TaskContainer may show split.
- if (mayShowSplit(taskContainer)) {
- mPresenter.startOverrideSplitAnimation(taskContainer.getTaskId());
- } else {
- mPresenter.stopOverrideSplitAnimation(taskContainer.getTaskId());
- }
+ taskContainer.setTaskBounds(config.windowConfiguration.getBounds());
}
/** Returns whether the given {@link TaskContainer} may show in split. */
@@ -1283,7 +1242,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
}
}
- updateAnimationOverride(taskContainer);
return container;
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index cb470bac5c9a..f494b32cff14 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -139,6 +139,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
super(executor, controller);
mController = controller;
registerOrganizer();
+ if (!SplitController.ENABLE_SHELL_TRANSITIONS) {
+ // TODO(b/207070762): cleanup with legacy app transition
+ // Animation will be handled by WM Shell when Shell transition is enabled.
+ overrideSplitAnimation();
+ }
}
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
index ee2e139bb0b2..d7eb9a01f57c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
@@ -18,13 +18,10 @@ package androidx.window.extensions.embedding;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
-import android.util.ArraySet;
import android.util.Log;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
@@ -44,8 +41,7 @@ class TaskFragmentAnimationController {
private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
@VisibleForTesting
final RemoteAnimationDefinition mDefinition;
- /** Task Ids that we have registered for remote animation. */
- private final ArraySet<Integer> mRegisterTasks = new ArraySet<>();
+ private boolean mIsRegistered;
TaskFragmentAnimationController(@NonNull TaskFragmentOrganizer organizer) {
mOrganizer = organizer;
@@ -54,39 +50,30 @@ class TaskFragmentAnimationController {
new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */);
mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter);
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_OPEN, animationAdapter);
mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, animationAdapter);
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_CLOSE, animationAdapter);
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
}
- void registerRemoteAnimations(int taskId) {
+ void registerRemoteAnimations() {
if (DEBUG) {
Log.v(TAG, "registerRemoteAnimations");
}
- if (mRegisterTasks.contains(taskId)) {
+ if (mIsRegistered) {
return;
}
- mOrganizer.registerRemoteAnimations(taskId, mDefinition);
- mRegisterTasks.add(taskId);
+ mOrganizer.registerRemoteAnimations(mDefinition);
+ mIsRegistered = true;
}
- void unregisterRemoteAnimations(int taskId) {
+ void unregisterRemoteAnimations() {
if (DEBUG) {
Log.v(TAG, "unregisterRemoteAnimations");
}
- if (!mRegisterTasks.contains(taskId)) {
+ if (!mIsRegistered) {
return;
}
- mOrganizer.unregisterRemoteAnimations(taskId);
- mRegisterTasks.remove(taskId);
- }
-
- void unregisterAllRemoteAnimations() {
- final ArraySet<Integer> tasks = new ArraySet<>(mRegisterTasks);
- for (int taskId : tasks) {
- unregisterRemoteAnimations(taskId);
- }
+ mOrganizer.unregisterRemoteAnimations();
+ mIsRegistered = false;
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
index 8c416e881059..0e13c59e593c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
@@ -20,11 +20,9 @@ import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
import android.animation.Animator;
@@ -169,11 +167,9 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
switch (transit) {
case TRANSIT_OLD_ACTIVITY_OPEN:
case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
- case TRANSIT_OLD_TASK_OPEN:
return createOpenAnimationAdapters(targets);
case TRANSIT_OLD_ACTIVITY_CLOSE:
case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
- case TRANSIT_OLD_TASK_CLOSE:
return createCloseAnimationAdapters(targets);
case TRANSIT_OLD_TASK_FRAGMENT_CHANGE:
return createChangeAnimationAdapters(targets);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
index 79813c7d064e..31aa09c902b1 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
@@ -18,7 +18,6 @@ package androidx.window.extensions.embedding;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -26,10 +25,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import android.content.Intent;
import android.content.res.Configuration;
@@ -85,35 +82,20 @@ public class JetpackTaskFragmentOrganizerTest {
@Test
public void testUnregisterOrganizer() {
- mOrganizer.startOverrideSplitAnimation(TASK_ID);
- mOrganizer.startOverrideSplitAnimation(TASK_ID + 1);
+ mOrganizer.overrideSplitAnimation();
mOrganizer.unregisterOrganizer();
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID + 1);
+ verify(mOrganizer).unregisterRemoteAnimations();
}
@Test
- public void testStartOverrideSplitAnimation() {
+ public void testOverrideSplitAnimation() {
assertNull(mOrganizer.mAnimationController);
- mOrganizer.startOverrideSplitAnimation(TASK_ID);
+ mOrganizer.overrideSplitAnimation();
assertNotNull(mOrganizer.mAnimationController);
- verify(mOrganizer).registerRemoteAnimations(TASK_ID,
- mOrganizer.mAnimationController.mDefinition);
- }
-
- @Test
- public void testStopOverrideSplitAnimation() {
- mOrganizer.stopOverrideSplitAnimation(TASK_ID);
-
- verify(mOrganizer, never()).unregisterRemoteAnimations(anyInt());
-
- mOrganizer.startOverrideSplitAnimation(TASK_ID);
- mOrganizer.stopOverrideSplitAnimation(TASK_ID);
-
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+ verify(mOrganizer).registerRemoteAnimations(mOrganizer.mAnimationController.mDefinition);
}
@Test
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
index d31342bfb309..379ea0c534ba 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
@@ -16,11 +16,8 @@
package androidx.window.extensions.embedding;
-import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import android.platform.test.annotations.Presubmit;
@@ -57,41 +54,31 @@ public class TaskFragmentAnimationControllerTest {
@Test
public void testRegisterRemoteAnimations() {
- mAnimationController.registerRemoteAnimations(TASK_ID);
+ mAnimationController.registerRemoteAnimations();
- verify(mOrganizer).registerRemoteAnimations(TASK_ID, mAnimationController.mDefinition);
+ verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition);
- mAnimationController.registerRemoteAnimations(TASK_ID);
+ mAnimationController.registerRemoteAnimations();
// No extra call if it has been registered.
- verify(mOrganizer).registerRemoteAnimations(TASK_ID, mAnimationController.mDefinition);
+ verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition);
}
@Test
public void testUnregisterRemoteAnimations() {
- mAnimationController.unregisterRemoteAnimations(TASK_ID);
+ mAnimationController.unregisterRemoteAnimations();
// No call if it is not registered.
- verify(mOrganizer, never()).unregisterRemoteAnimations(anyInt());
+ verify(mOrganizer, never()).unregisterRemoteAnimations();
- mAnimationController.registerRemoteAnimations(TASK_ID);
- mAnimationController.unregisterRemoteAnimations(TASK_ID);
+ mAnimationController.registerRemoteAnimations();
+ mAnimationController.unregisterRemoteAnimations();
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+ verify(mOrganizer).unregisterRemoteAnimations();
- mAnimationController.unregisterRemoteAnimations(TASK_ID);
+ mAnimationController.unregisterRemoteAnimations();
// No extra call if it has been unregistered.
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
- }
-
- @Test
- public void testUnregisterAllRemoteAnimations() {
- mAnimationController.registerRemoteAnimations(TASK_ID);
- mAnimationController.registerRemoteAnimations(TASK_ID + 1);
- mAnimationController.unregisterAllRemoteAnimations();
-
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
- verify(mOrganizer).unregisterRemoteAnimations(TASK_ID + 1);
+ verify(mOrganizer).unregisterRemoteAnimations();
}
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index bd22b32742a1..5380de760a82 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -570,6 +570,34 @@ public class AppTransitionController {
}
/**
+ * Whether the transition contains any embedded {@link TaskFragment} that does not fill the
+ * parent {@link Task} before or after the transition.
+ */
+ private boolean transitionContainsTaskFragmentWithBoundsOverride() {
+ for (int i = mDisplayContent.mChangingContainers.size() - 1; i >= 0; i--) {
+ final WindowContainer wc = mDisplayContent.mChangingContainers.valueAt(i);
+ if (wc.isEmbedded()) {
+ // Contains embedded TaskFragment with bounds changed.
+ return true;
+ }
+ }
+ mTempTransitionWindows.clear();
+ mTempTransitionWindows.addAll(mDisplayContent.mClosingApps);
+ mTempTransitionWindows.addAll(mDisplayContent.mOpeningApps);
+ boolean containsTaskFragmentWithBoundsOverride = false;
+ for (int i = mTempTransitionWindows.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mTempTransitionWindows.get(i).asActivityRecord();
+ final TaskFragment tf = r.getTaskFragment();
+ if (tf != null && tf.isEmbeddedWithBoundsOverride()) {
+ containsTaskFragmentWithBoundsOverride = true;
+ break;
+ }
+ }
+ mTempTransitionWindows.clear();
+ return containsTaskFragmentWithBoundsOverride;
+ }
+
+ /**
* Finds the common parent {@link Task} that is parent of all embedded app windows in the
* current transition.
* @return {@code null} if app windows in the transition are not children of the same Task, or
@@ -672,12 +700,17 @@ public class AppTransitionController {
if (transitionMayContainNonAppWindows(transit)) {
return false;
}
+ if (!transitionContainsTaskFragmentWithBoundsOverride()) {
+ // No need to play TaskFragment remote animation if all embedded TaskFragment in the
+ // transition fill the Task.
+ return false;
+ }
final Task task = findParentTaskForAllEmbeddedWindows();
final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task);
final RemoteAnimationDefinition definition = organizer != null
? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
- .getRemoteAnimationDefinition(organizer, task.mTaskId)
+ .getRemoteAnimationDefinition(organizer)
: null;
final RemoteAnimationAdapter adapter = definition != null
? definition.getAdapter(transit, activityTypes)
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 911a8da1db99..f0e3644a3ff5 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -583,15 +583,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
@Override
boolean isEmbedded() {
- if (mIsEmbedded) {
- return true;
- }
- final WindowContainer<?> parent = getParent();
- if (parent != null) {
- final TaskFragment taskFragment = parent.asTaskFragment();
- return taskFragment != null && taskFragment.isEmbedded();
- }
- return false;
+ return mIsEmbedded;
}
@EmbeddingCheckResult
@@ -2510,6 +2502,22 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return mTaskFragmentOrganizer != null;
}
+ /**
+ * Whether this is an embedded {@link TaskFragment} that does not fill the parent {@link Task}.
+ */
+ boolean isEmbeddedWithBoundsOverride() {
+ if (!mIsEmbedded) {
+ return false;
+ }
+ final Task task = getTask();
+ if (task == null) {
+ return false;
+ }
+ final Rect taskBounds = task.getBounds();
+ final Rect taskFragBounds = getBounds();
+ return !taskBounds.equals(taskFragBounds) && taskBounds.contains(taskFragBounds);
+ }
+
/** Whether the Task should be visible. */
boolean isTaskVisibleRequested() {
final Task task = getTask();
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 2e716ae23f20..484de2b3bc34 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -36,7 +36,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.content.res.Configuration;
-import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -133,12 +132,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
new WeakHashMap<>();
/**
- * Map from Task Id to {@link RemoteAnimationDefinition}.
- * @see android.window.TaskFragmentOrganizer#registerRemoteAnimations(int,
- * RemoteAnimationDefinition) )
+ * {@link RemoteAnimationDefinition} for embedded activities transition animation that is
+ * organized by this organizer.
*/
- private final SparseArray<RemoteAnimationDefinition> mRemoteAnimationDefinitions =
- new SparseArray<>();
+ @Nullable
+ private RemoteAnimationDefinition mRemoteAnimationDefinition;
/**
* Map from {@link TaskFragmentTransaction#getTransactionToken()} to the
@@ -455,7 +453,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
@Override
- public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, int taskId,
+ public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer,
@NonNull RemoteAnimationDefinition definition) {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
@@ -468,20 +466,19 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
if (organizerState == null) {
throw new IllegalStateException("The organizer hasn't been registered.");
}
- if (organizerState.mRemoteAnimationDefinitions.contains(taskId)) {
+ if (organizerState.mRemoteAnimationDefinition != null) {
throw new IllegalStateException(
"The organizer has already registered remote animations="
- + organizerState.mRemoteAnimationDefinitions.get(taskId)
- + " for TaskId=" + taskId);
+ + organizerState.mRemoteAnimationDefinition);
}
definition.setCallingPidUid(pid, uid);
- organizerState.mRemoteAnimationDefinitions.put(taskId, definition);
+ organizerState.mRemoteAnimationDefinition = definition;
}
}
@Override
- public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, int taskId) {
+ public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer) {
final int pid = Binder.getCallingPid();
final long uid = Binder.getCallingUid();
synchronized (mGlobalLock) {
@@ -495,7 +492,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return;
}
- organizerState.mRemoteAnimationDefinitions.remove(taskId);
+ organizerState.mRemoteAnimationDefinition = null;
}
}
@@ -527,16 +524,16 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
/**
* Gets the {@link RemoteAnimationDefinition} set on the given organizer if exists. Returns
- * {@code null} if it doesn't, or if the organizer has activity(ies) embedded in untrusted mode.
+ * {@code null} if it doesn't.
*/
@Nullable
public RemoteAnimationDefinition getRemoteAnimationDefinition(
- @NonNull ITaskFragmentOrganizer organizer, int taskId) {
+ @NonNull ITaskFragmentOrganizer organizer) {
synchronized (mGlobalLock) {
final TaskFragmentOrganizerState organizerState =
mTaskFragmentOrganizerState.get(organizer.asBinder());
return organizerState != null
- ? organizerState.mRemoteAnimationDefinitions.get(taskId)
+ ? organizerState.mRemoteAnimationDefinition
: null;
}
}
@@ -1085,16 +1082,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return false;
}
final TaskFragment taskFragment = activity.getOrganizedTaskFragment();
- if (taskFragment == null) {
- return false;
- }
- final Task parentTask = taskFragment.getTask();
- if (parentTask != null) {
- final Rect taskBounds = parentTask.getBounds();
- final Rect taskFragBounds = taskFragment.getBounds();
- return !taskBounds.equals(taskFragBounds) && taskBounds.contains(taskFragBounds);
- }
- return false;
+ return taskFragment != null && taskFragment.isEmbeddedWithBoundsOverride();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 0332c4b4597b..43e79f9cbb15 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
@@ -56,6 +57,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.annotation.Nullable;
+import android.graphics.Rect;
import android.gui.DropInputMode;
import android.os.Binder;
import android.os.IBinder;
@@ -918,7 +920,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Create a TaskFragment with embedded activity.
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
@@ -935,11 +937,77 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
@Test
+ public void testOverrideTaskFragmentAdapter_noOverrideWithOnlyTaskFragmentFillingTask() {
+ final Task task = createTask(mDisplayContent);
+ final ActivityRecord closingActivity = createActivityRecord(task);
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+
+ // Create a TaskFragment with embedded activity.
+ final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
+
+ // Make sure the TaskFragment is not embedded.
+ assertFalse(taskFragment.isEmbeddedWithBoundsOverride());
+ final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
+ prepareActivityForAppTransition(closingActivity);
+ prepareActivityForAppTransition(openingActivity);
+ final int uid = 12345;
+ closingActivity.info.applicationInfo.uid = uid;
+ openingActivity.info.applicationInfo.uid = uid;
+ task.effectiveUid = uid;
+ spyOn(mDisplayContent.mAppTransition);
+
+ // Prepare and start transition.
+ prepareAndTriggerAppTransition(openingActivity, closingActivity,
+ null /* changingTaskFragment */);
+ mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+
+ // Animation is not run by the remote handler because the activity is filling the Task.
+ assertFalse(remoteAnimationRunner.isAnimationStarted());
+ }
+
+ @Test
+ public void testOverrideTaskFragmentAdapter_overrideWithTaskFragmentNotFillingTask() {
+ final Task task = createTask(mDisplayContent);
+ final ActivityRecord closingActivity = createActivityRecord(task);
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+
+ // Create a TaskFragment with embedded activity.
+ final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
+
+ // Make sure the TaskFragment is embedded.
+ taskFragment.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ final Rect embeddedBounds = new Rect(task.getBounds());
+ embeddedBounds.right = embeddedBounds.left + embeddedBounds.width() / 2;
+ taskFragment.setBounds(embeddedBounds);
+ assertTrue(taskFragment.isEmbeddedWithBoundsOverride());
+ final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
+ prepareActivityForAppTransition(closingActivity);
+ prepareActivityForAppTransition(openingActivity);
+ final int uid = 12345;
+ closingActivity.info.applicationInfo.uid = uid;
+ openingActivity.info.applicationInfo.uid = uid;
+ task.effectiveUid = uid;
+ spyOn(mDisplayContent.mAppTransition);
+
+ // Prepare and start transition.
+ prepareAndTriggerAppTransition(openingActivity, closingActivity,
+ null /* changingTaskFragment */);
+ mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+
+ // Animation run by the remote handler.
+ assertTrue(remoteAnimationRunner.isAnimationStarted());
+ }
+
+ @Test
public void testOverrideTaskFragmentAdapter_overrideWithNonEmbeddedActivity() {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Closing non-embedded activity.
final ActivityRecord closingActivity = createActivityRecord(task);
@@ -964,7 +1032,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Closing TaskFragment with embedded activity.
final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
@@ -991,7 +1059,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Closing activity in Task1.
final ActivityRecord closingActivity = createActivityRecord(mDisplayContent);
@@ -1015,7 +1083,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Closing TaskFragment with embedded activity.
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
@@ -1043,7 +1111,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Create a TaskFragment with embedded activity.
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
@@ -1069,7 +1137,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Create a TaskFragment with embedded activities, one is trusted embedded, and the other
// one is untrusted embedded.
@@ -1128,7 +1196,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Create a TaskFragment with only trusted embedded activity
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
@@ -1168,7 +1236,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
// Create a TaskFragment with only trusted embedded activity
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
@@ -1259,7 +1327,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
/** Registers remote animation for the organizer. */
- private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer, int taskId,
+ private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer,
TestRemoteAnimationRunner remoteAnimationRunner) {
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
remoteAnimationRunner, 10, 1);
@@ -1268,9 +1336,10 @@ public class AppTransitionControllerTest extends WindowTestsBase {
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, adapter);
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter);
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, adapter);
+ definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter);
+ definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, adapter);
mAtm.mTaskFragmentOrganizerController.registerOrganizer(iOrganizer);
- mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, taskId,
- definition);
+ mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, definition);
}
private static ITaskFragmentOrganizer getITaskFragmentOrganizer(
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index c53518210af9..426afffdb880 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -474,13 +474,13 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
@Test
public void testRegisterRemoteAnimations() {
- mController.registerRemoteAnimations(mIOrganizer, TASK_ID, mDefinition);
+ mController.registerRemoteAnimations(mIOrganizer, mDefinition);
- assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer, TASK_ID));
+ assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer));
- mController.unregisterRemoteAnimations(mIOrganizer, TASK_ID);
+ mController.unregisterRemoteAnimations(mIOrganizer);
- assertNull(mController.getRemoteAnimationDefinition(mIOrganizer, TASK_ID));
+ assertNull(mController.getRemoteAnimationDefinition(mIOrganizer));
}
@Test