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

Commit 01dbb45a authored by Kweku Adams's avatar Kweku Adams
Browse files

Enable testing specific stop reasons.

Make it possible to test stopping jobs with specific stop reasons.

Bug: 241778401
Test: atest CtsJobSchedulerTestCases:NotificationTest
Change-Id: I7eade33a3d210411578c0f3520fc1f2ef6b66b47
parent db63d9a6
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1816,15 +1816,17 @@ class JobConcurrencyManager {
    }

    @GuardedBy("mLock")
    boolean executeTimeoutCommandLocked(PrintWriter pw, String pkgName, int userId,
            @Nullable String namespace, boolean hasJobId, int jobId) {
    boolean executeStopCommandLocked(PrintWriter pw, String pkgName, int userId,
            @Nullable String namespace, boolean matchJobId, int jobId,
            int stopReason, int internalStopReason) {
        boolean foundSome = false;
        for (int i = 0; i < mActiveServices.size(); i++) {
            final JobServiceContext jc = mActiveServices.get(i);
            final JobStatus js = jc.getRunningJobLocked();
            if (jc.timeoutIfExecutingLocked(pkgName, userId, namespace, hasJobId, jobId, "shell")) {
            if (jc.stopIfExecutingLocked(pkgName, userId, namespace, matchJobId, jobId,
                    stopReason, internalStopReason)) {
                foundSome = true;
                pw.print("Timing out: ");
                pw.print("Stopping job: ");
                js.printUniqueId(pw);
                pw.print(" ");
                pw.println(js.getServiceComponent().flattenToShortString());
+8 −5
Original line number Diff line number Diff line
@@ -4306,15 +4306,18 @@ public class JobSchedulerService extends com.android.server.SystemService
    }

    // Shell command infrastructure: immediately timeout currently executing jobs
    int executeTimeoutCommand(PrintWriter pw, String pkgName, int userId,
            @Nullable String namespace, boolean hasJobId, int jobId) {
    int executeStopCommand(PrintWriter pw, String pkgName, int userId,
            @Nullable String namespace, boolean hasJobId, int jobId,
            int stopReason, int internalStopReason) {
        if (DEBUG) {
            Slog.v(TAG, "executeTimeoutCommand(): " + pkgName + "/" + userId + " " + jobId);
            Slog.v(TAG, "executeStopJobCommand(): " + pkgName + "/" + userId + " " + jobId
                    + ": " + stopReason + "("
                    + JobParameters.getInternalReasonCodeDescription(internalStopReason) + ")");
        }

        synchronized (mLock) {
            final boolean foundSome = mConcurrencyManager.executeTimeoutCommandLocked(pw,
                    pkgName, userId, namespace, hasJobId, jobId);
            final boolean foundSome = mConcurrencyManager.executeStopCommandLocked(pw,
                    pkgName, userId, namespace, hasJobId, jobId, stopReason, internalStopReason);
            if (!foundSome) {
                pw.println("No matching executing jobs found.");
            }
+80 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.job;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.job.JobParameters;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -83,6 +84,8 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
                    return resetExecutionQuota(pw);
                case "reset-schedule-quota":
                    return resetScheduleQuota(pw);
                case "stop":
                    return stop(pw);
                case "trigger-dock-state":
                    return triggerDockState(pw);
                default:
@@ -255,8 +258,9 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {

        final long ident = Binder.clearCallingIdentity();
        try {
            return mInternal.executeTimeoutCommand(pw, pkgName, userId, namespace,
                    jobIdStr != null, jobId);
            return mInternal.executeStopCommand(pw, pkgName, userId, namespace,
                    jobIdStr != null, jobId,
                    JobParameters.STOP_REASON_TIMEOUT, JobParameters.INTERNAL_STOP_REASON_TIMEOUT);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
@@ -542,6 +546,60 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        return 0;
    }

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

        int userId = UserHandle.USER_ALL;
        String namespace = null;
        int stopReason = JobParameters.STOP_REASON_USER;
        int internalStopReason = JobParameters.INTERNAL_STOP_REASON_UNKNOWN;

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

                case "-n":
                case "--namespace":
                    namespace = getNextArgRequired();
                    break;

                case "-s":
                case "--stop-reason":
                    stopReason = Integer.parseInt(getNextArgRequired());
                    break;

                case "-i":
                case "--internal-stop-reason":
                    internalStopReason = Integer.parseInt(getNextArgRequired());
                    break;

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

        if (userId == UserHandle.USER_CURRENT) {
            userId = ActivityManager.getCurrentUser();
        }

        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.executeStopCommand(pw, pkgName, userId, namespace,
                    jobIdStr != null, jobId, stopReason, internalStopReason);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    private int triggerDockState(PrintWriter pw) throws Exception {
        checkPermission("trigger wireless charging dock state");

@@ -589,9 +647,28 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        pw.println("         if both are given.");
        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("  stop [-u | --user USER_ID] [-n | --namespace NAMESPACE]"
                + " [-s | --stop-reason STOP_REASON] [-i | --internal-stop-reason STOP_REASON]"
                + " [PACKAGE] [JOB_ID]");
        pw.println("    Trigger immediate stop of currently executing jobs using the specified");
        pw.println("    stop reasons.");
        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("      -n or --namespace: specify the namespace this job sits in; the default");
        pw.println("         is null (no namespace).");
        pw.println("      -s or --stop-reason: specify the stop reason given to the job.");
        pw.println("         Valid values are those that can be returned from");
        pw.println("         JobParameters.getStopReason().");
        pw.println("          The default value is STOP_REASON_USER.");
        pw.println("      -i or --internal-stop-reason: specify the internal stop reason.");
        pw.println("         JobScheduler will use for internal processing.");
        pw.println("         Valid values are those that can be returned from");
        pw.println("         JobParameters.getInternalStopReason().");
        pw.println("          The default value is INTERNAL_STOP_REASON_UNDEFINED.");
        pw.println("  timeout [-u | --user USER_ID] [-n | --namespace NAMESPACE]"
                + " [PACKAGE] [JOB_ID]");
        pw.println("    Trigger immediate timeout of currently executing jobs, as if their.");
        pw.println("    Trigger immediate timeout of currently executing jobs, as if their");
        pw.println("    execution timeout had expired.");
        pw.println("    Options:");
        pw.println("      -u or --user: specify which user's job is to be run; the default is");
+4 −5
Original line number Diff line number Diff line
@@ -591,17 +591,16 @@ public final class JobServiceContext implements ServiceConnection {
    }

    @GuardedBy("mLock")
    boolean timeoutIfExecutingLocked(String pkgName, int userId, @Nullable String namespace,
            boolean matchJobId, int jobId, String reason) {
    boolean stopIfExecutingLocked(String pkgName, int userId, @Nullable String namespace,
            boolean matchJobId, int jobId, int stopReason, int internalStopReason) {
        final JobStatus executing = getRunningJobLocked();
        if (executing != null && (userId == UserHandle.USER_ALL || userId == executing.getUserId())
                && (pkgName == null || pkgName.equals(executing.getSourcePackageName()))
                && Objects.equals(namespace, executing.getNamespace())
                && (!matchJobId || jobId == executing.getJobId())) {
            if (mVerb == VERB_EXECUTING) {
                mParams.setStopReason(JobParameters.STOP_REASON_TIMEOUT,
                        JobParameters.INTERNAL_STOP_REASON_TIMEOUT, reason);
                sendStopMessageLocked("force timeout from shell");
                mParams.setStopReason(stopReason, internalStopReason, "stop from shell");
                sendStopMessageLocked("stop from shell");
                return true;
            }
        }