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

Commit 3f2b6552 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Purge Nonexistent User Jobs on Boot



In the case that a user has been removed but their jobs still exist on
disk, the JobSchedulerService will remove all jobs not associated with
current users on boot.
Exposed UserManagerService#getUserIds() via UserManagerInternal for
quick user id retrieval.

Fixes: 38261977
Test: manual

Change-Id: Id4b3c0a4142b4818fcd875eef18ea03f3c45ca40
Signed-off-by: default avatarMichael Wachenschwanz <mwachens@google.com>
parent 7e08c7ec
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -167,4 +167,12 @@ public abstract class UserManagerInternal {
     * Remove user's running state
     */
    public abstract void removeUserState(int userId);

    /**
     * Returns an array of user ids. This array is cached in UserManagerService and passed as a
     * reference, so do not modify the returned array.
     *
     * @return the array of user ids.
     */
    public abstract int[] getUserIds();
}
+10 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.provider.Settings;
import android.util.KeyValueListParser;
import android.util.Slog;
@@ -751,6 +752,13 @@ public final class JobSchedulerService extends com.android.server.SystemService
        }
    }

    private void cancelJobsForNonExistentUsers() {
        UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
        synchronized (mLock) {
            mJobs.removeJobsOfNonUsers(umi.getUserIds());
        }
    }

    void cancelJobsForPackageAndUid(String pkgName, int uid) {
        synchronized (mLock) {
            final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
@@ -941,6 +949,8 @@ public final class JobSchedulerService extends com.android.server.SystemService
            } catch (RemoteException e) {
                // ignored; both services live in system_server
            }
            // Remove any jobs that are not associated with any of the current users.
            cancelJobsForNonExistentUsers();
        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            synchronized (mLock) {
                // Let's go!
+20 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.util.SparseArray;
import android.util.Xml;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.IoThread;
import com.android.server.job.controllers.JobStatus;
@@ -171,6 +172,14 @@ public class JobStore {
        return removed;
    }

    /**
     * Remove the jobs of users not specified in the whitelist.
     * @param whitelist Array of User IDs whose jobs are not to be removed.
     */
    public void removeJobsOfNonUsers(int[] whitelist) {
        mJobSet.removeJobsOfNonUsers(whitelist);
    }

    @VisibleForTesting
    public void clear() {
        mJobSet.clear();
@@ -839,6 +848,17 @@ public class JobStore {
            return didRemove;
        }

        // Remove the jobs all users not specified by the whitelist of user ids
        public void removeJobsOfNonUsers(int[] whitelist) {
            for (int jobIndex = mJobs.size() - 1; jobIndex >= 0; jobIndex--) {
                int jobUserId = UserHandle.getUserId(mJobs.keyAt(jobIndex));
                // check if job's user id is not in the whitelist
                if (!ArrayUtils.contains(whitelist, jobUserId)) {
                    mJobs.removeAt(jobIndex);
                }
            }
        }

        public boolean contains(JobStatus job) {
            final int uid = job.getUid();
            ArraySet<JobStatus> jobs = mJobs.get(uid);
+5 −0
Original line number Diff line number Diff line
@@ -3683,6 +3683,11 @@ public class UserManagerService extends IUserManager.Stub {
            }
        }

        @Override
        public int[] getUserIds() {
            return UserManagerService.this.getUserIds();
        }

        @Override
        public boolean isUserUnlockingOrUnlocked(int userId) {
            synchronized (mUserStates) {