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

Commit aab56dbc authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Show stacks underneath a resized stack

When a stack is resized, make sure any non-fullscreen stack beneath it
becomes visible. This may mean additional activities are resumed in the
process.

Bug: 19083171
Change-Id: I5e7a3f82d76932ea2b9dbf0324ea183c42ee5496
parent 728dace1
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -1735,6 +1735,22 @@ public class Am extends BaseCommand {
        int right = Integer.valueOf(rightStr);
        String bottomStr = nextArgRequired();
        int bottom = Integer.valueOf(bottomStr);
        if (left < 0) {
            System.err.println("Error: bad left arg: " + leftStr);
            return;
        }
        if (top < 0) {
            System.err.println("Error: bad top arg: " + topStr);
            return;
        }
        if (right <= 0) {
            System.err.println("Error: bad right arg: " + rightStr);
            return;
        }
        if (bottom <= 0) {
            System.err.println("Error: bad bottom arg: " + bottomStr);
            return;
        }

        try {
            mAm.resizeStack(stackId, new Rect(left, top, right, bottom));
+4 −3
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ import com.android.server.pm.UserManagerService;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.AppTransition;
import com.android.server.wm.WindowManagerService;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -8167,7 +8168,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    @Override
    public void resizeStack(int stackId, Rect bounds) {
        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                "resizeStackBox()");
                "resizeStack()");
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -10039,7 +10040,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                final boolean translucentChanged = r.changeWindowTranslucency(true);
                if (translucentChanged) {
                    r.task.stack.releaseBackgroundResources();
                    r.task.stack.releaseBackgroundResources(r);
                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
                }
                mWindowManager.setAppFullscreen(token, true);
@@ -10066,7 +10067,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                final boolean translucentChanged = r.changeWindowTranslucency(false);
                if (translucentChanged) {
                    r.task.stack.convertToTranslucent(r);
                    r.task.stack.convertActivityToTranslucent(r);
                }
                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
                mWindowManager.setAppFullscreen(token, false);
+25 −11
Original line number Diff line number Diff line
@@ -220,6 +220,9 @@ final class ActivityStack {
     */
    boolean mConfigWillChange;

    // Whether or not this stack covers the entire screen; by default stacks are full screen
    boolean mFullscreen = true;

    long mLaunchStartTime = 0;
    long mFullyDrawnStartTime = 0;

@@ -1125,7 +1128,8 @@ final class ActivityStack {

        final int numStacks = mStacks.size();
        while (stackNdx < numStacks) {
            tasks = mStacks.get(stackNdx).mTaskHistory;
            ActivityStack historyStack = mStacks.get(stackNdx);
            tasks = historyStack.mTaskHistory;
            final int numTasks = tasks.size();
            while (taskNdx < numTasks) {
                activities = tasks.get(taskNdx).mActivities;
@@ -1133,7 +1137,7 @@ final class ActivityStack {
                while (activityNdx < numActivities) {
                    final ActivityRecord activity = activities.get(activityNdx);
                    if (!activity.finishing) {
                        return activity.fullscreen ? null : activity;
                        return historyStack.mFullscreen && activity.fullscreen ? null : activity;
                    }
                    ++activityNdx;
                }
@@ -1149,7 +1153,7 @@ final class ActivityStack {

    // Checks if any of the stacks above this one has a fullscreen activity behind it.
    // If so, this stack is hidden, otherwise it is visible.
    private boolean isStackVisible() {
    private boolean isStackVisibleLocked() {
        if (!isAttached()) {
            return false;
        }
@@ -1164,11 +1168,18 @@ final class ActivityStack {
         * wallpaper to be shown behind it.
         */
        for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
            final ArrayList<TaskRecord> tasks = mStacks.get(i).getAllTasks();
            for (int taskNdx = 0; taskNdx < tasks.size(); taskNdx++) {
            ActivityStack stack = mStacks.get(i);
            // stack above isn't full screen, so, we assume we're still visible. at some point
            // we should look at the stack bounds to see if we're occluded even if the stack
            // isn't fullscreen
            if (!stack.mFullscreen) {
                continue;
            }
            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                final TaskRecord task = tasks.get(taskNdx);
                final ArrayList<ActivityRecord> activities = task.mActivities;
                for (int activityNdx = 0; activityNdx < activities.size(); activityNdx++) {
                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                    final ActivityRecord r = activities.get(activityNdx);

                    // Conditions for an activity to obscure the stack we're
@@ -1214,7 +1225,7 @@ final class ActivityStack {
        // If the top activity is not fullscreen, then we need to
        // make sure any activities under it are now visible.
        boolean aboveTop = true;
        boolean behindFullscreen = !isStackVisible();
        boolean behindFullscreen = !isStackVisibleLocked();

        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -1337,7 +1348,7 @@ final class ActivityStack {
                                    // This case created for transitioning activities from
                                    // translucent to opaque {@link Activity#convertToOpaque}.
                                    if (getVisibleBehindActivity() == r) {
                                        releaseBackgroundResources();
                                        releaseBackgroundResources(r);
                                    } else {
                                        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
                                            mStackSupervisor.mStoppingActivities.add(r);
@@ -1369,7 +1380,7 @@ final class ActivityStack {
        }
    }

    void convertToTranslucent(ActivityRecord r) {
    void convertActivityToTranslucent(ActivityRecord r) {
        mTranslucentActivityWaiting = r;
        mUndrawnActivitiesBelowTopTranslucent.clear();
        mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
@@ -3282,10 +3293,9 @@ final class ActivityStack {
        }
    }

    void releaseBackgroundResources() {
    void releaseBackgroundResources(ActivityRecord r) {
        if (hasVisibleBehindActivity() &&
                !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
            final ActivityRecord r = getVisibleBehindActivity();
            if (r == topRunningActivityLocked(null)) {
                // Don't release the top activity if it has requested to run behind the next
                // activity.
@@ -4143,6 +4153,10 @@ final class ActivityStack {
    boolean updateOverrideConfiguration(Configuration newConfig) {
        Configuration oldConfig = mOverrideConfig;
        mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
        // we override the configuration only when the stack's dimensions are different from
        // the display. in this manner, we know that if the override configuration is empty,
        // the stack is necessarily full screen
        mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
        return !mOverrideConfig.equals(oldConfig);
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
import android.util.TypedValue;

import com.android.server.EventLogTags;

import java.io.PrintWriter;
@@ -126,6 +127,7 @@ public class TaskStack {
        boolean oldFullscreen = mFullscreen;
        if (mDisplayContent != null) {
            mDisplayContent.getLogicalDisplayRect(mTmpRect);
            bounds.intersect(mTmpRect); // ensure bounds are entirely within the display rect
            mFullscreen = mTmpRect.equals(bounds);
        }