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