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

Commit 7fceefa1 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Cancel all jobs associated with a UID when appropriate."

parents b7ca94a3 a9058249
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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.
+33 −17
Original line number Diff line number Diff line
@@ -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.");
+10 −10
Original line number Diff line number Diff line
@@ -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);
+2 −3
Original line number Diff line number Diff line
@@ -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();
+2 −1
Original line number Diff line number Diff line
@@ -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