Merge "Only override ActivityEmbedding animation for embedded activities" into tm-qpr-dev
This commit is contained in:
@@ -39,13 +39,13 @@ interface ITaskFragmentOrganizerController {
|
|||||||
* animations if the transition only contains windows that belong to the organized
|
* animations if the transition only contains windows that belong to the organized
|
||||||
* TaskFragments in the given Task.
|
* TaskFragments in the given Task.
|
||||||
*/
|
*/
|
||||||
void registerRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId,
|
void registerRemoteAnimations(in ITaskFragmentOrganizer organizer,
|
||||||
in RemoteAnimationDefinition definition);
|
in RemoteAnimationDefinition definition);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters remote animations per transition type for the organizer.
|
* 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
|
* Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and
|
||||||
|
|||||||
@@ -140,16 +140,13 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
|
|||||||
/**
|
/**
|
||||||
* Registers remote animations per transition type for the organizer. It will override the
|
* 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
|
* animations if the transition only contains windows that belong to the organized
|
||||||
* TaskFragments in the given Task.
|
* TaskFragments, and at least one of the transition window is embedded (not filling the Task).
|
||||||
*
|
|
||||||
* @param taskId overrides if the transition only contains windows belonging to this Task.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@CallSuper
|
@CallSuper
|
||||||
public void registerRemoteAnimations(int taskId,
|
public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) {
|
||||||
@NonNull RemoteAnimationDefinition definition) {
|
|
||||||
try {
|
try {
|
||||||
getController().registerRemoteAnimations(mInterface, taskId, definition);
|
getController().registerRemoteAnimations(mInterface, definition);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
@@ -160,9 +157,9 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@CallSuper
|
@CallSuper
|
||||||
public void unregisterRemoteAnimations(int taskId) {
|
public void unregisterRemoteAnimations() {
|
||||||
try {
|
try {
|
||||||
getController().unregisterRemoteAnimations(mInterface, taskId);
|
getController().unregisterRemoteAnimations(mInterface);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import android.window.TaskFragmentOrganizer;
|
|||||||
import android.window.TaskFragmentTransaction;
|
import android.window.TaskFragmentTransaction;
|
||||||
import android.window.WindowContainerTransaction;
|
import android.window.WindowContainerTransaction;
|
||||||
|
|
||||||
import androidx.annotation.GuardedBy;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
@@ -85,26 +84,20 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
@Override
|
@Override
|
||||||
public void unregisterOrganizer() {
|
public void unregisterOrganizer() {
|
||||||
if (mAnimationController != null) {
|
if (mAnimationController != null) {
|
||||||
mAnimationController.unregisterAllRemoteAnimations();
|
mAnimationController.unregisterRemoteAnimations();
|
||||||
mAnimationController = null;
|
mAnimationController = null;
|
||||||
}
|
}
|
||||||
super.unregisterOrganizer();
|
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) {
|
if (mAnimationController == null) {
|
||||||
mAnimationController = new TaskFragmentAnimationController(this);
|
mAnimationController = new TaskFragmentAnimationController(this);
|
||||||
}
|
}
|
||||||
mAnimationController.registerRemoteAnimations(taskId);
|
mAnimationController.registerRemoteAnimations();
|
||||||
}
|
|
||||||
|
|
||||||
/** 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
updateContainersInTask(wct, taskContainer);
|
updateContainersInTask(wct, taskContainer);
|
||||||
updateAnimationOverride(taskContainer);
|
|
||||||
}
|
}
|
||||||
// The WCT should be applied and merged to the device state change transition if
|
// The WCT should be applied and merged to the device state change transition if
|
||||||
// there is one.
|
// there is one.
|
||||||
@@ -208,9 +207,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mSplitRules.clear();
|
mSplitRules.clear();
|
||||||
mSplitRules.addAll(rules);
|
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()) {
|
if (taskContainer.isEmpty()) {
|
||||||
// Cleanup the TaskContainer if it becomes empty.
|
// Cleanup the TaskContainer if it becomes empty.
|
||||||
mPresenter.stopOverrideSplitAnimation(taskContainer.getTaskId());
|
|
||||||
mTaskContainers.remove(taskContainer.getTaskId());
|
mTaskContainers.remove(taskContainer.getTaskId());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -622,43 +617,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer,
|
private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer,
|
||||||
@NonNull Configuration config) {
|
@NonNull Configuration config) {
|
||||||
final boolean wasInPip = taskContainer.isInPictureInPicture();
|
taskContainer.setTaskBounds(config.windowConfiguration.getBounds());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether the given {@link TaskContainer} may show in split. */
|
/** 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);
|
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateAnimationOverride(taskContainer);
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
super(executor, controller);
|
super(executor, controller);
|
||||||
mController = controller;
|
mController = controller;
|
||||||
registerOrganizer();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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_CLOSE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
|
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_CHANGE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
|
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_FRAGMENT_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
|
|
||||||
|
|
||||||
import android.util.ArraySet;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.RemoteAnimationAdapter;
|
import android.view.RemoteAnimationAdapter;
|
||||||
import android.view.RemoteAnimationDefinition;
|
import android.view.RemoteAnimationDefinition;
|
||||||
@@ -44,8 +41,7 @@ class TaskFragmentAnimationController {
|
|||||||
private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
|
private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final RemoteAnimationDefinition mDefinition;
|
final RemoteAnimationDefinition mDefinition;
|
||||||
/** Task Ids that we have registered for remote animation. */
|
private boolean mIsRegistered;
|
||||||
private final ArraySet<Integer> mRegisterTasks = new ArraySet<>();
|
|
||||||
|
|
||||||
TaskFragmentAnimationController(@NonNull TaskFragmentOrganizer organizer) {
|
TaskFragmentAnimationController(@NonNull TaskFragmentOrganizer organizer) {
|
||||||
mOrganizer = organizer;
|
mOrganizer = organizer;
|
||||||
@@ -54,39 +50,30 @@ class TaskFragmentAnimationController {
|
|||||||
new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */);
|
new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */);
|
||||||
mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter);
|
mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter);
|
||||||
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_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_ACTIVITY_CLOSE, animationAdapter);
|
||||||
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_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);
|
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerRemoteAnimations(int taskId) {
|
void registerRemoteAnimations() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.v(TAG, "registerRemoteAnimations");
|
Log.v(TAG, "registerRemoteAnimations");
|
||||||
}
|
}
|
||||||
if (mRegisterTasks.contains(taskId)) {
|
if (mIsRegistered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mOrganizer.registerRemoteAnimations(taskId, mDefinition);
|
mOrganizer.registerRemoteAnimations(mDefinition);
|
||||||
mRegisterTasks.add(taskId);
|
mIsRegistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterRemoteAnimations(int taskId) {
|
void unregisterRemoteAnimations() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.v(TAG, "unregisterRemoteAnimations");
|
Log.v(TAG, "unregisterRemoteAnimations");
|
||||||
}
|
}
|
||||||
if (!mRegisterTasks.contains(taskId)) {
|
if (!mIsRegistered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mOrganizer.unregisterRemoteAnimations(taskId);
|
mOrganizer.unregisterRemoteAnimations();
|
||||||
mRegisterTasks.remove(taskId);
|
mIsRegistered = false;
|
||||||
}
|
|
||||||
|
|
||||||
void unregisterAllRemoteAnimations() {
|
|
||||||
final ArraySet<Integer> tasks = new ArraySet<>(mRegisterTasks);
|
|
||||||
for (int taskId : tasks) {
|
|
||||||
unregisterRemoteAnimations(taskId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,9 @@ import static android.os.Process.THREAD_PRIORITY_DISPLAY;
|
|||||||
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
|
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_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_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_CHANGE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
|
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_FRAGMENT_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
|
|
||||||
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
|
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
@@ -169,11 +167,9 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
switch (transit) {
|
switch (transit) {
|
||||||
case TRANSIT_OLD_ACTIVITY_OPEN:
|
case TRANSIT_OLD_ACTIVITY_OPEN:
|
||||||
case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
|
case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
|
||||||
case TRANSIT_OLD_TASK_OPEN:
|
|
||||||
return createOpenAnimationAdapters(targets);
|
return createOpenAnimationAdapters(targets);
|
||||||
case TRANSIT_OLD_ACTIVITY_CLOSE:
|
case TRANSIT_OLD_ACTIVITY_CLOSE:
|
||||||
case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
|
case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
|
||||||
case TRANSIT_OLD_TASK_CLOSE:
|
|
||||||
return createCloseAnimationAdapters(targets);
|
return createCloseAnimationAdapters(targets);
|
||||||
case TRANSIT_OLD_TASK_FRAGMENT_CHANGE:
|
case TRANSIT_OLD_TASK_FRAGMENT_CHANGE:
|
||||||
return createChangeAnimationAdapters(targets);
|
return createChangeAnimationAdapters(targets);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package androidx.window.extensions.embedding;
|
|||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
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 androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer;
|
||||||
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
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.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@@ -85,35 +82,20 @@ public class JetpackTaskFragmentOrganizerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnregisterOrganizer() {
|
public void testUnregisterOrganizer() {
|
||||||
mOrganizer.startOverrideSplitAnimation(TASK_ID);
|
mOrganizer.overrideSplitAnimation();
|
||||||
mOrganizer.startOverrideSplitAnimation(TASK_ID + 1);
|
|
||||||
mOrganizer.unregisterOrganizer();
|
mOrganizer.unregisterOrganizer();
|
||||||
|
|
||||||
verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
|
verify(mOrganizer).unregisterRemoteAnimations();
|
||||||
verify(mOrganizer).unregisterRemoteAnimations(TASK_ID + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartOverrideSplitAnimation() {
|
public void testOverrideSplitAnimation() {
|
||||||
assertNull(mOrganizer.mAnimationController);
|
assertNull(mOrganizer.mAnimationController);
|
||||||
|
|
||||||
mOrganizer.startOverrideSplitAnimation(TASK_ID);
|
mOrganizer.overrideSplitAnimation();
|
||||||
|
|
||||||
assertNotNull(mOrganizer.mAnimationController);
|
assertNotNull(mOrganizer.mAnimationController);
|
||||||
verify(mOrganizer).registerRemoteAnimations(TASK_ID,
|
verify(mOrganizer).registerRemoteAnimations(mOrganizer.mAnimationController.mDefinition);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -16,11 +16,8 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
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 com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
@@ -57,41 +54,31 @@ public class TaskFragmentAnimationControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterRemoteAnimations() {
|
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.
|
// No extra call if it has been registered.
|
||||||
verify(mOrganizer).registerRemoteAnimations(TASK_ID, mAnimationController.mDefinition);
|
verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnregisterRemoteAnimations() {
|
public void testUnregisterRemoteAnimations() {
|
||||||
mAnimationController.unregisterRemoteAnimations(TASK_ID);
|
mAnimationController.unregisterRemoteAnimations();
|
||||||
|
|
||||||
// No call if it is not registered.
|
// No call if it is not registered.
|
||||||
verify(mOrganizer, never()).unregisterRemoteAnimations(anyInt());
|
verify(mOrganizer, never()).unregisterRemoteAnimations();
|
||||||
|
|
||||||
mAnimationController.registerRemoteAnimations(TASK_ID);
|
mAnimationController.registerRemoteAnimations();
|
||||||
mAnimationController.unregisterRemoteAnimations(TASK_ID);
|
mAnimationController.unregisterRemoteAnimations();
|
||||||
|
|
||||||
verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
|
verify(mOrganizer).unregisterRemoteAnimations();
|
||||||
|
|
||||||
mAnimationController.unregisterRemoteAnimations(TASK_ID);
|
mAnimationController.unregisterRemoteAnimations();
|
||||||
|
|
||||||
// No extra call if it has been unregistered.
|
// No extra call if it has been unregistered.
|
||||||
verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
|
verify(mOrganizer).unregisterRemoteAnimations();
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -561,6 +561,34 @@ public class AppTransitionController {
|
|||||||
|| shouldStartWallpaperAnimation(mDisplayContent);
|
|| 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
|
* Finds the common parent {@link Task} that is parent of all embedded app windows in the
|
||||||
* current transition.
|
* current transition.
|
||||||
@@ -664,12 +692,17 @@ public class AppTransitionController {
|
|||||||
if (transitionMayContainNonAppWindows(transit)) {
|
if (transitionMayContainNonAppWindows(transit)) {
|
||||||
return false;
|
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 Task task = findParentTaskForAllEmbeddedWindows();
|
||||||
final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task);
|
final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task);
|
||||||
final RemoteAnimationDefinition definition = organizer != null
|
final RemoteAnimationDefinition definition = organizer != null
|
||||||
? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
|
? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
|
||||||
.getRemoteAnimationDefinition(organizer, task.mTaskId)
|
.getRemoteAnimationDefinition(organizer)
|
||||||
: null;
|
: null;
|
||||||
final RemoteAnimationAdapter adapter = definition != null
|
final RemoteAnimationAdapter adapter = definition != null
|
||||||
? definition.getAdapter(transit, activityTypes)
|
? definition.getAdapter(transit, activityTypes)
|
||||||
|
|||||||
@@ -581,15 +581,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isEmbedded() {
|
boolean isEmbedded() {
|
||||||
if (mIsEmbedded) {
|
return mIsEmbedded;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final WindowContainer<?> parent = getParent();
|
|
||||||
if (parent != null) {
|
|
||||||
final TaskFragment taskFragment = parent.asTaskFragment();
|
|
||||||
return taskFragment != null && taskFragment.isEmbedded();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EmbeddingCheckResult
|
@EmbeddingCheckResult
|
||||||
@@ -2519,6 +2511,22 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
return mTaskFragmentOrganizer != null;
|
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. */
|
/** Whether the Task should be visible. */
|
||||||
boolean isTaskVisibleRequested() {
|
boolean isTaskVisibleRequested() {
|
||||||
final Task task = getTask();
|
final Task task = getTask();
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -133,12 +132,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
new WeakHashMap<>();
|
new WeakHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from Task Id to {@link RemoteAnimationDefinition}.
|
* {@link RemoteAnimationDefinition} for embedded activities transition animation that is
|
||||||
* @see android.window.TaskFragmentOrganizer#registerRemoteAnimations(int,
|
* organized by this organizer.
|
||||||
* RemoteAnimationDefinition) )
|
|
||||||
*/
|
*/
|
||||||
private final SparseArray<RemoteAnimationDefinition> mRemoteAnimationDefinitions =
|
@Nullable
|
||||||
new SparseArray<>();
|
private RemoteAnimationDefinition mRemoteAnimationDefinition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from {@link TaskFragmentTransaction#getTransactionToken()} to the
|
* Map from {@link TaskFragmentTransaction#getTransactionToken()} to the
|
||||||
@@ -455,7 +453,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, int taskId,
|
public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer,
|
||||||
@NonNull RemoteAnimationDefinition definition) {
|
@NonNull RemoteAnimationDefinition definition) {
|
||||||
final int pid = Binder.getCallingPid();
|
final int pid = Binder.getCallingPid();
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
@@ -468,20 +466,19 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
if (organizerState == null) {
|
if (organizerState == null) {
|
||||||
throw new IllegalStateException("The organizer hasn't been registered.");
|
throw new IllegalStateException("The organizer hasn't been registered.");
|
||||||
}
|
}
|
||||||
if (organizerState.mRemoteAnimationDefinitions.contains(taskId)) {
|
if (organizerState.mRemoteAnimationDefinition != null) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"The organizer has already registered remote animations="
|
"The organizer has already registered remote animations="
|
||||||
+ organizerState.mRemoteAnimationDefinitions.get(taskId)
|
+ organizerState.mRemoteAnimationDefinition);
|
||||||
+ " for TaskId=" + taskId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
definition.setCallingPidUid(pid, uid);
|
definition.setCallingPidUid(pid, uid);
|
||||||
organizerState.mRemoteAnimationDefinitions.put(taskId, definition);
|
organizerState.mRemoteAnimationDefinition = definition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, int taskId) {
|
public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer) {
|
||||||
final int pid = Binder.getCallingPid();
|
final int pid = Binder.getCallingPid();
|
||||||
final long uid = Binder.getCallingUid();
|
final long uid = Binder.getCallingUid();
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
@@ -495,7 +492,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
return;
|
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
|
* 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
|
@Nullable
|
||||||
public RemoteAnimationDefinition getRemoteAnimationDefinition(
|
public RemoteAnimationDefinition getRemoteAnimationDefinition(
|
||||||
@NonNull ITaskFragmentOrganizer organizer, int taskId) {
|
@NonNull ITaskFragmentOrganizer organizer) {
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
final TaskFragmentOrganizerState organizerState =
|
final TaskFragmentOrganizerState organizerState =
|
||||||
mTaskFragmentOrganizerState.get(organizer.asBinder());
|
mTaskFragmentOrganizerState.get(organizer.asBinder());
|
||||||
return organizerState != null
|
return organizerState != null
|
||||||
? organizerState.mRemoteAnimationDefinitions.get(taskId)
|
? organizerState.mRemoteAnimationDefinition
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1085,16 +1082,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final TaskFragment taskFragment = activity.getOrganizedTaskFragment();
|
final TaskFragment taskFragment = activity.getOrganizedTaskFragment();
|
||||||
if (taskFragment == null) {
|
return taskFragment != null && taskFragment.isEmbeddedWithBoundsOverride();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.LayoutParams.TYPE_BASE_APPLICATION;
|
||||||
import static android.view.WindowManager.TRANSIT_CHANGE;
|
import static android.view.WindowManager.TRANSIT_CHANGE;
|
||||||
import static android.view.WindowManager.TRANSIT_CLOSE;
|
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_ACTIVITY_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
|
import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
|
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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.gui.DropInputMode;
|
import android.gui.DropInputMode;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -918,7 +920,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Create a TaskFragment with embedded activity.
|
// Create a TaskFragment with embedded activity.
|
||||||
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
||||||
@@ -934,12 +936,78 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
assertTrue(remoteAnimationRunner.isAnimationStarted());
|
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
|
@Test
|
||||||
public void testOverrideTaskFragmentAdapter_overrideWithNonEmbeddedActivity() {
|
public void testOverrideTaskFragmentAdapter_overrideWithNonEmbeddedActivity() {
|
||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Closing non-embedded activity.
|
// Closing non-embedded activity.
|
||||||
final ActivityRecord closingActivity = createActivityRecord(task);
|
final ActivityRecord closingActivity = createActivityRecord(task);
|
||||||
@@ -964,7 +1032,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Closing TaskFragment with embedded activity.
|
// Closing TaskFragment with embedded activity.
|
||||||
final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
||||||
@@ -991,7 +1059,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Closing activity in Task1.
|
// Closing activity in Task1.
|
||||||
final ActivityRecord closingActivity = createActivityRecord(mDisplayContent);
|
final ActivityRecord closingActivity = createActivityRecord(mDisplayContent);
|
||||||
@@ -1015,7 +1083,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Closing TaskFragment with embedded activity.
|
// Closing TaskFragment with embedded activity.
|
||||||
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
||||||
@@ -1043,7 +1111,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Create a TaskFragment with embedded activity.
|
// Create a TaskFragment with embedded activity.
|
||||||
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
|
||||||
@@ -1069,7 +1137,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
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
|
// Create a TaskFragment with embedded activities, one is trusted embedded, and the other
|
||||||
// one is untrusted embedded.
|
// one is untrusted embedded.
|
||||||
@@ -1128,7 +1196,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Create a TaskFragment with only trusted embedded activity
|
// Create a TaskFragment with only trusted embedded activity
|
||||||
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
||||||
@@ -1168,7 +1236,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
final Task task = createTask(mDisplayContent);
|
final Task task = createTask(mDisplayContent);
|
||||||
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
|
||||||
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
|
setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
|
||||||
|
|
||||||
// Create a TaskFragment with only trusted embedded activity
|
// Create a TaskFragment with only trusted embedded activity
|
||||||
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
||||||
@@ -1259,7 +1327,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Registers remote animation for the organizer. */
|
/** Registers remote animation for the organizer. */
|
||||||
private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer, int taskId,
|
private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer,
|
||||||
TestRemoteAnimationRunner remoteAnimationRunner) {
|
TestRemoteAnimationRunner remoteAnimationRunner) {
|
||||||
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
|
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
|
||||||
remoteAnimationRunner, 10, 1);
|
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_CHANGE, adapter);
|
||||||
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter);
|
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter);
|
||||||
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, 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.registerOrganizer(iOrganizer);
|
||||||
mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, taskId,
|
mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, definition);
|
||||||
definition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ITaskFragmentOrganizer getITaskFragmentOrganizer(
|
private static ITaskFragmentOrganizer getITaskFragmentOrganizer(
|
||||||
|
|||||||
@@ -474,13 +474,13 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterRemoteAnimations() {
|
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
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user