diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 8455f43a2e4c2..18a57ae17fdaa 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -3263,6 +3263,9 @@ class ActivityStack extends ConfigurationContainer { // tell WindowManager that r is visible even though it is at the back of the stack. r.setVisibility(true); ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); + // Go ahead to execute app transition for this activity since the app transition + // will not be triggered through the resume channel. + getDisplay().mDisplayContent.executeAppTransition(); } else if (SHOW_APP_STARTING_PREVIEW && doShow) { // Figure out if we are transitioning from another activity that is // "has the same starting icon" as the next one. This allows the diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index a6e9c05043a3b..feb4a3653ced5 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -2072,7 +2072,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { r.mLaunchTaskBehind = false; mRecentTasks.add(task); mService.getTaskChangeNotificationController().notifyTaskStackChanged(); - r.setVisibility(false); + stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); // When launching tasks behind, update the last active time of the top task after the new // task has been shown briefly diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index bbc1d7f5f7597..54eb07f569833 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1846,7 +1846,7 @@ class ActivityStarter { // of this in the record so that we can skip it when trying to find // the top running activity. mDoResume = doResume; - if (!doResume || !r.okToShowLocked()) { + if (!doResume || !r.okToShowLocked() || mLaunchTaskBehind) { r.delayedResume = true; mDoResume = false; } @@ -2680,7 +2680,8 @@ class ActivityStarter { if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) || mPreferredDisplayId != DEFAULT_DISPLAY) { - final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront(); + final boolean onTop = + (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; final ActivityStack stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams); return stack; diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index eab5e0dd270ea..8007c0f316e0d 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -33,6 +33,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE; +import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND; import static android.view.WindowManager.TRANSIT_UNSET; import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN; @@ -581,8 +582,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree displayContent.mClosingApps.add(this); mEnteringAnimation = false; } - if (appTransition.getAppTransition() - == WindowManager.TRANSIT_TASK_OPEN_BEHIND) { + if (appTransition.getAppTransition() == TRANSIT_TASK_OPEN_BEHIND) { // We're launchingBehind, add the launching activity to mOpeningApps. final WindowState win = getDisplayContent().findFocusedWindow(); if (win != null) { @@ -593,7 +593,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree + " adding " + focusedToken + " to mOpeningApps"); } // Force animation to be loaded. - focusedToken.setHidden(true); displayContent.mOpeningApps.add(focusedToken); } } @@ -620,9 +619,14 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // * token is transitioning visibility state // * or the token was marked as hidden and is exiting before we had a chance to play the // transition animation - // * or this is an opening app and windows are being replaced. + // * or this is an opening app and windows are being replaced + // * or the token is the opening app and visible while opening task behind existing one. + final DisplayContent displayContent = getDisplayContent(); boolean visibilityChanged = false; - if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) { + if (isHidden() == visible || (isHidden() && mIsExiting) + || (visible && waitingForReplacement()) + || (visible && displayContent.mOpeningApps.contains(this) + && displayContent.mAppTransition.getAppTransition() == TRANSIT_TASK_OPEN_BEHIND)) { final AccessibilityController accessibilityController = mWmService.mAccessibilityController; boolean changed = false; @@ -675,13 +679,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } if (changed) { - getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw(); + displayContent.getInputMonitor().setUpdateInputWindowsNeededLw(); if (performLayout) { mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); mWmService.mWindowPlacerLocked.performSurfacePlacement(); } - getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/); + displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/); } } mUseTransferredAnimation = false; @@ -720,14 +724,14 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree setClientHidden(!visible); } - if (!getDisplayContent().mClosingApps.contains(this) - && !getDisplayContent().mOpeningApps.contains(this)) { + if (!displayContent.mClosingApps.contains(this) + && !displayContent.mOpeningApps.contains(this)) { // The token is not closing nor opening, so even if there is an animation set, that // doesn't mean that it goes through the normal app transition cycle so we have // to inform the docked controller about visibility change. // TODO(multi-display): notify docked divider on all displays where visibility was // affected. - getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged(); + displayContent.getDockedDividerController().notifyAppVisibilityChanged(); // Take the screenshot before possibly hiding the WSA, otherwise the screenshot // will not be taken. @@ -744,7 +748,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // no animation but there will still be a transition set. // We still need to delay hiding the surface such that it // can be synchronized with showing the next surface in the transition. - if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) { + if (isHidden() && !delayed && !displayContent.mAppTransition.isTransitionSet()) { SurfaceControl.openTransaction(); for (int i = mChildren.size() - 1; i >= 0; i--) { mChildren.get(i).mWinAnimator.hide("immediately hidden");