1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.job.controllers; 18 19 import static com.android.server.job.JobSchedulerService.DEBUG; 20 21 import android.content.Context; 22 import android.util.Slog; 23 import android.util.proto.ProtoOutputStream; 24 25 import com.android.internal.util.IndentingPrintWriter; 26 import com.android.server.job.JobSchedulerService; 27 import com.android.server.job.JobSchedulerService.Constants; 28 import com.android.server.job.StateChangedListener; 29 30 import java.util.function.Predicate; 31 32 /** 33 * Incorporates shared controller logic between the various controllers of the JobManager. 34 * These are solely responsible for tracking a list of jobs, and notifying the JM when these 35 * are ready to run, or whether they must be stopped. 36 */ 37 public abstract class StateController { 38 private static final String TAG = "JobScheduler.SC"; 39 40 protected final JobSchedulerService mService; 41 protected final StateChangedListener mStateChangedListener; 42 protected final Context mContext; 43 protected final Object mLock; 44 protected final Constants mConstants; 45 StateController(JobSchedulerService service)46 StateController(JobSchedulerService service) { 47 mService = service; 48 mStateChangedListener = service; 49 mContext = service.getTestableContext(); 50 mLock = service.getLock(); 51 mConstants = service.getConstants(); 52 } 53 54 /** 55 * Called when the system boot phase has reached 56 * {@link com.android.server.SystemService#PHASE_SYSTEM_SERVICES_READY}. 57 */ onSystemServicesReady()58 public void onSystemServicesReady() { 59 } 60 61 /** 62 * Implement the logic here to decide whether a job should be tracked by this controller. 63 * This logic is put here so the JobManager can be completely agnostic of Controller logic. 64 * Also called when updating a task, so implementing controllers have to be aware of 65 * preexisting tasks. 66 */ maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob)67 public abstract void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob); 68 69 /** 70 * Optionally implement logic here to prepare the job to be executed. 71 */ prepareForExecutionLocked(JobStatus jobStatus)72 public void prepareForExecutionLocked(JobStatus jobStatus) { 73 } 74 75 /** 76 * Remove task - this will happen if the task is cancelled, completed, etc. 77 */ maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate)78 public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, 79 boolean forUpdate); 80 81 /** 82 * Called when a new job is being created to reschedule an old failed job. 83 */ rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule)84 public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) { 85 } 86 87 /** 88 * Called when the JobScheduler.Constants are updated. 89 */ onConstantsUpdatedLocked()90 public void onConstantsUpdatedLocked() { 91 } 92 93 /** Called when a package is uninstalled from the device (not for an update). */ onAppRemovedLocked(String packageName, int uid)94 public void onAppRemovedLocked(String packageName, int uid) { 95 } 96 97 /** Called when a user is removed from the device. */ onUserRemovedLocked(int userId)98 public void onUserRemovedLocked(int userId) { 99 } 100 101 /** 102 * Called when JobSchedulerService has determined that the job is not ready to be run. The 103 * Controller can evaluate if it can or should do something to promote this job's readiness. 104 */ evaluateStateLocked(JobStatus jobStatus)105 public void evaluateStateLocked(JobStatus jobStatus) { 106 } 107 108 /** 109 * Called when something with the UID has changed. The controller should re-evaluate any 110 * internal state tracking dependent on this UID. 111 */ reevaluateStateLocked(int uid)112 public void reevaluateStateLocked(int uid) { 113 } 114 wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint)115 protected boolean wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint) { 116 // This is very cheap to check (just a few conditions on data in JobStatus). 117 final boolean jobWouldBeReady = jobStatus.wouldBeReadyWithConstraint(constraint); 118 if (DEBUG) { 119 Slog.v(TAG, "wouldBeReadyWithConstraintLocked: " + jobStatus.toShortString() 120 + " constraint=" + constraint 121 + " readyWithConstraint=" + jobWouldBeReady); 122 } 123 if (!jobWouldBeReady) { 124 // If the job wouldn't be ready, nothing to do here. 125 return false; 126 } 127 128 // This is potentially more expensive since JSS may have to query component 129 // presence. 130 return mService.areComponentsInPlaceLocked(jobStatus); 131 } 132 dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate)133 public abstract void dumpControllerStateLocked(IndentingPrintWriter pw, 134 Predicate<JobStatus> predicate); dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, Predicate<JobStatus> predicate)135 public abstract void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, 136 Predicate<JobStatus> predicate); 137 138 /** Dump any internal constants the Controller may have. */ dumpConstants(IndentingPrintWriter pw)139 public void dumpConstants(IndentingPrintWriter pw) { 140 } 141 142 /** Dump any internal constants the Controller may have. */ dumpConstants(ProtoOutputStream proto)143 public void dumpConstants(ProtoOutputStream proto) { 144 } 145 } 146