Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3731715b authored by Louis Chang's avatar Louis Chang
Browse files

Fix ActivityOptions.makeTaskLaunchBehind() doesn't work

- Activity tasks shouldn’t be moved to top if we were launching
  the activity in behind.

- Activities were temporarily set as visible if it was actively
  launched behind. Ensure the activities visibilities to avoid
  keeping activities in RESUMED state after finish animating.

- Fix black screen flashes while starting task-behind.
  The top app was set to hidden while starting an activity behind,
  even when it was on top and actually visible. So, black screen
  shown after reparenting the app token to leash for transition
  animation because the leash was also hidden since it was created
  from a hidden app.

Bug: 123382216
Test: atest StartActivityTests
Change-Id: I3cba33d7a0ce2d08d43a08e97f919bdd7bb21d7c
parent 4b235cb0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3259,6 +3259,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
+1 −1
Original line number Diff line number Diff line
@@ -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
+3 −2
Original line number Diff line number Diff line
@@ -1845,7 +1845,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;
        }
@@ -2679,7 +2679,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;
+15 −11
Original line number Diff line number Diff line
@@ -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;

@@ -568,8 +569,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) {
@@ -580,7 +580,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
                                    + " adding " + focusedToken + " to mOpeningApps");
                        }
                        // Force animation to be loaded.
                        focusedToken.setHidden(true);
                        displayContent.mOpeningApps.add(focusedToken);
                    }
                }
@@ -607,9 +606,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;
@@ -662,13 +666,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;
@@ -707,14 +711,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.
@@ -731,7 +735,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");