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

Commit 35712aea authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge "Cache reference to stack objects we use a lot in AM."

parents d469600a a0f5b5ee
Loading
Loading
Loading
Loading
+110 −12
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.am;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
@@ -45,13 +46,14 @@ import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.ConfigurationContainer;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Exactly one of these classes per Display in the system. Capable of holding zero or more
 * attached {@link ActivityStack}s.
 */
class ActivityDisplay extends ConfigurationContainer {
class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_AM;
    private static final String TAG_STACK = TAG + POSTFIX_STACK;

@@ -65,7 +67,7 @@ class ActivityDisplay extends ConfigurationContainer {

    /** All of the stacks on this display. Order matters, topmost stack is in front of all other
     * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
    final ArrayList<ActivityStack> mStacks = new ArrayList<>();
    private final ArrayList<ActivityStack> mStacks = new ArrayList<>();

    /** Array of all UIDs that are present on the display. */
    private IntArray mDisplayAccessUIDs = new IntArray();
@@ -77,6 +79,13 @@ class ActivityDisplay extends ConfigurationContainer {

    private boolean mSleeping;

    // Cached reference to some special stacks we tend to get a lot so we don't need to loop
    // through the list to find them.
    private ActivityStack mHomeStack = null;
    private ActivityStack mRecentsStack = null;
    private ActivityStack mPinnedStack = null;
    private ActivityStack mSplitScreenPrimaryStack = null;

    ActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
        mSupervisor = supervisor;
        mDisplayId = displayId;
@@ -95,6 +104,7 @@ class ActivityDisplay extends ConfigurationContainer {
        }
        if (DEBUG_STACK) Slog.v(TAG_STACK, "addChild: attaching " + stack
                + " to displayId=" + mDisplayId + " position=" + position);
        addStackReferenceIfNeeded(stack);
        positionChildAt(stack, position);
        mSupervisor.mService.updateSleepIfNeededLocked();
    }
@@ -103,6 +113,7 @@ class ActivityDisplay extends ConfigurationContainer {
        if (DEBUG_STACK) Slog.v(TAG_STACK, "removeChild: detaching " + stack
                + " from displayId=" + mDisplayId);
        mStacks.remove(stack);
        removeStackReferenceIfNeeded(stack);
        mSupervisor.mService.updateSleepIfNeededLocked();
    }

@@ -147,6 +158,16 @@ class ActivityDisplay extends ConfigurationContainer {
     * @see ConfigurationContainer#isCompatible(int, int)
     */
    <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
        if (activityType == ACTIVITY_TYPE_HOME) {
            return (T) mHomeStack;
        } else if (activityType == ACTIVITY_TYPE_RECENTS) {
            return (T) mRecentsStack;
        }
        if (windowingMode == WINDOWING_MODE_PINNED) {
            return (T) mPinnedStack;
        } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
            return (T) mSplitScreenPrimaryStack;
        }
        for (int i = mStacks.size() - 1; i >= 0; --i) {
            final ActivityStack stack = mStacks.get(i);
            // TODO: Should undefined windowing and activity type be compatible with standard type?
@@ -217,7 +238,7 @@ class ActivityDisplay extends ConfigurationContainer {
            }
        }

        final boolean inSplitScreenMode = hasSplitScreenStack();
        final boolean inSplitScreenMode = hasSplitScreenPrimaryStack();
        if (!inSplitScreenMode
                && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) {
            // Switch to fullscreen windowing mode if we are not in split-screen mode and we are
@@ -275,7 +296,7 @@ class ActivityDisplay extends ConfigurationContainer {
                if (stack.getWindowingMode() != windowingMode) {
                    continue;
                }
                mSupervisor.removeStackLocked(stack.mStackId);
                mSupervisor.removeStack(stack);
            }
        }
    }
@@ -290,9 +311,60 @@ class ActivityDisplay extends ConfigurationContainer {
            for (int i = mStacks.size() - 1; i >= 0; --i) {
                final ActivityStack stack = mStacks.get(i);
                if (stack.getActivityType() == activityType) {
                    mSupervisor.removeStackLocked(stack.mStackId);
                    mSupervisor.removeStack(stack);
                }
            }
        }
    }

    void onStackWindowingModeChanged(ActivityStack stack) {
        removeStackReferenceIfNeeded(stack);
        addStackReferenceIfNeeded(stack);
    }

    private void addStackReferenceIfNeeded(ActivityStack stack) {
        final int activityType = stack.getActivityType();
        final int windowingMode = stack.getWindowingMode();

        if (activityType == ACTIVITY_TYPE_HOME) {
            if (mHomeStack != null && mHomeStack != stack) {
                throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
                        + mHomeStack + " already exist on display=" + this + " stack=" + stack);
            }
            mHomeStack = stack;
        } else if (activityType == ACTIVITY_TYPE_RECENTS) {
            if (mRecentsStack != null && mRecentsStack != stack) {
                throw new IllegalArgumentException("addStackReferenceIfNeeded: recents stack="
                        + mRecentsStack + " already exist on display=" + this + " stack=" + stack);
            }
            mRecentsStack = stack;
        }
        if (windowingMode == WINDOWING_MODE_PINNED) {
            if (mPinnedStack != null && mPinnedStack != stack) {
                throw new IllegalArgumentException("addStackReferenceIfNeeded: pinned stack="
                        + mPinnedStack + " already exist on display=" + this
                        + " stack=" + stack);
            }
            mPinnedStack = stack;
        } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
            if (mSplitScreenPrimaryStack != null && mSplitScreenPrimaryStack != stack) {
                throw new IllegalArgumentException("addStackReferenceIfNeeded:"
                        + " split-screen-primary" + " stack=" + mSplitScreenPrimaryStack
                        + " already exist on display=" + this + " stack=" + stack);
            }
            mSplitScreenPrimaryStack = stack;
        }
    }

    private void removeStackReferenceIfNeeded(ActivityStack stack) {
        if (stack == mHomeStack) {
            mHomeStack = null;
        } else if (stack == mRecentsStack) {
            mRecentsStack = null;
        } else if (stack == mPinnedStack) {
            mPinnedStack = null;
        } else if (stack == mSplitScreenPrimaryStack) {
            mSplitScreenPrimaryStack = null;
        }
    }

