Merge "Only override ActivityEmbedding animation for embedded activities" into tm-qpr-dev

This commit is contained in:
Chris Li
2022-11-19 03:32:16 +00:00
committed by Android (Google) Code Review
14 changed files with 194 additions and 191 deletions

View File

@@ -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

View File

@@ -140,16 +140,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();
}
@@ -160,9 +157,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();
}

View File

@@ -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();
}
/**

View File

@@ -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;
}

View File

@@ -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();
}
}
/**

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -561,6 +561,34 @@ public class AppTransitionController {
|| shouldStartWallpaperAnimation(mDisplayContent);
}
/**
* 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.
@@ -664,12 +692,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)

View File

@@ -581,15 +581,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
@@ -2519,6 +2511,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();

View File

@@ -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();
}
}

View File

@@ -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);
@@ -934,12 +936,78 @@ public class AppTransitionControllerTest extends WindowTestsBase {
assertTrue(remoteAnimationRunner.isAnimationStarted());
}
@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(

View File

@@ -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