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 android.app.job; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.annotation.SystemService; 26 import android.annotation.UserIdInt; 27 import android.app.ActivityManager; 28 import android.app.usage.UsageStatsManager; 29 import android.compat.annotation.ChangeId; 30 import android.compat.annotation.EnabledAfter; 31 import android.content.ClipData; 32 import android.content.Context; 33 import android.content.pm.PackageManager; 34 import android.net.NetworkRequest; 35 import android.os.Build; 36 import android.os.Bundle; 37 import android.os.PersistableBundle; 38 39 import java.lang.annotation.Retention; 40 import java.lang.annotation.RetentionPolicy; 41 import java.util.List; 42 import java.util.Map; 43 44 /** 45 * This is an API for scheduling various types of jobs against the framework that will be executed 46 * in your application's own process. 47 * <p> 48 * See {@link android.app.job.JobInfo} for more description of the types of jobs that can be run 49 * and how to construct them. You will construct these JobInfo objects and pass them to the 50 * JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the 51 * system will execute this job on your application's {@link android.app.job.JobService}. 52 * You identify the service component that implements the logic for your job when you 53 * construct the JobInfo using 54 * {@link android.app.job.JobInfo.Builder#Builder(int,android.content.ComponentName)}. 55 * </p> 56 * <p> 57 * The framework will be intelligent about when it executes jobs, and attempt to batch 58 * and defer them as much as possible. Typically, if you don't specify a deadline on a job, it 59 * can be run at any moment depending on the current state of the JobScheduler's internal queue. 60 * </p> 61 * <p> 62 * Starting in Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, 63 * JobScheduler may try to optimize job execution by shifting execution to times with more available 64 * system resources in order to lower user impact. Factors in system health include sufficient 65 * battery, idle, charging, and access to an un-metered network. Jobs will initially be treated as 66 * if they have all these requirements, but as their deadlines approach, restrictions will become 67 * less strict. Requested requirements will not be affected by this change. 68 * </p> 69 * 70 * {@see android.app.job.JobInfo.Builder#setRequiresBatteryNotLow(boolean)} 71 * {@see android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)} 72 * {@see android.app.job.JobInfo.Builder#setRequiresCharging(boolean)} 73 * {@see android.app.job.JobInfo.Builder#setRequiredNetworkType(int)} 74 * 75 * <p> 76 * While a job is running, the system holds a wakelock on behalf of your app. For this reason, 77 * you do not need to take any action to guarantee that the device stays awake for the 78 * duration of the job. 79 * </p> 80 * <p>You do not 81 * instantiate this class directly; instead, retrieve it through 82 * {@link android.content.Context#getSystemService 83 * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}. 84 * 85 * <p> Prior to Android version {@link android.os.Build.VERSION_CODES#S}, jobs could only have 86 * a maximum of 100 jobs scheduled at a time. Starting with Android version 87 * {@link android.os.Build.VERSION_CODES#S}, that limit has been increased to 150. 88 * Expedited jobs also count towards the limit. 89 * 90 * <p> In Android version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, jobs had a maximum 91 * execution time of one minute. Starting with Android version 92 * {@link android.os.Build.VERSION_CODES#M} and ending with Android version 93 * {@link android.os.Build.VERSION_CODES#R}, jobs had a maximum execution time of 10 minutes. 94 * Starting from Android version {@link android.os.Build.VERSION_CODES#S}, jobs will still be 95 * stopped after 10 minutes if the system is busy or needs the resources, but if not, jobs 96 * may continue running longer than 10 minutes. 97 * 98 * <p class="caution"><strong>Note:</strong> Beginning with API 30 99 * ({@link android.os.Build.VERSION_CODES#R}), JobScheduler will throttle runaway applications. 100 * Calling {@link #schedule(JobInfo)} and other such methods with very high frequency can have a 101 * high cost and so, to make sure the system doesn't get overwhelmed, JobScheduler will begin 102 * to throttle apps, regardless of target SDK version. 103 */ 104 @SystemService(Context.JOB_SCHEDULER_SERVICE) 105 public abstract class JobScheduler { 106 /** 107 * Whether to throw an exception when an app doesn't properly implement all the necessary 108 * data transfer APIs. 109 * 110 * @hide 111 */ 112 @ChangeId 113 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) 114 public static final long THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION = 255371817L; 115 116 /** @hide */ 117 @IntDef(prefix = { "RESULT_" }, value = { 118 RESULT_FAILURE, 119 RESULT_SUCCESS, 120 }) 121 @Retention(RetentionPolicy.SOURCE) 122 public @interface Result {} 123 124 /** 125 * Returned from {@link #schedule(JobInfo)} if a job wasn't scheduled successfully. Scheduling 126 * can fail for a variety of reasons, including, but not limited to: 127 * <ul> 128 * <li>an invalid parameter was supplied (eg. the run-time for your job is too short, or the 129 * system can't resolve the requisite {@link JobService} in your package)</li> 130 * <li>the app has too many jobs scheduled</li> 131 * <li>the app has tried to schedule too many jobs in a short amount of time</li> 132 * </ul> 133 * Attempting to schedule the job again immediately after receiving this result will not 134 * guarantee a successful schedule. 135 */ 136 public static final int RESULT_FAILURE = 0; 137 /** 138 * Returned from {@link #schedule(JobInfo)} if this job has been successfully scheduled. 139 */ 140 public static final int RESULT_SUCCESS = 1; 141 142 /** The job doesn't exist. */ 143 public static final int PENDING_JOB_REASON_INVALID_JOB_ID = -2; 144 /** The job is currently running and is therefore not pending. */ 145 public static final int PENDING_JOB_REASON_EXECUTING = -1; 146 /** 147 * There is no known reason why the job is pending. 148 * If additional reasons are added on newer Android versions, the system may return this reason 149 * to apps whose target SDK is not high enough to expect that reason. 150 */ 151 public static final int PENDING_JOB_REASON_UNDEFINED = 0; 152 /** 153 * The app is in a state that prevents the job from running 154 * (eg. the {@link JobService} component is disabled). 155 */ 156 public static final int PENDING_JOB_REASON_APP = 1; 157 /** 158 * The current standby bucket prevents the job from running. 159 * 160 * @see UsageStatsManager#STANDBY_BUCKET_RESTRICTED 161 */ 162 public static final int PENDING_JOB_REASON_APP_STANDBY = 2; 163 /** 164 * The app is restricted from running in the background. 165 * 166 * @see ActivityManager#isBackgroundRestricted() 167 * @see PackageManager#isInstantApp() 168 */ 169 public static final int PENDING_JOB_REASON_BACKGROUND_RESTRICTION = 3; 170 /** 171 * The requested battery-not-low constraint is not satisfied. 172 * 173 * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean) 174 */ 175 public static final int PENDING_JOB_REASON_CONSTRAINT_BATTERY_NOT_LOW = 4; 176 /** 177 * The requested charging constraint is not satisfied. 178 * 179 * @see JobInfo.Builder#setRequiresCharging(boolean) 180 */ 181 public static final int PENDING_JOB_REASON_CONSTRAINT_CHARGING = 5; 182 /** 183 * The requested connectivity constraint is not satisfied. 184 * 185 * @see JobInfo.Builder#setRequiredNetwork(NetworkRequest) 186 * @see JobInfo.Builder#setRequiredNetworkType(int) 187 */ 188 public static final int PENDING_JOB_REASON_CONSTRAINT_CONNECTIVITY = 6; 189 /** 190 * The requested content trigger constraint is not satisfied. 191 * 192 * @see JobInfo.Builder#addTriggerContentUri(JobInfo.TriggerContentUri) 193 */ 194 public static final int PENDING_JOB_REASON_CONSTRAINT_CONTENT_TRIGGER = 7; 195 /** 196 * The requested idle constraint is not satisfied. 197 * 198 * @see JobInfo.Builder#setRequiresDeviceIdle(boolean) 199 */ 200 public static final int PENDING_JOB_REASON_CONSTRAINT_DEVICE_IDLE = 8; 201 /** 202 * The minimum latency has not transpired. 203 * 204 * @see JobInfo.Builder#setMinimumLatency(long) 205 */ 206 public static final int PENDING_JOB_REASON_CONSTRAINT_MINIMUM_LATENCY = 9; 207 /** 208 * The system's estimate of when the app will be launched is far away enough to warrant delaying 209 * this job. 210 * 211 * @see JobInfo#isPrefetch() 212 * @see JobInfo.Builder#setPrefetch(boolean) 213 */ 214 public static final int PENDING_JOB_REASON_CONSTRAINT_PREFETCH = 10; 215 /** 216 * The requested storage-not-low constraint is not satisfied. 217 * 218 * @see JobInfo.Builder#setRequiresStorageNotLow(boolean) 219 */ 220 public static final int PENDING_JOB_REASON_CONSTRAINT_STORAGE_NOT_LOW = 11; 221 /** 222 * The job is being deferred due to the device state (eg. Doze, battery saver, memory usage, 223 * thermal status, etc.). 224 */ 225 public static final int PENDING_JOB_REASON_DEVICE_STATE = 12; 226 /** 227 * JobScheduler thinks it can defer this job to a more optimal running time. 228 */ 229 public static final int PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION = 13; 230 /** 231 * The app has consumed all of its current quota. 232 * 233 * @see UsageStatsManager#getAppStandbyBucket() 234 * @see JobParameters#STOP_REASON_QUOTA 235 */ 236 public static final int PENDING_JOB_REASON_QUOTA = 14; 237 /** 238 * JobScheduler is respecting one of the user's actions (eg. force stop or adb shell commands) 239 * to defer this job. 240 */ 241 public static final int PENDING_JOB_REASON_USER = 15; 242 /** 243 * The override deadline has not transpired. 244 * 245 * @see JobInfo.Builder#setOverrideDeadline(long) 246 */ 247 @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_API) 248 public static final int PENDING_JOB_REASON_CONSTRAINT_DEADLINE = 16; 249 250 /** @hide */ 251 @IntDef(prefix = {"PENDING_JOB_REASON_"}, value = { 252 PENDING_JOB_REASON_UNDEFINED, 253 PENDING_JOB_REASON_APP, 254 PENDING_JOB_REASON_APP_STANDBY, 255 PENDING_JOB_REASON_BACKGROUND_RESTRICTION, 256 PENDING_JOB_REASON_CONSTRAINT_BATTERY_NOT_LOW, 257 PENDING_JOB_REASON_CONSTRAINT_CHARGING, 258 PENDING_JOB_REASON_CONSTRAINT_CONNECTIVITY, 259 PENDING_JOB_REASON_CONSTRAINT_CONTENT_TRIGGER, 260 PENDING_JOB_REASON_CONSTRAINT_DEVICE_IDLE, 261 PENDING_JOB_REASON_CONSTRAINT_MINIMUM_LATENCY, 262 PENDING_JOB_REASON_CONSTRAINT_PREFETCH, 263 PENDING_JOB_REASON_CONSTRAINT_STORAGE_NOT_LOW, 264 PENDING_JOB_REASON_DEVICE_STATE, 265 PENDING_JOB_REASON_EXECUTING, 266 PENDING_JOB_REASON_INVALID_JOB_ID, 267 PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION, 268 PENDING_JOB_REASON_QUOTA, 269 PENDING_JOB_REASON_USER, 270 PENDING_JOB_REASON_CONSTRAINT_DEADLINE, 271 }) 272 @Retention(RetentionPolicy.SOURCE) 273 public @interface PendingJobReason { 274 } 275 276 /** 277 * Get a JobScheduler instance that is dedicated to a specific namespace. Any API calls using 278 * this instance will interact with jobs in that namespace, unless the API documentation says 279 * otherwise. Attempting to update a job scheduled in another namespace will not be possible 280 * but will instead create or update the job inside the current namespace. A JobScheduler 281 * instance dedicated to a namespace must be used to schedule or update jobs in that namespace. 282 * 283 * <p class="note">Since leading and trailing whitespace can lead to hard-to-debug issues, 284 * they will be {@link String#trim() trimmed}. An empty String (after trimming) is not allowed. 285 * @see #getNamespace() 286 */ 287 @NonNull forNamespace(@onNull String namespace)288 public JobScheduler forNamespace(@NonNull String namespace) { 289 throw new RuntimeException("Not implemented. Must override in a subclass."); 290 } 291 292 /** 293 * Get the namespace this JobScheduler instance is operating in. A {@code null} value means 294 * that the app has not specified a namespace for this instance, and it is therefore using the 295 * default namespace. 296 */ 297 @Nullable getNamespace()298 public String getNamespace() { 299 throw new RuntimeException("Not implemented. Must override in a subclass."); 300 } 301 302 /** @hide */ 303 @Nullable sanitizeNamespace(@ullable String namespace)304 public static String sanitizeNamespace(@Nullable String namespace) { 305 if (namespace == null) { 306 return null; 307 } 308 return namespace.trim().intern(); 309 } 310 311 /** 312 * Schedule a job to be executed. Will replace any currently scheduled job with the same 313 * ID with the new information in the {@link JobInfo}. If a job with the given ID is currently 314 * running, it will be stopped. 315 * 316 * <p class="caution"><strong>Note:</strong> Scheduling a job can have a high cost, even if it's 317 * rescheduling the same job and the job didn't execute, especially on platform versions before 318 * version {@link android.os.Build.VERSION_CODES#Q}. As such, the system may throttle calls to 319 * this API if calls are made too frequently in a short amount of time. 320 * 321 * <p>Note: The JobService component needs to be enabled in order to successfully schedule a 322 * job. 323 * 324 * @param job The job you wish scheduled. See 325 * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs 326 * you can schedule. 327 * @return the result of the schedule request. 328 * @throws IllegalArgumentException if the specified {@link JobService} doesn't exist or is 329 * disabled. 330 */ schedule(@onNull JobInfo job)331 public abstract @Result int schedule(@NonNull JobInfo job); 332 333 /** 334 * Similar to {@link #schedule}, but allows you to enqueue work for a new <em>or existing</em> 335 * job. If a job with the same ID is already scheduled, it will be replaced with the 336 * new {@link JobInfo}, but any previously enqueued work will remain and be dispatched the 337 * next time it runs. If a job with the same ID is already running, the new work will be 338 * enqueued for it without stopping the job. 339 * 340 * <p>The work you enqueue is later retrieved through 341 * {@link JobParameters#dequeueWork() JobParameters.dequeueWork}. Be sure to see there 342 * about how to process work; the act of enqueueing work changes how you should handle the 343 * overall lifecycle of an executing job.</p> 344 * 345 * <p>It is strongly encouraged that you use the same {@link JobInfo} for all work you 346 * enqueue. This will allow the system to optimally schedule work along with any pending 347 * and/or currently running work. If the JobInfo changes from the last time the job was 348 * enqueued, the system will need to update the associated JobInfo, which can cause a disruption 349 * in execution. In particular, this can result in any currently running job that is processing 350 * previous work to be stopped and restarted with the new JobInfo.</p> 351 * 352 * <p>It is recommended that you avoid using 353 * {@link JobInfo.Builder#setExtras(PersistableBundle)} or 354 * {@link JobInfo.Builder#setTransientExtras(Bundle)} with a JobInfo you are using to 355 * enqueue work. The system will try to compare these extras with the previous JobInfo, 356 * but there are situations where it may get this wrong and count the JobInfo as changing. 357 * (That said, you should be relatively safe with a simple set of consistent data in these 358 * fields.) You should never use {@link JobInfo.Builder#setClipData(ClipData, int)} with 359 * work you are enqueuing, since currently this will always be treated as a different JobInfo, 360 * even if the ClipData contents are exactly the same.</p> 361 * 362 * <p class="caution"><strong>Note:</strong> Scheduling a job can have a high cost, even if it's 363 * rescheduling the same job and the job didn't execute, especially on platform versions before 364 * version {@link android.os.Build.VERSION_CODES#Q}. As such, the system may throttle calls to 365 * this API if calls are made too frequently in a short amount of time. 366 * 367 * <p class="caution"><strong>Note:</strong> Prior to Android version 368 * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, JobWorkItems could not be persisted. 369 * Apps were not allowed to enqueue JobWorkItems with persisted jobs and the system would throw 370 * an {@link IllegalArgumentException} if they attempted to do so. Starting with 371 * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, 372 * JobWorkItems can be persisted alongside the hosting job. 373 * However, Intents cannot be persisted. Set a {@link PersistableBundle} using 374 * {@link JobWorkItem.Builder#setExtras(PersistableBundle)} for any information that needs 375 * to be persisted. 376 * 377 * <p>Note: The JobService component needs to be enabled in order to successfully schedule a 378 * job. 379 * 380 * @param job The job you wish to enqueue work for. See 381 * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs 382 * you can schedule. 383 * @param work New work to enqueue. This will be available later when the job starts running. 384 * @return the result of the enqueue request. 385 * @throws IllegalArgumentException if the specified {@link JobService} doesn't exist or is 386 * disabled. 387 */ enqueue(@onNull JobInfo job, @NonNull JobWorkItem work)388 public abstract @Result int enqueue(@NonNull JobInfo job, @NonNull JobWorkItem work); 389 390 /** 391 * 392 * @param job The job to be scheduled. 393 * @param packageName The package on behalf of which the job is to be scheduled. This will be 394 * used to track battery usage and appIdleState. 395 * @param userId User on behalf of whom this job is to be scheduled. 396 * @param tag Debugging tag for dumps associated with this job (instead of the service class) 397 * @hide 398 */ 399 @SuppressWarnings("HiddenAbstractMethod") 400 @SystemApi 401 @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) scheduleAsPackage(@onNull JobInfo job, @NonNull String packageName, int userId, String tag)402 public abstract @Result int scheduleAsPackage(@NonNull JobInfo job, @NonNull String packageName, 403 int userId, String tag); 404 405 /** 406 * Cancel the specified job. If the job is currently executing, it is stopped 407 * immediately and the return value from its {@link JobService#onStopJob(JobParameters)} 408 * method is ignored. 409 * 410 * @param jobId unique identifier for the job to be canceled, as supplied to 411 * {@link JobInfo.Builder#Builder(int, android.content.ComponentName) 412 * JobInfo.Builder(int, android.content.ComponentName)}. 413 */ cancel(int jobId)414 public abstract void cancel(int jobId); 415 416 /** 417 * Cancel all jobs that have been scheduled in the current namespace by the 418 * calling application. 419 * 420 * <p> 421 * Starting with Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, this 422 * will only cancel within the current namespace. If a namespace hasn't been explicitly set 423 * with {@link #forNamespace(String)}, then this will cancel jobs in the default namespace. 424 * To cancel all jobs scheduled by the application, 425 * use {@link #cancelInAllNamespaces()} instead. 426 */ cancelAll()427 public abstract void cancelAll(); 428 429 /** 430 * Cancel <em>all</em> jobs that have been scheduled by the calling application, regardless of 431 * namespace. 432 */ cancelInAllNamespaces()433 public void cancelInAllNamespaces() { 434 throw new RuntimeException("Not implemented. Must override in a subclass."); 435 } 436 437 /** 438 * Retrieve all jobs that have been scheduled by the calling application. 439 * 440 * @return a list of all of the app's scheduled jobs. This includes jobs that are 441 * currently started as well as those that are still waiting to run. 442 */ getAllPendingJobs()443 public abstract @NonNull List<JobInfo> getAllPendingJobs(); 444 445 /** 446 * Retrieve all jobs that have been scheduled by the calling application within the current 447 * namespace. 448 * 449 * @return a list of all of the app's scheduled jobs scheduled with the current namespace. 450 * If a namespace hasn't been explicitly set with {@link #forNamespace(String)}, 451 * then this will return jobs in the default namespace. 452 * This includes jobs that are currently started as well as those that are still waiting to run. 453 */ 454 @NonNull getPendingJobsInAllNamespaces()455 public Map<String, List<JobInfo>> getPendingJobsInAllNamespaces() { 456 throw new RuntimeException("Not implemented. Must override in a subclass."); 457 } 458 459 /** 460 * Look up the description of a scheduled job. 461 * 462 * @return The {@link JobInfo} description of the given scheduled job, or {@code null} 463 * if the supplied job ID does not correspond to any job. 464 */ getPendingJob(int jobId)465 public abstract @Nullable JobInfo getPendingJob(int jobId); 466 467 /** 468 * Returns a reason why the job is pending and not currently executing. If there are multiple 469 * reasons why a job may be pending, this will only return one of them. 470 * 471 * @apiNote 472 * To know all the potential reasons why the job may be pending, 473 * use {@link #getPendingJobReasons(int)} instead. 474 */ 475 @PendingJobReason getPendingJobReason(int jobId)476 public int getPendingJobReason(int jobId) { 477 return PENDING_JOB_REASON_UNDEFINED; 478 } 479 480 /** 481 * Returns potential reasons why the job with the given {@code jobId} may be pending 482 * and not currently executing. 483 * 484 * The returned array will include {@link PendingJobReason reasons} composed of both 485 * explicitly set constraints on the job and implicit constraints imposed by the system. 486 * The results can be used to debug why a given job may not be currently executing. 487 */ 488 @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_API) 489 @NonNull 490 @PendingJobReason getPendingJobReasons(int jobId)491 public int[] getPendingJobReasons(int jobId) { 492 return new int[] { PENDING_JOB_REASON_UNDEFINED }; 493 } 494 495 /** 496 * For the given {@code jobId}, returns a limited historical view of why the job may have 497 * been pending execution. The returned list is composed of {@link PendingJobReasonsInfo} 498 * objects, each of which include a timestamp since epoch along with an array of 499 * unsatisfied constraints represented by {@link PendingJobReason PendingJobReason constants}. 500 * <p> 501 * These constants could either be explicitly set constraints on the job or implicit 502 * constraints imposed by the system due to various reasons. 503 * The results can be used to debug why a given job may have been pending execution. 504 * <p> 505 * If the only {@link PendingJobReason} for the timestamp is 506 * {@link PendingJobReason#PENDING_JOB_REASON_UNDEFINED}, it could mean that 507 * the job was ready to be executed at that point in time. 508 * <p> 509 * Note: there is no set interval for the timestamps in the returned list since 510 * constraint changes occur based on device status and various other factors. 511 * <p> 512 * Note: the pending job reasons history is not persisted across device reboots. 513 * <p> 514 * @throws IllegalArgumentException if the {@code jobId} is invalid. 515 * @see #getPendingJobReasons(int) 516 */ 517 @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_HISTORY_API) 518 @NonNull getPendingJobReasonsHistory(int jobId)519 public List<PendingJobReasonsInfo> getPendingJobReasonsHistory(int jobId) { 520 throw new UnsupportedOperationException("Not implemented by " + getClass()); 521 } 522 523 /** 524 * Returns {@code true} if the calling app currently holds the 525 * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run 526 * user-initiated jobs. 527 */ canRunUserInitiatedJobs()528 public boolean canRunUserInitiatedJobs() { 529 return false; 530 } 531 532 /** 533 * Returns {@code true} if the app currently holds the 534 * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run 535 * user-initiated jobs. 536 * @hide 537 * TODO(255371817): consider exposing this to apps who could call 538 * {@link #scheduleAsPackage(JobInfo, String, int, String)} 539 */ hasRunUserInitiatedJobsPermission(@onNull String packageName, @UserIdInt int userId)540 public boolean hasRunUserInitiatedJobsPermission(@NonNull String packageName, 541 @UserIdInt int userId) { 542 return false; 543 } 544 545 /** 546 * <b>For internal system callers only!</b> 547 * Returns a list of all currently-executing jobs. 548 * @hide 549 */ 550 @Nullable getStartedJobs()551 public List<JobInfo> getStartedJobs() { 552 return null; 553 } 554 555 /** 556 * <b>For internal system callers only!</b> 557 * Returns a snapshot of the state of all jobs known to the system. 558 * 559 * <p class="note">This is a slow operation, so it should be called sparingly. 560 * @hide 561 */ 562 @Nullable getAllJobSnapshots()563 public List<JobSnapshot> getAllJobSnapshots() { 564 return null; 565 } 566 567 /** 568 * @hide 569 */ 570 @RequiresPermission(allOf = { 571 android.Manifest.permission.MANAGE_ACTIVITY_TASKS, 572 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) registerUserVisibleJobObserver(@onNull IUserVisibleJobObserver observer)573 public void registerUserVisibleJobObserver(@NonNull IUserVisibleJobObserver observer) { 574 } 575 576 /** 577 * @hide 578 */ 579 @RequiresPermission(allOf = { 580 android.Manifest.permission.MANAGE_ACTIVITY_TASKS, 581 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) unregisterUserVisibleJobObserver( @onNull IUserVisibleJobObserver observer)582 public void unregisterUserVisibleJobObserver( 583 @NonNull IUserVisibleJobObserver observer) { 584 585 } 586 587 /** 588 * @hide 589 */ 590 @RequiresPermission(allOf = { 591 android.Manifest.permission.MANAGE_ACTIVITY_TASKS, 592 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) notePendingUserRequestedAppStop(@onNull String packageName, int userId, @Nullable String debugReason)593 public void notePendingUserRequestedAppStop(@NonNull String packageName, int userId, 594 @Nullable String debugReason) { 595 } 596 } 597