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

Commit cd501ecd authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Winson Chung
Browse files

Show recents at correct time when starting activity in docked stack

Previous logic relied on the returnTo type of the task of the activity
we are launching which can get the wrong signal at times because the
original task might have been started from home, but since we are
already in docked mode it shouldn't cause recents activity to be
launched.
We now decide if recents ability should be shown based on if the home
stack is currently visible at the time we started the new activity.
Also, renamed ActivityStack.getStackVisibilityLocked() to
ActivityStack.shouldBeVisible() since it is used to determine if the
stack should be visible and also so it isn't confused with the new
method ActivityStack.isVisible() which returns true if the stack is
currently visible.

Test: manual
Change-Id: I051e72ce93c886d25526af2afef851c95812ab3e
Fixes: 37005549
parent 11d1a392
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ class ActivityMetricsLogger {
        mLastLogTimeSecs = now;

        ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID);
        if (stack != null && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) {
        if (stack != null && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
            mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
            return;
        }
+12 −7
Original line number Diff line number Diff line
@@ -116,7 +116,6 @@ import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.Watchdog;
@@ -1560,12 +1559,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        return true;
    }

    /** Returns true if the stack is currently considered visible. */
    boolean isVisible() {
        return mWindowContainerController != null && mWindowContainerController.isVisible();
    }

    /**
     * Returns stack's visibility: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE} or
     * {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
     * Returns what the stack visibility should be: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE}
     * or {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
     *
     * @param starting The currently starting activity or null if there is none.
     */
    int getStackVisibilityLocked(ActivityRecord starting) {
    int shouldBeVisible(ActivityRecord starting) {
        if (!isAttached()) {
            return STACK_INVISIBLE;
        }
@@ -1715,7 +1720,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            // If the top activity is not fullscreen, then we need to
            // make sure any activities under it are now visible.
            boolean aboveTop = top != null;
            final int stackVisibility = getStackVisibilityLocked(starting);
            final int stackVisibility = shouldBeVisible(starting);
            final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
            final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
            boolean behindFullscreenActivity = stackInvisible;
@@ -2097,7 +2102,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        // activities as we need to display their starting window until they are done initializing.
        boolean behindFullscreenActivity = false;

        if (getStackVisibilityLocked(null) == STACK_INVISIBLE) {
        if (shouldBeVisible(null) == STACK_INVISIBLE) {
            // The stack is not visible, so no activity in it should be displaying a starting
            // window. Mark all activities below top and behind fullscreen.
            aboveTop = false;
@@ -4184,7 +4189,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        if (hasVisibleBehindActivity() &&
                !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
            if (r == topRunningActivityLocked()
                    && getStackVisibilityLocked(null) == STACK_VISIBLE) {
                    && shouldBeVisible(null) == STACK_VISIBLE) {
                // Don't release the top activity if it has requested to run behind the next
                // activity and the stack is currently visible.
                return;
+6 −8
Original line number Diff line number Diff line
@@ -164,7 +164,6 @@ import android.view.Display;
import android.view.InputEvent;
import android.view.Surface;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -174,7 +173,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.StackWindowController;
import com.android.server.wm.WindowManagerService;

import java.io.FileDescriptor;
@@ -2184,7 +2182,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            for (int j = stacks.size() - 1; j >= 0; --j) {
                final ActivityStack stack = stacks.get(j);
                if (stack != currentFocus && stack.isFocusable()
                        && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) {
                        && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
                    return stack;
                }
            }
@@ -2345,7 +2343,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            }
            ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
            final boolean isFullscreenStackVisible = fullscreenStack != null &&
                    fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
                    fullscreenStack.shouldBeVisible(null) == STACK_VISIBLE;
            // If we are moving from the pinned stack, then the animation takes care of updating
            // the picture-in-picture mode.
            final boolean schedulePictureInPictureModeChange = (fromStackId != PINNED_STACK_ID);
@@ -2520,7 +2518,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            final ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
            if (fullscreenStack != null) {
                final boolean isFullscreenStackVisible =
                        fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
                        fullscreenStack.shouldBeVisible(null) == STACK_VISIBLE;
                for (int i = 0; i < tasks.size(); i++) {
                    // Insert the task either at the top of the fullscreen stack if it is hidden,
                    // or to the bottom if it is currently visible
@@ -3545,7 +3543,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    ActivityStack stack = stacks.get(stackNdx);
                    if (!dumpVisibleStacksOnly ||
                            stack.getStackVisibilityLocked(null) == STACK_VISIBLE) {
                            stack.shouldBeVisible(null) == STACK_VISIBLE) {
                        activities.addAll(stack.getDumpActivitiesLocked(name));
                    }
                }
@@ -3852,7 +3850,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        info.displayId = DEFAULT_DISPLAY;
        info.stackId = stack.mStackId;
        info.userId = stack.mCurrentUser;
        info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
        info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE;
        info.position = display != null
                ? display.mStacks.indexOf(stack)
                : 0;
@@ -4971,7 +4969,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            for (int j = display.mStacks.size() - 1; j >= 0; j--) {
                final ActivityStack stack = display.mStacks.get(j);
                // Get top activity from a visible stack and add it to the list.
                if (stack.getStackVisibilityLocked(null /* starting */)
                if (stack.shouldBeVisible(null /* starting */)
                        == ActivityStack.STACK_VISIBLE) {
                    final ActivityRecord top = stack.topActivity();
                    if (top != null) {
+5 −23
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ import static com.android.server.am.ActivityManagerService.ANIMATE;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
@@ -118,14 +117,11 @@ import android.os.UserManager;
import android.service.voice.IVoiceInteractionSession;
import android.util.EventLog;
import android.util.Slog;
import android.view.Display;

import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.server.LocalServices;
import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
import com.android.server.pm.InstantAppResolver;
import com.android.server.vr.VrManagerInternal;
import com.android.server.wm.WindowManagerService;

import java.util.ArrayList;
@@ -562,31 +558,17 @@ class ActivityStarter {
            startedActivityStackId = targetStack.mStackId;
        }

        // If we launched the activity from a no display activity that was launched from the home
        // screen, we also need to start recents to un-minimize the docked stack, since the
        // noDisplay activity will be finished shortly after.
        // Note that some apps have trampoline activities without noDisplay being set. In that case,
        // we have another heuristic in DockedStackDividerController.notifyAppTransitionStarting
        // that tries to detect that case.
        // TODO: We should prevent noDisplay activities from affecting task/stack ordering and
        // visibility instead of using this flag.
        final boolean noDisplayActivityOverHome = sourceRecord != null
                && sourceRecord.noDisplay
                && sourceRecord.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE;
        if (startedActivityStackId == DOCKED_STACK_ID
                && (prevFocusedStackId == HOME_STACK_ID || noDisplayActivityOverHome)) {
        if (startedActivityStackId == DOCKED_STACK_ID) {
            final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
            final ActivityRecord topActivityHomeStack = homeStack != null
                    ? homeStack.topRunningActivityLocked() : null;
            if (topActivityHomeStack == null
                    || topActivityHomeStack.mActivityType != RECENTS_ACTIVITY_TYPE) {
            final boolean homeStackVisible = homeStack != null && homeStack.isVisible();
            if (homeStackVisible) {
                // We launch an activity while being in home stack, which means either launcher or
                // recents into docked stack. We don't want the launched activity to be alone in a
                // docked stack, so we want to immediately launch recents too.
                if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
                mWindowManager.showRecentApps(true /* fromHome */);
                return;
            }
            return;
        }

        if (startedActivityStackId == PINNED_STACK_ID
@@ -2150,7 +2132,7 @@ class ActivityStarter {
                // activity into parent's stack, because we can't find a better place.
                final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
                if (dockedStack != null
                        && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
                        && dockedStack.shouldBeVisible(r) == STACK_INVISIBLE) {
                    // There is a docked stack, but it isn't visible, so we can't launch into that.
                    return null;
                } else {
+7 −1
Original line number Diff line number Diff line
@@ -94,6 +94,12 @@ public class StackWindowController
        }
    }

    public boolean isVisible() {
        synchronized (mWindowMap) {
            return mContainer != null && mContainer.isVisible();
        }
    }

    public void reparent(int displayId, Rect outStackBounds) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
@@ -363,7 +369,7 @@ public class StackWindowController
    }

    /** Calls directly into activity manager so window manager lock shouldn't held. */
    public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
    void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
        if (mListener != null) {
            mListener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
        }