Loading apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java +12 −0 Original line number Diff line number Diff line Loading @@ -25,11 +25,13 @@ import android.app.job.JobInfo; import android.app.job.JobScheduler; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.app.job.PendingJobReasonsInfo; import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.RemoteException; import android.util.ArrayMap; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -182,6 +184,16 @@ public class JobSchedulerImpl extends JobScheduler { } } @Override @NonNull public List<PendingJobReasonsInfo> getPendingJobReasonsHistory(int jobId) { try { return mBinder.getPendingJobReasonsHistory(mNamespace, jobId); } catch (RemoteException e) { return Collections.EMPTY_LIST; } } @Override public boolean canRunUserInitiatedJobs() { try { Loading apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.job.IUserVisibleJobObserver; import android.app.job.JobInfo; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.app.job.PendingJobReasonsInfo; import android.content.pm.ParceledListSlice; import java.util.Map; Loading @@ -40,6 +41,7 @@ interface IJobScheduler { JobInfo getPendingJob(String namespace, int jobId); int getPendingJobReason(String namespace, int jobId); int[] getPendingJobReasons(String namespace, int jobId); List<PendingJobReasonsInfo> getPendingJobReasonsHistory(String namespace, int jobId); boolean canRunUserInitiatedJobs(String packageName); boolean hasRunUserInitiatedJobsPermission(String packageName, int userId); List<JobInfo> getStartedJobs(); Loading apex/jobscheduler/framework/java/android/app/job/JobScheduler.java +28 −0 Original line number Diff line number Diff line Loading @@ -492,6 +492,34 @@ public abstract class JobScheduler { return new int[] { PENDING_JOB_REASON_UNDEFINED }; } /** * For the given {@code jobId}, returns a limited historical view of why the job may have * been pending execution. The returned list is composed of {@link PendingJobReasonsInfo} * objects, each of which include a timestamp since epoch along with an array of * unsatisfied constraints represented by {@link PendingJobReason PendingJobReason constants}. * <p> * These constants could either be explicitly set constraints on the job or implicit * constraints imposed by the system due to various reasons. * The results can be used to debug why a given job may have been pending execution. * <p> * If the only {@link PendingJobReason} for the timestamp is * {@link PendingJobReason#PENDING_JOB_REASON_UNDEFINED}, it could mean that * the job was ready to be executed at that point in time. * <p> * Note: there is no set interval for the timestamps in the returned list since * constraint changes occur based on device status and various other factors. * <p> * Note: the pending job reasons history is not persisted across device reboots. * <p> * @throws IllegalArgumentException if the {@code jobId} is invalid. * @see #getPendingJobReasons(int) */ @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_HISTORY_API) @NonNull public List<PendingJobReasonsInfo> getPendingJobReasonsHistory(int jobId) { throw new UnsupportedOperationException("Not implemented by " + getClass()); } /** * Returns {@code true} if the calling app currently holds the * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run Loading apex/jobscheduler/framework/java/android/app/job/PendingJobReasonsInfo.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.job; parcelable PendingJobReasonsInfo; apex/jobscheduler/framework/java/android/app/job/PendingJobReasonsInfo.java 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.job; import android.annotation.CurrentTimeMillisLong; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; /** * A simple wrapper which includes a timestamp (in millis since epoch) * and an array of {@link JobScheduler.PendingJobReason reasons} at that timestamp * for why a particular job may be pending. */ @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_HISTORY_API) public final class PendingJobReasonsInfo implements Parcelable { @CurrentTimeMillisLong private final long mTimestampMillis; @NonNull @JobScheduler.PendingJobReason private final int[] mPendingJobReasons; public PendingJobReasonsInfo(long timestampMillis, @NonNull @JobScheduler.PendingJobReason int[] reasons) { mTimestampMillis = timestampMillis; mPendingJobReasons = reasons; } /** * @return the time (in millis since epoch) associated with the set of pending job reasons. */ @CurrentTimeMillisLong public long getTimestampMillis() { return mTimestampMillis; } /** * Returns a set of {@link android.app.job.JobScheduler.PendingJobReason reasons} representing * why the job may not have executed at the associated timestamp. * <p> * These reasons could either be explicitly set constraints on the job or implicit * constraints imposed by the system due to various reasons. * <p> * Note: if the only {@link android.app.job.JobScheduler.PendingJobReason} present is * {@link JobScheduler.PendingJobReason#PENDING_JOB_REASON_UNDEFINED}, it could mean * that the job was ready to be executed at that time. */ @NonNull @JobScheduler.PendingJobReason public int[] getPendingJobReasons() { return mPendingJobReasons; } private PendingJobReasonsInfo(Parcel in) { mTimestampMillis = in.readLong(); mPendingJobReasons = in.createIntArray(); } @NonNull public static final Creator<PendingJobReasonsInfo> CREATOR = new Creator<>() { @Override public PendingJobReasonsInfo createFromParcel(Parcel in) { return new PendingJobReasonsInfo(in); } @Override public PendingJobReasonsInfo[] newArray(int size) { return new PendingJobReasonsInfo[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeLong(mTimestampMillis); dest.writeIntArray(mPendingJobReasons); } } Loading
apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java +12 −0 Original line number Diff line number Diff line Loading @@ -25,11 +25,13 @@ import android.app.job.JobInfo; import android.app.job.JobScheduler; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.app.job.PendingJobReasonsInfo; import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.RemoteException; import android.util.ArrayMap; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -182,6 +184,16 @@ public class JobSchedulerImpl extends JobScheduler { } } @Override @NonNull public List<PendingJobReasonsInfo> getPendingJobReasonsHistory(int jobId) { try { return mBinder.getPendingJobReasonsHistory(mNamespace, jobId); } catch (RemoteException e) { return Collections.EMPTY_LIST; } } @Override public boolean canRunUserInitiatedJobs() { try { Loading
apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.job.IUserVisibleJobObserver; import android.app.job.JobInfo; import android.app.job.JobSnapshot; import android.app.job.JobWorkItem; import android.app.job.PendingJobReasonsInfo; import android.content.pm.ParceledListSlice; import java.util.Map; Loading @@ -40,6 +41,7 @@ interface IJobScheduler { JobInfo getPendingJob(String namespace, int jobId); int getPendingJobReason(String namespace, int jobId); int[] getPendingJobReasons(String namespace, int jobId); List<PendingJobReasonsInfo> getPendingJobReasonsHistory(String namespace, int jobId); boolean canRunUserInitiatedJobs(String packageName); boolean hasRunUserInitiatedJobsPermission(String packageName, int userId); List<JobInfo> getStartedJobs(); Loading
apex/jobscheduler/framework/java/android/app/job/JobScheduler.java +28 −0 Original line number Diff line number Diff line Loading @@ -492,6 +492,34 @@ public abstract class JobScheduler { return new int[] { PENDING_JOB_REASON_UNDEFINED }; } /** * For the given {@code jobId}, returns a limited historical view of why the job may have * been pending execution. The returned list is composed of {@link PendingJobReasonsInfo} * objects, each of which include a timestamp since epoch along with an array of * unsatisfied constraints represented by {@link PendingJobReason PendingJobReason constants}. * <p> * These constants could either be explicitly set constraints on the job or implicit * constraints imposed by the system due to various reasons. * The results can be used to debug why a given job may have been pending execution. * <p> * If the only {@link PendingJobReason} for the timestamp is * {@link PendingJobReason#PENDING_JOB_REASON_UNDEFINED}, it could mean that * the job was ready to be executed at that point in time. * <p> * Note: there is no set interval for the timestamps in the returned list since * constraint changes occur based on device status and various other factors. * <p> * Note: the pending job reasons history is not persisted across device reboots. * <p> * @throws IllegalArgumentException if the {@code jobId} is invalid. * @see #getPendingJobReasons(int) */ @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_HISTORY_API) @NonNull public List<PendingJobReasonsInfo> getPendingJobReasonsHistory(int jobId) { throw new UnsupportedOperationException("Not implemented by " + getClass()); } /** * Returns {@code true} if the calling app currently holds the * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run Loading
apex/jobscheduler/framework/java/android/app/job/PendingJobReasonsInfo.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.job; parcelable PendingJobReasonsInfo;
apex/jobscheduler/framework/java/android/app/job/PendingJobReasonsInfo.java 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.job; import android.annotation.CurrentTimeMillisLong; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; /** * A simple wrapper which includes a timestamp (in millis since epoch) * and an array of {@link JobScheduler.PendingJobReason reasons} at that timestamp * for why a particular job may be pending. */ @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_HISTORY_API) public final class PendingJobReasonsInfo implements Parcelable { @CurrentTimeMillisLong private final long mTimestampMillis; @NonNull @JobScheduler.PendingJobReason private final int[] mPendingJobReasons; public PendingJobReasonsInfo(long timestampMillis, @NonNull @JobScheduler.PendingJobReason int[] reasons) { mTimestampMillis = timestampMillis; mPendingJobReasons = reasons; } /** * @return the time (in millis since epoch) associated with the set of pending job reasons. */ @CurrentTimeMillisLong public long getTimestampMillis() { return mTimestampMillis; } /** * Returns a set of {@link android.app.job.JobScheduler.PendingJobReason reasons} representing * why the job may not have executed at the associated timestamp. * <p> * These reasons could either be explicitly set constraints on the job or implicit * constraints imposed by the system due to various reasons. * <p> * Note: if the only {@link android.app.job.JobScheduler.PendingJobReason} present is * {@link JobScheduler.PendingJobReason#PENDING_JOB_REASON_UNDEFINED}, it could mean * that the job was ready to be executed at that time. */ @NonNull @JobScheduler.PendingJobReason public int[] getPendingJobReasons() { return mPendingJobReasons; } private PendingJobReasonsInfo(Parcel in) { mTimestampMillis = in.readLong(); mPendingJobReasons = in.createIntArray(); } @NonNull public static final Creator<PendingJobReasonsInfo> CREATOR = new Creator<>() { @Override public PendingJobReasonsInfo createFromParcel(Parcel in) { return new PendingJobReasonsInfo(in); } @Override public PendingJobReasonsInfo[] newArray(int size) { return new PendingJobReasonsInfo[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeLong(mTimestampMillis); dest.writeIntArray(mPendingJobReasons); } }