From 5d346051bd6da471203fed94357f58491822a4eb Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 8 Mar 2016 12:56:08 -0800 Subject: [PATCH] Add 'shell cmd jobscheduler run ....' to run a job immediately During development one needs to be able to test changes conveniently, and when the jobs would normally have hard-to-simulate constraints like idle-time or long minimum latencies, testing becomes difficult. This CL introduces the ability to run a specific job immediately from the adb shell. Without the "-f"/"--force" flag, the job still won't run if it has unmet "functional" requirements such as being connected via an unmetered network. With that flag, the job will be run immediately regardless of its declared constraints (so it may not work properly due to lack of network connectivity or similar). Bug 27501783 Change-Id: Icc046f53f8846690c8234e60066e85c283d325ce --- .../server/job/JobSchedulerService.java | 43 ++++- .../server/job/JobSchedulerShellCommand.java | 154 ++++++++++++++++++ .../server/job/controllers/JobStatus.java | 27 ++- 3 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 services/core/java/com/android/server/job/JobSchedulerShellCommand.java diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index fba7e7d76ac32..d2b77aab70b89 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -47,14 +47,15 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; +import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.util.Slog; import android.util.SparseArray; - import android.util.SparseIntArray; import android.util.TimeUtils; + import com.android.internal.app.IBatteryStats; import com.android.internal.util.ArrayUtils; import com.android.internal.app.ProcessStats; @@ -1337,8 +1338,48 @@ public final class JobSchedulerService extends com.android.server.SystemService Binder.restoreCallingIdentity(identityToken); } } + + @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, + String[] args, ResultReceiver resultReceiver) throws RemoteException { + (new JobSchedulerShellCommand(JobSchedulerService.this)).exec( + this, in, out, err, args, resultReceiver); + } }; + // Shell command infrastructure: run the given job immediately + int executeRunCommand(String pkgName, int userId, int jobId, boolean force) { + if (DEBUG) { + Slog.v(TAG, "executeRunCommand(): " + pkgName + "/" + userId + + " " + jobId + " f=" + force); + } + + try { + final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0, userId); + if (uid < 0) { + return JobSchedulerShellCommand.CMD_ERR_NO_PACKAGE; + } + + synchronized (mLock) { + final JobStatus js = mJobs.getJobByUidAndJobId(uid, jobId); + if (js == null) { + return JobSchedulerShellCommand.CMD_ERR_NO_JOB; + } + + js.overrideState = (force) ? JobStatus.OVERRIDE_FULL : JobStatus.OVERRIDE_SOFT; + if (!js.isConstraintsSatisfied()) { + js.overrideState = 0; + return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; + } + + mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget(); + } + } catch (RemoteException e) { + // can't happen + } + return 0; + } + private String printContextIdToJobMap(JobStatus[] map, String initial) { StringBuilder s = new StringBuilder(initial + ": "); for (int i=0; i