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: Michael Wachenschwanz <mwachens@google.com>
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user