Merge "Generalize the recents animation to work with non-home activity." into pi-dev

am: 1b5a0deb81

Change-Id: Id6b57ef9890c75cf5d5735c049236a7daa4c0045
This commit is contained in:
Winson Chung
2018-04-06 09:56:31 -07:00
committed by android-build-merger
7 changed files with 251 additions and 240 deletions

View File

@@ -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() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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