Merge "Cancel all jobs associated with a UID when appropriate."
This commit is contained in:
@@ -36,9 +36,11 @@ public interface JobSchedulerInternal {
|
||||
|
||||
/**
|
||||
* Cancel the jobs for a given uid (e.g. when app data is cleared)
|
||||
*
|
||||
* @param includeProxiedJobs Include jobs scheduled for this UID by other apps
|
||||
*/
|
||||
void cancelJobsForUid(int uid, @JobParameters.StopReason int reason, int debugReasonCode,
|
||||
String debugReason);
|
||||
void cancelJobsForUid(int uid, boolean includeProxiedJobs,
|
||||
@JobParameters.StopReason int reason, int debugReasonCode, String debugReason);
|
||||
|
||||
/**
|
||||
* These are for activity manager to communicate to use what is currently performing backups.
|
||||
|
||||
@@ -970,12 +970,12 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
// Has this package scheduled any jobs, such that we will take action
|
||||
// if it were to be force-stopped?
|
||||
if (pkgUid != -1) {
|
||||
List<JobStatus> jobsForUid;
|
||||
ArraySet<JobStatus> jobsForUid;
|
||||
synchronized (mLock) {
|
||||
jobsForUid = mJobs.getJobsByUid(pkgUid);
|
||||
}
|
||||
for (int i = jobsForUid.size() - 1; i >= 0; i--) {
|
||||
if (jobsForUid.get(i).getSourcePackageName().equals(pkgName)) {
|
||||
if (jobsForUid.valueAt(i).getSourcePackageName().equals(pkgName)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Restart query: package " + pkgName + " at uid "
|
||||
+ pkgUid + " has jobs");
|
||||
@@ -1292,10 +1292,11 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
|
||||
public List<JobInfo> getPendingJobs(int uid) {
|
||||
synchronized (mLock) {
|
||||
List<JobStatus> jobs = mJobs.getJobsByUid(uid);
|
||||
ArraySet<JobStatus> jobs = mJobs.getJobsByUid(uid);
|
||||
ArrayList<JobInfo> outList = new ArrayList<JobInfo>(jobs.size());
|
||||
// Write out for loop to avoid addAll() creating an Iterator.
|
||||
for (int i = jobs.size() - 1; i >= 0; i--) {
|
||||
JobStatus job = jobs.get(i);
|
||||
final JobStatus job = jobs.valueAt(i);
|
||||
outList.add(job.getJob());
|
||||
}
|
||||
return outList;
|
||||
@@ -1304,9 +1305,9 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
|
||||
public JobInfo getPendingJob(int uid, int jobId) {
|
||||
synchronized (mLock) {
|
||||
List<JobStatus> jobs = mJobs.getJobsByUid(uid);
|
||||
ArraySet<JobStatus> jobs = mJobs.getJobsByUid(uid);
|
||||
for (int i = jobs.size() - 1; i >= 0; i--) {
|
||||
JobStatus job = jobs.get(i);
|
||||
JobStatus job = jobs.valueAt(i);
|
||||
if (job.getJobId() == jobId) {
|
||||
return job.getJob();
|
||||
}
|
||||
@@ -1348,7 +1349,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
Slog.wtfStack(TAG, "Can't cancel all jobs for system package");
|
||||
return;
|
||||
}
|
||||
final List<JobStatus> jobsForUid = new ArrayList<>();
|
||||
final ArraySet<JobStatus> jobsForUid = new ArraySet<>();
|
||||
if (includeSchedulingApp) {
|
||||
mJobs.getJobsByUid(uid, jobsForUid);
|
||||
}
|
||||
@@ -1356,7 +1357,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
mJobs.getJobsBySourceUid(uid, jobsForUid);
|
||||
}
|
||||
for (int i = jobsForUid.size() - 1; i >= 0; i--) {
|
||||
final JobStatus job = jobsForUid.get(i);
|
||||
final JobStatus job = jobsForUid.valueAt(i);
|
||||
final boolean shouldCancel =
|
||||
(includeSchedulingApp
|
||||
&& job.getServiceComponent().getPackageName().equals(pkgName))
|
||||
@@ -1368,14 +1369,16 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point from client to cancel all jobs originating from their uid.
|
||||
* Entry point from client to cancel all jobs scheduled for or from their uid.
|
||||
* This will remove the job from the master list, and cancel the job if it was staged for
|
||||
* execution or being executed.
|
||||
*
|
||||
* @param uid Uid to check against for removal of a job.
|
||||
* @param includeSourceApp Whether to include jobs scheduled for this UID by another UID.
|
||||
* If false, only jobs scheduled by this UID will be cancelled.
|
||||
*/
|
||||
public boolean cancelJobsForUid(int uid, @JobParameters.StopReason int reason,
|
||||
int internalReasonCode, String debugReason) {
|
||||
public boolean cancelJobsForUid(int uid, boolean includeSourceApp,
|
||||
@JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
|
||||
if (uid == Process.SYSTEM_UID) {
|
||||
Slog.wtfStack(TAG, "Can't cancel all jobs for system uid");
|
||||
return false;
|
||||
@@ -1383,9 +1386,15 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
|
||||
boolean jobsCanceled = false;
|
||||
synchronized (mLock) {
|
||||
final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
|
||||
final ArraySet<JobStatus> jobsForUid = new ArraySet<>();
|
||||
// Get jobs scheduled by the app.
|
||||
mJobs.getJobsByUid(uid, jobsForUid);
|
||||
if (includeSourceApp) {
|
||||
// Get jobs scheduled for the app by someone else.
|
||||
mJobs.getJobsBySourceUid(uid, jobsForUid);
|
||||
}
|
||||
for (int i = 0; i < jobsForUid.size(); i++) {
|
||||
JobStatus toRemove = jobsForUid.get(i);
|
||||
JobStatus toRemove = jobsForUid.valueAt(i);
|
||||
cancelJobImplLocked(toRemove, null, reason, internalReasonCode, debugReason);
|
||||
jobsCanceled = true;
|
||||
}
|
||||
@@ -2220,6 +2229,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
|
||||
if (disabled) {
|
||||
cancelJobsForUid(uid,
|
||||
/* includeSourceApp */ true,
|
||||
JobParameters.STOP_REASON_BACKGROUND_RESTRICTION,
|
||||
JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
|
||||
"uid gone");
|
||||
@@ -2241,6 +2251,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
final boolean disabled = message.arg2 != 0;
|
||||
if (disabled) {
|
||||
cancelJobsForUid(uid,
|
||||
/* includeSourceApp */ true,
|
||||
JobParameters.STOP_REASON_BACKGROUND_RESTRICTION,
|
||||
JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
|
||||
"app uid idle");
|
||||
@@ -2899,9 +2910,10 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelJobsForUid(int uid, @JobParameters.StopReason int reason,
|
||||
int internalReasonCode, String debugReason) {
|
||||
JobSchedulerService.this.cancelJobsForUid(uid, reason, internalReasonCode, debugReason);
|
||||
public void cancelJobsForUid(int uid, boolean includeProxiedJobs,
|
||||
@JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
|
||||
JobSchedulerService.this.cancelJobsForUid(uid,
|
||||
includeProxiedJobs, reason, internalReasonCode, debugReason);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3273,6 +3285,8 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
JobSchedulerService.this.cancelJobsForUid(uid,
|
||||
// Documentation says only jobs scheduled BY the app will be cancelled
|
||||
/* includeSourceApp */ false,
|
||||
JobParameters.STOP_REASON_CANCELLED_BY_APP,
|
||||
JobParameters.INTERNAL_STOP_REASON_CANCELED,
|
||||
"cancelAll() called by app, callingUid=" + uid);
|
||||
@@ -3484,7 +3498,9 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
|
||||
if (!hasJobId) {
|
||||
pw.println("Canceling all jobs for " + pkgName + " in user " + userId);
|
||||
if (!cancelJobsForUid(pkgUid, JobParameters.STOP_REASON_USER,
|
||||
if (!cancelJobsForUid(pkgUid,
|
||||
/* includeSourceApp */ false,
|
||||
JobParameters.STOP_REASON_USER,
|
||||
JobParameters.INTERNAL_STOP_REASON_CANCELED,
|
||||
"cancel shell command for package")) {
|
||||
pw.println("No matching jobs found.");
|
||||
|
||||
@@ -291,11 +291,11 @@ public final class JobStore {
|
||||
* @return A list of all the jobs scheduled for the source app. Never null.
|
||||
*/
|
||||
@NonNull
|
||||
public List<JobStatus> getJobsBySourceUid(int sourceUid) {
|
||||
public ArraySet<JobStatus> getJobsBySourceUid(int sourceUid) {
|
||||
return mJobSet.getJobsBySourceUid(sourceUid);
|
||||
}
|
||||
|
||||
public void getJobsBySourceUid(int sourceUid, @NonNull List<JobStatus> insertInto) {
|
||||
public void getJobsBySourceUid(int sourceUid, @NonNull Set<JobStatus> insertInto) {
|
||||
mJobSet.getJobsBySourceUid(sourceUid, insertInto);
|
||||
}
|
||||
|
||||
@@ -304,11 +304,11 @@ public final class JobStore {
|
||||
* @return All JobStatus objects for a given uid from the master list. Never null.
|
||||
*/
|
||||
@NonNull
|
||||
public List<JobStatus> getJobsByUid(int uid) {
|
||||
public ArraySet<JobStatus> getJobsByUid(int uid) {
|
||||
return mJobSet.getJobsByUid(uid);
|
||||
}
|
||||
|
||||
public void getJobsByUid(int uid, @NonNull List<JobStatus> insertInto) {
|
||||
public void getJobsByUid(int uid, @NonNull Set<JobStatus> insertInto) {
|
||||
mJobSet.getJobsByUid(uid, insertInto);
|
||||
}
|
||||
|
||||
@@ -1232,13 +1232,13 @@ public final class JobStore {
|
||||
mJobsPerSourceUid = new SparseArray<>();
|
||||
}
|
||||
|
||||
public List<JobStatus> getJobsByUid(int uid) {
|
||||
ArrayList<JobStatus> matchingJobs = new ArrayList<JobStatus>();
|
||||
public ArraySet<JobStatus> getJobsByUid(int uid) {
|
||||
ArraySet<JobStatus> matchingJobs = new ArraySet<>();
|
||||
getJobsByUid(uid, matchingJobs);
|
||||
return matchingJobs;
|
||||
}
|
||||
|
||||
public void getJobsByUid(int uid, List<JobStatus> insertInto) {
|
||||
public void getJobsByUid(int uid, Set<JobStatus> insertInto) {
|
||||
ArraySet<JobStatus> jobs = mJobs.get(uid);
|
||||
if (jobs != null) {
|
||||
insertInto.addAll(jobs);
|
||||
@@ -1246,13 +1246,13 @@ public final class JobStore {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<JobStatus> getJobsBySourceUid(int sourceUid) {
|
||||
final ArrayList<JobStatus> result = new ArrayList<JobStatus>();
|
||||
public ArraySet<JobStatus> getJobsBySourceUid(int sourceUid) {
|
||||
final ArraySet<JobStatus> result = new ArraySet<>();
|
||||
getJobsBySourceUid(sourceUid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void getJobsBySourceUid(int sourceUid, List<JobStatus> insertInto) {
|
||||
public void getJobsBySourceUid(int sourceUid, Set<JobStatus> insertInto) {
|
||||
final ArraySet<JobStatus> jobs = mJobsPerSourceUid.get(sourceUid);
|
||||
if (jobs != null) {
|
||||
insertInto.addAll(jobs);
|
||||
|
||||
@@ -50,7 +50,6 @@ import com.android.server.utils.AlarmQueue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -397,10 +396,10 @@ public final class FlexibilityController extends StateController {
|
||||
return;
|
||||
}
|
||||
final long nowElapsed = sElapsedRealtimeClock.millis();
|
||||
List<JobStatus> jobsByUid = mService.getJobStore().getJobsByUid(uid);
|
||||
ArraySet<JobStatus> jobsByUid = mService.getJobStore().getJobsBySourceUid(uid);
|
||||
boolean hasPrefetch = false;
|
||||
for (int i = 0; i < jobsByUid.size(); i++) {
|
||||
JobStatus js = jobsByUid.get(i);
|
||||
JobStatus js = jobsByUid.valueAt(i);
|
||||
if (js.hasFlexibilityConstraint()) {
|
||||
js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
|
||||
hasPrefetch |= js.getJob().isPrefetch();
|
||||
|
||||
@@ -3937,7 +3937,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
// Clear its scheduled jobs
|
||||
JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
|
||||
// Clearing data is a user-initiated action.
|
||||
js.cancelJobsForUid(appInfo.uid, JobParameters.STOP_REASON_USER,
|
||||
js.cancelJobsForUid(appInfo.uid, /* includeProxiedJobs */ true,
|
||||
JobParameters.STOP_REASON_USER,
|
||||
JobParameters.INTERNAL_STOP_REASON_DATA_CLEARED, "clear data");
|
||||
|
||||
// Clear its pending alarms
|
||||
|
||||
Reference in New Issue
Block a user