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

Commit 8c67d12f authored by Christopher Tate's avatar Christopher Tate
Browse files

Add 'cancel' job scheduler shell command

Bug: 65120523
Test: manual
Change-Id: Icb93d0032d71671ba8f68a2b802a323f726af08b
parent 2f3072bc
Loading
Loading
Loading
Loading
+41 −3
Original line number Diff line number Diff line
@@ -795,18 +795,22 @@ public final class JobSchedulerService extends com.android.server.SystemService
     * @param uid Uid to check against for removal of a job.
     *
     */
    public void cancelJobsForUid(int uid, String reason) {
    public boolean cancelJobsForUid(int uid, String reason) {
        if (uid == Process.SYSTEM_UID) {
            Slog.wtfStack(TAG, "Can't cancel all jobs for system uid");
            return;
            return false;
        }

        boolean jobsCanceled = false;
        synchronized (mLock) {
            final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
            for (int i=0; i<jobsForUid.size(); i++) {
                JobStatus toRemove = jobsForUid.get(i);
                cancelJobImplLocked(toRemove, null, reason);
                jobsCanceled = true;
            }
        }
        return jobsCanceled;
    }

    /**
@@ -816,13 +820,14 @@ public final class JobSchedulerService extends com.android.server.SystemService
     * @param uid Uid of the calling client.
     * @param jobId Id of the job, provided at schedule-time.
     */
    public void cancelJob(int uid, int jobId) {
    public boolean cancelJob(int uid, int jobId) {
        JobStatus toCancel;
        synchronized (mLock) {
            toCancel = mJobs.getJobByUidAndJobId(uid, jobId);
            if (toCancel != null) {
                cancelJobImplLocked(toCancel, null, "cancel() called by app");
            }
            return (toCancel != null);
        }
    }

@@ -2147,6 +2152,39 @@ public final class JobSchedulerService extends com.android.server.SystemService
        return 0;
    }

    // Shell command infrastructure: cancel a scheduled job
    int executeCancelCommand(PrintWriter pw, String pkgName, int userId,
            boolean hasJobId, int jobId) {
        if (DEBUG) {
            Slog.v(TAG, "executeCancelCommand(): " + pkgName + "/" + userId + " " + jobId);
        }

        int pkgUid = -1;
        try {
            IPackageManager pm = AppGlobals.getPackageManager();
            pkgUid = pm.getPackageUid(pkgName, 0, userId);
        } catch (RemoteException e) { /* can't happen */ }

        if (pkgUid < 0) {
            pw.println("Package " + pkgName + " not found.");
            return JobSchedulerShellCommand.CMD_ERR_NO_PACKAGE;
        }

        if (!hasJobId) {
            pw.println("Canceling all jobs for " + pkgName + " in user " + userId);
            if (!cancelJobsForUid(pkgUid, "cancel shell command for package")) {
                pw.println("No matching jobs found.");
            }
        } else {
            pw.println("Canceling job " + pkgName + "/#" + jobId + " in user " + userId);
            if (!cancelJob(pkgUid, jobId)) {
                pw.println("No matching job found.");
            }
        }

        return 0;
    }

    void setMonitorBattery(boolean enabled) {
        synchronized (mLock) {
            if (mBatteryController != null) {
+44 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public final class JobSchedulerShellCommand extends ShellCommand {
                    return runJob(pw);
                case "timeout":
                    return timeout(pw);
                case "cancel":
                    return cancelJob(pw);
                case "monitor-battery":
                    return monitorBattery(pw);
                case "get-battery-seq":
@@ -205,6 +207,42 @@ public final class JobSchedulerShellCommand extends ShellCommand {
        }
    }

    private int cancelJob(PrintWriter pw) throws Exception {
        checkPermission("cancel jobs");

        int userId = UserHandle.USER_SYSTEM;

        String opt;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
                case "-u":
                case "--user":
                    userId = UserHandle.parseUserArg(getNextArgRequired());
                    break;

                default:
                    pw.println("Error: unknown option '" + opt + "'");
                    return -1;
            }
        }

        if (userId < 0) {
            pw.println("Error: must specify a concrete user ID");
            return -1;
        }

        final String pkgName = getNextArg();
        final String jobIdStr = getNextArg();
        final int jobId = jobIdStr != null ? Integer.parseInt(jobIdStr) : -1;

        final long ident = Binder.clearCallingIdentity();
        try {
            return mInternal.executeCancelCommand(pw, pkgName, userId, jobIdStr != null, jobId);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    private int monitorBattery(PrintWriter pw) throws Exception {
        checkPermission("change battery monitoring");
        String opt = getNextArgRequired();
@@ -315,6 +353,12 @@ public final class JobSchedulerShellCommand extends ShellCommand {
        pw.println("    Options:");
        pw.println("      -u or --user: specify which user's job is to be run; the default is");
        pw.println("         all users");
        pw.println("  cancel [-u | --user USER_ID] PACKAGE [JOB_ID]");
        pw.println("    Cancel a scheduled job.  If a job ID is not supplied, all jobs scheduled");
        pw.println("    by that package will be canceled.  USE WITH CAUTION.");
        pw.println("    Options:");
        pw.println("      -u or --user: specify which user's job is to be run; the default is");
        pw.println("         the primary or system user");
        pw.println("  monitor-battery [on|off]");
        pw.println("    Control monitoring of all battery changes.  Off by default.  Turning");
        pw.println("    on makes get-battery-seq useful.");