@@ -310,20 +382,42 @@ class ActivityDisplay extends ConfigurationContainer {
        return ACTIVITY_TYPE_UNDEFINED;
    }

    ActivityStack getSplitScreenStack() {
        return getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
    /**
     * Get the topmost stack on the display. It may be different from focused stack, because
     * focus may be on another display.
     */
    ActivityStack getTopStack() {
        return mStacks.isEmpty() ? null : mStacks.get(mStacks.size() - 1);
    }

    boolean isTopStack(ActivityStack stack) {
        return stack == getTopStack();
    }

    boolean hasSplitScreenStack() {
        return getSplitScreenStack() != null;
    int getIndexOf(ActivityStack stack) {
        return mStacks.indexOf(stack);
    }

    void onLockTaskPackagesUpdated() {
        for (int i = mStacks.size() - 1; i >= 0; --i) {
            mStacks.get(i).onLockTaskPackagesUpdated();
        }
    }

    ActivityStack getSplitScreenPrimaryStack() {
        return mSplitScreenPrimaryStack;
    }

    boolean hasSplitScreenPrimaryStack() {
        return mSplitScreenPrimaryStack != null;
    }

    PinnedActivityStack getPinnedStack() {
        return getStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
        return (PinnedActivityStack) mPinnedStack;
    }

    boolean hasPinnedStack() {
        return getPinnedStack() != null;
        return mPinnedStack != null;
    }

    @Override
@@ -337,7 +431,7 @@ class ActivityDisplay extends ConfigurationContainer {
    }

    @Override
    protected ConfigurationContainer getChildAt(int index) {
    protected ActivityStack getChildAt(int index) {
        return mStacks.get(index);
    }

@@ -385,6 +479,10 @@ class ActivityDisplay extends ConfigurationContainer {
        mSleeping = asleep;
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.println(prefix + "displayId=" + mDisplayId + " mStacks=" + mStacks);
    }

    public void writeToProto(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
        super.writeToProto(proto, CONFIGURATION_CONTAINER);
+6 −5
Original line number Diff line number Diff line
@@ -176,7 +176,6 @@ import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.am.proto.ActivityManagerServiceProto.ACTIVITIES;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_NONE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
@@ -209,7 +208,6 @@ import android.app.ContentProviderHolder;
import android.app.Dialog;
import android.app.IActivityController;
import android.app.IActivityManager;
import android.app.IAppTask;
import android.app.IApplicationThread;
import android.app.IInstrumentationWatcher;
import android.app.INotificationManager;
@@ -10157,11 +10155,14 @@ public class ActivityManagerService extends IActivityManager.Stub
            final long ident = Binder.clearCallingIdentity();
            try {
                final ActivityStack stack = mStackSupervisor.getStack(stackId);
                if (stack != null && !stack.isActivityTypeStandardOrUndefined()) {
                if (stack == null) {
                    return;
                }
                if (!stack.isActivityTypeStandardOrUndefined()) {
                    throw new IllegalArgumentException(
                            "Removing non-standard stack is not allowed.");
                }
                mStackSupervisor.removeStackLocked(stackId);
                mStackSupervisor.removeStack(stack);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
@@ -10527,7 +10528,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        try {
            synchronized (this) {
                final ActivityStack stack =
                        mStackSupervisor.getDefaultDisplay().getSplitScreenStack();
                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
                if (toTop) {
                    mStackSupervisor.resizeStackLocked(stack, null /* destBounds */,
                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+1 −1
Original line number Diff line number Diff line
@@ -1558,7 +1558,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
            // On devices that support leanback only (Android TV), Recents activity can only be
            // visible if the home stack is the focused stack or we are in split-screen mode.
            final ActivityDisplay display = getDisplay();
            boolean hasSplitScreenStack = display != null && display.hasSplitScreenStack();
            boolean hasSplitScreenStack = display != null && display.hasSplitScreenPrimaryStack();
            isVisible = hasSplitScreenStack || mStackSupervisor.isFocusedStack(getStack());
        }

+32 −37
Original line number Diff line number Diff line
@@ -102,9 +102,6 @@ import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityController;
import android.app.ResultInfo;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration.ActivityType;
import android.app.WindowConfiguration.WindowingMode;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -473,6 +470,16 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        return mWindowContainerController;
    }

    @Override
    public void onConfigurationChanged(Configuration newParentConfig) {
        final int prevWindowingMode = getWindowingMode();
        super.onConfigurationChanged(newParentConfig);
        final ActivityDisplay display = getDisplay();
        if (display != null && prevWindowingMode != getWindowingMode()) {
            display.onStackWindowingModeChanged(this);
        }
    }

    /** Adds the stack to specified display and calls WindowManager to do the same. */
    void reparent(ActivityDisplay activityDisplay, boolean onTop) {
        removeFromDisplay();
@@ -1529,6 +1536,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                && !mForceHidden;
    }

    boolean isTopStackOnDisplay() {
        return getDisplay().isTopStack(this);
    }

    /**
     * Returns true if the stack should be visible.
     *
@@ -1539,22 +1550,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            return false;
        }

        if (mStackSupervisor.isFrontStackOnDisplay(this) || mStackSupervisor.isFocusedStack(this)) {
        final ActivityDisplay display = getDisplay();
        if (isTopStackOnDisplay() || mStackSupervisor.isFocusedStack(this)) {
            return true;
        }

        final ActivityDisplay display = getDisplay();
        final ArrayList<ActivityStack> displayStacks = display.mStacks;
        final int stackIndex = displayStacks.indexOf(this);

        if (stackIndex == displayStacks.size() - 1) {
            Slog.wtf(TAG,
                    "Stack=" + this + " isn't front stack but is at the top of the stack list");
            return false;
        }
        final int stackIndex = display.getIndexOf(this);

        // Check position and visibility of this stack relative to the front stack on its display.
        final ActivityStack topStack = getTopStackOnDisplay();
        final ActivityStack topStack = getDisplay().getTopStack();
        final int windowingMode = getWindowingMode();
        final int activityType = getActivityType();

@@ -1571,22 +1575,21 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        // A case would be if recents stack exists but has no tasks and is below the docked stack
        // and home stack is below recents
        if (activityType == ACTIVITY_TYPE_HOME) {
            final ActivityStack splitScreenStack = display.getStack(
                    WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
            int dockedStackIndex = displayStacks.indexOf(splitScreenStack);
            final ActivityStack splitScreenStack = display.getSplitScreenPrimaryStack();
            int dockedStackIndex = display.getIndexOf(splitScreenStack);
            if (dockedStackIndex > stackIndex && stackIndex != dockedStackIndex - 1) {
                return false;
            }
        }

        // Find the first stack behind front stack that actually got something visible.
        int stackBehindTopIndex = displayStacks.indexOf(topStack) - 1;
        int stackBehindTopIndex = display.getIndexOf(topStack) - 1;
        while (stackBehindTopIndex >= 0 &&
                displayStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
                display.getChildAt(stackBehindTopIndex).topRunningActivityLocked() == null) {
            stackBehindTopIndex--;
        }
        final ActivityStack stackBehindTop = (stackBehindTopIndex >= 0)
                ? displayStacks.get(stackBehindTopIndex) : null;
                ? display.getChildAt(stackBehindTopIndex) : null;
        int stackBehindTopWindowingMode = WINDOWING_MODE_UNDEFINED;
        int stackBehindTopActivityType = ACTIVITY_TYPE_UNDEFINED;
        if (stackBehindTop != null) {
@@ -1635,8 +1638,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            return false;
        }

        for (int i = stackIndex + 1; i < displayStacks.size(); i++) {
            final ActivityStack stack = displayStacks.get(i);
        final int stackCount = display.getChildCount();
        for (int i = stackIndex + 1; i < stackCount; i++) {
            final ActivityStack stack = display.getChildAt(i);

            if (!stack.mFullscreen && !stack.hasFullscreenTask()) {
                continue;
@@ -2572,8 +2576,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                    Slog.i(TAG, "Restarting because process died: " + next);
                    if (!next.hasBeenLaunched) {
                        next.hasBeenLaunched = true;
                    } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
                            mStackSupervisor.isFrontStackOnDisplay(lastStack)) {
                    } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null
                            && lastStack.isTopStackOnDisplay()) {
                        next.showStartingWindow(null /* prev */, false /* newTask */,
                                false /* taskSwitch */);
                    }
@@ -4428,7 +4432,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            AppTimeTracker timeTracker, String reason) {
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);

        final ActivityStack topStack = getTopStackOnDisplay();
        final ActivityStack topStack = getDisplay().getTopStack();
        final ActivityRecord topActivity = topStack != null ? topStack.topActivity() : null;
        final int numTasks = mTaskHistory.size();
        final int index = mTaskHistory.indexOf(tr);
@@ -4518,7 +4522,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        // If we have a watcher, preflight the move before committing to it.  First check
        // for *other* available tasks, but if none are available, then try again allowing the
        // current task to be selected.
        if (mStackSupervisor.isFrontStackOnDisplay(this) && mService.mController != null) {
        if (isTopStackOnDisplay() && mService.mController != null) {
            ActivityRecord next = topRunningActivityLocked(null, taskId);
            if (next == null) {
                next = topRunningActivityLocked(null, 0);
@@ -4566,7 +4570,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        }

        if (inPinnedWindowingMode()) {
            mStackSupervisor.removeStackLocked(mStackId);
            mStackSupervisor.removeStack(this);
            return true;
        }

@@ -4598,15 +4602,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        return true;
    }

    /**
     * Get the topmost stack on the current display. It may be different from focused stack, because
     * focus may be on another display.
     */
    private ActivityStack getTopStackOnDisplay() {
        final ArrayList<ActivityStack> stacks = getDisplay().mStacks;
        return stacks.isEmpty() ? null : stacks.get(stacks.size() - 1);
    }

    static void logStartActivity(int tag, ActivityRecord r, TaskRecord task) {
        final Uri data = r.intent.getData();
        final String strData = data != null ? data.toSafeString() : null;
@@ -5249,7 +5244,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                + mTaskHistory.size() + " tasks}";
    }

    void onLockTaskPackagesUpdatedLocked() {
    void onLockTaskPackagesUpdated() {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            mTaskHistory.get(taskNdx).setLockTaskAuth();
        }
+186 −216

File changed.

Preview size limit exceeded, changes collapsed.

Loading