Merge "Enable testing specific stop reasons."

This commit is contained in:
Kweku Adams
2023-02-14 20:00:57 +00:00
committed by Android (Google) Code Review
4 changed files with 98 additions and 17 deletions

View File

@@ -1863,15 +1863,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());

View File

@@ -4326,15 +4326,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.");
}

View File

@@ -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");

View File

@@ -608,17 +608,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;
}
}