Merge "Generalize the recents animation to work with non-home activity." into pi-dev
am: 1b5a0deb81
Change-Id: Id6b57ef9890c75cf5d5735c049236a7daa4c0045
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
@@ -44,7 +43,6 @@ import android.app.ActivityManagerInternal;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
@@ -702,57 +700,52 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the stack currently above the home stack. Can be null if there is no home stack, or
|
||||
* the home stack is already on top.
|
||||
* @return the stack currently above the {@param stack}. Can be null if the {@param stack} is
|
||||
* already top-most.
|
||||
*/
|
||||
ActivityStack getStackAboveHome() {
|
||||
if (mHomeStack == null) {
|
||||
// Skip if there is no home stack
|
||||
return null;
|
||||
}
|
||||
|
||||
final int stackIndex = mStacks.indexOf(mHomeStack) + 1;
|
||||
ActivityStack getStackAbove(ActivityStack stack) {
|
||||
final int stackIndex = mStacks.indexOf(stack) + 1;
|
||||
return (stackIndex < mStacks.size()) ? mStacks.get(stackIndex) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the home stack behind the last visible stack in the display if necessary. Generally
|
||||
* used in conjunction with {@link #moveHomeStackBehindStack}.
|
||||
* Adjusts the {@param stack} behind the last visible stack in the display if necessary.
|
||||
* Generally used in conjunction with {@link #moveStackBehindStack}.
|
||||
*/
|
||||
void moveHomeStackBehindBottomMostVisibleStack() {
|
||||
if (mHomeStack == null || mHomeStack.shouldBeVisible(null)) {
|
||||
// Skip if there is no home stack, or if it is already visible
|
||||
void moveStackBehindBottomMostVisibleStack(ActivityStack stack) {
|
||||
if (stack.shouldBeVisible(null)) {
|
||||
// Skip if the stack is already visible
|
||||
return;
|
||||
}
|
||||
|
||||
// Move the home stack to the bottom to not affect the following visibility checks
|
||||
positionChildAtBottom(mHomeStack);
|
||||
// Move the stack to the bottom to not affect the following visibility checks
|
||||
positionChildAtBottom(stack);
|
||||
|
||||
// Find the next position where the homes stack should be placed
|
||||
// Find the next position where the stack should be placed
|
||||
final int numStacks = mStacks.size();
|
||||
for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
|
||||
final ActivityStack stack = mStacks.get(stackNdx);
|
||||
if (stack == mHomeStack) {
|
||||
final ActivityStack s = mStacks.get(stackNdx);
|
||||
if (s == stack) {
|
||||
continue;
|
||||
}
|
||||
final int winMode = stack.getWindowingMode();
|
||||
final int winMode = s.getWindowingMode();
|
||||
final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN ||
|
||||
winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
if (stack.shouldBeVisible(null) && isValidWindowingMode) {
|
||||
// Move the home stack to behind this stack
|
||||
positionChildAt(mHomeStack, Math.max(0, stackNdx - 1));
|
||||
if (s.shouldBeVisible(null) && isValidWindowingMode) {
|
||||
// Move the provided stack to behind this stack
|
||||
positionChildAt(stack, Math.max(0, stackNdx - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the home stack behind the given {@param stack} if possible. If {@param stack} is not
|
||||
* currently in the display, then then the home stack is moved to the back. Generally used in
|
||||
* conjunction with {@link #moveHomeStackBehindBottomMostVisibleStack}.
|
||||
* Moves the {@param stack} behind the given {@param behindStack} if possible. If
|
||||
* {@param behindStack} is not currently in the display, then then the stack is moved to the
|
||||
* back. Generally used in conjunction with {@link #moveStackBehindBottomMostVisibleStack}.
|
||||
*/
|
||||
void moveHomeStackBehindStack(ActivityStack behindStack) {
|
||||
if (behindStack == null || behindStack == mHomeStack) {
|
||||
void moveStackBehindStack(ActivityStack stack, ActivityStack behindStack) {
|
||||
if (behindStack == null || behindStack == stack) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -760,11 +753,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
|
||||
// list, so we need to adjust the insertion index to account for the removed index
|
||||
// TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the
|
||||
// position internally
|
||||
final int homeStackIndex = mStacks.indexOf(mHomeStack);
|
||||
final int stackIndex = mStacks.indexOf(stack);
|
||||
final int behindStackIndex = mStacks.indexOf(behindStack);
|
||||
final int insertIndex = homeStackIndex <= behindStackIndex
|
||||
final int insertIndex = stackIndex <= behindStackIndex
|
||||
? behindStackIndex - 1 : behindStackIndex;
|
||||
positionChildAt(mHomeStack, Math.max(0, insertIndex));
|
||||
positionChildAt(stack, Math.max(0, insertIndex));
|
||||
}
|
||||
|
||||
boolean isSleeping() {
|
||||
|
||||
@@ -39,6 +39,7 @@ import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
|
||||
import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
|
||||
import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
|
||||
import static android.app.AppOpsManager.OP_NONE;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
@@ -205,8 +206,8 @@ import static android.view.WindowManager.TRANSIT_NONE;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
|
||||
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
|
||||
import static org.xmlpull.v1.XmlPullParser.START_TAG;
|
||||
|
||||
@@ -5249,8 +5250,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
try {
|
||||
synchronized (this) {
|
||||
mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition
|
||||
? REORDER_MOVE_HOME_TO_ORIGINAL_POSITION
|
||||
: REORDER_KEEP_HOME_IN_PLACE);
|
||||
? REORDER_MOVE_TO_ORIGINAL_POSITION
|
||||
: REORDER_KEEP_IN_PLACE);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
|
||||
@@ -18,19 +18,20 @@ package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
import static android.view.WindowManager.TRANSIT_NONE;
|
||||
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_TOP;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Trace;
|
||||
import android.util.Slog;
|
||||
@@ -51,16 +52,20 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
private final ActivityStartController mActivityStartController;
|
||||
private final WindowManagerService mWindowManager;
|
||||
private final UserController mUserController;
|
||||
private final ActivityDisplay mDefaultDisplay;
|
||||
private final int mCallingPid;
|
||||
|
||||
// The stack to restore the home stack behind when the animation is finished
|
||||
private ActivityStack mRestoreHomeBehindStack;
|
||||
private int mTargetActivityType;
|
||||
|
||||
// The stack to restore the target stack behind when the animation is finished
|
||||
private ActivityStack mRestoreTargetBehindStack;
|
||||
|
||||
RecentsAnimation(ActivityManagerService am, ActivityStackSupervisor stackSupervisor,
|
||||
ActivityStartController activityStartController, WindowManagerService wm,
|
||||
UserController userController, int callingPid) {
|
||||
mService = am;
|
||||
mStackSupervisor = stackSupervisor;
|
||||
mDefaultDisplay = stackSupervisor.getDefaultDisplay();
|
||||
mActivityStartController = activityStartController;
|
||||
mWindowManager = wm;
|
||||
mUserController = userController;
|
||||
@@ -76,23 +81,31 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the existing home activity is already on top, then cancel
|
||||
ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
|
||||
final boolean hasExistingHomeActivity = homeActivity != null;
|
||||
if (hasExistingHomeActivity) {
|
||||
final ActivityDisplay display = homeActivity.getDisplay();
|
||||
mRestoreHomeBehindStack = display.getStackAboveHome();
|
||||
if (mRestoreHomeBehindStack == null) {
|
||||
// If the activity is associated with the recents stack, then try and get that first
|
||||
mTargetActivityType = intent.getComponent() != null
|
||||
&& recentsComponent.equals(intent.getComponent())
|
||||
? ACTIVITY_TYPE_RECENTS
|
||||
: ACTIVITY_TYPE_HOME;
|
||||
final ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
|
||||
mTargetActivityType);
|
||||
ActivityRecord targetActivity = targetStack != null
|
||||
? targetStack.getTopActivity()
|
||||
: null;
|
||||
final boolean hasExistingActivity = targetActivity != null;
|
||||
if (hasExistingActivity) {
|
||||
final ActivityDisplay display = targetActivity.getDisplay();
|
||||
mRestoreTargetBehindStack = display.getStackAbove(targetStack);
|
||||
if (mRestoreTargetBehindStack == null) {
|
||||
notifyAnimationCancelBeforeStart(recentsAnimationRunner);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send launch hint if we are actually launching home. If it's already visible (shouldn't
|
||||
// happen in general) we don't need to send it.
|
||||
if (homeActivity == null || !homeActivity.visible) {
|
||||
// Send launch hint if we are actually launching the target. If it's already visible
|
||||
// (shouldn't happen in general) we don't need to send it.
|
||||
if (targetActivity == null || !targetActivity.visible) {
|
||||
mStackSupervisor.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */,
|
||||
homeActivity);
|
||||
targetActivity);
|
||||
}
|
||||
|
||||
mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
|
||||
@@ -102,48 +115,49 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
mWindowManager.deferSurfaceLayout();
|
||||
try {
|
||||
final ActivityDisplay display;
|
||||
if (hasExistingHomeActivity) {
|
||||
// Move the home activity into place for the animation if it is not already top most
|
||||
display = homeActivity.getDisplay();
|
||||
display.moveHomeStackBehindBottomMostVisibleStack();
|
||||
if (hasExistingActivity) {
|
||||
// Move the recents activity into place for the animation if it is not top most
|
||||
display = targetActivity.getDisplay();
|
||||
display.moveStackBehindBottomMostVisibleStack(targetStack);
|
||||
} else {
|
||||
// No home activity
|
||||
final ActivityOptions opts = ActivityOptions.makeBasic();
|
||||
opts.setLaunchActivityType(ACTIVITY_TYPE_HOME);
|
||||
opts.setAvoidMoveToFront();
|
||||
// No recents activity
|
||||
ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setLaunchActivityType(mTargetActivityType);
|
||||
options.setAvoidMoveToFront();
|
||||
intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
|
||||
|
||||
mActivityStartController
|
||||
.obtainStarter(intent, "startRecentsActivity_noHomeActivity")
|
||||
.obtainStarter(intent, "startRecentsActivity_noTargetActivity")
|
||||
.setCallingUid(recentsUid)
|
||||
.setCallingPackage(recentsComponent.getPackageName())
|
||||
.setActivityOptions(SafeActivityOptions.fromBundle(opts.toBundle()))
|
||||
.setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
|
||||
.setMayWait(mUserController.getCurrentUserId())
|
||||
.execute();
|
||||
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
|
||||
|
||||
homeActivity = mStackSupervisor.getHomeActivity();
|
||||
display = homeActivity.getDisplay();
|
||||
targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
|
||||
mTargetActivityType).getTopActivity();
|
||||
display = targetActivity.getDisplay();
|
||||
|
||||
// TODO: Maybe wait for app to draw in this particular case?
|
||||
}
|
||||
|
||||
// Mark the home activity as launch-behind to bump its visibility for the
|
||||
// Mark the target activity as launch-behind to bump its visibility for the
|
||||
// duration of the gesture that is driven by the recents component
|
||||
homeActivity.mLaunchTaskBehind = true;
|
||||
targetActivity.mLaunchTaskBehind = true;
|
||||
|
||||
// Fetch all the surface controls and pass them to the client to get the animation
|
||||
// started
|
||||
mWindowManager.cancelRecentsAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this,
|
||||
display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
|
||||
mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
|
||||
this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
|
||||
|
||||
// If we updated the launch-behind state, update the visibility of the activities after
|
||||
// we fetch the visible tasks to be controlled by the animation
|
||||
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
|
||||
|
||||
mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT,
|
||||
homeActivity);
|
||||
targetActivity);
|
||||
} finally {
|
||||
mWindowManager.continueSurfaceLayout();
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
@@ -155,9 +169,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
synchronized (mService) {
|
||||
if (mWindowManager.getRecentsAnimationController() == null) return;
|
||||
|
||||
// Just to be sure end the launch hint in case home was never launched. However, if
|
||||
// we're keeping home and making it visible, we can leave it on.
|
||||
if (reorderMode != REORDER_KEEP_HOME_IN_PLACE) {
|
||||
// Just to be sure end the launch hint in case the target activity was never launched.
|
||||
// However, if we're keeping the activity and making it visible, we can leave it on.
|
||||
if (reorderMode != REORDER_KEEP_IN_PLACE) {
|
||||
mStackSupervisor.sendPowerHintForLaunchEndIfNeeded();
|
||||
}
|
||||
|
||||
@@ -170,26 +184,27 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
try {
|
||||
mWindowManager.cleanupRecentsAnimation(reorderMode);
|
||||
|
||||
final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
|
||||
if (homeActivity == null) {
|
||||
final ActivityStack targetStack = mDefaultDisplay.getStack(
|
||||
WINDOWING_MODE_UNDEFINED, mTargetActivityType);
|
||||
final ActivityRecord targetActivity = targetStack.getTopActivity();
|
||||
if (targetActivity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore the launched-behind state
|
||||
homeActivity.mLaunchTaskBehind = false;
|
||||
targetActivity.mLaunchTaskBehind = false;
|
||||
|
||||
if (reorderMode == REORDER_MOVE_HOME_TO_TOP) {
|
||||
// Bring the home stack to the front
|
||||
final ActivityStack homeStack = homeActivity.getStack();
|
||||
mStackSupervisor.mNoAnimActivities.add(homeActivity);
|
||||
homeStack.moveToFront("RecentsAnimation.onAnimationFinished()");
|
||||
} else if (reorderMode == REORDER_MOVE_HOME_TO_ORIGINAL_POSITION){
|
||||
// Restore the home stack to its previous position
|
||||
final ActivityDisplay display = homeActivity.getDisplay();
|
||||
display.moveHomeStackBehindStack(mRestoreHomeBehindStack);
|
||||
if (reorderMode == REORDER_MOVE_TO_TOP) {
|
||||
// Bring the target stack to the front
|
||||
mStackSupervisor.mNoAnimActivities.add(targetActivity);
|
||||
targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
|
||||
} else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){
|
||||
// Restore the target stack to its previous position
|
||||
final ActivityDisplay display = targetActivity.getDisplay();
|
||||
display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack);
|
||||
} else {
|
||||
// Keep home stack in place, nothing changes, so ignore the transition logic
|
||||
// below
|
||||
// Keep target stack in place, nothing changes, so ignore the transition
|
||||
// logic below
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,8 +217,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
mWindowManager.executeAppTransition();
|
||||
|
||||
// After reordering the stacks, reset the minimized state. At this point, either
|
||||
// home is now top-most and we will stay minimized (if in split-screen), or we
|
||||
// will have returned to the app, and the minimized state should be reset
|
||||
// the target activity is now top-most and we will stay minimized (if in
|
||||
// split-screen), or we will have returned to the app, and the minimized state
|
||||
// should be reset
|
||||
mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */);
|
||||
} finally {
|
||||
mWindowManager.continueSurfaceLayout();
|
||||
|
||||
@@ -18,8 +18,10 @@ package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManagerInternal.APP_TRANSITION_RECENTS_ANIM;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
|
||||
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
@@ -68,14 +70,14 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final long FAILSAFE_DELAY = 1000;
|
||||
|
||||
public static final int REORDER_KEEP_HOME_IN_PLACE = 0;
|
||||
public static final int REORDER_MOVE_HOME_TO_TOP = 1;
|
||||
public static final int REORDER_MOVE_HOME_TO_ORIGINAL_POSITION = 2;
|
||||
public static final int REORDER_KEEP_IN_PLACE = 0;
|
||||
public static final int REORDER_MOVE_TO_TOP = 1;
|
||||
public static final int REORDER_MOVE_TO_ORIGINAL_POSITION = 2;
|
||||
|
||||
@IntDef(prefix = { "REORDER_MODE_" }, value = {
|
||||
REORDER_KEEP_HOME_IN_PLACE,
|
||||
REORDER_MOVE_HOME_TO_TOP,
|
||||
REORDER_MOVE_HOME_TO_ORIGINAL_POSITION
|
||||
REORDER_KEEP_IN_PLACE,
|
||||
REORDER_MOVE_TO_TOP,
|
||||
REORDER_MOVE_TO_ORIGINAL_POSITION
|
||||
})
|
||||
public @interface ReorderMode {}
|
||||
|
||||
@@ -85,11 +87,11 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
|
||||
private final int mDisplayId;
|
||||
private final Runnable mFailsafeRunnable = () -> {
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
};
|
||||
|
||||
// The recents component app token that is shown behind the visibile tasks
|
||||
private AppWindowToken mHomeAppToken;
|
||||
private AppWindowToken mTargetAppToken;
|
||||
private Rect mMinimizedHomeBounds = new Rect();
|
||||
|
||||
// We start the RecentsAnimationController in a pending-start state since we need to wait for
|
||||
@@ -160,8 +162,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
// Note, the callback will handle its own synchronization, do not lock on WM lock
|
||||
// prior to calling the callback
|
||||
mCallbacks.onAnimationFinished(moveHomeToTop
|
||||
? REORDER_MOVE_HOME_TO_TOP
|
||||
: REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
? REORDER_MOVE_TO_TOP
|
||||
: REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
@@ -240,7 +242,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
* because it may call cancelAnimation() which needs to properly clean up the controller
|
||||
* in the window manager.
|
||||
*/
|
||||
public void initialize(SparseBooleanArray recentTaskIds) {
|
||||
public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) {
|
||||
// Make leashes for each of the visible tasks and add it to the recents animation to be
|
||||
// started
|
||||
final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
|
||||
@@ -251,7 +253,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
final WindowConfiguration config = task.getWindowConfiguration();
|
||||
if (config.tasksAreFloating()
|
||||
|| config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
|
||||
|| config.getActivityType() == ACTIVITY_TYPE_HOME) {
|
||||
|| config.getActivityType() == targetActivityType) {
|
||||
continue;
|
||||
}
|
||||
addAnimation(task, !recentTaskIds.get(task.mTaskId));
|
||||
@@ -259,23 +261,23 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
// Skip the animation if there is nothing to animate
|
||||
if (mPendingAnimations.isEmpty()) {
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mRunner.asBinder().linkToDeath(this, 0);
|
||||
} catch (RemoteException e) {
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjust the wallpaper visibility for the showing home activity
|
||||
final AppWindowToken recentsComponentAppToken =
|
||||
dc.getHomeStack().getTopChild().getTopFullscreenAppToken();
|
||||
// Adjust the wallpaper visibility for the showing target activity
|
||||
final AppWindowToken recentsComponentAppToken = dc.getStack(WINDOWING_MODE_UNDEFINED,
|
||||
targetActivityType).getTopChild().getTopFullscreenAppToken();
|
||||
if (recentsComponentAppToken != null) {
|
||||
if (DEBUG) Log.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")");
|
||||
mHomeAppToken = recentsComponentAppToken;
|
||||
mTargetAppToken = recentsComponentAppToken;
|
||||
if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) {
|
||||
dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
dc.setLayoutNeeded();
|
||||
@@ -319,12 +321,14 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
new RemoteAnimationTarget[appAnimations.size()]);
|
||||
mPendingStart = false;
|
||||
|
||||
final Rect minimizedHomeBounds =
|
||||
mHomeAppToken != null && mHomeAppToken.inSplitScreenSecondaryWindowingMode()
|
||||
? mMinimizedHomeBounds : null;
|
||||
final Rect contentInsets =
|
||||
mHomeAppToken != null && mHomeAppToken.findMainWindow() != null
|
||||
? mHomeAppToken.findMainWindow().mContentInsets : null;
|
||||
final Rect minimizedHomeBounds = mTargetAppToken != null
|
||||
&& mTargetAppToken.inSplitScreenSecondaryWindowingMode()
|
||||
? mMinimizedHomeBounds
|
||||
: null;
|
||||
final Rect contentInsets = mTargetAppToken != null
|
||||
&& mTargetAppToken.findMainWindow() != null
|
||||
? mTargetAppToken.findMainWindow().mContentInsets
|
||||
: null;
|
||||
mRunner.onAnimationStart_New(mController, appTargets, contentInsets,
|
||||
minimizedHomeBounds);
|
||||
} catch (RemoteException e) {
|
||||
@@ -363,8 +367,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
|
||||
final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
|
||||
adapter.mTask.setCanAffectSystemUiFlags(true);
|
||||
if (reorderMode == REORDER_MOVE_HOME_TO_TOP
|
||||
|| reorderMode == REORDER_KEEP_HOME_IN_PLACE) {
|
||||
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
|
||||
adapter.mTask.dontAnimateDimExit();
|
||||
}
|
||||
adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
|
||||
@@ -383,12 +386,12 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
}
|
||||
|
||||
void checkAnimationReady(WallpaperController wallpaperController) {
|
||||
if (mPendingStart) {
|
||||
final boolean wallpaperReady = !isHomeAppOverWallpaper()
|
||||
final boolean wallpaperReady = !isTargetOverWallpaper()
|
||||
|| (wallpaperController.getWallpaperTarget() != null
|
||||
&& wallpaperController.wallpaperTransitionReady());
|
||||
if (wallpaperReady) {
|
||||
@@ -402,8 +405,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
}
|
||||
|
||||
boolean isWallpaperVisible(WindowState w) {
|
||||
return w != null && w.mAppToken != null && mHomeAppToken == w.mAppToken
|
||||
&& isHomeAppOverWallpaper();
|
||||
return w != null && w.mAppToken != null && mTargetAppToken == w.mAppToken
|
||||
&& isTargetOverWallpaper();
|
||||
}
|
||||
|
||||
boolean hasInputConsumerForApp(AppWindowToken appToken) {
|
||||
@@ -412,12 +415,12 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
boolean updateInputConsumerForApp(InputConsumerImpl recentsAnimationInputConsumer,
|
||||
boolean hasFocus) {
|
||||
// Update the input consumer touchable region to match the home app main window
|
||||
final WindowState homeAppMainWindow = mHomeAppToken != null
|
||||
? mHomeAppToken.findMainWindow()
|
||||
// Update the input consumer touchable region to match the target app main window
|
||||
final WindowState targetAppMainWindow = mTargetAppToken != null
|
||||
? mTargetAppToken.findMainWindow()
|
||||
: null;
|
||||
if (homeAppMainWindow != null) {
|
||||
homeAppMainWindow.getBounds(mTmpRect);
|
||||
if (targetAppMainWindow != null) {
|
||||
targetAppMainWindow.getBounds(mTmpRect);
|
||||
recentsAnimationInputConsumer.mWindowHandle.hasFocus = hasFocus;
|
||||
recentsAnimationInputConsumer.mWindowHandle.touchableRegion.set(mTmpRect);
|
||||
return true;
|
||||
@@ -425,11 +428,11 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isHomeAppOverWallpaper() {
|
||||
if (mHomeAppToken == null) {
|
||||
private boolean isTargetOverWallpaper() {
|
||||
if (mTargetAppToken == null) {
|
||||
return false;
|
||||
}
|
||||
return mHomeAppToken.windowsCanBeWallpaperTarget();
|
||||
return mTargetAppToken.windowsCanBeWallpaperTarget();
|
||||
}
|
||||
|
||||
boolean isAnimatingTask(Task task) {
|
||||
@@ -511,7 +514,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
@Override
|
||||
public void onAnimationCancelled(SurfaceControl animationLeash) {
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -549,6 +552,6 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
final String innerPrefix = prefix + " ";
|
||||
pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":");
|
||||
pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart);
|
||||
pw.print(innerPrefix); pw.println("mHomeAppToken=" + mHomeAppToken);
|
||||
pw.print(innerPrefix); pw.println("mTargetAppToken=" + mTargetAppToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
|
||||
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
|
||||
@@ -620,7 +620,7 @@ class WallpaperController {
|
||||
// If there was a recents animation in progress, cancel that animation
|
||||
if (mService.getRecentsAnimationController() != null) {
|
||||
mService.getRecentsAnimationController().cancelAnimation(
|
||||
REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2689,7 +2689,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
public void initializeRecentsAnimation(
|
||||
public void initializeRecentsAnimation(int targetActivityType,
|
||||
IRecentsAnimationRunner recentsAnimationRunner,
|
||||
RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId,
|
||||
SparseBooleanArray recentTaskIds) {
|
||||
@@ -2697,7 +2697,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mRecentsAnimationController = new RecentsAnimationController(this,
|
||||
recentsAnimationRunner, callbacks, displayId);
|
||||
mAppTransition.updateBooster();
|
||||
mRecentsAnimationController.initialize(recentTaskIds);
|
||||
mRecentsAnimationController.initialize(targetActivityType, recentTaskIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
|
||||
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
|
||||
import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
|
||||
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
|
||||
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
|
||||
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
|
||||
@@ -43,9 +41,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.servertransaction.DestroyActivityItem;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Debug;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.filters.SmallTest;
|
||||
@@ -67,6 +63,7 @@ import org.junit.Test;
|
||||
public class ActivityStackTests extends ActivityTestsBase {
|
||||
private ActivityManagerService mService;
|
||||
private ActivityStackSupervisor mSupervisor;
|
||||
private ActivityDisplay mDefaultDisplay;
|
||||
private ActivityStack mStack;
|
||||
private TaskRecord mTask;
|
||||
|
||||
@@ -77,8 +74,9 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
mService = createActivityManagerService();
|
||||
mSupervisor = mService.mStackSupervisor;
|
||||
mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
mDefaultDisplay = mService.mStackSupervisor.getDefaultDisplay();
|
||||
mStack = mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
|
||||
}
|
||||
|
||||
@@ -112,9 +110,8 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
|
||||
// Create primary splitscreen stack. This will create secondary stacks and places the
|
||||
// existing fullscreen stack on the bottom.
|
||||
final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay()
|
||||
.createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
|
||||
// Assert windowing mode.
|
||||
assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
@@ -124,8 +121,7 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
null /* task */);
|
||||
|
||||
// Assert that stack is at the bottom.
|
||||
assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen),
|
||||
0);
|
||||
assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
|
||||
|
||||
// Ensure no longer in splitscreen.
|
||||
assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
|
||||
@@ -165,16 +161,15 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
@Test
|
||||
public void testShouldBeVisible_Fullscreen() throws Exception {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
|
||||
final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
|
||||
assertTrue(homeStack.shouldBeVisible(null /* starting */));
|
||||
assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
|
||||
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
// Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
|
||||
// should be visible since it is always on-top.
|
||||
@@ -191,14 +186,13 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
@Test
|
||||
public void testShouldBeVisible_SplitScreen() throws Exception {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
// Home stack should always be fullscreen for this test.
|
||||
homeStack.setSupportsSplitScreen(false);
|
||||
final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
|
||||
// Home stack shouldn't be visible if both halves of split-screen are opaque.
|
||||
@@ -214,7 +208,7 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
|
||||
|
||||
final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
// First split-screen secondary shouldn't be visible behind another opaque split-split
|
||||
// secondary.
|
||||
@@ -228,7 +222,7 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
|
||||
|
||||
final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
|
||||
|
||||
// Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
|
||||
@@ -258,11 +252,11 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
@Test
|
||||
public void testShouldBeVisible_Finishing() throws Exception {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
translucentStack.setIsTranslucent(true);
|
||||
|
||||
assertTrue(homeStack.shouldBeVisible(null /* starting */));
|
||||
@@ -286,76 +280,74 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
|
||||
homeStack.setIsTranslucent(false);
|
||||
fullscreenStack.setIsTranslucent(false);
|
||||
|
||||
// Ensure that we don't move the home stack if it is already behind the top fullscreen stack
|
||||
int homeStackIndex = display.getIndexOf(homeStack);
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack);
|
||||
display.moveHomeStackBehindBottomMostVisibleStack();
|
||||
assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
|
||||
int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
|
||||
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
|
||||
assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
|
||||
homeStack.setIsTranslucent(false);
|
||||
fullscreenStack.setIsTranslucent(true);
|
||||
|
||||
// Ensure that we don't move the home stack if it is already behind the top fullscreen stack
|
||||
int homeStackIndex = display.getIndexOf(homeStack);
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack);
|
||||
display.moveHomeStackBehindBottomMostVisibleStack();
|
||||
assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
|
||||
int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
|
||||
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
|
||||
assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
|
||||
homeStack.setIsTranslucent(false);
|
||||
fullscreenStack.setIsTranslucent(false);
|
||||
|
||||
// Ensure we don't move the home stack if it is already on top
|
||||
int homeStackIndex = display.getIndexOf(homeStack);
|
||||
assertTrue(display.getStackAboveHome() == null);
|
||||
display.moveHomeStackBehindBottomMostVisibleStack();
|
||||
assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
|
||||
int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null);
|
||||
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
|
||||
assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
|
||||
homeStack.setIsTranslucent(false);
|
||||
@@ -364,22 +356,23 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
// Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
|
||||
// pinned stack
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack1);
|
||||
display.moveHomeStackBehindBottomMostVisibleStack();
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack2);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
|
||||
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
|
||||
homeStack.setIsTranslucent(false);
|
||||
fullscreenStack1.setIsTranslucent(false);
|
||||
@@ -387,21 +380,22 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
// Ensure that we move the home stack behind the bottom most non-translucent fullscreen
|
||||
// stack
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack1);
|
||||
display.moveHomeStackBehindBottomMostVisibleStack();
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack1);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
|
||||
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindStack_BehindHomeStack() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
|
||||
homeStack.setIsTranslucent(false);
|
||||
@@ -409,45 +403,49 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
fullscreenStack2.setIsTranslucent(false);
|
||||
|
||||
// Ensure we don't move the home stack behind itself
|
||||
int homeStackIndex = display.getIndexOf(homeStack);
|
||||
display.moveHomeStackBehindStack(homeStack);
|
||||
assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
|
||||
int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
|
||||
mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
|
||||
assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHomeStackBehindStack() {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
display.removeChild(mStack);
|
||||
mDefaultDisplay.removeChild(mStack);
|
||||
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
|
||||
|
||||
display.moveHomeStackBehindStack(fullscreenStack1);
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack1);
|
||||
display.moveHomeStackBehindStack(fullscreenStack2);
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack2);
|
||||
display.moveHomeStackBehindStack(fullscreenStack4);
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack4);
|
||||
display.moveHomeStackBehindStack(fullscreenStack2);
|
||||
assertTrue(display.getStackAboveHome() == fullscreenStack2);
|
||||
mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
|
||||
mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
|
||||
mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4);
|
||||
mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
|
||||
assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitScreenMoveToFront() throws Exception {
|
||||
final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
|
||||
final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
|
||||
final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
|
||||
mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
|
||||
true /* onTop */);
|
||||
final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
|
||||
|
||||
splitScreenPrimary.setIsTranslucent(false);
|
||||
|
||||
Reference in New Issue
Block a user