Merge "Move JobServiceContext handling to the concurrency manager." into tm-dev

This commit is contained in:
Kweku Adams
2022-03-16 19:16:16 +00:00
committed by Android (Google) Code Review
3 changed files with 181 additions and 176 deletions

View File

@@ -17,6 +17,7 @@
package com.android.server.job; package com.android.server.job;
import static com.android.server.job.JobSchedulerService.MAX_JOB_CONTEXTS_COUNT; import static com.android.server.job.JobSchedulerService.MAX_JOB_CONTEXTS_COUNT;
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
import android.annotation.IntDef; import android.annotation.IntDef;
@@ -32,9 +33,11 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.os.BatteryStats;
import android.os.Handler; import android.os.Handler;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.util.ArraySet; import android.util.ArraySet;
@@ -51,19 +54,24 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.app.procstats.ProcessStats; import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.util.StatLogger; import com.android.internal.util.StatLogger;
import com.android.server.JobSchedulerBackgroundThread; import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.job.controllers.JobStatus; import com.android.server.job.controllers.JobStatus;
import com.android.server.job.controllers.StateController; import com.android.server.job.controllers.StateController;
import com.android.server.job.restrictions.JobRestriction;
import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerInternal;
import java.io.PrintWriter;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate;
/** /**
* This class decides, given the various configuration and the system status, which jobs can start * This class decides, given the various configuration and the system status, which jobs can start
@@ -278,6 +286,11 @@ class JobConcurrencyManager {
String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT]; String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT];
/**
* Set of JobServiceContexts that we use to run jobs.
*/
final List<JobServiceContext> mActiveServices = new ArrayList<>();
private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>(); private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>();
private final WorkCountTracker mWorkCountTracker = new WorkCountTracker(); private final WorkCountTracker mWorkCountTracker = new WorkCountTracker();
@@ -358,6 +371,20 @@ class JobConcurrencyManager {
onInteractiveStateChanged(mPowerManager.isInteractive()); onInteractiveStateChanged(mPowerManager.isInteractive());
} }
/**
* Called when the boot phase reaches
* {@link com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START}.
*/
void onThirdPartyAppsCanStart() {
final IBatteryStats batteryStats = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
mActiveServices.add(
new JobServiceContext(mService, this, batteryStats,
mService.mJobPackageTracker, mContext.getMainLooper()));
}
}
@GuardedBy("mLock") @GuardedBy("mLock")
void onAppRemovedLocked(String pkgName, int uid) { void onAppRemovedLocked(String pkgName, int uid) {
final PackageStats packageStats = mActivePkgStats.get(UserHandle.getUserId(uid), pkgName); final PackageStats packageStats = mActivePkgStats.get(UserHandle.getUserId(uid), pkgName);
@@ -390,6 +417,7 @@ class JobConcurrencyManager {
case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
if (mPowerManager != null && mPowerManager.isDeviceIdleMode()) { if (mPowerManager != null && mPowerManager.isDeviceIdleMode()) {
synchronized (mLock) { synchronized (mLock) {
stopUnexemptedJobsForDoze();
stopLongRunningJobsLocked("deep doze"); stopLongRunningJobsLocked("deep doze");
} }
} }
@@ -470,6 +498,11 @@ class JobConcurrencyManager {
} }
} }
@GuardedBy("mLock")
ArraySet<JobStatus> getRunningJobsLocked() {
return mRunningJobs;
}
@GuardedBy("mLock") @GuardedBy("mLock")
boolean isJobRunningLocked(JobStatus job) { boolean isJobRunningLocked(JobStatus job) {
return mRunningJobs.contains(job); return mRunningJobs.contains(job);
@@ -546,7 +579,7 @@ class JobConcurrencyManager {
} }
final List<JobStatus> pendingJobs = mService.mPendingJobs; final List<JobStatus> pendingJobs = mService.mPendingJobs;
final List<JobServiceContext> activeServices = mService.mActiveServices; final List<JobServiceContext> activeServices = mActiveServices;
// To avoid GC churn, we recycle the arrays. // To avoid GC churn, we recycle the arrays.
JobStatus[] contextIdToJobMap = mRecycledAssignContextIdToJobMap; JobStatus[] contextIdToJobMap = mRecycledAssignContextIdToJobMap;
@@ -718,10 +751,45 @@ class JobConcurrencyManager {
noteConcurrency(); noteConcurrency();
} }
@GuardedBy("mLock")
boolean stopJobOnServiceContextLocked(JobStatus job,
@JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
if (!mRunningJobs.contains(job)) {
return false;
}
for (int i = 0; i < mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus executing = jsc.getRunningJobLocked();
if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
jsc.cancelExecutingJobLocked(reason, internalReasonCode, debugReason);
return true;
}
}
Slog.wtf(TAG, "Couldn't find running job on a context");
mRunningJobs.remove(job);
return false;
}
@GuardedBy("mLock")
private void stopUnexemptedJobsForDoze() {
// When becoming idle, make sure no jobs are actively running,
// except those using the idle exemption flag.
for (int i = 0; i < mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus executing = jsc.getRunningJobLocked();
if (executing != null && !executing.canRunInDoze()) {
jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
JobParameters.INTERNAL_STOP_REASON_DEVICE_IDLE,
"cancelled due to doze");
}
}
}
@GuardedBy("mLock") @GuardedBy("mLock")
private void stopLongRunningJobsLocked(@NonNull String debugReason) { private void stopLongRunningJobsLocked(@NonNull String debugReason) {
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; ++i) { for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; ++i) {
final JobServiceContext jsc = mService.mActiveServices.get(i); final JobServiceContext jsc = mActiveServices.get(i);
final JobStatus jobStatus = jsc.getRunningJobLocked(); final JobStatus jobStatus = jsc.getRunningJobLocked();
if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime()) { if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime()) {
@@ -731,6 +799,41 @@ class JobConcurrencyManager {
} }
} }
@GuardedBy("mLock")
void stopNonReadyActiveJobsLocked() {
for (int i = 0; i < mActiveServices.size(); i++) {
JobServiceContext serviceContext = mActiveServices.get(i);
final JobStatus running = serviceContext.getRunningJobLocked();
if (running == null) {
continue;
}
if (!running.isReady()) {
if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
&& running.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) {
serviceContext.cancelExecutingJobLocked(
running.getStopReason(),
JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET,
"cancelled due to restricted bucket");
} else {
serviceContext.cancelExecutingJobLocked(
running.getStopReason(),
JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
"cancelled due to unsatisfied constraints");
}
} else {
final JobRestriction restriction = mService.checkIfRestricted(running);
if (restriction != null) {
final int internalReasonCode = restriction.getInternalReason();
serviceContext.cancelExecutingJobLocked(restriction.getReason(),
internalReasonCode,
"restricted due to "
+ JobParameters.getInternalReasonCodeDescription(
internalReasonCode));
}
}
}
}
private void noteConcurrency() { private void noteConcurrency() {
mService.mJobPackageTracker.noteConcurrency(mRunningJobs.size(), mService.mJobPackageTracker.noteConcurrency(mRunningJobs.size(),
// TODO: log per type instead of only TOP // TODO: log per type instead of only TOP
@@ -1077,6 +1180,24 @@ class JobConcurrencyManager {
return null; return null;
} }
@GuardedBy("mLock")
boolean executeTimeoutCommandLocked(PrintWriter pw, String pkgName, int userId,
boolean hasJobId, int jobId) {
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, hasJobId, jobId, "shell")) {
foundSome = true;
pw.print("Timing out: ");
js.printUniqueId(pw);
pw.print(" ");
pw.println(js.getServiceComponent().flattenToShortString());
}
}
return foundSome;
}
@GuardedBy("mLock") @GuardedBy("mLock")
private String printPendingQueueLocked() { private String printPendingQueueLocked() {
StringBuilder s = new StringBuilder("Pending queue: "); StringBuilder s = new StringBuilder("Pending queue: ");
@@ -1200,6 +1321,43 @@ class JobConcurrencyManager {
} }
} }
@GuardedBy("mLock")
void dumpActiveJobsLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate,
long nowElapsed, long nowUptime) {
pw.println("Active jobs:");
pw.increaseIndent();
for (int i = 0; i < mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus job = jsc.getRunningJobLocked();
if (job != null && !predicate.test(job)) {
continue;
}
pw.print("Slot #"); pw.print(i); pw.print(": ");
jsc.dumpLocked(pw, nowElapsed);
if (job != null) {
pw.increaseIndent();
pw.increaseIndent();
job.dump(pw, false, nowElapsed);
pw.decreaseIndent();
pw.print("Evaluated bias: ");
pw.println(JobInfo.getBiasString(job.lastEvaluatedBias));
pw.print("Active at ");
TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
pw.print(", pending for ");
TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
pw.decreaseIndent();
pw.println();
}
}
pw.decreaseIndent();
}
public void dumpProtoLocked(ProtoOutputStream proto, long tag, long now, long nowRealtime) { public void dumpProtoLocked(ProtoOutputStream proto, long tag, long now, long nowRealtime) {
final long token = proto.start(tag); final long token = proto.start(tag);

View File

@@ -57,7 +57,6 @@ import android.content.pm.ServiceInfo;
import android.net.Uri; import android.net.Uri;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.os.BatteryManagerInternal; import android.os.BatteryManagerInternal;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal; import android.os.BatteryStatsInternal;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
@@ -67,7 +66,6 @@ import android.os.Message;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Process; import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.WorkSource; import android.os.WorkSource;
@@ -90,7 +88,6 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.SomeArgs; import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils;
@@ -100,7 +97,6 @@ import com.android.server.AppStateTrackerImpl;
import com.android.server.DeviceIdleInternal; import com.android.server.DeviceIdleInternal;
import com.android.server.JobSchedulerBackgroundThread; import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob; import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
import com.android.server.job.controllers.BackgroundJobsController; import com.android.server.job.controllers.BackgroundJobsController;
import com.android.server.job.controllers.BatteryController; import com.android.server.job.controllers.BatteryController;
@@ -243,12 +239,6 @@ public class JobSchedulerService extends com.android.server.SystemService
static final int MSG_CHECK_CHANGED_JOB_LIST = 8; static final int MSG_CHECK_CHANGED_JOB_LIST = 8;
static final int MSG_CHECK_MEDIA_EXEMPTION = 9; static final int MSG_CHECK_MEDIA_EXEMPTION = 9;
/**
* Track Services that have currently active or pending jobs. The index is provided by
* {@link JobStatus#getServiceToken()}
*/
final List<JobServiceContext> mActiveServices = new ArrayList<>();
/** List of controllers that will notify this service of updates to jobs. */ /** List of controllers that will notify this service of updates to jobs. */
final List<StateController> mControllers; final List<StateController> mControllers;
/** /**
@@ -307,7 +297,6 @@ public class JobSchedulerService extends com.android.server.SystemService
PackageManagerInternal mLocalPM; PackageManagerInternal mLocalPM;
ActivityManagerInternal mActivityManagerInternal; ActivityManagerInternal mActivityManagerInternal;
IBatteryStats mBatteryStats;
DeviceIdleInternal mLocalDeviceIdleController; DeviceIdleInternal mLocalDeviceIdleController;
@VisibleForTesting @VisibleForTesting
AppStateTrackerImpl mAppStateTracker; AppStateTrackerImpl mAppStateTracker;
@@ -1578,7 +1567,8 @@ public class JobSchedulerService extends com.android.server.SystemService
mJobPackageTracker.noteNonpending(cancelled); mJobPackageTracker.noteNonpending(cancelled);
} }
// Cancel if running. // Cancel if running.
stopJobOnServiceContextLocked(cancelled, reason, internalReasonCode, debugReason); mConcurrencyManager.stopJobOnServiceContextLocked(
cancelled, reason, internalReasonCode, debugReason);
// If this is a replacement, bring in the new version of the job // If this is a replacement, bring in the new version of the job
if (incomingJob != null) { if (incomingJob != null) {
if (DEBUG) Slog.i(TAG, "Tracking replacement job " + incomingJob.toShortString()); if (DEBUG) Slog.i(TAG, "Tracking replacement job " + incomingJob.toShortString());
@@ -1627,19 +1617,7 @@ public class JobSchedulerService extends com.android.server.SystemService
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Doze state changed: " + deviceIdle); Slog.d(TAG, "Doze state changed: " + deviceIdle);
} }
if (deviceIdle) { if (!deviceIdle) {
// When becoming idle, make sure no jobs are actively running,
// except those using the idle exemption flag.
for (int i=0; i<mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus executing = jsc.getRunningJobLocked();
if (executing != null && !executing.canRunInDoze()) {
jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
JobParameters.INTERNAL_STOP_REASON_DEVICE_IDLE,
"cancelled due to doze");
}
}
} else {
// When coming out of idle, allow thing to start back up. // When coming out of idle, allow thing to start back up.
if (mReadyToRock) { if (mReadyToRock) {
if (mLocalDeviceIdleController != null) { if (mLocalDeviceIdleController != null) {
@@ -1682,10 +1660,10 @@ public class JobSchedulerService extends com.android.server.SystemService
// active is true if pending queue contains jobs OR some job is running. // active is true if pending queue contains jobs OR some job is running.
boolean active = mPendingJobs.size() > 0; boolean active = mPendingJobs.size() > 0;
if (mPendingJobs.size() <= 0) { if (mPendingJobs.size() <= 0) {
for (int i=0; i<mActiveServices.size(); i++) { final ArraySet<JobStatus> runningJobs = mConcurrencyManager.getRunningJobsLocked();
final JobServiceContext jsc = mActiveServices.get(i); for (int i = runningJobs.size() - 1; i >= 0; --i) {
final JobStatus job = jsc.getRunningJobLocked(); final JobStatus job = runningJobs.valueAt(i);
if (job != null && !job.canRunInDoze()) { if (!job.canRunInDoze()) {
// We will report active if we have a job running and it does not have an // We will report active if we have a job running and it does not have an
// exception that allows it to run in Doze. // exception that allows it to run in Doze.
active = true; active = true;
@@ -1895,16 +1873,9 @@ public class JobSchedulerService extends com.android.server.SystemService
synchronized (mLock) { synchronized (mLock) {
// Let's go! // Let's go!
mReadyToRock = true; mReadyToRock = true;
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
mLocalDeviceIdleController = mLocalDeviceIdleController =
LocalServices.getService(DeviceIdleInternal.class); LocalServices.getService(DeviceIdleInternal.class);
// Create the "runners". mConcurrencyManager.onThirdPartyAppsCanStart();
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
mActiveServices.add(
new JobServiceContext(this, mConcurrencyManager, mBatteryStats,
mJobPackageTracker, getContext().getMainLooper()));
}
// Attach jobs to their controllers. // Attach jobs to their controllers.
mJobs.forEachJob((job) -> { mJobs.forEachJob((job) -> {
for (int controller = 0; controller < mControllers.size(); controller++) { for (int controller = 0; controller < mControllers.size(); controller++) {
@@ -1961,19 +1932,6 @@ public class JobSchedulerService extends com.android.server.SystemService
return removed; return removed;
} }
private boolean stopJobOnServiceContextLocked(JobStatus job,
@JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
for (int i = 0; i < mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus executing = jsc.getRunningJobLocked();
if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
jsc.cancelExecutingJobLocked(reason, internalReasonCode, debugReason);
return true;
}
}
return false;
}
/** Return {@code true} if the specified job is currently executing. */ /** Return {@code true} if the specified job is currently executing. */
@GuardedBy("mLock") @GuardedBy("mLock")
public boolean isCurrentlyRunningLocked(JobStatus job) { public boolean isCurrentlyRunningLocked(JobStatus job) {
@@ -2383,7 +2341,8 @@ public class JobSchedulerService extends com.android.server.SystemService
* - if passes all the restrictions or has {@link JobInfo#BIAS_FOREGROUND_SERVICE} bias * - if passes all the restrictions or has {@link JobInfo#BIAS_FOREGROUND_SERVICE} bias
* or higher. * or higher.
*/ */
private JobRestriction checkIfRestricted(JobStatus job) { @GuardedBy("mLock")
JobRestriction checkIfRestricted(JobStatus job) {
if (evaluateJobBiasLocked(job) >= JobInfo.BIAS_FOREGROUND_SERVICE) { if (evaluateJobBiasLocked(job) >= JobInfo.BIAS_FOREGROUND_SERVICE) {
// Jobs with BIAS_FOREGROUND_SERVICE or higher should not be restricted // Jobs with BIAS_FOREGROUND_SERVICE or higher should not be restricted
return null; return null;
@@ -2397,38 +2356,9 @@ public class JobSchedulerService extends com.android.server.SystemService
return null; return null;
} }
@GuardedBy("mLock")
private void stopNonReadyActiveJobsLocked() { private void stopNonReadyActiveJobsLocked() {
for (int i=0; i<mActiveServices.size(); i++) { mConcurrencyManager.stopNonReadyActiveJobsLocked();
JobServiceContext serviceContext = mActiveServices.get(i);
final JobStatus running = serviceContext.getRunningJobLocked();
if (running == null) {
continue;
}
if (!running.isReady()) {
if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
&& running.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) {
serviceContext.cancelExecutingJobLocked(
running.getStopReason(),
JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET,
"cancelled due to restricted bucket");
} else {
serviceContext.cancelExecutingJobLocked(
running.getStopReason(),
JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
"cancelled due to unsatisfied constraints");
}
} else {
final JobRestriction restriction = checkIfRestricted(running);
if (restriction != null) {
final int internalReasonCode = restriction.getInternalReason();
serviceContext.cancelExecutingJobLocked(restriction.getReason(),
internalReasonCode,
"restricted due to "
+ JobParameters.getInternalReasonCodeDescription(
internalReasonCode));
}
}
}
} }
/** /**
@@ -2598,7 +2528,7 @@ public class JobSchedulerService extends com.android.server.SystemService
debugReason = "couldn't figure out why the job should stop running"; debugReason = "couldn't figure out why the job should stop running";
} }
} }
stopJobOnServiceContextLocked(job, job.getStopReason(), mConcurrencyManager.stopJobOnServiceContextLocked(job, job.getStopReason(),
internalStopReason, debugReason); internalStopReason, debugReason);
} else if (mPendingJobs.remove(job)) { } else if (mPendingJobs.remove(job)) {
noteJobNonPending(job); noteJobNonPending(job);
@@ -3516,9 +3446,11 @@ public class JobSchedulerService extends com.android.server.SystemService
final ArrayList<JobInfo> runningJobs; final ArrayList<JobInfo> runningJobs;
synchronized (mLock) { synchronized (mLock) {
runningJobs = new ArrayList<>(mActiveServices.size()); final ArraySet<JobStatus> runningJobStatuses =
for (JobServiceContext jsc : mActiveServices) { mConcurrencyManager.getRunningJobsLocked();
final JobStatus job = jsc.getRunningJobLocked(); runningJobs = new ArrayList<>(runningJobStatuses.size());
for (int i = runningJobStatuses.size() - 1; i >= 0; --i) {
final JobStatus job = runningJobStatuses.valueAt(i);
if (job != null) { if (job != null) {
runningJobs.add(job.getJob()); runningJobs.add(job.getJob());
} }
@@ -3599,18 +3531,8 @@ public class JobSchedulerService extends com.android.server.SystemService
} }
synchronized (mLock) { synchronized (mLock) {
boolean foundSome = false; final boolean foundSome = mConcurrencyManager.executeTimeoutCommandLocked(pw,
for (int i = 0; i < mActiveServices.size(); i++) { pkgName, userId, hasJobId, jobId);
final JobServiceContext jc = mActiveServices.get(i);
final JobStatus js = jc.getRunningJobLocked();
if (jc.timeoutIfExecutingLocked(pkgName, userId, hasJobId, jobId, "shell")) {
foundSome = true;
pw.print("Timing out: ");
js.printUniqueId(pw);
pw.print(" ");
pw.println(js.getServiceComponent().flattenToShortString());
}
}
if (!foundSome) { if (!foundSome) {
pw.println("No matching executing jobs found."); pw.println("No matching executing jobs found.");
} }
@@ -4037,38 +3959,7 @@ public class JobSchedulerService extends com.android.server.SystemService
pw.decreaseIndent(); pw.decreaseIndent();
pw.println(); pw.println();
pw.println("Active jobs:"); mConcurrencyManager.dumpActiveJobsLocked(pw, predicate, nowElapsed, nowUptime);
pw.increaseIndent();
for (int i=0; i<mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus job = jsc.getRunningJobLocked();
if (job != null && !predicate.test(job)) {
continue;
}
pw.print("Slot #"); pw.print(i); pw.print(": ");
jsc.dumpLocked(pw, nowElapsed);
if (job != null) {
pw.increaseIndent();
pw.increaseIndent();
job.dump(pw, false, nowElapsed);
pw.decreaseIndent();
pw.print("Evaluated bias: ");
pw.println(JobInfo.getBiasString(job.lastEvaluatedBias));
pw.print("Active at ");
TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
pw.print(", pending for ");
TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
pw.decreaseIndent();
pw.println();
}
}
pw.decreaseIndent();
pw.println(); pw.println();
boolean recentPrinted = false; boolean recentPrinted = false;
@@ -4228,45 +4119,6 @@ public class JobSchedulerService extends com.android.server.SystemService
proto.end(pjToken); proto.end(pjToken);
} }
for (JobServiceContext jsc : mActiveServices) {
final long ajToken = proto.start(JobSchedulerServiceDumpProto.ACTIVE_JOBS);
final JobStatus job = jsc.getRunningJobLocked();
if (job == null) {
final long ijToken = proto.start(ActiveJob.INACTIVE);
proto.write(ActiveJob.InactiveJob.TIME_SINCE_STOPPED_MS,
nowElapsed - jsc.mStoppedTime);
if (jsc.mStoppedReason != null) {
proto.write(ActiveJob.InactiveJob.STOPPED_REASON,
jsc.mStoppedReason);
}
proto.end(ijToken);
} else {
final long rjToken = proto.start(ActiveJob.RUNNING);
job.writeToShortProto(proto, ActiveJob.RunningJob.INFO);
proto.write(ActiveJob.RunningJob.RUNNING_DURATION_MS,
nowElapsed - jsc.getExecutionStartTimeElapsed());
proto.write(ActiveJob.RunningJob.TIME_UNTIL_TIMEOUT_MS,
jsc.getTimeoutElapsed() - nowElapsed);
job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed);
proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY,
evaluateJobBiasLocked(job));
proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS,
nowUptime - job.madeActive);
proto.write(ActiveJob.RunningJob.PENDING_DURATION_MS,
job.madeActive - job.madePending);
proto.end(rjToken);
}
proto.end(ajToken);
}
if (filterUid == -1) { if (filterUid == -1) {
proto.write(JobSchedulerServiceDumpProto.IS_READY_TO_ROCK, mReadyToRock); proto.write(JobSchedulerServiceDumpProto.IS_READY_TO_ROCK, mReadyToRock);
proto.write(JobSchedulerServiceDumpProto.REPORTED_ACTIVE, mReportedActive); proto.write(JobSchedulerServiceDumpProto.REPORTED_ACTIVE, mReportedActive);

View File

@@ -441,11 +441,6 @@ public final class JobStatus {
/** The reason a job most recently went from ready to not ready. */ /** The reason a job most recently went from ready to not ready. */
private int mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED; private int mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
/** Provide a handle to the service that this job will be run on. */
public int getServiceToken() {
return callingUid;
}
/** /**
* Core constructor for JobStatus instances. All other ctors funnel down to this one. * Core constructor for JobStatus instances. All other ctors funnel down to this one.
* *