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

Commit 3ee3b9d1 authored by Suprabh Shukla's avatar Suprabh Shukla Committed by Android (Google) Code Review
Browse files

Merge "Keeping only running users recents in memory"

parents 12747879 09a88f5f
Loading
Loading
Loading
Loading
+24 −28
Original line number Diff line number Diff line
@@ -201,6 +201,7 @@ import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.Xml;
import android.view.Display;
@@ -565,7 +566,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    /**
     * List of intents that were used to start the most recent tasks.
     */
    private final RecentTasks mRecentTasks;
    final RecentTasks mRecentTasks;
    /**
     * For addAppTask: cached of the last activity component that was added.
@@ -1052,11 +1053,6 @@ public final class ActivityManagerService extends ActivityManagerNative
     */
    final AppOpsService mAppOpsService;
    /**
     * Save recent tasks information across reboots.
     */
    final TaskPersister mTaskPersister;
    /**
     * Current configuration information.  HistoryRecord objects are given
     * a reference to this object to indicate which configuration they are
@@ -2509,10 +2505,10 @@ public final class ActivityManagerService extends ActivityManagerNative
        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
        mRecentTasks = new RecentTasks(this);
        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
        mStackSupervisor = new ActivityStackSupervisor(this);
        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
        mRecentTasks = new RecentTasks(this, mStackSupervisor);
        mProcessCpuThread = new Thread("CpuTracker") {
            @Override
@@ -2566,6 +2562,10 @@ public final class ActivityManagerService extends ActivityManagerNative
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }
    void onUserStoppedLocked(int userId) {
        mRecentTasks.unloadUserRecentsLocked(userId);
    }
    public void initPowerManagement() {
        mStackSupervisor.initPowerManagement();
        mBatteryStatsService.initPowerManagement();
@@ -8862,6 +8862,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                    android.Manifest.permission.GET_DETAILED_TASKS)
                    == PackageManager.PERMISSION_GRANTED;
            mRecentTasks.loadUserRecentsLocked(userId);
            final int recentsCount = mRecentTasks.size();
            ArrayList<ActivityManager.RecentTaskInfo> res =
                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
@@ -9024,8 +9026,9 @@ public final class ActivityManagerService extends ActivityManagerNative
                thumbnailInfo.taskHeight = displaySize.y;
                thumbnailInfo.screenOrientation = mConfiguration.orientation;
                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
                        intent, description, thumbnailInfo);
                TaskRecord task = new TaskRecord(this,
                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
                        ainfo, intent, description, thumbnailInfo);
                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
                if (trimIdx >= 0) {
@@ -9184,9 +9187,10 @@ public final class ActivityManagerService extends ActivityManagerNative
                passedIconFile.getName());
        if (!legitIconFile.getPath().equals(filePath)
                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
            throw new IllegalArgumentException("Bad file path: " + filePath);
            throw new IllegalArgumentException("Bad file path: " + filePath
                    + " passed for userId " + userId);
        }
        return mTaskPersister.getTaskDescriptionIcon(filePath);
        return mRecentTasks.getTaskDescriptionIcon(filePath);
    }
    @Override
@@ -11156,11 +11160,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    /** Pokes the task persister. */
    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
        if (task != null && task.stack != null && task.stack.isHomeStack()) {
            // Never persist the home stack.
            return;
        }
        mTaskPersister.wakeup(task, flush);
        mRecentTasks.notifyTaskPersisterLocked(task, flush);
    }
    /** Notifies all listeners when the task stack has changed. */
@@ -12573,11 +12573,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            // security checks.
            mUserController.updateCurrentProfileIdsLocked();
            mRecentTasks.clear();
            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
            mTaskPersister.startPersisting();
            mRecentTasks.onSystemReady();
            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                if (mWaitingUpdate) {
@@ -20837,10 +20833,6 @@ public final class ActivityManagerService extends ActivityManagerNative
        return mUserController.stopUser(userId, force, callback);
    }
    void onUserRemovedLocked(int userId) {
        mRecentTasks.removeTasksForUserLocked(userId);
    }
    @Override
    public UserInfo getCurrentUser() {
        return mUserController.getCurrentUser();
@@ -20895,6 +20887,10 @@ public final class ActivityManagerService extends ActivityManagerNative
        return newInfo;
    }
    public boolean isUserStopped(int userId) {
        return mUserController.getStartedUserStateLocked(userId) == null;
    }
    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
        if (aInfo == null
                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
@@ -21047,7 +21043,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        @Override
        public void onUserRemoved(int userId) {
            synchronized (ActivityManagerService.this) {
                ActivityManagerService.this.onUserRemovedLocked(userId);
                ActivityManagerService.this.onUserStoppedLocked(userId);
            }
        }
    }
+14 −1
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.UserHandle;

import com.android.internal.util.ArrayUtils;

import java.io.PrintWriter;

class ActivityManagerShellCommand extends ShellCommand {
@@ -58,6 +60,8 @@ class ActivityManagerShellCommand extends ShellCommand {
                    return runTrackAssociations(pw);
                case "untrack-associations":
                    return runUntrackAssociations(pw);
                case "is-user-stopped":
                    return runIsUserStopped(pw);
                default:
                    return handleDefaultCommands(cmd);
            }
@@ -67,6 +71,13 @@ class ActivityManagerShellCommand extends ShellCommand {
        return -1;
    }

    int runIsUserStopped(PrintWriter pw) {
        int userId = UserHandle.parseUserArg(getNextArgRequired());
        boolean stopped = mInternal.isUserStopped(userId);
        pw.println(stopped);
        return 0;
    }

