Loading apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java +61 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.job.IJobScheduler; import android.app.job.IUserVisibleJobObserver; Loading @@ -25,10 +26,13 @@ import android.app.job.JobScheduler; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.RemoteException; import android.util.ArrayMap; import java.util.List; import java.util.Map; import java.util.Set; /** * Concrete implementation of the JobScheduler interface Loading @@ -41,16 +45,42 @@ import java.util.List; public class JobSchedulerImpl extends JobScheduler { IJobScheduler mBinder; private final Context mContext; private final String mNamespace; public JobSchedulerImpl(@NonNull Context context, IJobScheduler binder) { this(context, binder, null); } private JobSchedulerImpl(@NonNull Context context, IJobScheduler binder, @Nullable String namespace) { mContext = context; mBinder = binder; mNamespace = namespace; } private JobSchedulerImpl(JobSchedulerImpl jsi, @Nullable String namespace) { this(jsi.mContext, jsi.mBinder, namespace); } @NonNull @Override public JobScheduler forNamespace(@NonNull String namespace) { if (namespace == null) { throw new IllegalArgumentException("namespace cannot be null"); } return new JobSchedulerImpl(this, namespace); } @Nullable @Override public String getNamespace() { return mNamespace; } @Override public int schedule(JobInfo job) { try { return mBinder.schedule(job); return mBinder.schedule(mNamespace, job); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } Loading @@ -59,7 +89,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public int enqueue(JobInfo job, JobWorkItem work) { try { return mBinder.enqueue(job, work); return mBinder.enqueue(mNamespace, job, work); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } Loading @@ -68,7 +98,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) { try { return mBinder.scheduleAsPackage(job, packageName, userId, tag); return mBinder.scheduleAsPackage(mNamespace, job, packageName, userId, tag); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } Loading @@ -77,23 +107,44 @@ public class JobSchedulerImpl extends JobScheduler { @Override public void cancel(int jobId) { try { mBinder.cancel(jobId); mBinder.cancel(mNamespace, jobId); } catch (RemoteException e) {} } @Override public void cancelAll() { try { mBinder.cancelAll(); mBinder.cancelAllInNamespace(mNamespace); } catch (RemoteException e) {} } @Override public void cancelInAllNamespaces() { try { mBinder.cancelAll(); } catch (RemoteException e) {} } @Override public List<JobInfo> getAllPendingJobs() { try { return mBinder.getAllPendingJobs().getList(); return mBinder.getAllPendingJobsInNamespace(mNamespace).getList(); } catch (RemoteException e) { return null; } } @Override public Map<String, List<JobInfo>> getPendingJobsInAllNamespaces() { try { final Map<String, ParceledListSlice<JobInfo>> parceledList = mBinder.getAllPendingJobs(); final ArrayMap<String, List<JobInfo>> jobMap = new ArrayMap<>(); final Set<String> keys = parceledList.keySet(); for (String key : keys) { jobMap.put(key, parceledList.get(key).getList()); } return jobMap; } catch (RemoteException e) { return null; } Loading @@ -102,7 +153,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public JobInfo getPendingJob(int jobId) { try { return mBinder.getPendingJob(jobId); return mBinder.getPendingJob(mNamespace, jobId); } catch (RemoteException e) { return null; } Loading @@ -111,7 +162,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public int getPendingJobReason(int jobId) { try { return mBinder.getPendingJobReason(jobId); return mBinder.getPendingJobReason(mNamespace, jobId); } catch (RemoteException e) { return PENDING_JOB_REASON_UNDEFINED; } Loading apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl +11 −7 Original line number Diff line number Diff line Loading @@ -21,20 +21,24 @@ import android.app.job.JobInfo; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.content.pm.ParceledListSlice; import java.util.Map; /** * IPC interface that supports the app-facing {@link #JobScheduler} api. * {@hide} */ interface IJobScheduler { int schedule(in JobInfo job); int enqueue(in JobInfo job, in JobWorkItem work); int scheduleAsPackage(in JobInfo job, String packageName, int userId, String tag); void cancel(int jobId); int schedule(String namespace, in JobInfo job); int enqueue(String namespace, in JobInfo job, in JobWorkItem work); int scheduleAsPackage(String namespace, in JobInfo job, String packageName, int userId, String tag); void cancel(String namespace, int jobId); void cancelAll(); ParceledListSlice getAllPendingJobs(); JobInfo getPendingJob(int jobId); int getPendingJobReason(int jobId); void cancelAllInNamespace(String namespace); // Returns Map<String, ParceledListSlice>, where the keys are the namespaces. Map<String, ParceledListSlice<JobInfo>> getAllPendingJobs(); ParceledListSlice<JobInfo> getAllPendingJobsInNamespace(String namespace); JobInfo getPendingJob(String namespace, int jobId); int getPendingJobReason(String namespace, int jobId); boolean canRunLongJobs(String packageName); boolean hasRunLongJobsPermission(String packageName, int userId); List<JobInfo> getStartedJobs(); Loading apex/jobscheduler/framework/java/android/app/job/JobInfo.java +3 −0 Original line number Diff line number Diff line Loading @@ -1251,6 +1251,9 @@ public class JobInfo implements Parcelable { * in them all being treated the same. The priorities each have slightly different * behaviors, as noted in their relevant javadoc. * * Starting in Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, * the priority will only affect sorting order within the job's namespace. * * <b>NOTE:</b> Setting all of your jobs to high priority will not be * beneficial to your app and in fact may hurt its performance in the * long run. Loading apex/jobscheduler/framework/java/android/app/job/JobParameters.java +19 −1 Original line number Diff line number Diff line Loading @@ -277,6 +277,8 @@ public class JobParameters implements Parcelable { @UnsupportedAppUsage private final int jobId; @Nullable private final String mJobNamespace; private final PersistableBundle extras; private final Bundle transientExtras; private final ClipData clipData; Loading @@ -295,7 +297,7 @@ public class JobParameters implements Parcelable { private String debugStopReason; // Human readable stop reason for debugging. /** @hide */ public JobParameters(IBinder callback, int jobId, PersistableBundle extras, public JobParameters(IBinder callback, String namespace, int jobId, PersistableBundle extras, Bundle transientExtras, ClipData clipData, int clipGrantFlags, boolean overrideDeadlineExpired, boolean isExpedited, boolean isUserInitiated, Uri[] triggeredContentUris, Loading @@ -312,6 +314,7 @@ public class JobParameters implements Parcelable { this.mTriggeredContentUris = triggeredContentUris; this.mTriggeredContentAuthorities = triggeredContentAuthorities; this.network = network; this.mJobNamespace = namespace; } /** Loading @@ -321,6 +324,19 @@ public class JobParameters implements Parcelable { return jobId; } /** * Get the namespace this job was placed in. * * @see JobScheduler#forNamespace(String) * @return The namespace this job was scheduled in. Will be {@code null} if there was no * explicit namespace set and this job is therefore in the default namespace. * @hide */ @Nullable public String getJobNamespace() { return mJobNamespace; } /** * @return The reason {@link JobService#onStopJob(JobParameters)} was called on this job. Will * be {@link #STOP_REASON_UNDEFINED} if {@link JobService#onStopJob(JobParameters)} has not Loading Loading @@ -540,6 +556,7 @@ public class JobParameters implements Parcelable { private JobParameters(Parcel in) { jobId = in.readInt(); mJobNamespace = in.readString(); extras = in.readPersistableBundle(); transientExtras = in.readBundle(); if (in.readInt() != 0) { Loading Loading @@ -581,6 +598,7 @@ public class JobParameters implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(jobId); dest.writeString(mJobNamespace); dest.writePersistableBundle(extras); dest.writeBundle(transientExtras); if (clipData != null) { Loading apex/jobscheduler/framework/java/android/app/job/JobScheduler.java +50 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.PersistableBundle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.Map; /** * This is an API for scheduling various types of jobs against the framework that will be executed Loading Loading @@ -263,6 +264,31 @@ public abstract class JobScheduler { public @interface PendingJobReason { } /** * Get a JobScheduler instance that is dedicated to a specific namespace. Any API calls using * this instance will interact with jobs in that namespace, unless the API documentation says * otherwise. Attempting to update a job scheduled in another namespace will not be possible * but will instead create or update the job inside the current namespace. A JobScheduler * instance dedicated to a namespace must be used to schedule or update jobs in that namespace. * @see #getNamespace() * @hide */ @NonNull public JobScheduler forNamespace(@NonNull String namespace) { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Get the namespace this JobScheduler instance is operating in. A {@code null} value means * that the app has not specified a namespace for this instance, and it is therefore using the * default namespace. * @hide */ @Nullable public String getNamespace() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Schedule a job to be executed. Will replace any currently scheduled job with the same * ID with the new information in the {@link JobInfo}. If a job with the given ID is currently Loading Loading @@ -363,6 +389,15 @@ public abstract class JobScheduler { */ public abstract void cancelAll(); /** * Cancel <em>all</em> jobs that have been scheduled by the calling application, regardless of * namespace. * @hide */ public void cancelInAllNamespaces() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Retrieve all jobs that have been scheduled by the calling application. * Loading @@ -371,6 +406,21 @@ public abstract class JobScheduler { */ public abstract @NonNull List<JobInfo> getAllPendingJobs(); /** * Retrieve all jobs that have been scheduled by the calling application within the current * namespace. * * @return a list of all of the app's scheduled jobs scheduled with the current namespace. * If a namespace hasn't been explicitly set with {@link #forNamespace(String)}, * then this will return jobs in the default namespace. * This includes jobs that are currently started as well as those that are still waiting to run. * @hide */ @NonNull public Map<String, List<JobInfo>> getPendingJobsInAllNamespaces() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Look up the description of a scheduled job. * Loading Loading
apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java +61 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.job.IJobScheduler; import android.app.job.IUserVisibleJobObserver; Loading @@ -25,10 +26,13 @@ import android.app.job.JobScheduler; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.RemoteException; import android.util.ArrayMap; import java.util.List; import java.util.Map; import java.util.Set; /** * Concrete implementation of the JobScheduler interface Loading @@ -41,16 +45,42 @@ import java.util.List; public class JobSchedulerImpl extends JobScheduler { IJobScheduler mBinder; private final Context mContext; private final String mNamespace; public JobSchedulerImpl(@NonNull Context context, IJobScheduler binder) { this(context, binder, null); } private JobSchedulerImpl(@NonNull Context context, IJobScheduler binder, @Nullable String namespace) { mContext = context; mBinder = binder; mNamespace = namespace; } private JobSchedulerImpl(JobSchedulerImpl jsi, @Nullable String namespace) { this(jsi.mContext, jsi.mBinder, namespace); } @NonNull @Override public JobScheduler forNamespace(@NonNull String namespace) { if (namespace == null) { throw new IllegalArgumentException("namespace cannot be null"); } return new JobSchedulerImpl(this, namespace); } @Nullable @Override public String getNamespace() { return mNamespace; } @Override public int schedule(JobInfo job) { try { return mBinder.schedule(job); return mBinder.schedule(mNamespace, job); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } Loading @@ -59,7 +89,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public int enqueue(JobInfo job, JobWorkItem work) { try { return mBinder.enqueue(job, work); return mBinder.enqueue(mNamespace, job, work); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } Loading @@ -68,7 +98,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) { try { return mBinder.scheduleAsPackage(job, packageName, userId, tag); return mBinder.scheduleAsPackage(mNamespace, job, packageName, userId, tag); } catch (RemoteException e) { return JobScheduler.RESULT_FAILURE; } Loading @@ -77,23 +107,44 @@ public class JobSchedulerImpl extends JobScheduler { @Override public void cancel(int jobId) { try { mBinder.cancel(jobId); mBinder.cancel(mNamespace, jobId); } catch (RemoteException e) {} } @Override public void cancelAll() { try { mBinder.cancelAll(); mBinder.cancelAllInNamespace(mNamespace); } catch (RemoteException e) {} } @Override public void cancelInAllNamespaces() { try { mBinder.cancelAll(); } catch (RemoteException e) {} } @Override public List<JobInfo> getAllPendingJobs() { try { return mBinder.getAllPendingJobs().getList(); return mBinder.getAllPendingJobsInNamespace(mNamespace).getList(); } catch (RemoteException e) { return null; } } @Override public Map<String, List<JobInfo>> getPendingJobsInAllNamespaces() { try { final Map<String, ParceledListSlice<JobInfo>> parceledList = mBinder.getAllPendingJobs(); final ArrayMap<String, List<JobInfo>> jobMap = new ArrayMap<>(); final Set<String> keys = parceledList.keySet(); for (String key : keys) { jobMap.put(key, parceledList.get(key).getList()); } return jobMap; } catch (RemoteException e) { return null; } Loading @@ -102,7 +153,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public JobInfo getPendingJob(int jobId) { try { return mBinder.getPendingJob(jobId); return mBinder.getPendingJob(mNamespace, jobId); } catch (RemoteException e) { return null; } Loading @@ -111,7 +162,7 @@ public class JobSchedulerImpl extends JobScheduler { @Override public int getPendingJobReason(int jobId) { try { return mBinder.getPendingJobReason(jobId); return mBinder.getPendingJobReason(mNamespace, jobId); } catch (RemoteException e) { return PENDING_JOB_REASON_UNDEFINED; } Loading
apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl +11 −7 Original line number Diff line number Diff line Loading @@ -21,20 +21,24 @@ import android.app.job.JobInfo; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.content.pm.ParceledListSlice; import java.util.Map; /** * IPC interface that supports the app-facing {@link #JobScheduler} api. * {@hide} */ interface IJobScheduler { int schedule(in JobInfo job); int enqueue(in JobInfo job, in JobWorkItem work); int scheduleAsPackage(in JobInfo job, String packageName, int userId, String tag); void cancel(int jobId); int schedule(String namespace, in JobInfo job); int enqueue(String namespace, in JobInfo job, in JobWorkItem work); int scheduleAsPackage(String namespace, in JobInfo job, String packageName, int userId, String tag); void cancel(String namespace, int jobId); void cancelAll(); ParceledListSlice getAllPendingJobs(); JobInfo getPendingJob(int jobId); int getPendingJobReason(int jobId); void cancelAllInNamespace(String namespace); // Returns Map<String, ParceledListSlice>, where the keys are the namespaces. Map<String, ParceledListSlice<JobInfo>> getAllPendingJobs(); ParceledListSlice<JobInfo> getAllPendingJobsInNamespace(String namespace); JobInfo getPendingJob(String namespace, int jobId); int getPendingJobReason(String namespace, int jobId); boolean canRunLongJobs(String packageName); boolean hasRunLongJobsPermission(String packageName, int userId); List<JobInfo> getStartedJobs(); Loading
apex/jobscheduler/framework/java/android/app/job/JobInfo.java +3 −0 Original line number Diff line number Diff line Loading @@ -1251,6 +1251,9 @@ public class JobInfo implements Parcelable { * in them all being treated the same. The priorities each have slightly different * behaviors, as noted in their relevant javadoc. * * Starting in Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, * the priority will only affect sorting order within the job's namespace. * * <b>NOTE:</b> Setting all of your jobs to high priority will not be * beneficial to your app and in fact may hurt its performance in the * long run. Loading
apex/jobscheduler/framework/java/android/app/job/JobParameters.java +19 −1 Original line number Diff line number Diff line Loading @@ -277,6 +277,8 @@ public class JobParameters implements Parcelable { @UnsupportedAppUsage private final int jobId; @Nullable private final String mJobNamespace; private final PersistableBundle extras; private final Bundle transientExtras; private final ClipData clipData; Loading @@ -295,7 +297,7 @@ public class JobParameters implements Parcelable { private String debugStopReason; // Human readable stop reason for debugging. /** @hide */ public JobParameters(IBinder callback, int jobId, PersistableBundle extras, public JobParameters(IBinder callback, String namespace, int jobId, PersistableBundle extras, Bundle transientExtras, ClipData clipData, int clipGrantFlags, boolean overrideDeadlineExpired, boolean isExpedited, boolean isUserInitiated, Uri[] triggeredContentUris, Loading @@ -312,6 +314,7 @@ public class JobParameters implements Parcelable { this.mTriggeredContentUris = triggeredContentUris; this.mTriggeredContentAuthorities = triggeredContentAuthorities; this.network = network; this.mJobNamespace = namespace; } /** Loading @@ -321,6 +324,19 @@ public class JobParameters implements Parcelable { return jobId; } /** * Get the namespace this job was placed in. * * @see JobScheduler#forNamespace(String) * @return The namespace this job was scheduled in. Will be {@code null} if there was no * explicit namespace set and this job is therefore in the default namespace. * @hide */ @Nullable public String getJobNamespace() { return mJobNamespace; } /** * @return The reason {@link JobService#onStopJob(JobParameters)} was called on this job. Will * be {@link #STOP_REASON_UNDEFINED} if {@link JobService#onStopJob(JobParameters)} has not Loading Loading @@ -540,6 +556,7 @@ public class JobParameters implements Parcelable { private JobParameters(Parcel in) { jobId = in.readInt(); mJobNamespace = in.readString(); extras = in.readPersistableBundle(); transientExtras = in.readBundle(); if (in.readInt() != 0) { Loading Loading @@ -581,6 +598,7 @@ public class JobParameters implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(jobId); dest.writeString(mJobNamespace); dest.writePersistableBundle(extras); dest.writeBundle(transientExtras); if (clipData != null) { Loading
apex/jobscheduler/framework/java/android/app/job/JobScheduler.java +50 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.PersistableBundle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.Map; /** * This is an API for scheduling various types of jobs against the framework that will be executed Loading Loading @@ -263,6 +264,31 @@ public abstract class JobScheduler { public @interface PendingJobReason { } /** * Get a JobScheduler instance that is dedicated to a specific namespace. Any API calls using * this instance will interact with jobs in that namespace, unless the API documentation says * otherwise. Attempting to update a job scheduled in another namespace will not be possible * but will instead create or update the job inside the current namespace. A JobScheduler * instance dedicated to a namespace must be used to schedule or update jobs in that namespace. * @see #getNamespace() * @hide */ @NonNull public JobScheduler forNamespace(@NonNull String namespace) { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Get the namespace this JobScheduler instance is operating in. A {@code null} value means * that the app has not specified a namespace for this instance, and it is therefore using the * default namespace. * @hide */ @Nullable public String getNamespace() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Schedule a job to be executed. Will replace any currently scheduled job with the same * ID with the new information in the {@link JobInfo}. If a job with the given ID is currently Loading Loading @@ -363,6 +389,15 @@ public abstract class JobScheduler { */ public abstract void cancelAll(); /** * Cancel <em>all</em> jobs that have been scheduled by the calling application, regardless of * namespace. * @hide */ public void cancelInAllNamespaces() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Retrieve all jobs that have been scheduled by the calling application. * Loading @@ -371,6 +406,21 @@ public abstract class JobScheduler { */ public abstract @NonNull List<JobInfo> getAllPendingJobs(); /** * Retrieve all jobs that have been scheduled by the calling application within the current * namespace. * * @return a list of all of the app's scheduled jobs scheduled with the current namespace. * If a namespace hasn't been explicitly set with {@link #forNamespace(String)}, * then this will return jobs in the default namespace. * This includes jobs that are currently started as well as those that are still waiting to run. * @hide */ @NonNull public Map<String, List<JobInfo>> getPendingJobsInAllNamespaces() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** * Look up the description of a scheduled job. * Loading