blob: 51be38be990dc9ab7077a32e1e45585bc8f8624c [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.job.controllers;
import static com.android.server.job.JobSchedulerService.DEBUG;
import android.content.Context;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobSchedulerService.Constants;
import com.android.server.job.StateChangedListener;
import java.util.function.Predicate;
/**
* Incorporates shared controller logic between the various controllers of the JobManager.
* These are solely responsible for tracking a list of jobs, and notifying the JM when these
* are ready to run, or whether they must be stopped.
*/
public abstract class StateController {
private static final String TAG = "JobScheduler.SC";
protected final JobSchedulerService mService;
protected final StateChangedListener mStateChangedListener;
protected final Context mContext;
protected final Object mLock;
protected final Constants mConstants;
StateController(JobSchedulerService service) {
mService = service;
mStateChangedListener = service;
mContext = service.getTestableContext();
mLock = service.getLock();
mConstants = service.getConstants();
}
/**
* Called when the system boot phase has reached
* {@link com.android.server.SystemService#PHASE_SYSTEM_SERVICES_READY}.
*/
public void onSystemServicesReady() {
}
/**
* Implement the logic here to decide whether a job should be tracked by this controller.
* This logic is put here so the JobManager can be completely agnostic of Controller logic.
* Also called when updating a task, so implementing controllers have to be aware of
* preexisting tasks.
*/
public abstract void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob);
/**
* Optionally implement logic here to prepare the job to be executed.
*/
public void prepareForExecutionLocked(JobStatus jobStatus) {
}
/**
* Remove task - this will happen if the task is cancelled, completed, etc.
*/
public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
boolean forUpdate);
/**
* Called when a new job is being created to reschedule an old failed job.
*/
public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) {
}
/**
* Called when the JobScheduler.Constants are updated.
*/
public void onConstantsUpdatedLocked() {
}
/** Called when a package is uninstalled from the device (not for an update). */
public void onAppRemovedLocked(String packageName, int uid) {
}
/** Called when a user is removed from the device. */
public void onUserRemovedLocked(int userId) {
}
/**
* Called when JobSchedulerService has determined that the job is not ready to be run. The
* Controller can evaluate if it can or should do something to promote this job's readiness.
*/
public void evaluateStateLocked(JobStatus jobStatus) {
}
/**
* Called when something with the UID has changed. The controller should re-evaluate any
* internal state tracking dependent on this UID.
*/
public void reevaluateStateLocked(int uid) {
}
protected boolean wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint) {
// This is very cheap to check (just a few conditions on data in JobStatus).
final boolean jobWouldBeReady = jobStatus.wouldBeReadyWithConstraint(constraint);
if (DEBUG) {
Slog.v(TAG, "wouldBeReadyWithConstraintLocked: " + jobStatus.toShortString()
+ " constraint=" + constraint
+ " readyWithConstraint=" + jobWouldBeReady);
}
if (!jobWouldBeReady) {
// If the job wouldn't be ready, nothing to do here.
return false;
}
// This is potentially more expensive since JSS may have to query component
// presence.
return mService.areComponentsInPlaceLocked(jobStatus);
}
public abstract void dumpControllerStateLocked(IndentingPrintWriter pw,
Predicate<JobStatus> predicate);
public abstract void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
Predicate<JobStatus> predicate);
/** Dump any internal constants the Controller may have. */
public void dumpConstants(IndentingPrintWriter pw) {
}
/** Dump any internal constants the Controller may have. */
public void dumpConstants(ProtoOutputStream proto) {
}
}