    int runForceStop(PrintWriter pw) throws RemoteException {
        int userId = UserHandle.USER_ALL;

@@ -107,7 +118,7 @@ class ActivityManagerShellCommand extends ShellCommand {
    int runWrite(PrintWriter pw) {
        mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
                "registerUidObserver()");
        mInternal.mTaskPersister.flush();
        mInternal.mRecentTasks.flush();
        pw.println("All tasks persisted.");
        return 0;
    }
@@ -190,6 +201,8 @@ class ActivityManagerShellCommand extends ShellCommand {
            pw.println("    Enable association tracking.");
            pw.println("  untrack-associations");
            pw.println("    Disable and clear association tracking.");
            pw.println("  is-user-stopped <USER_ID>");
            pw.println("    returns whether <USER_ID> has been stopped or not");
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -1268,7 +1268,7 @@ final class ActivityRecord {
            final String iconFilename = createImageFilename(createTime, task.taskId);
            final File iconFile = new File(TaskPersister.getUserImagesDir(userId), iconFilename);
            final String iconFilePath = iconFile.getAbsolutePath();
            mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilePath);
            service.mRecentTasks.saveImage(icon, iconFilePath);
            _taskDescription.setIconFilename(iconFilePath);
        }
        taskDescription = _taskDescription;
+5 −3
Original line number Diff line number Diff line
@@ -2617,8 +2617,9 @@ final class ActivityStack {
                    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
                            + " out to bottom task " + bottom.task);
                } else {
                    targetTask = createTaskRecord(mStackSupervisor.getNextTaskId(), target.info,
                            null, null, null, false);
                    targetTask = createTaskRecord(
                            mStackSupervisor.getNextTaskIdForUserLocked(target.userId),
                            target.info, null, null, null, false);
                    targetTask.affinityIntent = target.intent;
                    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
                            + " out to new task " + target.task);
@@ -4824,7 +4825,8 @@ final class ActivityStack {
        final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);

        final TaskRecord task = createTaskRecord(
                mStackSupervisor.getNextTaskId(), r.info, r.intent, null, null, true);
                mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
                r.info, r.intent, null, null, true);
        r.setTask(task, null);
        task.addActivityToTop(r);
        setAppTask(r, task);
+42 −17
Original line number Diff line number Diff line
@@ -262,10 +262,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
    // For debugging to make sure the caller when acquiring/releasing our
    // wake lock is the system process.
    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
    /** The number of distinct task ids that can be assigned to the tasks of a single user */
    private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;

    final ActivityManagerService mService;

    private final RecentTasks mRecentTasks;
    private RecentTasks mRecentTasks;

    final ActivityStackSupervisorHandler mHandler;

@@ -276,9 +278,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
    /** Counter for next free stack ID to use for dynamic activity stacks. */
    private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID;

    /** Task identifier that activities are currently being started in.  Incremented each time a
     * new task is created. */
    private int mCurTaskId = 0;
    /**
     * Maps the task identifier that activities are currently being started in to the userId of the
     * task. Each time a new task is created, the entry for the userId of the task is incremented
     */
    private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20);

    /** The current user */
    int mCurrentUser;
@@ -436,14 +440,17 @@ public final class ActivityStackSupervisor implements DisplayListener {
        }
    }

    public ActivityStackSupervisor(ActivityManagerService service, RecentTasks recentTasks) {
    public ActivityStackSupervisor(ActivityManagerService service) {
        mService = service;
        mRecentTasks = recentTasks;
        mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
        mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
        mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
    }

    void setRecentTasks(RecentTasks recentTasks) {
        mRecentTasks = recentTasks;
    }

    /**
     * At the time when the constructor runs, the power manager has not yet been
     * initialized.  So we initialize our wakelocks afterwards.
@@ -685,20 +692,37 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return null;
    }

    void setNextTaskId(int taskId) {
        if (taskId > mCurTaskId) {
            mCurTaskId = taskId;
    void setNextTaskIdForUserLocked(int taskId, int userId) {
        final int currentTaskId = mCurTaskIdForUser.get(userId, -1);
        if (taskId > currentTaskId) {
            mCurTaskIdForUser.put(userId, taskId);
        }
    }

    int getNextTaskId() {
        do {
            mCurTaskId++;
            if (mCurTaskId <= 0) {
                mCurTaskId = 1;
    int getNextTaskIdForUserLocked(int userId) {
        mRecentTasks.loadUserRecentsLocked(userId);
        final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER);
        // for a userId u, a taskId can only be in the range
        // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
        // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
        int candidateTaskId = currentTaskId;
        while (anyTaskForIdLocked(candidateTaskId, !RESTORE_FROM_RECENTS,
                INVALID_STACK_ID) != null) {
            candidateTaskId++;
            if (candidateTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) {
                // Wrap around as there will be smaller task ids that are available now.
                candidateTaskId -= MAX_TASK_IDS_PER_USER;
            }
            if (candidateTaskId == currentTaskId) {
                // Something wrong!
                // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user
                throw new IllegalStateException("Cannot get an available task id."
                        + " Reached limit of " + MAX_TASK_IDS_PER_USER
                        + " running tasks per user.");
            }
        } while (anyTaskForIdLocked(mCurTaskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID) != null);
        return mCurTaskId;
        }
        mCurTaskIdForUser.put(userId, candidateTaskId);
        return candidateTaskId;
    }

    ActivityRecord resumedAppLocked() {
@@ -2805,7 +2829,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
        pw.print(prefix);
        pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
Loading