Loading apex/jobscheduler/framework/java/android/app/job/IJobCallback.aidl +0 −39 Original line number Original line Diff line number Diff line Loading @@ -29,25 +29,6 @@ import android.app.job.JobWorkItem; * {@hide} * {@hide} */ */ interface IJobCallback { interface IJobCallback { /** * Immediate callback to the system after sending a data transfer download progress request * signal; used to quickly detect ANR. * * @param jobId Unique integer used to identify this job. * @param workId Unique integer used to identify a specific work item. * @param transferredBytes How much data has been downloaded, in bytes. */ void acknowledgeGetTransferredDownloadBytesMessage(int jobId, int workId, long transferredBytes); /** * Immediate callback to the system after sending a data transfer upload progress request * signal; used to quickly detect ANR. * * @param jobId Unique integer used to identify this job. * @param workId Unique integer used to identify a specific work item. * @param transferredBytes How much data has been uploaded, in bytes. */ void acknowledgeGetTransferredUploadBytesMessage(int jobId, int workId, long transferredBytes); /** /** * Immediate callback to the system after sending a start signal, used to quickly detect ANR. * Immediate callback to the system after sending a start signal, used to quickly detect ANR. * * Loading Loading @@ -84,24 +65,4 @@ interface IJobCallback { */ */ @UnsupportedAppUsage @UnsupportedAppUsage void jobFinished(int jobId, boolean reschedule); void jobFinished(int jobId, boolean reschedule); /* * Inform JobScheduler of a change in the estimated transfer payload. * * @param jobId Unique integer used to identify this job. * @param item The particular JobWorkItem this progress is associated with, if any. * @param downloadBytes How many bytes the app expects to download. * @param uploadBytes How many bytes the app expects to upload. */ void updateEstimatedNetworkBytes(int jobId, in JobWorkItem item, long downloadBytes, long uploadBytes); /* * Update JobScheduler of how much data the job has successfully transferred. * * @param jobId Unique integer used to identify this job. * @param item The particular JobWorkItem this progress is associated with, if any. * @param transferredDownloadBytes The number of bytes that have successfully been downloaded. * @param transferredUploadBytes The number of bytes that have successfully been uploaded. */ void updateTransferredNetworkBytes(int jobId, in JobWorkItem item, long transferredDownloadBytes, long transferredUploadBytes); } } apex/jobscheduler/framework/java/android/app/job/IJobService.aidl +0 −5 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.app.job; package android.app.job; import android.app.job.JobParameters; import android.app.job.JobParameters; import android.app.job.JobWorkItem; /** /** * Interface that the framework uses to communicate with application code that implements a * Interface that the framework uses to communicate with application code that implements a Loading @@ -32,8 +31,4 @@ oneway interface IJobService { /** Stop execution of application's job. */ /** Stop execution of application's job. */ @UnsupportedAppUsage @UnsupportedAppUsage void stopJob(in JobParameters jobParams); void stopJob(in JobParameters jobParams); /** Update JS of how much data has been downloaded. */ void getTransferredDownloadBytes(in JobParameters jobParams, in JobWorkItem jobWorkItem); /** Update JS of how much data has been uploaded. */ void getTransferredUploadBytes(in JobParameters jobParams, in JobWorkItem jobWorkItem); } } apex/jobscheduler/framework/java/android/app/job/JobScheduler.java +0 −13 Original line number Original line Diff line number Diff line Loading @@ -23,11 +23,8 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.SystemService; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.ClipData; import android.content.ClipData; import android.content.Context; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.os.Bundle; import android.os.PersistableBundle; import android.os.PersistableBundle; Loading Loading @@ -97,16 +94,6 @@ import java.util.List; */ */ @SystemService(Context.JOB_SCHEDULER_SERVICE) @SystemService(Context.JOB_SCHEDULER_SERVICE) public abstract class JobScheduler { public abstract class JobScheduler { /** * Whether to throw an exception when an app doesn't properly implement all the necessary * data transfer APIs. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION = 255371817L; /** @hide */ /** @hide */ @IntDef(prefix = { "RESULT_" }, value = { @IntDef(prefix = { "RESULT_" }, value = { RESULT_FAILURE, RESULT_FAILURE, Loading apex/jobscheduler/framework/java/android/app/job/JobService.java +0 −185 Original line number Original line Diff line number Diff line Loading @@ -16,13 +16,7 @@ package android.app.job; package android.app.job; import static android.app.job.JobScheduler.THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION; import android.annotation.BytesLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Service; import android.app.Service; import android.compat.Compatibility; import android.content.Intent; import android.content.Intent; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -78,28 +72,6 @@ public abstract class JobService extends Service { public boolean onStopJob(JobParameters params) { public boolean onStopJob(JobParameters params) { return JobService.this.onStopJob(params); return JobService.this.onStopJob(params); } } @Override @BytesLong public long getTransferredDownloadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (item == null) { return JobService.this.getTransferredDownloadBytes(); } else { return JobService.this.getTransferredDownloadBytes(item); } } @Override @BytesLong public long getTransferredUploadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (item == null) { return JobService.this.getTransferredUploadBytes(); } else { return JobService.this.getTransferredUploadBytes(item); } } }; }; } } return mEngine.getBinder(); return mEngine.getBinder(); Loading Loading @@ -199,161 +171,4 @@ public abstract class JobService extends Service { * to end the job entirely. Regardless of the value returned, your job must stop executing. * to end the job entirely. Regardless of the value returned, your job must stop executing. */ */ public abstract boolean onStopJob(JobParameters params); public abstract boolean onStopJob(JobParameters params); /** * Update how much data this job will transfer. This method can * be called multiple times within the first 30 seconds after * {@link #onStartJob(JobParameters)} has been called. Only * one call will be heeded after that time has passed. * * This method (or an overload) must be called within the first * 30 seconds for a data transfer job if a payload size estimate * was not provided at the time of scheduling. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) */ public final void updateEstimatedNetworkBytes(@NonNull JobParameters params, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { mEngine.updateEstimatedNetworkBytes(params, null, downloadBytes, uploadBytes); } /** * Update how much data will transfer for the JobWorkItem. This * method can be called multiple times within the first 30 seconds * after {@link #onStartJob(JobParameters)} has been called. * Only one call will be heeded after that time has passed. * * This method (or an overload) must be called within the first * 30 seconds for a data transfer job if a payload size estimate * was not provided at the time of scheduling. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) */ public final void updateEstimatedNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem jobWorkItem, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { mEngine.updateEstimatedNetworkBytes(params, jobWorkItem, downloadBytes, uploadBytes); } /** * Tell JobScheduler how much data has successfully been transferred for the data transfer job. */ public final void updateTransferredNetworkBytes(@NonNull JobParameters params, @BytesLong long transferredDownloadBytes, @BytesLong long transferredUploadBytes) { mEngine.updateTransferredNetworkBytes(params, null, transferredDownloadBytes, transferredUploadBytes); } /** * Tell JobScheduler how much data has been transferred for the data transfer * {@link JobWorkItem}. */ public final void updateTransferredNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem item, @BytesLong long transferredDownloadBytes, @BytesLong long transferredUploadBytes) { mEngine.updateTransferredNetworkBytes(params, item, transferredDownloadBytes, transferredUploadBytes); } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated download bytes and * {@link #updateTransferredNetworkBytes(JobParameters, long, long)} * hasn't been called recently. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredDownloadBytes() { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated upload bytes and * {@link #updateTransferredNetworkBytes(JobParameters, long, long)} * hasn't been called recently. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredUploadBytes() { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated download bytes and * {@link #updateTransferredNetworkBytes(JobParameters, JobWorkItem, long, long)} * hasn't been called recently and the job has * {@link JobWorkItem JobWorkItems} that have been * {@link JobParameters#dequeueWork dequeued} but not * {@link JobParameters#completeWork(JobWorkItem) completed}. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredDownloadBytes(@NonNull JobWorkItem item) { if (item == null) { return getTransferredDownloadBytes(); } if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated upload bytes and * {@link #updateTransferredNetworkBytes(JobParameters, JobWorkItem, long, long)} * hasn't been called recently and the job has * {@link JobWorkItem JobWorkItems} that have been * {@link JobParameters#dequeueWork dequeued} but not * {@link JobParameters#completeWork(JobWorkItem) completed}. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredUploadBytes(@NonNull JobWorkItem item) { if (item == null) { return getTransferredUploadBytes(); } if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } } } apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java +5 −220 Original line number Original line Diff line number Diff line Loading @@ -16,13 +16,7 @@ package android.app.job; package android.app.job; import static android.app.job.JobScheduler.THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION; import android.annotation.BytesLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Service; import android.app.Service; import android.compat.Compatibility; import android.content.Intent; import android.content.Intent; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; Loading @@ -31,8 +25,6 @@ import android.os.Message; import android.os.RemoteException; import android.os.RemoteException; import android.util.Log; import android.util.Log; import com.android.internal.os.SomeArgs; import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; /** /** Loading @@ -59,20 +51,6 @@ public abstract class JobServiceEngine { * Message that the client has completed execution of this job. * Message that the client has completed execution of this job. */ */ private static final int MSG_JOB_FINISHED = 2; private static final int MSG_JOB_FINISHED = 2; /** * Message that will result in a call to * {@link #getTransferredDownloadBytes(JobParameters, JobWorkItem)}. */ private static final int MSG_GET_TRANSFERRED_DOWNLOAD_BYTES = 3; /** * Message that will result in a call to * {@link #getTransferredUploadBytes(JobParameters, JobWorkItem)}. */ private static final int MSG_GET_TRANSFERRED_UPLOAD_BYTES = 4; /** Message that the client wants to update JobScheduler of the data transfer progress. */ private static final int MSG_UPDATE_TRANSFERRED_NETWORK_BYTES = 5; /** Message that the client wants to update JobScheduler of the estimated transfer size. */ private static final int MSG_UPDATE_ESTIMATED_NETWORK_BYTES = 6; private final IJobService mBinder; private final IJobService mBinder; Loading @@ -89,32 +67,6 @@ public abstract class JobServiceEngine { mService = new WeakReference<>(service); mService = new WeakReference<>(service); } } @Override public void getTransferredDownloadBytes(@NonNull JobParameters jobParams, @Nullable JobWorkItem jobWorkItem) throws RemoteException { JobServiceEngine service = mService.get(); if (service != null) { SomeArgs args = SomeArgs.obtain(); args.arg1 = jobParams; args.arg2 = jobWorkItem; service.mHandler.obtainMessage(MSG_GET_TRANSFERRED_DOWNLOAD_BYTES, args) .sendToTarget(); } } @Override public void getTransferredUploadBytes(@NonNull JobParameters jobParams, @Nullable JobWorkItem jobWorkItem) throws RemoteException { JobServiceEngine service = mService.get(); if (service != null) { SomeArgs args = SomeArgs.obtain(); args.arg1 = jobParams; args.arg2 = jobWorkItem; service.mHandler.obtainMessage(MSG_GET_TRANSFERRED_UPLOAD_BYTES, args) .sendToTarget(); } } @Override @Override public void startJob(JobParameters jobParams) throws RemoteException { public void startJob(JobParameters jobParams) throws RemoteException { JobServiceEngine service = mService.get(); JobServiceEngine service = mService.get(); Loading Loading @@ -146,9 +98,9 @@ public abstract class JobServiceEngine { @Override @Override public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { case MSG_EXECUTE_JOB: { final JobParameters params = (JobParameters) msg.obj; final JobParameters params = (JobParameters) msg.obj; switch (msg.what) { case MSG_EXECUTE_JOB: try { try { boolean workOngoing = JobServiceEngine.this.onStartJob(params); boolean workOngoing = JobServiceEngine.this.onStartJob(params); ackStartMessage(params, workOngoing); ackStartMessage(params, workOngoing); Loading @@ -157,9 +109,7 @@ public abstract class JobServiceEngine { throw new RuntimeException(e); throw new RuntimeException(e); } } break; break; } case MSG_STOP_JOB: case MSG_STOP_JOB: { final JobParameters params = (JobParameters) msg.obj; try { try { boolean ret = JobServiceEngine.this.onStopJob(params); boolean ret = JobServiceEngine.this.onStopJob(params); ackStopMessage(params, ret); ackStopMessage(params, ret); Loading @@ -168,9 +118,7 @@ public abstract class JobServiceEngine { throw new RuntimeException(e); throw new RuntimeException(e); } } break; break; } case MSG_JOB_FINISHED: case MSG_JOB_FINISHED: { final JobParameters params = (JobParameters) msg.obj; final boolean needsReschedule = (msg.arg2 == 1); final boolean needsReschedule = (msg.arg2 == 1); IJobCallback callback = params.getCallback(); IJobCallback callback = params.getCallback(); if (callback != null) { if (callback != null) { Loading @@ -184,110 +132,12 @@ public abstract class JobServiceEngine { Log.e(TAG, "finishJob() called for a nonexistent job id."); Log.e(TAG, "finishJob() called for a nonexistent job id."); } } break; break; } case MSG_GET_TRANSFERRED_DOWNLOAD_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; final JobWorkItem item = (JobWorkItem) args.arg2; try { long ret = JobServiceEngine.this.getTransferredDownloadBytes(params, item); ackGetTransferredDownloadBytesMessage(params, item, ret); } catch (Exception e) { Log.e(TAG, "Application unable to handle getTransferredDownloadBytes.", e); throw new RuntimeException(e); } args.recycle(); break; } case MSG_GET_TRANSFERRED_UPLOAD_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; final JobWorkItem item = (JobWorkItem) args.arg2; try { long ret = JobServiceEngine.this.getTransferredUploadBytes(params, item); ackGetTransferredUploadBytesMessage(params, item, ret); } catch (Exception e) { Log.e(TAG, "Application unable to handle getTransferredUploadBytes.", e); throw new RuntimeException(e); } args.recycle(); break; } case MSG_UPDATE_TRANSFERRED_NETWORK_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; IJobCallback callback = params.getCallback(); if (callback != null) { try { callback.updateTransferredNetworkBytes(params.getJobId(), (JobWorkItem) args.arg2, args.argl1, args.argl2); } catch (RemoteException e) { Log.e(TAG, "Error updating data transfer progress to system:" + " binder has gone away."); } } else { Log.e(TAG, "updateDataTransferProgress() called for a nonexistent job id."); } args.recycle(); break; } case MSG_UPDATE_ESTIMATED_NETWORK_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; IJobCallback callback = params.getCallback(); if (callback != null) { try { callback.updateEstimatedNetworkBytes(params.getJobId(), (JobWorkItem) args.arg2, args.argl1, args.argl2); } catch (RemoteException e) { Log.e(TAG, "Error updating estimated transfer size to system:" + " binder has gone away."); } } else { Log.e(TAG, "updateEstimatedNetworkBytes() called for a nonexistent job id."); } args.recycle(); break; } default: default: Log.e(TAG, "Unrecognised message received."); Log.e(TAG, "Unrecognised message received."); break; break; } } } } private void ackGetTransferredDownloadBytesMessage(@NonNull JobParameters params, @Nullable JobWorkItem item, long progress) { final IJobCallback callback = params.getCallback(); final int jobId = params.getJobId(); final int workId = item == null ? -1 : item.getWorkId(); if (callback != null) { try { callback.acknowledgeGetTransferredDownloadBytesMessage(jobId, workId, progress); } catch (RemoteException e) { Log.e(TAG, "System unreachable for returning progress."); } } else if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Attempting to ack a job that has already been processed."); } } private void ackGetTransferredUploadBytesMessage(@NonNull JobParameters params, @Nullable JobWorkItem item, long progress) { final IJobCallback callback = params.getCallback(); final int jobId = params.getJobId(); final int workId = item == null ? -1 : item.getWorkId(); if (callback != null) { try { callback.acknowledgeGetTransferredUploadBytesMessage(jobId, workId, progress); } catch (RemoteException e) { Log.e(TAG, "System unreachable for returning progress."); } } else if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Attempting to ack a job that has already been processed."); } } private void ackStartMessage(JobParameters params, boolean workOngoing) { private void ackStartMessage(JobParameters params, boolean workOngoing) { final IJobCallback callback = params.getCallback(); final IJobCallback callback = params.getCallback(); final int jobId = params.getJobId(); final int jobId = params.getJobId(); Loading Loading @@ -363,69 +213,4 @@ public abstract class JobServiceEngine { m.arg2 = needsReschedule ? 1 : 0; m.arg2 = needsReschedule ? 1 : 0; m.sendToTarget(); m.sendToTarget(); } } /** * Engine's request to get how much data has been downloaded. * * @see JobService#getTransferredDownloadBytes() */ @BytesLong public long getTransferredDownloadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Engine's request to get how much data has been uploaded. * * @see JobService#getTransferredUploadBytes() */ @BytesLong public long getTransferredUploadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Call in to engine to report data transfer progress. * * @see JobService#updateTransferredNetworkBytes(JobParameters, long, long) */ public void updateTransferredNetworkBytes(@NonNull JobParameters params, @Nullable JobWorkItem item, long downloadBytes, long uploadBytes) { if (params == null) { throw new NullPointerException("params"); } SomeArgs args = SomeArgs.obtain(); args.arg1 = params; args.arg2 = item; args.argl1 = downloadBytes; args.argl2 = uploadBytes; mHandler.obtainMessage(MSG_UPDATE_TRANSFERRED_NETWORK_BYTES, args).sendToTarget(); } /** * Call in to engine to report data transfer progress. * * @see JobService#updateEstimatedNetworkBytes(JobParameters, JobWorkItem, long, long) */ public void updateEstimatedNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem item, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { if (params == null) { throw new NullPointerException("params"); } SomeArgs args = SomeArgs.obtain(); args.arg1 = params; args.arg2 = item; args.argl1 = downloadBytes; args.argl2 = uploadBytes; mHandler.obtainMessage(MSG_UPDATE_ESTIMATED_NETWORK_BYTES, args).sendToTarget(); } } } No newline at end of file Loading
apex/jobscheduler/framework/java/android/app/job/IJobCallback.aidl +0 −39 Original line number Original line Diff line number Diff line Loading @@ -29,25 +29,6 @@ import android.app.job.JobWorkItem; * {@hide} * {@hide} */ */ interface IJobCallback { interface IJobCallback { /** * Immediate callback to the system after sending a data transfer download progress request * signal; used to quickly detect ANR. * * @param jobId Unique integer used to identify this job. * @param workId Unique integer used to identify a specific work item. * @param transferredBytes How much data has been downloaded, in bytes. */ void acknowledgeGetTransferredDownloadBytesMessage(int jobId, int workId, long transferredBytes); /** * Immediate callback to the system after sending a data transfer upload progress request * signal; used to quickly detect ANR. * * @param jobId Unique integer used to identify this job. * @param workId Unique integer used to identify a specific work item. * @param transferredBytes How much data has been uploaded, in bytes. */ void acknowledgeGetTransferredUploadBytesMessage(int jobId, int workId, long transferredBytes); /** /** * Immediate callback to the system after sending a start signal, used to quickly detect ANR. * Immediate callback to the system after sending a start signal, used to quickly detect ANR. * * Loading Loading @@ -84,24 +65,4 @@ interface IJobCallback { */ */ @UnsupportedAppUsage @UnsupportedAppUsage void jobFinished(int jobId, boolean reschedule); void jobFinished(int jobId, boolean reschedule); /* * Inform JobScheduler of a change in the estimated transfer payload. * * @param jobId Unique integer used to identify this job. * @param item The particular JobWorkItem this progress is associated with, if any. * @param downloadBytes How many bytes the app expects to download. * @param uploadBytes How many bytes the app expects to upload. */ void updateEstimatedNetworkBytes(int jobId, in JobWorkItem item, long downloadBytes, long uploadBytes); /* * Update JobScheduler of how much data the job has successfully transferred. * * @param jobId Unique integer used to identify this job. * @param item The particular JobWorkItem this progress is associated with, if any. * @param transferredDownloadBytes The number of bytes that have successfully been downloaded. * @param transferredUploadBytes The number of bytes that have successfully been uploaded. */ void updateTransferredNetworkBytes(int jobId, in JobWorkItem item, long transferredDownloadBytes, long transferredUploadBytes); } }
apex/jobscheduler/framework/java/android/app/job/IJobService.aidl +0 −5 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ package android.app.job; package android.app.job; import android.app.job.JobParameters; import android.app.job.JobParameters; import android.app.job.JobWorkItem; /** /** * Interface that the framework uses to communicate with application code that implements a * Interface that the framework uses to communicate with application code that implements a Loading @@ -32,8 +31,4 @@ oneway interface IJobService { /** Stop execution of application's job. */ /** Stop execution of application's job. */ @UnsupportedAppUsage @UnsupportedAppUsage void stopJob(in JobParameters jobParams); void stopJob(in JobParameters jobParams); /** Update JS of how much data has been downloaded. */ void getTransferredDownloadBytes(in JobParameters jobParams, in JobWorkItem jobWorkItem); /** Update JS of how much data has been uploaded. */ void getTransferredUploadBytes(in JobParameters jobParams, in JobWorkItem jobWorkItem); } }
apex/jobscheduler/framework/java/android/app/job/JobScheduler.java +0 −13 Original line number Original line Diff line number Diff line Loading @@ -23,11 +23,8 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.SystemService; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.ClipData; import android.content.ClipData; import android.content.Context; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.os.Bundle; import android.os.PersistableBundle; import android.os.PersistableBundle; Loading Loading @@ -97,16 +94,6 @@ import java.util.List; */ */ @SystemService(Context.JOB_SCHEDULER_SERVICE) @SystemService(Context.JOB_SCHEDULER_SERVICE) public abstract class JobScheduler { public abstract class JobScheduler { /** * Whether to throw an exception when an app doesn't properly implement all the necessary * data transfer APIs. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION = 255371817L; /** @hide */ /** @hide */ @IntDef(prefix = { "RESULT_" }, value = { @IntDef(prefix = { "RESULT_" }, value = { RESULT_FAILURE, RESULT_FAILURE, Loading
apex/jobscheduler/framework/java/android/app/job/JobService.java +0 −185 Original line number Original line Diff line number Diff line Loading @@ -16,13 +16,7 @@ package android.app.job; package android.app.job; import static android.app.job.JobScheduler.THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION; import android.annotation.BytesLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Service; import android.app.Service; import android.compat.Compatibility; import android.content.Intent; import android.content.Intent; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -78,28 +72,6 @@ public abstract class JobService extends Service { public boolean onStopJob(JobParameters params) { public boolean onStopJob(JobParameters params) { return JobService.this.onStopJob(params); return JobService.this.onStopJob(params); } } @Override @BytesLong public long getTransferredDownloadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (item == null) { return JobService.this.getTransferredDownloadBytes(); } else { return JobService.this.getTransferredDownloadBytes(item); } } @Override @BytesLong public long getTransferredUploadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (item == null) { return JobService.this.getTransferredUploadBytes(); } else { return JobService.this.getTransferredUploadBytes(item); } } }; }; } } return mEngine.getBinder(); return mEngine.getBinder(); Loading Loading @@ -199,161 +171,4 @@ public abstract class JobService extends Service { * to end the job entirely. Regardless of the value returned, your job must stop executing. * to end the job entirely. Regardless of the value returned, your job must stop executing. */ */ public abstract boolean onStopJob(JobParameters params); public abstract boolean onStopJob(JobParameters params); /** * Update how much data this job will transfer. This method can * be called multiple times within the first 30 seconds after * {@link #onStartJob(JobParameters)} has been called. Only * one call will be heeded after that time has passed. * * This method (or an overload) must be called within the first * 30 seconds for a data transfer job if a payload size estimate * was not provided at the time of scheduling. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) */ public final void updateEstimatedNetworkBytes(@NonNull JobParameters params, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { mEngine.updateEstimatedNetworkBytes(params, null, downloadBytes, uploadBytes); } /** * Update how much data will transfer for the JobWorkItem. This * method can be called multiple times within the first 30 seconds * after {@link #onStartJob(JobParameters)} has been called. * Only one call will be heeded after that time has passed. * * This method (or an overload) must be called within the first * 30 seconds for a data transfer job if a payload size estimate * was not provided at the time of scheduling. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) */ public final void updateEstimatedNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem jobWorkItem, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { mEngine.updateEstimatedNetworkBytes(params, jobWorkItem, downloadBytes, uploadBytes); } /** * Tell JobScheduler how much data has successfully been transferred for the data transfer job. */ public final void updateTransferredNetworkBytes(@NonNull JobParameters params, @BytesLong long transferredDownloadBytes, @BytesLong long transferredUploadBytes) { mEngine.updateTransferredNetworkBytes(params, null, transferredDownloadBytes, transferredUploadBytes); } /** * Tell JobScheduler how much data has been transferred for the data transfer * {@link JobWorkItem}. */ public final void updateTransferredNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem item, @BytesLong long transferredDownloadBytes, @BytesLong long transferredUploadBytes) { mEngine.updateTransferredNetworkBytes(params, item, transferredDownloadBytes, transferredUploadBytes); } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated download bytes and * {@link #updateTransferredNetworkBytes(JobParameters, long, long)} * hasn't been called recently. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredDownloadBytes() { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated upload bytes and * {@link #updateTransferredNetworkBytes(JobParameters, long, long)} * hasn't been called recently. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredUploadBytes() { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated download bytes and * {@link #updateTransferredNetworkBytes(JobParameters, JobWorkItem, long, long)} * hasn't been called recently and the job has * {@link JobWorkItem JobWorkItems} that have been * {@link JobParameters#dequeueWork dequeued} but not * {@link JobParameters#completeWork(JobWorkItem) completed}. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredDownloadBytes(@NonNull JobWorkItem item) { if (item == null) { return getTransferredDownloadBytes(); } if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Get the number of bytes the app has successfully downloaded for this job. JobScheduler * will call this if the job has specified positive estimated upload bytes and * {@link #updateTransferredNetworkBytes(JobParameters, JobWorkItem, long, long)} * hasn't been called recently and the job has * {@link JobWorkItem JobWorkItems} that have been * {@link JobParameters#dequeueWork dequeued} but not * {@link JobParameters#completeWork(JobWorkItem) completed}. * * <p> * This must be implemented for all data transfer jobs. * * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @BytesLong public long getTransferredUploadBytes(@NonNull JobWorkItem item) { if (item == null) { return getTransferredUploadBytes(); } if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { // Regular jobs don't have to implement this and JobScheduler won't call this API for // non-data transfer jobs. throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } } }
apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java +5 −220 Original line number Original line Diff line number Diff line Loading @@ -16,13 +16,7 @@ package android.app.job; package android.app.job; import static android.app.job.JobScheduler.THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION; import android.annotation.BytesLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Service; import android.app.Service; import android.compat.Compatibility; import android.content.Intent; import android.content.Intent; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; Loading @@ -31,8 +25,6 @@ import android.os.Message; import android.os.RemoteException; import android.os.RemoteException; import android.util.Log; import android.util.Log; import com.android.internal.os.SomeArgs; import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; /** /** Loading @@ -59,20 +51,6 @@ public abstract class JobServiceEngine { * Message that the client has completed execution of this job. * Message that the client has completed execution of this job. */ */ private static final int MSG_JOB_FINISHED = 2; private static final int MSG_JOB_FINISHED = 2; /** * Message that will result in a call to * {@link #getTransferredDownloadBytes(JobParameters, JobWorkItem)}. */ private static final int MSG_GET_TRANSFERRED_DOWNLOAD_BYTES = 3; /** * Message that will result in a call to * {@link #getTransferredUploadBytes(JobParameters, JobWorkItem)}. */ private static final int MSG_GET_TRANSFERRED_UPLOAD_BYTES = 4; /** Message that the client wants to update JobScheduler of the data transfer progress. */ private static final int MSG_UPDATE_TRANSFERRED_NETWORK_BYTES = 5; /** Message that the client wants to update JobScheduler of the estimated transfer size. */ private static final int MSG_UPDATE_ESTIMATED_NETWORK_BYTES = 6; private final IJobService mBinder; private final IJobService mBinder; Loading @@ -89,32 +67,6 @@ public abstract class JobServiceEngine { mService = new WeakReference<>(service); mService = new WeakReference<>(service); } } @Override public void getTransferredDownloadBytes(@NonNull JobParameters jobParams, @Nullable JobWorkItem jobWorkItem) throws RemoteException { JobServiceEngine service = mService.get(); if (service != null) { SomeArgs args = SomeArgs.obtain(); args.arg1 = jobParams; args.arg2 = jobWorkItem; service.mHandler.obtainMessage(MSG_GET_TRANSFERRED_DOWNLOAD_BYTES, args) .sendToTarget(); } } @Override public void getTransferredUploadBytes(@NonNull JobParameters jobParams, @Nullable JobWorkItem jobWorkItem) throws RemoteException { JobServiceEngine service = mService.get(); if (service != null) { SomeArgs args = SomeArgs.obtain(); args.arg1 = jobParams; args.arg2 = jobWorkItem; service.mHandler.obtainMessage(MSG_GET_TRANSFERRED_UPLOAD_BYTES, args) .sendToTarget(); } } @Override @Override public void startJob(JobParameters jobParams) throws RemoteException { public void startJob(JobParameters jobParams) throws RemoteException { JobServiceEngine service = mService.get(); JobServiceEngine service = mService.get(); Loading Loading @@ -146,9 +98,9 @@ public abstract class JobServiceEngine { @Override @Override public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { case MSG_EXECUTE_JOB: { final JobParameters params = (JobParameters) msg.obj; final JobParameters params = (JobParameters) msg.obj; switch (msg.what) { case MSG_EXECUTE_JOB: try { try { boolean workOngoing = JobServiceEngine.this.onStartJob(params); boolean workOngoing = JobServiceEngine.this.onStartJob(params); ackStartMessage(params, workOngoing); ackStartMessage(params, workOngoing); Loading @@ -157,9 +109,7 @@ public abstract class JobServiceEngine { throw new RuntimeException(e); throw new RuntimeException(e); } } break; break; } case MSG_STOP_JOB: case MSG_STOP_JOB: { final JobParameters params = (JobParameters) msg.obj; try { try { boolean ret = JobServiceEngine.this.onStopJob(params); boolean ret = JobServiceEngine.this.onStopJob(params); ackStopMessage(params, ret); ackStopMessage(params, ret); Loading @@ -168,9 +118,7 @@ public abstract class JobServiceEngine { throw new RuntimeException(e); throw new RuntimeException(e); } } break; break; } case MSG_JOB_FINISHED: case MSG_JOB_FINISHED: { final JobParameters params = (JobParameters) msg.obj; final boolean needsReschedule = (msg.arg2 == 1); final boolean needsReschedule = (msg.arg2 == 1); IJobCallback callback = params.getCallback(); IJobCallback callback = params.getCallback(); if (callback != null) { if (callback != null) { Loading @@ -184,110 +132,12 @@ public abstract class JobServiceEngine { Log.e(TAG, "finishJob() called for a nonexistent job id."); Log.e(TAG, "finishJob() called for a nonexistent job id."); } } break; break; } case MSG_GET_TRANSFERRED_DOWNLOAD_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; final JobWorkItem item = (JobWorkItem) args.arg2; try { long ret = JobServiceEngine.this.getTransferredDownloadBytes(params, item); ackGetTransferredDownloadBytesMessage(params, item, ret); } catch (Exception e) { Log.e(TAG, "Application unable to handle getTransferredDownloadBytes.", e); throw new RuntimeException(e); } args.recycle(); break; } case MSG_GET_TRANSFERRED_UPLOAD_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; final JobWorkItem item = (JobWorkItem) args.arg2; try { long ret = JobServiceEngine.this.getTransferredUploadBytes(params, item); ackGetTransferredUploadBytesMessage(params, item, ret); } catch (Exception e) { Log.e(TAG, "Application unable to handle getTransferredUploadBytes.", e); throw new RuntimeException(e); } args.recycle(); break; } case MSG_UPDATE_TRANSFERRED_NETWORK_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; IJobCallback callback = params.getCallback(); if (callback != null) { try { callback.updateTransferredNetworkBytes(params.getJobId(), (JobWorkItem) args.arg2, args.argl1, args.argl2); } catch (RemoteException e) { Log.e(TAG, "Error updating data transfer progress to system:" + " binder has gone away."); } } else { Log.e(TAG, "updateDataTransferProgress() called for a nonexistent job id."); } args.recycle(); break; } case MSG_UPDATE_ESTIMATED_NETWORK_BYTES: { final SomeArgs args = (SomeArgs) msg.obj; final JobParameters params = (JobParameters) args.arg1; IJobCallback callback = params.getCallback(); if (callback != null) { try { callback.updateEstimatedNetworkBytes(params.getJobId(), (JobWorkItem) args.arg2, args.argl1, args.argl2); } catch (RemoteException e) { Log.e(TAG, "Error updating estimated transfer size to system:" + " binder has gone away."); } } else { Log.e(TAG, "updateEstimatedNetworkBytes() called for a nonexistent job id."); } args.recycle(); break; } default: default: Log.e(TAG, "Unrecognised message received."); Log.e(TAG, "Unrecognised message received."); break; break; } } } } private void ackGetTransferredDownloadBytesMessage(@NonNull JobParameters params, @Nullable JobWorkItem item, long progress) { final IJobCallback callback = params.getCallback(); final int jobId = params.getJobId(); final int workId = item == null ? -1 : item.getWorkId(); if (callback != null) { try { callback.acknowledgeGetTransferredDownloadBytesMessage(jobId, workId, progress); } catch (RemoteException e) { Log.e(TAG, "System unreachable for returning progress."); } } else if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Attempting to ack a job that has already been processed."); } } private void ackGetTransferredUploadBytesMessage(@NonNull JobParameters params, @Nullable JobWorkItem item, long progress) { final IJobCallback callback = params.getCallback(); final int jobId = params.getJobId(); final int workId = item == null ? -1 : item.getWorkId(); if (callback != null) { try { callback.acknowledgeGetTransferredUploadBytesMessage(jobId, workId, progress); } catch (RemoteException e) { Log.e(TAG, "System unreachable for returning progress."); } } else if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Attempting to ack a job that has already been processed."); } } private void ackStartMessage(JobParameters params, boolean workOngoing) { private void ackStartMessage(JobParameters params, boolean workOngoing) { final IJobCallback callback = params.getCallback(); final IJobCallback callback = params.getCallback(); final int jobId = params.getJobId(); final int jobId = params.getJobId(); Loading Loading @@ -363,69 +213,4 @@ public abstract class JobServiceEngine { m.arg2 = needsReschedule ? 1 : 0; m.arg2 = needsReschedule ? 1 : 0; m.sendToTarget(); m.sendToTarget(); } } /** * Engine's request to get how much data has been downloaded. * * @see JobService#getTransferredDownloadBytes() */ @BytesLong public long getTransferredDownloadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Engine's request to get how much data has been uploaded. * * @see JobService#getTransferredUploadBytes() */ @BytesLong public long getTransferredUploadBytes(@NonNull JobParameters params, @Nullable JobWorkItem item) { if (Compatibility.isChangeEnabled(THROW_ON_INVALID_DATA_TRANSFER_IMPLEMENTATION)) { throw new RuntimeException("Not implemented. Must override in a subclass."); } return 0; } /** * Call in to engine to report data transfer progress. * * @see JobService#updateTransferredNetworkBytes(JobParameters, long, long) */ public void updateTransferredNetworkBytes(@NonNull JobParameters params, @Nullable JobWorkItem item, long downloadBytes, long uploadBytes) { if (params == null) { throw new NullPointerException("params"); } SomeArgs args = SomeArgs.obtain(); args.arg1 = params; args.arg2 = item; args.argl1 = downloadBytes; args.argl2 = uploadBytes; mHandler.obtainMessage(MSG_UPDATE_TRANSFERRED_NETWORK_BYTES, args).sendToTarget(); } /** * Call in to engine to report data transfer progress. * * @see JobService#updateEstimatedNetworkBytes(JobParameters, JobWorkItem, long, long) */ public void updateEstimatedNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem item, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { if (params == null) { throw new NullPointerException("params"); } SomeArgs args = SomeArgs.obtain(); args.arg1 = params; args.arg2 = item; args.argl1 = downloadBytes; args.argl2 = uploadBytes; mHandler.obtainMessage(MSG_UPDATE_ESTIMATED_NETWORK_BYTES, args).sendToTarget(); } } } No newline at end of file