use of com.android.server.job.controllers.JobStatus in project android_frameworks_base by DirtyUnicorns.
the class JobSchedulerService method assignJobsToContextsLocked.
/**
* Takes jobs from pending queue and runs them on available contexts.
* If no contexts are available, preempts lower priority jobs to
* run higher priority ones.
* Lock on mJobs before calling this function.
*/
private void assignJobsToContextsLocked() {
if (DEBUG) {
Slog.d(TAG, printPendingQueue());
}
int memLevel;
try {
memLevel = ActivityManagerNative.getDefault().getMemoryTrimLevel();
} catch (RemoteException e) {
memLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
}
switch(memLevel) {
case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
mMaxActiveJobs = mConstants.BG_MODERATE_JOB_COUNT;
break;
case ProcessStats.ADJ_MEM_FACTOR_LOW:
mMaxActiveJobs = mConstants.BG_LOW_JOB_COUNT;
break;
case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
mMaxActiveJobs = mConstants.BG_CRITICAL_JOB_COUNT;
break;
default:
mMaxActiveJobs = mConstants.BG_NORMAL_JOB_COUNT;
break;
}
JobStatus[] contextIdToJobMap = mTmpAssignContextIdToJobMap;
boolean[] act = mTmpAssignAct;
int[] preferredUidForContext = mTmpAssignPreferredUidForContext;
int numActive = 0;
int numForeground = 0;
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
final JobServiceContext js = mActiveServices.get(i);
final JobStatus status = js.getRunningJob();
if ((contextIdToJobMap[i] = status) != null) {
numActive++;
if (status.lastEvaluatedPriority >= JobInfo.PRIORITY_TOP_APP) {
numForeground++;
}
}
act[i] = false;
preferredUidForContext[i] = js.getPreferredUid();
}
if (DEBUG) {
Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs initial"));
}
for (int i = 0; i < mPendingJobs.size(); i++) {
JobStatus nextPending = mPendingJobs.get(i);
// If job is already running, go to next job.
int jobRunningContext = findJobContextIdFromMap(nextPending, contextIdToJobMap);
if (jobRunningContext != -1) {
continue;
}
final int priority = evaluateJobPriorityLocked(nextPending);
nextPending.lastEvaluatedPriority = priority;
// Find a context for nextPending. The context should be available OR
// it should have lowest priority among all running jobs
// (sharing the same Uid as nextPending)
int minPriority = Integer.MAX_VALUE;
int minPriorityContextId = -1;
for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) {
JobStatus job = contextIdToJobMap[j];
int preferredUid = preferredUidForContext[j];
if (job == null) {
if ((numActive < mMaxActiveJobs || (priority >= JobInfo.PRIORITY_TOP_APP && numForeground < mConstants.FG_JOB_COUNT)) && (preferredUid == nextPending.getUid() || preferredUid == JobServiceContext.NO_PREFERRED_UID)) {
// This slot is free, and we haven't yet hit the limit on
// concurrent jobs... we can just throw the job in to here.
minPriorityContextId = j;
break;
}
// concurrent jobs.
continue;
}
if (job.getUid() != nextPending.getUid()) {
continue;
}
if (evaluateJobPriorityLocked(job) >= nextPending.lastEvaluatedPriority) {
continue;
}
if (minPriority > nextPending.lastEvaluatedPriority) {
minPriority = nextPending.lastEvaluatedPriority;
minPriorityContextId = j;
}
}
if (minPriorityContextId != -1) {
contextIdToJobMap[minPriorityContextId] = nextPending;
act[minPriorityContextId] = true;
numActive++;
if (priority >= JobInfo.PRIORITY_TOP_APP) {
numForeground++;
}
}
}
if (DEBUG) {
Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs final"));
}
mJobPackageTracker.noteConcurrency(numActive, numForeground);
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
boolean preservePreferredUid = false;
if (act[i]) {
JobStatus js = mActiveServices.get(i).getRunningJob();
if (js != null) {
if (DEBUG) {
Slog.d(TAG, "preempting job: " + mActiveServices.get(i).getRunningJob());
}
// preferredUid will be set to uid of currently running job.
mActiveServices.get(i).preemptExecutingJob();
preservePreferredUid = true;
} else {
final JobStatus pendingJob = contextIdToJobMap[i];
if (DEBUG) {
Slog.d(TAG, "About to run job on context " + String.valueOf(i) + ", job: " + pendingJob);
}
for (int ic = 0; ic < mControllers.size(); ic++) {
mControllers.get(ic).prepareForExecutionLocked(pendingJob);
}
if (!mActiveServices.get(i).executeRunnableJob(pendingJob)) {
Slog.d(TAG, "Error executing " + pendingJob);
}
if (mPendingJobs.remove(pendingJob)) {
mJobPackageTracker.noteNonpending(pendingJob);
}
}
}
if (!preservePreferredUid) {
mActiveServices.get(i).clearPreferredUid();
}
}
}
use of com.android.server.job.controllers.JobStatus in project android_frameworks_base by DirtyUnicorns.
the class JobSchedulerService method getPendingJobs.
public List<JobInfo> getPendingJobs(int uid) {
synchronized (mLock) {
List<JobStatus> jobs = mJobs.getJobsByUid(uid);
ArrayList<JobInfo> outList = new ArrayList<JobInfo>(jobs.size());
for (int i = jobs.size() - 1; i >= 0; i--) {
JobStatus job = jobs.get(i);
outList.add(job.getJob());
}
return outList;
}
}
use of com.android.server.job.controllers.JobStatus in project android_frameworks_base by DirtyUnicorns.
the class JobSchedulerService method reportActive.
void reportActive() {
// active is true if pending queue contains jobs OR some job is running.
boolean active = mPendingJobs.size() > 0;
if (mPendingJobs.size() <= 0) {
for (int i = 0; i < mActiveServices.size(); i++) {
final JobServiceContext jsc = mActiveServices.get(i);
final JobStatus job = jsc.getRunningJob();
if (job != null && (job.getJob().getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) == 0 && !job.dozeWhitelisted) {
// We will report active if we have a job running and it is not an exception
// due to being in the foreground or whitelisted.
active = true;
break;
}
}
}
if (mReportedActive != active) {
mReportedActive = active;
if (mLocalDeviceIdleController != null) {
mLocalDeviceIdleController.setJobsActive(active);
}
}
}
use of com.android.server.job.controllers.JobStatus in project android_frameworks_base by DirtyUnicorns.
the class JobSchedulerService method cancelJobsForUser.
void cancelJobsForUser(int userHandle) {
List<JobStatus> jobsForUser;
synchronized (mLock) {
jobsForUser = mJobs.getJobsByUser(userHandle);
}
for (int i = 0; i < jobsForUser.size(); i++) {
JobStatus toRemove = jobsForUser.get(i);
cancelJobImpl(toRemove, null);
}
}
use of com.android.server.job.controllers.JobStatus in project android_frameworks_base by DirtyUnicorns.
the class JobSchedulerService method executeRunCommand.
// 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;
}
Aggregations