• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotation.NonNull;
22 import android.content.Context;
23 import android.provider.DeviceConfig;
24 import android.util.IndentingPrintWriter;
25 import android.util.Slog;
26 import android.util.proto.ProtoOutputStream;
27 
28 import com.android.internal.annotations.GuardedBy;
29 import com.android.internal.util.FrameworkStatsLog;
30 import com.android.server.job.JobSchedulerService;
31 import com.android.server.job.JobSchedulerService.Constants;
32 import com.android.server.job.StateChangedListener;
33 
34 import java.util.function.Predicate;
35 
36 /**
37  * Incorporates shared controller logic between the various controllers of the JobManager.
38  * These are solely responsible for tracking a list of jobs, and notifying the JM when these
39  * are ready to run, or whether they must be stopped.
40  */
41 public abstract class StateController {
42     private static final String TAG = "JobScheduler.SC";
43 
44     protected final JobSchedulerService mService;
45     protected final StateChangedListener mStateChangedListener;
46     protected final Context mContext;
47     protected final Object mLock;
48     protected final Constants mConstants;
49 
StateController(JobSchedulerService service)50     StateController(JobSchedulerService service) {
51         mService = service;
52         mStateChangedListener = service;
53         mContext = service.getTestableContext();
54         mLock = service.getLock();
55         mConstants = service.getConstants();
56     }
57 
58     /**
59      * Called when the system boot phase has reached
60      * {@link com.android.server.SystemService#PHASE_SYSTEM_SERVICES_READY}.
61      */
onSystemServicesReady()62     public void onSystemServicesReady() {
63     }
64 
65     /**
66      * Implement the logic here to decide whether a job should be tracked by this controller.
67      * This logic is put here so the JobManager can be completely agnostic of Controller logic.
68      * Also called when updating a task, so implementing controllers have to be aware of
69      * preexisting tasks.
70      */
maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob)71     public abstract void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob);
72 
73     /**
74      * Optionally implement logic here to prepare the job to be executed.
75      */
prepareForExecutionLocked(JobStatus jobStatus)76     public void prepareForExecutionLocked(JobStatus jobStatus) {
77     }
78 
79     /**
80      * Optionally implement logic here for when a job that was about to be executed failed to start.
81      */
unprepareFromExecutionLocked(JobStatus jobStatus)82     public void unprepareFromExecutionLocked(JobStatus jobStatus) {
83     }
84 
85     /**
86      * Remove task - this will happen if the task is cancelled, completed, etc.
87      */
maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate)88     public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
89             boolean forUpdate);
90 
91     /**
92      * Called when a new job is being created to reschedule an old failed job.
93      */
rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule)94     public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) {
95     }
96 
97     /** Notice that updated configuration constants are about to be read. */
prepareForUpdatedConstantsLocked()98     public void prepareForUpdatedConstantsLocked() {}
99 
100     /** Process the specified constant and update internal constants if relevant. */
processConstantLocked(@onNull DeviceConfig.Properties properties, @NonNull String key)101     public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
102             @NonNull String key) {}
103 
104     /**
105      * Called when the JobScheduler.Constants are updated.
106      */
onConstantsUpdatedLocked()107     public void onConstantsUpdatedLocked() {
108     }
109 
110     /** Called when a package is uninstalled from the device (not for an update). */
onAppRemovedLocked(String packageName, int uid)111     public void onAppRemovedLocked(String packageName, int uid) {
112     }
113 
114     /** Called when a user is added to the device. */
onUserAddedLocked(int userId)115     public void onUserAddedLocked(int userId) {
116     }
117 
118     /** Called when a user is removed from the device. */
onUserRemovedLocked(int userId)119     public void onUserRemovedLocked(int userId) {
120     }
121 
122     /**
123      * Called when JobSchedulerService has determined that the job is not ready to be run. The
124      * Controller can evaluate if it can or should do something to promote this job's readiness.
125      */
evaluateStateLocked(JobStatus jobStatus)126     public void evaluateStateLocked(JobStatus jobStatus) {
127     }
128 
129     /**
130      * Called when something with the UID has changed. The controller should re-evaluate any
131      * internal state tracking dependent on this UID.
132      */
reevaluateStateLocked(int uid)133     public void reevaluateStateLocked(int uid) {
134     }
135 
136     /**
137      * Called when the battery status changes.
138      */
139     @GuardedBy("mLock")
onBatteryStateChangedLocked()140     public void onBatteryStateChangedLocked() {
141     }
142 
143     /**
144      * Called when a UID's base bias has changed. The more positive the bias, the more
145      * important the UID is.
146      */
147     @GuardedBy("mLock")
onUidBiasChangedLocked(int uid, int prevBias, int newBias)148     public void onUidBiasChangedLocked(int uid, int prevBias, int newBias) {
149     }
150 
wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint)151     protected boolean wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint) {
152         // This is very cheap to check (just a few conditions on data in JobStatus).
153         final boolean jobWouldBeReady = jobStatus.wouldBeReadyWithConstraint(constraint);
154         if (DEBUG) {
155             Slog.v(TAG, "wouldBeReadyWithConstraintLocked: " + jobStatus.toShortString()
156                     + " constraint=" + constraint
157                     + " readyWithConstraint=" + jobWouldBeReady);
158         }
159         if (!jobWouldBeReady) {
160             // If the job wouldn't be ready, nothing to do here.
161             return false;
162         }
163 
164         // This is potentially more expensive since JSS may have to query component
165         // presence.
166         return mService.areComponentsInPlaceLocked(jobStatus);
167     }
168 
logDeviceWideConstraintStateToStatsd(int constraint, boolean satisfied)169     protected void logDeviceWideConstraintStateToStatsd(int constraint, boolean satisfied) {
170         FrameworkStatsLog.write(
171                 FrameworkStatsLog.DEVICE_WIDE_JOB_CONSTRAINT_CHANGED,
172                 JobStatus.getProtoConstraint(constraint),
173                 satisfied
174                         ? FrameworkStatsLog.DEVICE_WIDE_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED
175                         : FrameworkStatsLog.DEVICE_WIDE_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED);
176     }
177 
dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate)178     public abstract void dumpControllerStateLocked(IndentingPrintWriter pw,
179             Predicate<JobStatus> predicate);
dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, Predicate<JobStatus> predicate)180     public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
181             Predicate<JobStatus> predicate) {}
182 
183     /** Dump any internal constants the Controller may have. */
dumpConstants(IndentingPrintWriter pw)184     public void dumpConstants(IndentingPrintWriter pw) {
185     }
186 
187     /** Dump any internal constants the Controller may have. */
dumpConstants(ProtoOutputStream proto)188     public void dumpConstants(ProtoOutputStream proto) {
189     }
190 }
191