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

Commit 362c7222 authored by Filip Gruszczynski's avatar Filip Gruszczynski Committed by Android (Google) Code Review
Browse files

Merge "Split ActivityStack.ensureActivitiesVisibleLocked."

parents 9f5de191 9104aeab
Loading
Loading
Loading
Loading
+155 −140
Original line number Diff line number Diff line
@@ -1418,19 +1418,9 @@ final class ActivityStack {
        if (top == null) {
            return;
        }
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                "ensureActivitiesVisible behind " + top
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
                + " configChanges=0x" + Integer.toHexString(configChanges));

        if (mTranslucentActivityWaiting != top) {
            mUndrawnActivitiesBelowTopTranslucent.clear();
            if (mTranslucentActivityWaiting != null) {
                // Call the callback with a timeout indication.
                notifyActivityDrawnLocked(null);
                mTranslucentActivityWaiting = null;
            }
            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
        }
        checkTranslucentActivityWaiting(top);

        // If the top activity is not fullscreen, then we need to
        // make sure any activities under it are now visible.
@@ -1458,7 +1448,6 @@ final class ActivityStack {
                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                            "Make visible? " + r + " finishing=" + r.finishing
                            + " state=" + r.state);

                    // First: if this is not the current activity being started, make
                    // sure it matches the current configuration.
                    if (r != starting) {
@@ -1466,27 +1455,8 @@ final class ActivityStack {
                    }

                    if (r.app == null || r.app.thread == null) {
                        // We need to make sure the app is running if it's the top, or it is
                        // just made visible from invisible.
                        // If the app is already visible, it must have died while it was visible.
                        // In this case, we'll show the dead window but will not restart the app.
                        // Otherwise we could end up thrashing.
                        if (r == top || !r.visible) {
                            // This activity needs to be visible, but isn't even running...
                            // get it started and resume if no other stack in this stack is resumed.
                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                    "Start and freeze screen for " + r);
                            if (r != starting) {
                                r.startFreezingScreenLocked(r.app, configChanges);
                            }
                            if (!r.visible || r.mLaunchTaskBehind) {
                                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                        "Starting and making visible: " + r);
                                setVisible(r, true);
                            }
                            if (r != starting) {
                                mStackSupervisor.startSpecificActivityLocked(
                                        r, noStackActivityResumed, false);
                        if (makeVisibleAndRestartIfNeeded(starting, configChanges, top,
                                noStackActivityResumed, r)) {
                            if (activityNdx >= activities.size()) {
                                // Record may be removed if its process needs to restart.
                                activityNdx = activities.size() - 1;
@@ -1494,74 +1464,84 @@ final class ActivityStack {
                                noStackActivityResumed = false;
                            }
                        }
                        }
                    } else if (r.visible) {
                        // If this activity is already visible, then there is nothing
                        // else to do here.
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                "Skipping: already visible at " + r);
                        r.stopFreezingScreenLocked(false);
                        try {
                            if (r.returningOptions != null) {
                                r.app.thread.scheduleOnNewActivityOptions(r.appToken,
                                        r.returningOptions);
                            }
                        } catch(RemoteException e) {
                        }
                        if (r.state == ActivityState.RESUMED) {
                        if (alreadyVisible(r)) {
                            noStackActivityResumed = false;
                        }
                    } else {
                        // This activity is not currently visible, but is running.
                        // Tell it to become visible.
                        r.visible = true;
                        if (r.state != ActivityState.RESUMED && r != starting) {
                            // If this activity is paused, tell it
                            // to now show its window.
                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                    "Making visible and scheduling visibility: " + r);
                            try {
                        becomeVisible(starting, r);
                    }
                    // Aggregate current change flags.
                    configChanges |= r.configChangeFlags;
                    behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
                            behindFullscreenActivity, task, r);
                } else {
                    becomeInvisible(stackInvisible, behindFullscreenActivity, r);
                }
            }
            if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
                // The visibility of tasks and the activities they contain in freeform stack are
                // determined individually unlike other stacks where the visibility or fullscreen
                // status of an activity in a previous task affects other.
                behindFullscreenActivity = stackInvisible;
            }
        }

        if (mTranslucentActivityWaiting != null &&
                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
            notifyActivityDrawnLocked(null);
        }
    }

    private void checkTranslucentActivityWaiting(ActivityRecord top) {
        if (mTranslucentActivityWaiting != top) {
            mUndrawnActivitiesBelowTopTranslucent.clear();
            if (mTranslucentActivityWaiting != null) {
                                    r.updateOptionsLocked(r.returningOptions);
                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
                // Call the callback with a timeout indication.
                notifyActivityDrawnLocked(null);
                mTranslucentActivityWaiting = null;
            }
            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
        }
    }

    private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
            ActivityRecord top, boolean noStackActivityResumed, ActivityRecord r) {
        // We need to make sure the app is running if it's the top, or it is just made visible from
        // invisible. If the app is already visible, it must have died while it was visible. In this
        // case, we'll show the dead window but will not restart the app. Otherwise we could end up
        // thrashing.
        if (r == top || !r.visible) {
            // This activity needs to be visible, but isn't even running...
            // get it started and resume if no other stack in this stack is resumed.
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
            if (r != starting) {
                r.startFreezingScreenLocked(r.app, configChanges);
            }
            if (!r.visible || r.mLaunchTaskBehind) {
                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
                setVisible(r, true);
                                r.sleeping = false;
                                r.app.pendingUiClean = true;
                                r.app.thread.scheduleWindowVisibility(r.appToken, true);
                                r.stopFreezingScreenLocked(false);
                            } catch (Exception e) {
                                // Just skip on any failure; we'll make it
                                // visible when it next restarts.
                                Slog.w(TAG, "Exception thrown making visibile: "
                                        + r.intent.getComponent(), e);
            }
            if (r != starting) {
                mStackSupervisor.startSpecificActivityLocked(r, noStackActivityResumed, false);
                return true;
            }
        }
        return false;
    }

                    // Aggregate current change flags.
                    configChanges |= r.configChangeFlags;

                    if (r.fullscreen) {
                        // At this point, nothing else needs to be shown in this task.
                        behindFullscreenActivity = true;
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
                                + " stackInvisible=" + stackInvisible
                                + " behindFullscreenActivity=" + behindFullscreenActivity);
                    } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
                        behindFullscreenActivity = true;
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
                                + " stackInvisible=" + stackInvisible
    private void becomeInvisible(boolean stackInvisible, boolean behindFullscreenActivity,
            ActivityRecord r) {
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing="
                + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible
                + " behindFullscreenActivity=" + behindFullscreenActivity);
        if (!r.visible) {
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
            return;
        }
                } else {
                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                            "Make invisible? " + r + " finishing=" + r.finishing
                            + " state=" + r.state + " stackInvisible=" + stackInvisible
                            + " behindFullscreenActivity=" + behindFullscreenActivity);
                    // Now for any activities that aren't visible to the user, make
                    // sure they no longer are keeping the screen frozen.
                    if (r.visible) {
        // Now for any activities that aren't visible to the user, make sure they no longer are
        // keeping the screen frozen.
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r);
        try {
            setVisible(r, false);
@@ -1595,29 +1575,64 @@ final class ActivityStack {
                    break;
            }
        } catch (Exception e) {
                            // Just skip on any failure; we'll make it
                            // visible when it next restarts.
                            Slog.w(TAG, "Exception thrown making hidden: "
                                    + r.intent.getComponent(), e);
            // Just skip on any failure; we'll make it visible when it next restarts.
            Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e);
        }
                    } else {
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
    }

    private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity,
            TaskRecord task, ActivityRecord r) {
        if (r.fullscreen) {
            // At this point, nothing else needs to be shown in this task.
            behindFullscreenActivity = true;
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
                    + " stackInvisible=" + stackInvisible
                    + " behindFullscreenActivity=" + behindFullscreenActivity);
        } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
            behindFullscreenActivity = true;
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
                    + " stackInvisible=" + stackInvisible
                    + " behindFullscreenActivity=" + behindFullscreenActivity);
        }
        return behindFullscreenActivity;
    }

    private void becomeVisible(ActivityRecord starting, ActivityRecord r) {
        // This activity is not currently visible, but is running. Tell it to become visible.
        r.visible = true;
        if (r.state != ActivityState.RESUMED && r != starting) {
            // If this activity is paused, tell it to now show its window.
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                    "Making visible and scheduling visibility: " + r);
            try {
                if (mTranslucentActivityWaiting != null) {
                    r.updateOptionsLocked(r.returningOptions);
                    mUndrawnActivitiesBelowTopTranslucent.add(r);
                }
                setVisible(r, true);
                r.sleeping = false;
                r.app.pendingUiClean = true;
                r.app.thread.scheduleWindowVisibility(r.appToken, true);
                r.stopFreezingScreenLocked(false);
            } catch (Exception e) {
                // Just skip on any failure; we'll make it
                // visible when it next restarts.
                Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e);
            }
            if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
                // The visibility of tasks and the activities they contain in freeform stack are
                // determined individually unlike other stacks where the visibility or fullscreen
                // status of an activity in a previous task affects other.
                behindFullscreenActivity = stackInvisible;
        }
    }

        if (mTranslucentActivityWaiting != null &&
                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
            notifyActivityDrawnLocked(null);
    private boolean alreadyVisible(ActivityRecord r) {
        // If this activity is already visible, then there is nothing else to do here.
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r);
        r.stopFreezingScreenLocked(false);
        try {
            if (r.returningOptions != null) {
                r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions);
            }
        } catch(RemoteException e) {
        }
        return r.state == ActivityState.RESUMED;
    }

    void convertActivityToTranslucent(ActivityRecord r) {