diff options
| author | Makoto Onuki <omakoto@google.com> | 2019-08-12 18:49:51 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-08-12 18:49:51 +0000 |
| commit | 3fedfcb409d85937c5b773d95ca7fdf8694c532e (patch) | |
| tree | 811a3e44f22f93d45b47a08f2a2839c006595dea /core/java/android | |
| parent | d5a2c65eb1015d7b6a880a0974679e4e1c642bcb (diff) | |
| parent | 62242c48e0511bd06a94b6e471cc70a2fb9d8a2a (diff) | |
Merge "Introduce framework-minus-apex and create jobscheduler-framework.jar"
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/JobSchedulerImpl.java | 121 | ||||
| -rw-r--r-- | core/java/android/app/job/IJobCallback.aidl | 68 | ||||
| -rw-r--r-- | core/java/android/app/job/IJobScheduler.aidl | 38 | ||||
| -rw-r--r-- | core/java/android/app/job/IJobService.aidl | 34 | ||||
| -rw-r--r-- | core/java/android/app/job/JobInfo.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/app/job/JobInfo.java | 1597 | ||||
| -rw-r--r-- | core/java/android/app/job/JobParameters.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/app/job/JobParameters.java | 372 | ||||
| -rw-r--r-- | core/java/android/app/job/JobScheduler.java | 191 | ||||
| -rw-r--r-- | core/java/android/app/job/JobSchedulerFrameworkInitializer.java | 39 | ||||
| -rw-r--r-- | core/java/android/app/job/JobService.java | 157 | ||||
| -rw-r--r-- | core/java/android/app/job/JobServiceEngine.java | 220 | ||||
| -rw-r--r-- | core/java/android/app/job/JobSnapshot.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/app/job/JobSnapshot.java | 119 | ||||
| -rw-r--r-- | core/java/android/app/job/JobWorkItem.aidl | 20 | ||||
| -rw-r--r-- | core/java/android/app/job/JobWorkItem.java | 212 |
16 files changed, 0 insertions, 3245 deletions
diff --git a/core/java/android/app/JobSchedulerImpl.java b/core/java/android/app/JobSchedulerImpl.java deleted file mode 100644 index 924a70809747..000000000000 --- a/core/java/android/app/JobSchedulerImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -// in android.app so ContextImpl has package access -package android.app; - -import android.app.job.IJobScheduler; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.app.job.JobSnapshot; -import android.app.job.JobWorkItem; -import android.os.RemoteException; - -import java.util.List; - - -// APEX NOTE: Class path referred to by robolectric, so can't move it. - -/** - * Concrete implementation of the JobScheduler interface - * @hide - */ -public class JobSchedulerImpl extends JobScheduler { - IJobScheduler mBinder; - - public JobSchedulerImpl(IJobScheduler binder) { - mBinder = binder; - } - - @Override - public int schedule(JobInfo job) { - try { - return mBinder.schedule(job); - } catch (RemoteException e) { - return JobScheduler.RESULT_FAILURE; - } - } - - @Override - public int enqueue(JobInfo job, JobWorkItem work) { - try { - return mBinder.enqueue(job, work); - } catch (RemoteException e) { - return JobScheduler.RESULT_FAILURE; - } - } - - @Override - public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) { - try { - return mBinder.scheduleAsPackage(job, packageName, userId, tag); - } catch (RemoteException e) { - return JobScheduler.RESULT_FAILURE; - } - } - - @Override - public void cancel(int jobId) { - try { - mBinder.cancel(jobId); - } catch (RemoteException e) {} - - } - - @Override - public void cancelAll() { - try { - mBinder.cancelAll(); - } catch (RemoteException e) {} - - } - - @Override - public List<JobInfo> getAllPendingJobs() { - try { - return mBinder.getAllPendingJobs().getList(); - } catch (RemoteException e) { - return null; - } - } - - @Override - public JobInfo getPendingJob(int jobId) { - try { - return mBinder.getPendingJob(jobId); - } catch (RemoteException e) { - return null; - } - } - - @Override - public List<JobInfo> getStartedJobs() { - try { - return mBinder.getStartedJobs(); - } catch (RemoteException e) { - return null; - } - } - - @Override - public List<JobSnapshot> getAllJobSnapshots() { - try { - return mBinder.getAllJobSnapshots().getList(); - } catch (RemoteException e) { - return null; - } - } -} diff --git a/core/java/android/app/job/IJobCallback.aidl b/core/java/android/app/job/IJobCallback.aidl deleted file mode 100644 index d281da037fde..000000000000 --- a/core/java/android/app/job/IJobCallback.aidl +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright 2014, 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.app.job.JobWorkItem; - -/** - * The server side of the JobScheduler IPC protocols. The app-side implementation - * invokes on this interface to indicate completion of the (asynchronous) instructions - * issued by the server. - * - * In all cases, the 'who' parameter is the caller's service binder, used to track - * which Job Service instance is reporting. - * - * {@hide} - */ -interface IJobCallback { - /** - * Immediate callback to the system after sending a start signal, used to quickly detect ANR. - * - * @param jobId Unique integer used to identify this job. - * @param ongoing True to indicate that the client is processing the job. False if the job is - * complete - */ - @UnsupportedAppUsage - void acknowledgeStartMessage(int jobId, boolean ongoing); - /** - * Immediate callback to the system after sending a stop signal, used to quickly detect ANR. - * - * @param jobId Unique integer used to identify this job. - * @param reschedule Whether or not to reschedule this job. - */ - @UnsupportedAppUsage - void acknowledgeStopMessage(int jobId, boolean reschedule); - /* - * Called to deqeue next work item for the job. - */ - @UnsupportedAppUsage - JobWorkItem dequeueWork(int jobId); - /* - * Called to report that job has completed processing a work item. - */ - @UnsupportedAppUsage - boolean completeWork(int jobId, int workId); - /* - * Tell the job manager that the client is done with its execution, so that it can go on to - * the next one and stop attributing wakelock time to us etc. - * - * @param jobId Unique integer used to identify this job. - * @param reschedule Whether or not to reschedule this job. - */ - @UnsupportedAppUsage - void jobFinished(int jobId, boolean reschedule); -} diff --git a/core/java/android/app/job/IJobScheduler.aidl b/core/java/android/app/job/IJobScheduler.aidl deleted file mode 100644 index 3006f50e54fc..000000000000 --- a/core/java/android/app/job/IJobScheduler.aidl +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2014 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.app.job.JobInfo; -import android.app.job.JobSnapshot; -import android.app.job.JobWorkItem; -import android.content.pm.ParceledListSlice; - - /** - * 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); - void cancelAll(); - ParceledListSlice getAllPendingJobs(); - JobInfo getPendingJob(int jobId); - List<JobInfo> getStartedJobs(); - ParceledListSlice getAllJobSnapshots(); -} diff --git a/core/java/android/app/job/IJobService.aidl b/core/java/android/app/job/IJobService.aidl deleted file mode 100644 index 22ad252b9639..000000000000 --- a/core/java/android/app/job/IJobService.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2014, 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.app.job.JobParameters; - -/** - * Interface that the framework uses to communicate with application code that implements a - * JobService. End user code does not implement this interface directly; instead, the app's - * service implementation will extend android.app.job.JobService. - * {@hide} - */ -oneway interface IJobService { - /** Begin execution of application's job. */ - @UnsupportedAppUsage - void startJob(in JobParameters jobParams); - /** Stop execution of application's job. */ - @UnsupportedAppUsage - void stopJob(in JobParameters jobParams); -} diff --git a/core/java/android/app/job/JobInfo.aidl b/core/java/android/app/job/JobInfo.aidl deleted file mode 100644 index 7b198a8ab14d..000000000000 --- a/core/java/android/app/job/JobInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (C) 2014 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 JobInfo; diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java deleted file mode 100644 index 8b3b3a28f2bc..000000000000 --- a/core/java/android/app/job/JobInfo.java +++ /dev/null @@ -1,1597 +0,0 @@ -/* - * Copyright (C) 2014 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 static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.util.TimeUtils.formatDuration; - -import android.annotation.BytesLong; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.UnsupportedAppUsage; -import android.content.ClipData; -import android.content.ComponentName; -import android.net.NetworkRequest; -import android.net.NetworkSpecifier; -import android.net.Uri; -import android.os.BaseBundle; -import android.os.Build; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.PersistableBundle; -import android.util.Log; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; - -/** - * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the - * parameters required to schedule work against the calling application. These are constructed - * using the {@link JobInfo.Builder}. - * You must specify at least one sort of constraint on the JobInfo object that you are creating. - * The goal here is to provide the scheduler with high-level semantics about the work you want to - * accomplish. Doing otherwise with throw an exception in your app. - */ -public class JobInfo implements Parcelable { - private static String TAG = "JobInfo"; - - /** @hide */ - @IntDef(prefix = { "NETWORK_TYPE_" }, value = { - NETWORK_TYPE_NONE, - NETWORK_TYPE_ANY, - NETWORK_TYPE_UNMETERED, - NETWORK_TYPE_NOT_ROAMING, - NETWORK_TYPE_CELLULAR, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface NetworkType {} - - /** Default. */ - public static final int NETWORK_TYPE_NONE = 0; - /** This job requires network connectivity. */ - public static final int NETWORK_TYPE_ANY = 1; - /** This job requires network connectivity that is unmetered. */ - public static final int NETWORK_TYPE_UNMETERED = 2; - /** This job requires network connectivity that is not roaming. */ - public static final int NETWORK_TYPE_NOT_ROAMING = 3; - /** This job requires network connectivity that is a cellular network. */ - public static final int NETWORK_TYPE_CELLULAR = 4; - - /** - * This job requires metered connectivity such as most cellular data - * networks. - * - * @deprecated Cellular networks may be unmetered, or Wi-Fi networks may be - * metered, so this isn't a good way of selecting a specific - * transport. Instead, use {@link #NETWORK_TYPE_CELLULAR} or - * {@link android.net.NetworkRequest.Builder#addTransportType(int)} - * if your job requires a specific network transport. - */ - @Deprecated - public static final int NETWORK_TYPE_METERED = NETWORK_TYPE_CELLULAR; - - /** Sentinel value indicating that bytes are unknown. */ - public static final int NETWORK_BYTES_UNKNOWN = -1; - - /** - * Amount of backoff a job has initially by default, in milliseconds. - */ - public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 30000L; // 30 seconds. - - /** - * Maximum backoff we allow for a job, in milliseconds. - */ - public static final long MAX_BACKOFF_DELAY_MILLIS = 5 * 60 * 60 * 1000; // 5 hours. - - /** @hide */ - @IntDef(prefix = { "BACKOFF_POLICY_" }, value = { - BACKOFF_POLICY_LINEAR, - BACKOFF_POLICY_EXPONENTIAL, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface BackoffPolicy {} - - /** - * Linearly back-off a failed job. See - * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)} - * retry_time(current_time, num_failures) = - * current_time + initial_backoff_millis * num_failures, num_failures >= 1 - */ - public static final int BACKOFF_POLICY_LINEAR = 0; - - /** - * Exponentially back-off a failed job. See - * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)} - * - * retry_time(current_time, num_failures) = - * current_time + initial_backoff_millis * 2 ^ (num_failures - 1), num_failures >= 1 - */ - public static final int BACKOFF_POLICY_EXPONENTIAL = 1; - - /* Minimum interval for a periodic job, in milliseconds. */ - private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L; // 15 minutes - - /* Minimum flex for a periodic job, in milliseconds. */ - private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes - - /** - * Minimum backoff interval for a job, in milliseconds - * @hide - */ - public static final long MIN_BACKOFF_MILLIS = 10 * 1000L; // 10 seconds - - /** - * Query the minimum interval allowed for periodic scheduled jobs. Attempting - * to declare a smaller period that this when scheduling a job will result in a - * job that is still periodic, but will run with this effective period. - * - * @return The minimum available interval for scheduling periodic jobs, in milliseconds. - */ - public static final long getMinPeriodMillis() { - return MIN_PERIOD_MILLIS; - } - - /** - * Query the minimum flex time allowed for periodic scheduled jobs. Attempting - * to declare a shorter flex time than this when scheduling such a job will - * result in this amount as the effective flex time for the job. - * - * @return The minimum available flex time for scheduling periodic jobs, in milliseconds. - */ - public static final long getMinFlexMillis() { - return MIN_FLEX_MILLIS; - } - - /** - * Query the minimum automatic-reschedule backoff interval permitted for jobs. - * @hide - */ - public static final long getMinBackoffMillis() { - return MIN_BACKOFF_MILLIS; - } - - /** - * Default type of backoff. - * @hide - */ - public static final int DEFAULT_BACKOFF_POLICY = BACKOFF_POLICY_EXPONENTIAL; - - /** - * Default of {@link #getPriority}. - * @hide - */ - public static final int PRIORITY_DEFAULT = 0; - - /** - * Value of {@link #getPriority} for expedited syncs. - * @hide - */ - public static final int PRIORITY_SYNC_EXPEDITED = 10; - - /** - * Value of {@link #getPriority} for first time initialization syncs. - * @hide - */ - public static final int PRIORITY_SYNC_INITIALIZATION = 20; - - /** - * Value of {@link #getPriority} for a BFGS app (overrides the supplied - * JobInfo priority if it is smaller). - * @hide - */ - public static final int PRIORITY_BOUND_FOREGROUND_SERVICE = 30; - - /** @hide For backward compatibility. */ - @UnsupportedAppUsage - public static final int PRIORITY_FOREGROUND_APP = PRIORITY_BOUND_FOREGROUND_SERVICE; - - /** - * Value of {@link #getPriority} for a FG service app (overrides the supplied - * JobInfo priority if it is smaller). - * @hide - */ - @UnsupportedAppUsage - public static final int PRIORITY_FOREGROUND_SERVICE = 35; - - /** - * Value of {@link #getPriority} for the current top app (overrides the supplied - * JobInfo priority if it is smaller). - * @hide - */ - public static final int PRIORITY_TOP_APP = 40; - - /** - * Adjustment of {@link #getPriority} if the app has often (50% or more of the time) - * been running jobs. - * @hide - */ - public static final int PRIORITY_ADJ_OFTEN_RUNNING = -40; - - /** - * Adjustment of {@link #getPriority} if the app has always (90% or more of the time) - * been running jobs. - * @hide - */ - public static final int PRIORITY_ADJ_ALWAYS_RUNNING = -80; - - /** - * Indicates that the implementation of this job will be using - * {@link JobService#startForeground(int, android.app.Notification)} to run - * in the foreground. - * <p> - * When set, the internal scheduling of this job will ignore any background - * network restrictions for the requesting app. Note that this flag alone - * doesn't actually place your {@link JobService} in the foreground; you - * still need to post the notification yourself. - * <p> - * To use this flag, the caller must hold the - * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL} permission. - * - * @hide - */ - @UnsupportedAppUsage - public static final int FLAG_WILL_BE_FOREGROUND = 1 << 0; - - /** - * Allows this job to run despite doze restrictions as long as the app is in the foreground - * or on the temporary whitelist - * @hide - */ - public static final int FLAG_IMPORTANT_WHILE_FOREGROUND = 1 << 1; - - /** - * @hide - */ - public static final int FLAG_PREFETCH = 1 << 2; - - /** - * This job needs to be exempted from the app standby throttling. Only the system (UID 1000) - * can set it. Jobs with a time constrant must not have it. - * - * @hide - */ - public static final int FLAG_EXEMPT_FROM_APP_STANDBY = 1 << 3; - - /** - * @hide - */ - public static final int CONSTRAINT_FLAG_CHARGING = 1 << 0; - - /** - * @hide - */ - public static final int CONSTRAINT_FLAG_BATTERY_NOT_LOW = 1 << 1; - - /** - * @hide - */ - public static final int CONSTRAINT_FLAG_DEVICE_IDLE = 1 << 2; - - /** - * @hide - */ - public static final int CONSTRAINT_FLAG_STORAGE_NOT_LOW = 1 << 3; - - @UnsupportedAppUsage - private final int jobId; - private final PersistableBundle extras; - private final Bundle transientExtras; - private final ClipData clipData; - private final int clipGrantFlags; - @UnsupportedAppUsage - private final ComponentName service; - private final int constraintFlags; - private final TriggerContentUri[] triggerContentUris; - private final long triggerContentUpdateDelay; - private final long triggerContentMaxDelay; - private final boolean hasEarlyConstraint; - private final boolean hasLateConstraint; - private final NetworkRequest networkRequest; - private final long networkDownloadBytes; - private final long networkUploadBytes; - private final long minLatencyMillis; - private final long maxExecutionDelayMillis; - private final boolean isPeriodic; - private final boolean isPersisted; - private final long intervalMillis; - private final long flexMillis; - private final long initialBackoffMillis; - private final int backoffPolicy; - private final int priority; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private final int flags; - - /** - * Unique job id associated with this application (uid). This is the same job ID - * you supplied in the {@link Builder} constructor. - */ - public int getId() { - return jobId; - } - - /** - * @see JobInfo.Builder#setExtras(PersistableBundle) - */ - public @NonNull PersistableBundle getExtras() { - return extras; - } - - /** - * @see JobInfo.Builder#setTransientExtras(Bundle) - */ - public @NonNull Bundle getTransientExtras() { - return transientExtras; - } - - /** - * @see JobInfo.Builder#setClipData(ClipData, int) - */ - public @Nullable ClipData getClipData() { - return clipData; - } - - /** - * @see JobInfo.Builder#setClipData(ClipData, int) - */ - public int getClipGrantFlags() { - return clipGrantFlags; - } - - /** - * Name of the service endpoint that will be called back into by the JobScheduler. - */ - public @NonNull ComponentName getService() { - return service; - } - - /** @hide */ - public int getPriority() { - return priority; - } - - /** @hide */ - public int getFlags() { - return flags; - } - - /** @hide */ - public boolean isExemptedFromAppStandby() { - return ((flags & FLAG_EXEMPT_FROM_APP_STANDBY) != 0) && !isPeriodic(); - } - - /** - * @see JobInfo.Builder#setRequiresCharging(boolean) - */ - public boolean isRequireCharging() { - return (constraintFlags & CONSTRAINT_FLAG_CHARGING) != 0; - } - - /** - * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean) - */ - public boolean isRequireBatteryNotLow() { - return (constraintFlags & CONSTRAINT_FLAG_BATTERY_NOT_LOW) != 0; - } - - /** - * @see JobInfo.Builder#setRequiresDeviceIdle(boolean) - */ - public boolean isRequireDeviceIdle() { - return (constraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0; - } - - /** - * @see JobInfo.Builder#setRequiresStorageNotLow(boolean) - */ - public boolean isRequireStorageNotLow() { - return (constraintFlags & CONSTRAINT_FLAG_STORAGE_NOT_LOW) != 0; - } - - /** - * @hide - */ - public int getConstraintFlags() { - return constraintFlags; - } - - /** - * Which content: URIs must change for the job to be scheduled. Returns null - * if there are none required. - * @see JobInfo.Builder#addTriggerContentUri(TriggerContentUri) - */ - public @Nullable TriggerContentUri[] getTriggerContentUris() { - return triggerContentUris; - } - - /** - * When triggering on content URI changes, this is the delay from when a change - * is detected until the job is scheduled. - * @see JobInfo.Builder#setTriggerContentUpdateDelay(long) - */ - public long getTriggerContentUpdateDelay() { - return triggerContentUpdateDelay; - } - - /** - * When triggering on content URI changes, this is the maximum delay we will - * use before scheduling the job. - * @see JobInfo.Builder#setTriggerContentMaxDelay(long) - */ - public long getTriggerContentMaxDelay() { - return triggerContentMaxDelay; - } - - /** - * Return the basic description of the kind of network this job requires. - * - * @deprecated This method attempts to map {@link #getRequiredNetwork()} - * into the set of simple constants, which results in a loss of - * fidelity. Callers should move to using - * {@link #getRequiredNetwork()} directly. - * @see Builder#setRequiredNetworkType(int) - */ - @Deprecated - public @NetworkType int getNetworkType() { - if (networkRequest == null) { - return NETWORK_TYPE_NONE; - } else if (networkRequest.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { - return NETWORK_TYPE_UNMETERED; - } else if (networkRequest.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) { - return NETWORK_TYPE_NOT_ROAMING; - } else if (networkRequest.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { - return NETWORK_TYPE_CELLULAR; - } else { - return NETWORK_TYPE_ANY; - } - } - - /** - * Return the detailed description of the kind of network this job requires, - * or {@code null} if no specific kind of network is required. - * - * @see Builder#setRequiredNetwork(NetworkRequest) - */ - public @Nullable NetworkRequest getRequiredNetwork() { - return networkRequest; - } - - /** - * Return the estimated size of download traffic that will be performed by - * this job, in bytes. - * - * @return Estimated size of download traffic, or - * {@link #NETWORK_BYTES_UNKNOWN} when unknown. - * @see Builder#setEstimatedNetworkBytes(long, long) - */ - public @BytesLong long getEstimatedNetworkDownloadBytes() { - return networkDownloadBytes; - } - - /** - * Return the estimated size of upload traffic that will be performed by - * this job, in bytes. - * - * @return Estimated size of upload traffic, or - * {@link #NETWORK_BYTES_UNKNOWN} when unknown. - * @see Builder#setEstimatedNetworkBytes(long, long) - */ - public @BytesLong long getEstimatedNetworkUploadBytes() { - return networkUploadBytes; - } - - /** - * Set for a job that does not recur periodically, to specify a delay after which the job - * will be eligible for execution. This value is not set if the job recurs periodically. - * @see JobInfo.Builder#setMinimumLatency(long) - */ - public long getMinLatencyMillis() { - return minLatencyMillis; - } - - /** - * @see JobInfo.Builder#setOverrideDeadline(long) - */ - public long getMaxExecutionDelayMillis() { - return maxExecutionDelayMillis; - } - - /** - * Track whether this job will repeat with a given period. - * @see JobInfo.Builder#setPeriodic(long) - * @see JobInfo.Builder#setPeriodic(long, long) - */ - public boolean isPeriodic() { - return isPeriodic; - } - - /** - * @see JobInfo.Builder#setPersisted(boolean) - */ - public boolean isPersisted() { - return isPersisted; - } - - /** - * Set to the interval between occurrences of this job. This value is <b>not</b> set if the - * job does not recur periodically. - * @see JobInfo.Builder#setPeriodic(long) - * @see JobInfo.Builder#setPeriodic(long, long) - */ - public long getIntervalMillis() { - return intervalMillis; - } - - /** - * Flex time for this job. Only valid if this is a periodic job. The job can - * execute at any time in a window of flex length at the end of the period. - * @see JobInfo.Builder#setPeriodic(long) - * @see JobInfo.Builder#setPeriodic(long, long) - */ - public long getFlexMillis() { - return flexMillis; - } - - /** - * The amount of time the JobScheduler will wait before rescheduling a failed job. This value - * will be increased depending on the backoff policy specified at job creation time. Defaults - * to 30 seconds, minimum is currently 10 seconds. - * @see JobInfo.Builder#setBackoffCriteria(long, int) - */ - public long getInitialBackoffMillis() { - return initialBackoffMillis; - } - - /** - * Return the backoff policy of this job. - * @see JobInfo.Builder#setBackoffCriteria(long, int) - */ - public @BackoffPolicy int getBackoffPolicy() { - return backoffPolicy; - } - - /** - * @see JobInfo.Builder#setImportantWhileForeground(boolean) - */ - public boolean isImportantWhileForeground() { - return (flags & FLAG_IMPORTANT_WHILE_FOREGROUND) != 0; - } - - /** - * @see JobInfo.Builder#setPrefetch(boolean) - */ - public boolean isPrefetch() { - return (flags & FLAG_PREFETCH) != 0; - } - - /** - * User can specify an early constraint of 0L, which is valid, so we keep track of whether the - * function was called at all. - * @hide - */ - public boolean hasEarlyConstraint() { - return hasEarlyConstraint; - } - - /** - * User can specify a late constraint of 0L, which is valid, so we keep track of whether the - * function was called at all. - * @hide - */ - public boolean hasLateConstraint() { - return hasLateConstraint; - } - - private static boolean kindofEqualsBundle(BaseBundle a, BaseBundle b) { - return (a == b) || (a != null && a.kindofEquals(b)); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof JobInfo)) { - return false; - } - JobInfo j = (JobInfo) o; - if (jobId != j.jobId) { - return false; - } - // XXX won't be correct if one is parcelled and the other not. - if (!kindofEqualsBundle(extras, j.extras)) { - return false; - } - // XXX won't be correct if one is parcelled and the other not. - if (!kindofEqualsBundle(transientExtras, j.transientExtras)) { - return false; - } - // XXX for now we consider two different clip data objects to be different, - // regardless of whether their contents are the same. - if (clipData != j.clipData) { - return false; - } - if (clipGrantFlags != j.clipGrantFlags) { - return false; - } - if (!Objects.equals(service, j.service)) { - return false; - } - if (constraintFlags != j.constraintFlags) { - return false; - } - if (!Arrays.equals(triggerContentUris, j.triggerContentUris)) { - return false; - } - if (triggerContentUpdateDelay != j.triggerContentUpdateDelay) { - return false; - } - if (triggerContentMaxDelay != j.triggerContentMaxDelay) { - return false; - } - if (hasEarlyConstraint != j.hasEarlyConstraint) { - return false; - } - if (hasLateConstraint != j.hasLateConstraint) { - return false; - } - if (!Objects.equals(networkRequest, j.networkRequest)) { - return false; - } - if (networkDownloadBytes != j.networkDownloadBytes) { - return false; - } - if (networkUploadBytes != j.networkUploadBytes) { - return false; - } - if (minLatencyMillis != j.minLatencyMillis) { - return false; - } - if (maxExecutionDelayMillis != j.maxExecutionDelayMillis) { - return false; - } - if (isPeriodic != j.isPeriodic) { - return false; - } - if (isPersisted != j.isPersisted) { - return false; - } - if (intervalMillis != j.intervalMillis) { - return false; - } - if (flexMillis != j.flexMillis) { - return false; - } - if (initialBackoffMillis != j.initialBackoffMillis) { - return false; - } - if (backoffPolicy != j.backoffPolicy) { - return false; - } - if (priority != j.priority) { - return false; - } - if (flags != j.flags) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int hashCode = jobId; - if (extras != null) { - hashCode = 31 * hashCode + extras.hashCode(); - } - if (transientExtras != null) { - hashCode = 31 * hashCode + transientExtras.hashCode(); - } - if (clipData != null) { - hashCode = 31 * hashCode + clipData.hashCode(); - } - hashCode = 31*hashCode + clipGrantFlags; - if (service != null) { - hashCode = 31 * hashCode + service.hashCode(); - } - hashCode = 31 * hashCode + constraintFlags; - if (triggerContentUris != null) { - hashCode = 31 * hashCode + Arrays.hashCode(triggerContentUris); - } - hashCode = 31 * hashCode + Long.hashCode(triggerContentUpdateDelay); - hashCode = 31 * hashCode + Long.hashCode(triggerContentMaxDelay); - hashCode = 31 * hashCode + Boolean.hashCode(hasEarlyConstraint); - hashCode = 31 * hashCode + Boolean.hashCode(hasLateConstraint); - if (networkRequest != null) { - hashCode = 31 * hashCode + networkRequest.hashCode(); - } - hashCode = 31 * hashCode + Long.hashCode(networkDownloadBytes); - hashCode = 31 * hashCode + Long.hashCode(networkUploadBytes); - hashCode = 31 * hashCode + Long.hashCode(minLatencyMillis); - hashCode = 31 * hashCode + Long.hashCode(maxExecutionDelayMillis); - hashCode = 31 * hashCode + Boolean.hashCode(isPeriodic); - hashCode = 31 * hashCode + Boolean.hashCode(isPersisted); - hashCode = 31 * hashCode + Long.hashCode(intervalMillis); - hashCode = 31 * hashCode + Long.hashCode(flexMillis); - hashCode = 31 * hashCode + Long.hashCode(initialBackoffMillis); - hashCode = 31 * hashCode + backoffPolicy; - hashCode = 31 * hashCode + priority; - hashCode = 31 * hashCode + flags; - return hashCode; - } - - private JobInfo(Parcel in) { - jobId = in.readInt(); - extras = in.readPersistableBundle(); - transientExtras = in.readBundle(); - if (in.readInt() != 0) { - clipData = ClipData.CREATOR.createFromParcel(in); - clipGrantFlags = in.readInt(); - } else { - clipData = null; - clipGrantFlags = 0; - } - service = in.readParcelable(null); - constraintFlags = in.readInt(); - triggerContentUris = in.createTypedArray(TriggerContentUri.CREATOR); - triggerContentUpdateDelay = in.readLong(); - triggerContentMaxDelay = in.readLong(); - if (in.readInt() != 0) { - networkRequest = NetworkRequest.CREATOR.createFromParcel(in); - } else { - networkRequest = null; - } - networkDownloadBytes = in.readLong(); - networkUploadBytes = in.readLong(); - minLatencyMillis = in.readLong(); - maxExecutionDelayMillis = in.readLong(); - isPeriodic = in.readInt() == 1; - isPersisted = in.readInt() == 1; - intervalMillis = in.readLong(); - flexMillis = in.readLong(); - initialBackoffMillis = in.readLong(); - backoffPolicy = in.readInt(); - hasEarlyConstraint = in.readInt() == 1; - hasLateConstraint = in.readInt() == 1; - priority = in.readInt(); - flags = in.readInt(); - } - - private JobInfo(JobInfo.Builder b) { - jobId = b.mJobId; - extras = b.mExtras.deepCopy(); - transientExtras = b.mTransientExtras.deepCopy(); - clipData = b.mClipData; - clipGrantFlags = b.mClipGrantFlags; - service = b.mJobService; - constraintFlags = b.mConstraintFlags; - triggerContentUris = b.mTriggerContentUris != null - ? b.mTriggerContentUris.toArray(new TriggerContentUri[b.mTriggerContentUris.size()]) - : null; - triggerContentUpdateDelay = b.mTriggerContentUpdateDelay; - triggerContentMaxDelay = b.mTriggerContentMaxDelay; - networkRequest = b.mNetworkRequest; - networkDownloadBytes = b.mNetworkDownloadBytes; - networkUploadBytes = b.mNetworkUploadBytes; - minLatencyMillis = b.mMinLatencyMillis; - maxExecutionDelayMillis = b.mMaxExecutionDelayMillis; - isPeriodic = b.mIsPeriodic; - isPersisted = b.mIsPersisted; - intervalMillis = b.mIntervalMillis; - flexMillis = b.mFlexMillis; - initialBackoffMillis = b.mInitialBackoffMillis; - backoffPolicy = b.mBackoffPolicy; - hasEarlyConstraint = b.mHasEarlyConstraint; - hasLateConstraint = b.mHasLateConstraint; - priority = b.mPriority; - flags = b.mFlags; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(jobId); - out.writePersistableBundle(extras); - out.writeBundle(transientExtras); - if (clipData != null) { - out.writeInt(1); - clipData.writeToParcel(out, flags); - out.writeInt(clipGrantFlags); - } else { - out.writeInt(0); - } - out.writeParcelable(service, flags); - out.writeInt(constraintFlags); - out.writeTypedArray(triggerContentUris, flags); - out.writeLong(triggerContentUpdateDelay); - out.writeLong(triggerContentMaxDelay); - if (networkRequest != null) { - out.writeInt(1); - networkRequest.writeToParcel(out, flags); - } else { - out.writeInt(0); - } - out.writeLong(networkDownloadBytes); - out.writeLong(networkUploadBytes); - out.writeLong(minLatencyMillis); - out.writeLong(maxExecutionDelayMillis); - out.writeInt(isPeriodic ? 1 : 0); - out.writeInt(isPersisted ? 1 : 0); - out.writeLong(intervalMillis); - out.writeLong(flexMillis); - out.writeLong(initialBackoffMillis); - out.writeInt(backoffPolicy); - out.writeInt(hasEarlyConstraint ? 1 : 0); - out.writeInt(hasLateConstraint ? 1 : 0); - out.writeInt(priority); - out.writeInt(this.flags); - } - - public static final @android.annotation.NonNull Creator<JobInfo> CREATOR = new Creator<JobInfo>() { - @Override - public JobInfo createFromParcel(Parcel in) { - return new JobInfo(in); - } - - @Override - public JobInfo[] newArray(int size) { - return new JobInfo[size]; - } - }; - - @Override - public String toString() { - return "(job:" + jobId + "/" + service.flattenToShortString() + ")"; - } - - /** - * Information about a content URI modification that a job would like to - * trigger on. - */ - public static final class TriggerContentUri implements Parcelable { - private final Uri mUri; - private final int mFlags; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = { "FLAG_" }, value = { - FLAG_NOTIFY_FOR_DESCENDANTS, - }) - public @interface Flags { } - - /** - * Flag for trigger: also trigger if any descendants of the given URI change. - * Corresponds to the <var>notifyForDescendants</var> of - * {@link android.content.ContentResolver#registerContentObserver}. - */ - public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1<<0; - - /** - * Create a new trigger description. - * @param uri The URI to observe. Must be non-null. - * @param flags Flags for the observer. - */ - public TriggerContentUri(@NonNull Uri uri, @Flags int flags) { - mUri = uri; - mFlags = flags; - } - - /** - * Return the Uri this trigger was created for. - */ - public Uri getUri() { - return mUri; - } - - /** - * Return the flags supplied for the trigger. - */ - public @Flags int getFlags() { - return mFlags; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof TriggerContentUri)) { - return false; - } - TriggerContentUri t = (TriggerContentUri) o; - return Objects.equals(t.mUri, mUri) && t.mFlags == mFlags; - } - - @Override - public int hashCode() { - return (mUri == null ? 0 : mUri.hashCode()) ^ mFlags; - } - - private TriggerContentUri(Parcel in) { - mUri = Uri.CREATOR.createFromParcel(in); - mFlags = in.readInt(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - mUri.writeToParcel(out, flags); - out.writeInt(mFlags); - } - - public static final @android.annotation.NonNull Creator<TriggerContentUri> CREATOR = new Creator<TriggerContentUri>() { - @Override - public TriggerContentUri createFromParcel(Parcel in) { - return new TriggerContentUri(in); - } - - @Override - public TriggerContentUri[] newArray(int size) { - return new TriggerContentUri[size]; - } - }; - } - - /** Builder class for constructing {@link JobInfo} objects. */ - public static final class Builder { - private final int mJobId; - private final ComponentName mJobService; - private PersistableBundle mExtras = PersistableBundle.EMPTY; - private Bundle mTransientExtras = Bundle.EMPTY; - private ClipData mClipData; - private int mClipGrantFlags; - private int mPriority = PRIORITY_DEFAULT; - private int mFlags; - // Requirements. - private int mConstraintFlags; - private NetworkRequest mNetworkRequest; - private long mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN; - private long mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN; - private ArrayList<TriggerContentUri> mTriggerContentUris; - private long mTriggerContentUpdateDelay = -1; - private long mTriggerContentMaxDelay = -1; - private boolean mIsPersisted; - // One-off parameters. - private long mMinLatencyMillis; - private long mMaxExecutionDelayMillis; - // Periodic parameters. - private boolean mIsPeriodic; - private boolean mHasEarlyConstraint; - private boolean mHasLateConstraint; - private long mIntervalMillis; - private long mFlexMillis; - // Back-off parameters. - private long mInitialBackoffMillis = DEFAULT_INITIAL_BACKOFF_MILLIS; - private int mBackoffPolicy = DEFAULT_BACKOFF_POLICY; - /** Easy way to track whether the client has tried to set a back-off policy. */ - private boolean mBackoffPolicySet = false; - - /** - * Initialize a new Builder to construct a {@link JobInfo}. - * - * @param jobId Application-provided id for this job. Subsequent calls to cancel, or - * jobs created with the same jobId, will update the pre-existing job with - * the same id. This ID must be unique across all clients of the same uid - * (not just the same package). You will want to make sure this is a stable - * id across app updates, so probably not based on a resource ID. - * @param jobService The endpoint that you implement that will receive the callback from the - * JobScheduler. - */ - public Builder(int jobId, @NonNull ComponentName jobService) { - mJobService = jobService; - mJobId = jobId; - } - - /** @hide */ - @UnsupportedAppUsage - public Builder setPriority(int priority) { - mPriority = priority; - return this; - } - - /** @hide */ - @UnsupportedAppUsage - public Builder setFlags(int flags) { - mFlags = flags; - return this; - } - - /** - * Set optional extras. This is persisted, so we only allow primitive types. - * @param extras Bundle containing extras you want the scheduler to hold on to for you. - * @see JobInfo#getExtras() - */ - public Builder setExtras(@NonNull PersistableBundle extras) { - mExtras = extras; - return this; - } - - /** - * Set optional transient extras. - * - * <p>Because setting this property is not compatible with persisted - * jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when - * {@link android.app.job.JobInfo.Builder#build()} is called.</p> - * - * @param extras Bundle containing extras you want the scheduler to hold on to for you. - * @see JobInfo#getTransientExtras() - */ - public Builder setTransientExtras(@NonNull Bundle extras) { - mTransientExtras = extras; - return this; - } - - /** - * Set a {@link ClipData} associated with this Job. - * - * <p>The main purpose of providing a ClipData is to allow granting of - * URI permissions for data associated with the clip. The exact kind - * of permission grant to perform is specified through <var>grantFlags</var>. - * - * <p>If the ClipData contains items that are Intents, any - * grant flags in those Intents will be ignored. Only flags provided as an argument - * to this method are respected, and will be applied to all Uri or - * Intent items in the clip (or sub-items of the clip). - * - * <p>Because setting this property is not compatible with persisted - * jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when - * {@link android.app.job.JobInfo.Builder#build()} is called.</p> - * - * @param clip The new clip to set. May be null to clear the current clip. - * @param grantFlags The desired permissions to grant for any URIs. This should be - * a combination of {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}, - * {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, and - * {@link android.content.Intent#FLAG_GRANT_PREFIX_URI_PERMISSION}. - * @see JobInfo#getClipData() - * @see JobInfo#getClipGrantFlags() - */ - public Builder setClipData(@Nullable ClipData clip, int grantFlags) { - mClipData = clip; - mClipGrantFlags = grantFlags; - return this; - } - - /** - * Set basic description of the kind of network your job requires. If - * you need more precise control over network capabilities, see - * {@link #setRequiredNetwork(NetworkRequest)}. - * <p> - * If your job doesn't need a network connection, you don't need to call - * this method, as the default value is {@link #NETWORK_TYPE_NONE}. - * <p> - * Calling this method defines network as a strict requirement for your - * job. If the network requested is not available your job will never - * run. See {@link #setOverrideDeadline(long)} to change this behavior. - * Calling this method will override any requirements previously defined - * by {@link #setRequiredNetwork(NetworkRequest)}; you typically only - * want to call one of these methods. - * <p class="note"> - * When your job executes in - * {@link JobService#onStartJob(JobParameters)}, be sure to use the - * specific network returned by {@link JobParameters#getNetwork()}, - * otherwise you'll use the default network which may not meet this - * constraint. - * - * @see #setRequiredNetwork(NetworkRequest) - * @see JobInfo#getNetworkType() - * @see JobParameters#getNetwork() - */ - public Builder setRequiredNetworkType(@NetworkType int networkType) { - if (networkType == NETWORK_TYPE_NONE) { - return setRequiredNetwork(null); - } else { - final NetworkRequest.Builder builder = new NetworkRequest.Builder(); - - // All types require validated Internet - builder.addCapability(NET_CAPABILITY_INTERNET); - builder.addCapability(NET_CAPABILITY_VALIDATED); - builder.removeCapability(NET_CAPABILITY_NOT_VPN); - - if (networkType == NETWORK_TYPE_ANY) { - // No other capabilities - } else if (networkType == NETWORK_TYPE_UNMETERED) { - builder.addCapability(NET_CAPABILITY_NOT_METERED); - } else if (networkType == NETWORK_TYPE_NOT_ROAMING) { - builder.addCapability(NET_CAPABILITY_NOT_ROAMING); - } else if (networkType == NETWORK_TYPE_CELLULAR) { - builder.addTransportType(TRANSPORT_CELLULAR); - } - - return setRequiredNetwork(builder.build()); - } - } - - /** - * Set detailed description of the kind of network your job requires. - * <p> - * If your job doesn't need a network connection, you don't need to call - * this method, as the default is {@code null}. - * <p> - * Calling this method defines network as a strict requirement for your - * job. If the network requested is not available your job will never - * run. See {@link #setOverrideDeadline(long)} to change this behavior. - * Calling this method will override any requirements previously defined - * by {@link #setRequiredNetworkType(int)}; you typically only want to - * call one of these methods. - * <p class="note"> - * When your job executes in - * {@link JobService#onStartJob(JobParameters)}, be sure to use the - * specific network returned by {@link JobParameters#getNetwork()}, - * otherwise you'll use the default network which may not meet this - * constraint. - * - * @param networkRequest The detailed description of the kind of network - * this job requires, or {@code null} if no specific kind of - * network is required. Defining a {@link NetworkSpecifier} - * is only supported for jobs that aren't persisted. - * @see #setRequiredNetworkType(int) - * @see JobInfo#getRequiredNetwork() - * @see JobParameters#getNetwork() - */ - public Builder setRequiredNetwork(@Nullable NetworkRequest networkRequest) { - mNetworkRequest = networkRequest; - return this; - } - - /** - * Set the estimated size of network traffic that will be performed by - * this job, in bytes. - * <p> - * Apps are encouraged to provide values that are as accurate as - * possible, but when the exact size isn't available, an - * order-of-magnitude estimate can be provided instead. Here are some - * specific examples: - * <ul> - * <li>A job that is backing up a photo knows the exact size of that - * photo, so it should provide that size as the estimate. - * <li>A job that refreshes top news stories wouldn't know an exact - * size, but if the size is expected to be consistently around 100KB, it - * can provide that order-of-magnitude value as the estimate. - * <li>A job that synchronizes email could end up using an extreme range - * of data, from under 1KB when nothing has changed, to dozens of MB - * when there are new emails with attachments. Jobs that cannot provide - * reasonable estimates should use the sentinel value - * {@link JobInfo#NETWORK_BYTES_UNKNOWN}. - * </ul> - * Note that the system may choose to delay jobs with large network - * usage estimates when the device has a poor network connection, in - * order to save battery. - * <p> - * The values provided here only reflect the traffic that will be - * performed by the base job; if you're using {@link JobWorkItem} then - * you also need to define the network traffic used by each work item - * when constructing them. - * - * @param downloadBytes The estimated size of network traffic that will - * be downloaded by this job, in bytes. - * @param uploadBytes The estimated size of network traffic that will be - * uploaded by this job, in bytes. - * @see JobInfo#getEstimatedNetworkDownloadBytes() - * @see JobInfo#getEstimatedNetworkUploadBytes() - * @see JobWorkItem#JobWorkItem(android.content.Intent, long, long) - */ - public Builder setEstimatedNetworkBytes(@BytesLong long downloadBytes, - @BytesLong long uploadBytes) { - mNetworkDownloadBytes = downloadBytes; - mNetworkUploadBytes = uploadBytes; - return this; - } - - /** - * Specify that to run this job, the device must be charging (or be a - * non-battery-powered device connected to permanent power, such as Android TV - * devices). This defaults to {@code false}. - * - * <p class="note">For purposes of running jobs, a battery-powered device - * "charging" is not quite the same as simply being connected to power. If the - * device is so busy that the battery is draining despite a power connection, jobs - * with this constraint will <em>not</em> run. This can happen during some - * common use cases such as video chat, particularly if the device is plugged in - * to USB rather than to wall power. - * - * @param requiresCharging Pass {@code true} to require that the device be - * charging in order to run the job. - * @see JobInfo#isRequireCharging() - */ - public Builder setRequiresCharging(boolean requiresCharging) { - mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_CHARGING) - | (requiresCharging ? CONSTRAINT_FLAG_CHARGING : 0); - return this; - } - - /** - * Specify that to run this job, the device's battery level must not be low. - * This defaults to false. If true, the job will only run when the battery level - * is not low, which is generally the point where the user is given a "low battery" - * warning. - * @param batteryNotLow Whether or not the device's battery level must not be low. - * @see JobInfo#isRequireBatteryNotLow() - */ - public Builder setRequiresBatteryNotLow(boolean batteryNotLow) { - mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_BATTERY_NOT_LOW) - | (batteryNotLow ? CONSTRAINT_FLAG_BATTERY_NOT_LOW : 0); - return this; - } - - /** - * When set {@code true}, ensure that this job will not run if the device is in active use. - * The default state is {@code false}: that is, the for the job to be runnable even when - * someone is interacting with the device. - * - * <p>This state is a loose definition provided by the system. In general, it means that - * the device is not currently being used interactively, and has not been in use for some - * time. As such, it is a good time to perform resource heavy jobs. Bear in mind that - * battery usage will still be attributed to your application, and surfaced to the user in - * battery stats.</p> - * - * <p class="note">Despite the similar naming, this job constraint is <em>not</em> - * related to the system's "device idle" or "doze" states. This constraint only - * determines whether a job is allowed to run while the device is directly in use. - * - * @param requiresDeviceIdle Pass {@code true} to prevent the job from running - * while the device is being used interactively. - * @see JobInfo#isRequireDeviceIdle() - */ - public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) { - mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_DEVICE_IDLE) - | (requiresDeviceIdle ? CONSTRAINT_FLAG_DEVICE_IDLE : 0); - return this; - } - - /** - * Specify that to run this job, the device's available storage must not be low. - * This defaults to false. If true, the job will only run when the device is not - * in a low storage state, which is generally the point where the user is given a - * "low storage" warning. - * @param storageNotLow Whether or not the device's available storage must not be low. - * @see JobInfo#isRequireStorageNotLow() - */ - public Builder setRequiresStorageNotLow(boolean storageNotLow) { - mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_STORAGE_NOT_LOW) - | (storageNotLow ? CONSTRAINT_FLAG_STORAGE_NOT_LOW : 0); - return this; - } - - /** - * Add a new content: URI that will be monitored with a - * {@link android.database.ContentObserver}, and will cause the job to execute if changed. - * If you have any trigger content URIs associated with a job, it will not execute until - * there has been a change report for one or more of them. - * - * <p>Note that trigger URIs can not be used in combination with - * {@link #setPeriodic(long)} or {@link #setPersisted(boolean)}. To continually monitor - * for content changes, you need to schedule a new JobInfo observing the same URIs - * before you finish execution of the JobService handling the most recent changes. - * Following this pattern will ensure you do not lost any content changes: while your - * job is running, the system will continue monitoring for content changes, and propagate - * any it sees over to the next job you schedule.</p> - * - * <p>Because setting this property is not compatible with periodic or - * persisted jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when - * {@link android.app.job.JobInfo.Builder#build()} is called.</p> - * - * <p>The following example shows how this feature can be used to monitor for changes - * in the photos on a device.</p> - * - * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/PhotosContentJob.java - * job} - * - * @param uri The content: URI to monitor. - * @see JobInfo#getTriggerContentUris() - */ - public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) { - if (mTriggerContentUris == null) { - mTriggerContentUris = new ArrayList<>(); - } - mTriggerContentUris.add(uri); - return this; - } - - /** - * Set the delay (in milliseconds) from when a content change is detected until - * the job is scheduled. If there are more changes during that time, the delay - * will be reset to start at the time of the most recent change. - * @param durationMs Delay after most recent content change, in milliseconds. - * @see JobInfo#getTriggerContentUpdateDelay() - */ - public Builder setTriggerContentUpdateDelay(long durationMs) { - mTriggerContentUpdateDelay = durationMs; - return this; - } - - /** - * Set the maximum total delay (in milliseconds) that is allowed from the first - * time a content change is detected until the job is scheduled. - * @param durationMs Delay after initial content change, in milliseconds. - * @see JobInfo#getTriggerContentMaxDelay() - */ - public Builder setTriggerContentMaxDelay(long durationMs) { - mTriggerContentMaxDelay = durationMs; - return this; - } - - /** - * Specify that this job should recur with the provided interval, not more than once per - * period. You have no control over when within this interval this job will be executed, - * only the guarantee that it will be executed at most once within this interval. - * Setting this function on the builder with {@link #setMinimumLatency(long)} or - * {@link #setOverrideDeadline(long)} will result in an error. - * @param intervalMillis Millisecond interval for which this job will repeat. - * @see JobInfo#getIntervalMillis() - * @see JobInfo#getFlexMillis() - */ - public Builder setPeriodic(long intervalMillis) { - return setPeriodic(intervalMillis, intervalMillis); - } - - /** - * Specify that this job should recur with the provided interval and flex. The job can - * execute at any time in a window of flex length at the end of the period. - * @param intervalMillis Millisecond interval for which this job will repeat. A minimum - * value of {@link #getMinPeriodMillis()} is enforced. - * @param flexMillis Millisecond flex for this job. Flex is clamped to be at least - * {@link #getMinFlexMillis()} or 5 percent of the period, whichever is - * higher. - * @see JobInfo#getIntervalMillis() - * @see JobInfo#getFlexMillis() - */ - public Builder setPeriodic(long intervalMillis, long flexMillis) { - final long minPeriod = getMinPeriodMillis(); - if (intervalMillis < minPeriod) { - Log.w(TAG, "Requested interval " + formatDuration(intervalMillis) + " for job " - + mJobId + " is too small; raising to " + formatDuration(minPeriod)); - intervalMillis = minPeriod; - } - - final long percentClamp = 5 * intervalMillis / 100; - final long minFlex = Math.max(percentClamp, getMinFlexMillis()); - if (flexMillis < minFlex) { - Log.w(TAG, "Requested flex " + formatDuration(flexMillis) + " for job " + mJobId - + " is too small; raising to " + formatDuration(minFlex)); - flexMillis = minFlex; - } - - mIsPeriodic = true; - mIntervalMillis = intervalMillis; - mFlexMillis = flexMillis; - mHasEarlyConstraint = mHasLateConstraint = true; - return this; - } - - /** - * Specify that this job should be delayed by the provided amount of time. - * Because it doesn't make sense setting this property on a periodic job, doing so will - * throw an {@link java.lang.IllegalArgumentException} when - * {@link android.app.job.JobInfo.Builder#build()} is called. - * @param minLatencyMillis Milliseconds before which this job will not be considered for - * execution. - * @see JobInfo#getMinLatencyMillis() - */ - public Builder setMinimumLatency(long minLatencyMillis) { - mMinLatencyMillis = minLatencyMillis; - mHasEarlyConstraint = true; - return this; - } - - /** - * Set deadline which is the maximum scheduling latency. The job will be run by this - * deadline even if other requirements are not met. Because it doesn't make sense setting - * this property on a periodic job, doing so will throw an - * {@link java.lang.IllegalArgumentException} when - * {@link android.app.job.JobInfo.Builder#build()} is called. - * @see JobInfo#getMaxExecutionDelayMillis() - */ - public Builder setOverrideDeadline(long maxExecutionDelayMillis) { - mMaxExecutionDelayMillis = maxExecutionDelayMillis; - mHasLateConstraint = true; - return this; - } - - /** - * Set up the back-off/retry policy. - * This defaults to some respectable values: {30 seconds, Exponential}. We cap back-off at - * 5hrs. - * Note that trying to set a backoff criteria for a job with - * {@link #setRequiresDeviceIdle(boolean)} will throw an exception when you call build(). - * This is because back-off typically does not make sense for these types of jobs. See - * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)} - * for more description of the return value for the case of a job executing while in idle - * mode. - * @param initialBackoffMillis Millisecond time interval to wait initially when job has - * failed. - * @see JobInfo#getInitialBackoffMillis() - * @see JobInfo#getBackoffPolicy() - */ - public Builder setBackoffCriteria(long initialBackoffMillis, - @BackoffPolicy int backoffPolicy) { - final long minBackoff = getMinBackoffMillis(); - if (initialBackoffMillis < minBackoff) { - Log.w(TAG, "Requested backoff " + formatDuration(initialBackoffMillis) + " for job " - + mJobId + " is too small; raising to " + formatDuration(minBackoff)); - initialBackoffMillis = minBackoff; - } - - mBackoffPolicySet = true; - mInitialBackoffMillis = initialBackoffMillis; - mBackoffPolicy = backoffPolicy; - return this; - } - - /** - * Setting this to true indicates that this job is important while the scheduling app - * is in the foreground or on the temporary whitelist for background restrictions. - * This means that the system will relax doze restrictions on this job during this time. - * - * Apps should use this flag only for short jobs that are essential for the app to function - * properly in the foreground. - * - * Note that once the scheduling app is no longer whitelisted from background restrictions - * and in the background, or the job failed due to unsatisfied constraints, - * this job should be expected to behave like other jobs without this flag. - * - * @param importantWhileForeground whether to relax doze restrictions for this job when the - * app is in the foreground. False by default. - * @see JobInfo#isImportantWhileForeground() - */ - public Builder setImportantWhileForeground(boolean importantWhileForeground) { - if (importantWhileForeground) { - mFlags |= FLAG_IMPORTANT_WHILE_FOREGROUND; - } else { - mFlags &= (~FLAG_IMPORTANT_WHILE_FOREGROUND); - } - return this; - } - - /** - * Setting this to true indicates that this job is designed to prefetch - * content that will make a material improvement to the experience of - * the specific user of this device. For example, fetching top headlines - * of interest to the current user. - * <p> - * The system may use this signal to relax the network constraints you - * originally requested, such as allowing a - * {@link JobInfo#NETWORK_TYPE_UNMETERED} job to run over a metered - * network when there is a surplus of metered data available. The system - * may also use this signal in combination with end user usage patterns - * to ensure data is prefetched before the user launches your app. - * @see JobInfo#isPrefetch() - */ - public Builder setPrefetch(boolean prefetch) { - if (prefetch) { - mFlags |= FLAG_PREFETCH; - } else { - mFlags &= (~FLAG_PREFETCH); - } - return this; - } - - /** - * Set whether or not to persist this job across device reboots. - * - * @param isPersisted True to indicate that the job will be written to - * disk and loaded at boot. - * @see JobInfo#isPersisted() - */ - @RequiresPermission(android.Manifest.permission.RECEIVE_BOOT_COMPLETED) - public Builder setPersisted(boolean isPersisted) { - mIsPersisted = isPersisted; - return this; - } - - /** - * @return The job object to hand to the JobScheduler. This object is immutable. - */ - public JobInfo build() { - // Check that network estimates require network type - if ((mNetworkDownloadBytes > 0 || mNetworkUploadBytes > 0) && mNetworkRequest == null) { - throw new IllegalArgumentException( - "Can't provide estimated network usage without requiring a network"); - } - // We can't serialize network specifiers - if (mIsPersisted && mNetworkRequest != null - && mNetworkRequest.networkCapabilities.getNetworkSpecifier() != null) { - throw new IllegalArgumentException( - "Network specifiers aren't supported for persistent jobs"); - } - // Check that a deadline was not set on a periodic job. - if (mIsPeriodic) { - if (mMaxExecutionDelayMillis != 0L) { - throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " + - "periodic job."); - } - if (mMinLatencyMillis != 0L) { - throw new IllegalArgumentException("Can't call setMinimumLatency() on a " + - "periodic job"); - } - if (mTriggerContentUris != null) { - throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " + - "periodic job"); - } - } - if (mIsPersisted) { - if (mTriggerContentUris != null) { - throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " + - "persisted job"); - } - if (!mTransientExtras.isEmpty()) { - throw new IllegalArgumentException("Can't call setTransientExtras() on a " + - "persisted job"); - } - if (mClipData != null) { - throw new IllegalArgumentException("Can't call setClipData() on a " + - "persisted job"); - } - } - if ((mFlags & FLAG_IMPORTANT_WHILE_FOREGROUND) != 0 && mHasEarlyConstraint) { - throw new IllegalArgumentException("An important while foreground job cannot " - + "have a time delay"); - } - if (mBackoffPolicySet && (mConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) { - throw new IllegalArgumentException("An idle mode job will not respect any" + - " back-off policy, so calling setBackoffCriteria with" + - " setRequiresDeviceIdle is an error."); - } - return new JobInfo(this); - } - - /** - * @hide - */ - public String summarize() { - final String service = (mJobService != null) - ? mJobService.flattenToShortString() - : "null"; - return "JobInfo.Builder{job:" + mJobId + "/" + service + "}"; - } - } - - /** - * Convert a priority integer into a human readable string for debugging. - * @hide - */ - public static String getPriorityString(int priority) { - switch (priority) { - case PRIORITY_DEFAULT: - return PRIORITY_DEFAULT + " [DEFAULT]"; - case PRIORITY_SYNC_EXPEDITED: - return PRIORITY_SYNC_EXPEDITED + " [SYNC_EXPEDITED]"; - case PRIORITY_SYNC_INITIALIZATION: - return PRIORITY_SYNC_INITIALIZATION + " [SYNC_INITIALIZATION]"; - case PRIORITY_BOUND_FOREGROUND_SERVICE: - return PRIORITY_BOUND_FOREGROUND_SERVICE + " [BFGS_APP]"; - case PRIORITY_FOREGROUND_SERVICE: - return PRIORITY_FOREGROUND_SERVICE + " [FGS_APP]"; - case PRIORITY_TOP_APP: - return PRIORITY_TOP_APP + " [TOP_APP]"; - - // PRIORITY_ADJ_* are adjustments and not used as real priorities. - // No need to convert to strings. - } - return priority + " [UNKNOWN]"; - } -} diff --git a/core/java/android/app/job/JobParameters.aidl b/core/java/android/app/job/JobParameters.aidl deleted file mode 100644 index e7551b9ab9f2..000000000000 --- a/core/java/android/app/job/JobParameters.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright 2014, 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 JobParameters; diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java deleted file mode 100644 index ecc859d8320c..000000000000 --- a/core/java/android/app/job/JobParameters.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (C) 2014 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.NonNull; -import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.app.job.IJobCallback; -import android.content.ClipData; -import android.net.Network; -import android.net.Uri; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.PersistableBundle; -import android.os.RemoteException; - -/** - * Contains the parameters used to configure/identify your job. You do not create this object - * yourself, instead it is handed in to your application by the System. - */ -public class JobParameters implements Parcelable { - - /** @hide */ - public static final int REASON_CANCELED = JobProtoEnums.STOP_REASON_CANCELLED; // 0. - /** @hide */ - public static final int REASON_CONSTRAINTS_NOT_SATISFIED = - JobProtoEnums.STOP_REASON_CONSTRAINTS_NOT_SATISFIED; //1. - /** @hide */ - public static final int REASON_PREEMPT = JobProtoEnums.STOP_REASON_PREEMPT; // 2. - /** @hide */ - public static final int REASON_TIMEOUT = JobProtoEnums.STOP_REASON_TIMEOUT; // 3. - /** @hide */ - public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4. - /** @hide */ - public static final int REASON_DEVICE_THERMAL = JobProtoEnums.STOP_REASON_DEVICE_THERMAL; // 5. - - /** - * All the stop reason codes. This should be regarded as an immutable array at runtime. - * @hide - */ - public static final int[] JOB_STOP_REASON_CODES = { - REASON_CANCELED, - REASON_CONSTRAINTS_NOT_SATISFIED, - REASON_PREEMPT, - REASON_TIMEOUT, - REASON_DEVICE_IDLE, - REASON_DEVICE_THERMAL, - }; - - /** @hide */ - public static String getReasonName(int reason) { - switch (reason) { - case REASON_CANCELED: return "canceled"; - case REASON_CONSTRAINTS_NOT_SATISFIED: return "constraints"; - case REASON_PREEMPT: return "preempt"; - case REASON_TIMEOUT: return "timeout"; - case REASON_DEVICE_IDLE: return "device_idle"; - case REASON_DEVICE_THERMAL: return "thermal"; - default: return "unknown:" + reason; - } - } - - @UnsupportedAppUsage - private final int jobId; - private final PersistableBundle extras; - private final Bundle transientExtras; - private final ClipData clipData; - private final int clipGrantFlags; - @UnsupportedAppUsage - private final IBinder callback; - private final boolean overrideDeadlineExpired; - private final Uri[] mTriggeredContentUris; - private final String[] mTriggeredContentAuthorities; - private final Network network; - - private int stopReason; // Default value of stopReason is REASON_CANCELED - private String debugStopReason; // Human readable stop reason for debugging. - - /** @hide */ - public JobParameters(IBinder callback, int jobId, PersistableBundle extras, - Bundle transientExtras, ClipData clipData, int clipGrantFlags, - boolean overrideDeadlineExpired, Uri[] triggeredContentUris, - String[] triggeredContentAuthorities, Network network) { - this.jobId = jobId; - this.extras = extras; - this.transientExtras = transientExtras; - this.clipData = clipData; - this.clipGrantFlags = clipGrantFlags; - this.callback = callback; - this.overrideDeadlineExpired = overrideDeadlineExpired; - this.mTriggeredContentUris = triggeredContentUris; - this.mTriggeredContentAuthorities = triggeredContentAuthorities; - this.network = network; - } - - /** - * @return The unique id of this job, specified at creation time. - */ - public int getJobId() { - return jobId; - } - - /** - * Reason onStopJob() was called on this job. - * @hide - */ - public int getStopReason() { - return stopReason; - } - - /** - * Reason onStopJob() was called on this job. - * @hide - */ - public String getDebugStopReason() { - return debugStopReason; - } - - /** - * @return The extras you passed in when constructing this job with - * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will - * never be null. If you did not set any extras this will be an empty bundle. - */ - public @NonNull PersistableBundle getExtras() { - return extras; - } - - /** - * @return The transient extras you passed in when constructing this job with - * {@link android.app.job.JobInfo.Builder#setTransientExtras(android.os.Bundle)}. This will - * never be null. If you did not set any extras this will be an empty bundle. - */ - public @NonNull Bundle getTransientExtras() { - return transientExtras; - } - - /** - * @return The clip you passed in when constructing this job with - * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be null - * if it was not set. - */ - public @Nullable ClipData getClipData() { - return clipData; - } - - /** - * @return The clip grant flags you passed in when constructing this job with - * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be 0 - * if it was not set. - */ - public int getClipGrantFlags() { - return clipGrantFlags; - } - - /** - * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this - * provides an easy way to tell whether the job is being executed due to the deadline - * expiring. Note: If the job is running because its deadline expired, it implies that its - * constraints will not be met. - */ - public boolean isOverrideDeadlineExpired() { - return overrideDeadlineExpired; - } - - /** - * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this - * reports which URIs have triggered the job. This will be null if either no URIs have - * triggered it (it went off due to a deadline or other reason), or the number of changed - * URIs is too large to report. Whether or not the number of URIs is too large, you can - * always use {@link #getTriggeredContentAuthorities()} to determine whether the job was - * triggered due to any content changes and the authorities they are associated with. - */ - public @Nullable Uri[] getTriggeredContentUris() { - return mTriggeredContentUris; - } - - /** - * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this - * reports which content authorities have triggered the job. It will only be null if no - * authorities have triggered it -- that is, the job executed for some other reason, such - * as a deadline expiring. If this is non-null, you can use {@link #getTriggeredContentUris()} - * to retrieve the details of which URIs changed (as long as that has not exceeded the maximum - * number it can reported). - */ - public @Nullable String[] getTriggeredContentAuthorities() { - return mTriggeredContentAuthorities; - } - - /** - * Return the network that should be used to perform any network requests - * for this job. - * <p> - * Devices may have multiple active network connections simultaneously, or - * they may not have a default network route at all. To correctly handle all - * situations like this, your job should always use the network returned by - * this method instead of implicitly using the default network route. - * <p> - * Note that the system may relax the constraints you originally requested, - * such as allowing a {@link JobInfo#NETWORK_TYPE_UNMETERED} job to run over - * a metered network when there is a surplus of metered data available. - * - * @return the network that should be used to perform any network requests - * for this job, or {@code null} if this job didn't set any required - * network type. - * @see JobInfo.Builder#setRequiredNetworkType(int) - */ - public @Nullable Network getNetwork() { - return network; - } - - /** - * Dequeue the next pending {@link JobWorkItem} from these JobParameters associated with their - * currently running job. Calling this method when there is no more work available and all - * previously dequeued work has been completed will result in the system taking care of - * stopping the job for you -- - * you should not call {@link JobService#jobFinished(JobParameters, boolean)} yourself - * (otherwise you risk losing an upcoming JobWorkItem that is being enqueued at the same time). - * - * <p>Once you are done with the {@link JobWorkItem} returned by this method, you must call - * {@link #completeWork(JobWorkItem)} with it to inform the system that you are done - * executing the work. The job will not be finished until all dequeued work has been - * completed. You do not, however, have to complete each returned work item before deqeueing - * the next one -- you can use {@link #dequeueWork()} multiple times before completing - * previous work if you want to process work in parallel, and you can complete the work - * in whatever order you want.</p> - * - * <p>If the job runs to the end of its available time period before all work has been - * completed, it will stop as normal. You should return true from - * {@link JobService#onStopJob(JobParameters)} in order to have the job rescheduled, and by - * doing so any pending as well as remaining uncompleted work will be re-queued - * for the next time the job runs.</p> - * - * <p>This example shows how to construct a JobService that will serially dequeue and - * process work that is available for it:</p> - * - * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/JobWorkService.java - * service} - * - * @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null. - * If null is returned, the system will also stop the job if all work has also been completed. - * (This means that for correct operation, you must always call dequeueWork() after you have - * completed other work, to check either for more work or allow the system to stop the job.) - */ - public @Nullable JobWorkItem dequeueWork() { - try { - return getCallback().dequeueWork(getJobId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Report the completion of executing a {@link JobWorkItem} previously returned by - * {@link #dequeueWork()}. This tells the system you are done with the - * work associated with that item, so it will not be returned again. Note that if this - * is the last work in the queue, completing it here will <em>not</em> finish the overall - * job -- for that to happen, you still need to call {@link #dequeueWork()} - * again. - * - * <p>If you are enqueueing work into a job, you must call this method for each piece - * of work you process. Do <em>not</em> call - * {@link JobService#jobFinished(JobParameters, boolean)} - * or else you can lose work in your queue.</p> - * - * @param work The work you have completed processing, as previously returned by - * {@link #dequeueWork()} - */ - public void completeWork(@NonNull JobWorkItem work) { - try { - if (!getCallback().completeWork(getJobId(), work.getWorkId())) { - throw new IllegalArgumentException("Given work is not active: " + work); - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** @hide */ - @UnsupportedAppUsage - public IJobCallback getCallback() { - return IJobCallback.Stub.asInterface(callback); - } - - private JobParameters(Parcel in) { - jobId = in.readInt(); - extras = in.readPersistableBundle(); - transientExtras = in.readBundle(); - if (in.readInt() != 0) { - clipData = ClipData.CREATOR.createFromParcel(in); - clipGrantFlags = in.readInt(); - } else { - clipData = null; - clipGrantFlags = 0; - } - callback = in.readStrongBinder(); - overrideDeadlineExpired = in.readInt() == 1; - mTriggeredContentUris = in.createTypedArray(Uri.CREATOR); - mTriggeredContentAuthorities = in.createStringArray(); - if (in.readInt() != 0) { - network = Network.CREATOR.createFromParcel(in); - } else { - network = null; - } - stopReason = in.readInt(); - debugStopReason = in.readString(); - } - - /** @hide */ - public void setStopReason(int reason, String debugStopReason) { - stopReason = reason; - this.debugStopReason = debugStopReason; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(jobId); - dest.writePersistableBundle(extras); - dest.writeBundle(transientExtras); - if (clipData != null) { - dest.writeInt(1); - clipData.writeToParcel(dest, flags); - dest.writeInt(clipGrantFlags); - } else { - dest.writeInt(0); - } - dest.writeStrongBinder(callback); - dest.writeInt(overrideDeadlineExpired ? 1 : 0); - dest.writeTypedArray(mTriggeredContentUris, flags); - dest.writeStringArray(mTriggeredContentAuthorities); - if (network != null) { - dest.writeInt(1); - network.writeToParcel(dest, flags); - } else { - dest.writeInt(0); - } - dest.writeInt(stopReason); - dest.writeString(debugStopReason); - } - - public static final @android.annotation.NonNull Creator<JobParameters> CREATOR = new Creator<JobParameters>() { - @Override - public JobParameters createFromParcel(Parcel in) { - return new JobParameters(in); - } - - @Override - public JobParameters[] newArray(int size) { - return new JobParameters[size]; - } - }; -} diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java deleted file mode 100644 index 08b1c2b9f548..000000000000 --- a/core/java/android/app/job/JobScheduler.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2014 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.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.content.ClipData; -import android.content.Context; -import android.os.Bundle; -import android.os.PersistableBundle; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; - -/** - * This is an API for scheduling various types of jobs against the framework that will be executed - * in your application's own process. - * <p> - * See {@link android.app.job.JobInfo} for more description of the types of jobs that can be run - * and how to construct them. You will construct these JobInfo objects and pass them to the - * JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the - * system will execute this job on your application's {@link android.app.job.JobService}. - * You identify the service component that implements the logic for your job when you - * construct the JobInfo using - * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}. - * </p> - * <p> - * The framework will be intelligent about when it executes jobs, and attempt to batch - * and defer them as much as possible. Typically if you don't specify a deadline on a job, it - * can be run at any moment depending on the current state of the JobScheduler's internal queue. - * <p> - * While a job is running, the system holds a wakelock on behalf of your app. For this reason, - * you do not need to take any action to guarantee that the device stays awake for the - * duration of the job. - * </p> - * <p>You do not - * instantiate this class directly; instead, retrieve it through - * {@link android.content.Context#getSystemService - * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}. - */ -@SystemService(Context.JOB_SCHEDULER_SERVICE) -public abstract class JobScheduler { - /** @hide */ - @IntDef(prefix = { "RESULT_" }, value = { - RESULT_FAILURE, - RESULT_SUCCESS, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Result {} - - /** - * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur - * if the run-time for your job is too short, or perhaps the system can't resolve the - * requisite {@link JobService} in your package. - */ - public static final int RESULT_FAILURE = 0; - /** - * Returned from {@link #schedule(JobInfo)} if this job has been successfully scheduled. - */ - public static final int RESULT_SUCCESS = 1; - - /** - * 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 - * running, it will be stopped. - * - * @param job The job you wish scheduled. See - * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs - * you can schedule. - * @return the result of the schedule request. - */ - public abstract @Result int schedule(@NonNull JobInfo job); - - /** - * Similar to {@link #schedule}, but allows you to enqueue work for a new <em>or existing</em> - * job. If a job with the same ID is already scheduled, it will be replaced with the - * new {@link JobInfo}, but any previously enqueued work will remain and be dispatched the - * next time it runs. If a job with the same ID is already running, the new work will be - * enqueued for it. - * - * <p>The work you enqueue is later retrieved through - * {@link JobParameters#dequeueWork() JobParameters.dequeueWork}. Be sure to see there - * about how to process work; the act of enqueueing work changes how you should handle the - * overall lifecycle of an executing job.</p> - * - * <p>It is strongly encouraged that you use the same {@link JobInfo} for all work you - * enqueue. This will allow the system to optimally schedule work along with any pending - * and/or currently running work. If the JobInfo changes from the last time the job was - * enqueued, the system will need to update the associated JobInfo, which can cause a disruption - * in execution. In particular, this can result in any currently running job that is processing - * previous work to be stopped and restarted with the new JobInfo.</p> - * - * <p>It is recommended that you avoid using - * {@link JobInfo.Builder#setExtras(PersistableBundle)} or - * {@link JobInfo.Builder#setTransientExtras(Bundle)} with a JobInfo you are using to - * enqueue work. The system will try to compare these extras with the previous JobInfo, - * but there are situations where it may get this wrong and count the JobInfo as changing. - * (That said, you should be relatively safe with a simple set of consistent data in these - * fields.) You should never use {@link JobInfo.Builder#setClipData(ClipData, int)} with - * work you are enqueue, since currently this will always be treated as a different JobInfo, - * even if the ClipData contents are exactly the same.</p> - * - * @param job The job you wish to enqueue work for. See - * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs - * you can schedule. - * @param work New work to enqueue. This will be available later when the job starts running. - * @return the result of the enqueue request. - */ - public abstract @Result int enqueue(@NonNull JobInfo job, @NonNull JobWorkItem work); - - /** - * - * @param job The job to be scheduled. - * @param packageName The package on behalf of which the job is to be scheduled. This will be - * used to track battery usage and appIdleState. - * @param userId User on behalf of whom this job is to be scheduled. - * @param tag Debugging tag for dumps associated with this job (instead of the service class) - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) - public abstract @Result int scheduleAsPackage(@NonNull JobInfo job, @NonNull String packageName, - int userId, String tag); - - /** - * Cancel the specified job. If the job is currently executing, it is stopped - * immediately and the return value from its {@link JobService#onStopJob(JobParameters)} - * method is ignored. - * - * @param jobId unique identifier for the job to be canceled, as supplied to - * {@link JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName) - * JobInfo.Builder(int, android.content.ComponentName)}. - */ - public abstract void cancel(int jobId); - - /** - * Cancel <em>all</em> jobs that have been scheduled by the calling application. - */ - public abstract void cancelAll(); - - /** - * Retrieve all jobs that have been scheduled by the calling application. - * - * @return a list of all of the app's scheduled jobs. This includes jobs that are - * currently started as well as those that are still waiting to run. - */ - public abstract @NonNull List<JobInfo> getAllPendingJobs(); - - /** - * Look up the description of a scheduled job. - * - * @return The {@link JobInfo} description of the given scheduled job, or {@code null} - * if the supplied job ID does not correspond to any job. - */ - public abstract @Nullable JobInfo getPendingJob(int jobId); - - /** - * <b>For internal system callers only!</b> - * Returns a list of all currently-executing jobs. - * @hide - */ - public abstract List<JobInfo> getStartedJobs(); - - /** - * <b>For internal system callers only!</b> - * Returns a snapshot of the state of all jobs known to the system. - * - * <p class="note">This is a slow operation, so it should be called sparingly. - * @hide - */ - public abstract List<JobSnapshot> getAllJobSnapshots(); -}
\ No newline at end of file diff --git a/core/java/android/app/job/JobSchedulerFrameworkInitializer.java b/core/java/android/app/job/JobSchedulerFrameworkInitializer.java deleted file mode 100644 index c90b8728bf4a..000000000000 --- a/core/java/android/app/job/JobSchedulerFrameworkInitializer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2019 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.app.JobSchedulerImpl; -import android.app.SystemServiceRegistry; -import android.content.Context; -import android.os.BatteryStats; - -/** - * This class needs to be pre-loaded by zygote. This is where the job scheduler service wrapper - * is registered. - * - * @hide - */ -public class JobSchedulerFrameworkInitializer { - static { - SystemServiceRegistry.registerStaticService( - Context.JOB_SCHEDULER_SERVICE, JobScheduler.class, - (b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b))); - - BatteryStats.setJobStopReasons(JobParameters.JOB_STOP_REASON_CODES, - JobParameters::getReasonName); - } -} diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java deleted file mode 100644 index 61afadab9b0c..000000000000 --- a/core/java/android/app/job/JobService.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2014 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.app.Service; -import android.content.Intent; -import android.os.IBinder; - -/** - * <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p> - * <p>This is the base class that handles asynchronous requests that were previously scheduled. You - * are responsible for overriding {@link JobService#onStartJob(JobParameters)}, which is where - * you will implement your job logic.</p> - * <p>This service executes each incoming job on a {@link android.os.Handler} running on your - * application's main thread. This means that you <b>must</b> offload your execution logic to - * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result - * in blocking any future callbacks from the JobManager - specifically - * {@link #onStopJob(android.app.job.JobParameters)}, which is meant to inform you that the - * scheduling requirements are no longer being met.</p> - */ -public abstract class JobService extends Service { - private static final String TAG = "JobService"; - - /** - * Job services must be protected with this permission: - * - * <pre class="prettyprint"> - * <service android:name="MyJobService" - * android:permission="android.permission.BIND_JOB_SERVICE" > - * ... - * </service> - * </pre> - * - * <p>If a job service is declared in the manifest but not protected with this - * permission, that service will be ignored by the system. - */ - public static final String PERMISSION_BIND = - "android.permission.BIND_JOB_SERVICE"; - - private JobServiceEngine mEngine; - - /** @hide */ - public final IBinder onBind(Intent intent) { - if (mEngine == null) { - mEngine = new JobServiceEngine(this) { - @Override - public boolean onStartJob(JobParameters params) { - return JobService.this.onStartJob(params); - } - - @Override - public boolean onStopJob(JobParameters params) { - return JobService.this.onStopJob(params); - } - }; - } - return mEngine.getBinder(); - } - - /** - * Call this to inform the JobScheduler that the job has finished its work. When the - * system receives this message, it releases the wakelock being held for the job. - * <p> - * You can request that the job be scheduled again by passing {@code true} as - * the <code>wantsReschedule</code> parameter. This will apply back-off policy - * for the job; this policy can be adjusted through the - * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)} method - * when the job is originally scheduled. The job's initial - * requirements are preserved when jobs are rescheduled, regardless of backed-off - * policy. - * <p class="note"> - * A job running while the device is dozing will not be rescheduled with the normal back-off - * policy. Instead, the job will be re-added to the queue and executed again during - * a future idle maintenance window. - * </p> - * - * @param params The parameters identifying this job, as supplied to - * the job in the {@link #onStartJob(JobParameters)} callback. - * @param wantsReschedule {@code true} if this job should be rescheduled according - * to the back-off criteria specified when it was first scheduled; {@code false} - * otherwise. - */ - public final void jobFinished(JobParameters params, boolean wantsReschedule) { - mEngine.jobFinished(params, wantsReschedule); - } - - /** - * Called to indicate that the job has begun executing. Override this method with the - * logic for your job. Like all other component lifecycle callbacks, this method executes - * on your application's main thread. - * <p> - * Return {@code true} from this method if your job needs to continue running. If you - * do this, the job remains active until you call - * {@link #jobFinished(JobParameters, boolean)} to tell the system that it has completed - * its work, or until the job's required constraints are no longer satisfied. For - * example, if the job was scheduled using - * {@link JobInfo.Builder#setRequiresCharging(boolean) setRequiresCharging(true)}, - * it will be immediately halted by the system if the user unplugs the device from power, - * the job's {@link #onStopJob(JobParameters)} callback will be invoked, and the app - * will be expected to shut down all ongoing work connected with that job. - * <p> - * The system holds a wakelock on behalf of your app as long as your job is executing. - * This wakelock is acquired before this method is invoked, and is not released until either - * you call {@link #jobFinished(JobParameters, boolean)}, or after the system invokes - * {@link #onStopJob(JobParameters)} to notify your job that it is being shut down - * prematurely. - * <p> - * Returning {@code false} from this method means your job is already finished. The - * system's wakelock for the job will be released, and {@link #onStopJob(JobParameters)} - * will not be invoked. - * - * @param params Parameters specifying info about this job, including the optional - * extras configured with {@link JobInfo.Builder#setExtras(android.os.PersistableBundle). - * This object serves to identify this specific running job instance when calling - * {@link #jobFinished(JobParameters, boolean)}. - * @return {@code true} if your service will continue running, using a separate thread - * when appropriate. {@code false} means that this job has completed its work. - */ - public abstract boolean onStartJob(JobParameters params); - - /** - * This method is called if the system has determined that you must stop execution of your job - * even before you've had a chance to call {@link #jobFinished(JobParameters, boolean)}. - * - * <p>This will happen if the requirements specified at schedule time are no longer met. For - * example you may have requested WiFi with - * {@link android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}, yet while your - * job was executing the user toggled WiFi. Another example is if you had specified - * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its - * idle maintenance window. You are solely responsible for the behavior of your application - * upon receipt of this message; your app will likely start to misbehave if you ignore it. - * <p> - * Once this method returns, the system releases the wakelock that it is holding on - * behalf of the job.</p> - * - * @param params The parameters identifying this job, as supplied to - * the job in the {@link #onStartJob(JobParameters)} callback. - * @return {@code true} to indicate to the JobManager whether you'd like to reschedule - * this job based on the retry criteria provided at job creation-time; or {@code false} - * to end the job entirely. Regardless of the value returned, your job must stop executing. - */ - public abstract boolean onStopJob(JobParameters params); -} diff --git a/core/java/android/app/job/JobServiceEngine.java b/core/java/android/app/job/JobServiceEngine.java deleted file mode 100644 index ab94da843635..000000000000 --- a/core/java/android/app/job/JobServiceEngine.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2014 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.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import android.util.Log; - -import com.android.internal.annotations.GuardedBy; - -import java.lang.ref.WeakReference; - -/** - * Helper for implementing a {@link android.app.Service} that interacts with - * {@link JobScheduler}. This is not intended for use by regular applications, but - * allows frameworks built on top of the platform to create their own - * {@link android.app.Service} that interact with {@link JobScheduler} as well as - * add in additional functionality. If you just want to execute jobs normally, you - * should instead be looking at {@link JobService}. - */ -public abstract class JobServiceEngine { - private static final String TAG = "JobServiceEngine"; - - /** - * Identifier for a message that will result in a call to - * {@link #onStartJob(android.app.job.JobParameters)}. - */ - private static final int MSG_EXECUTE_JOB = 0; - /** - * Message that will result in a call to {@link #onStopJob(android.app.job.JobParameters)}. - */ - private static final int MSG_STOP_JOB = 1; - /** - * Message that the client has completed execution of this job. - */ - private static final int MSG_JOB_FINISHED = 2; - - private final IJobService mBinder; - - /** - * Handler we post jobs to. Responsible for calling into the client logic, and handling the - * callback to the system. - */ - JobHandler mHandler; - - static final class JobInterface extends IJobService.Stub { - final WeakReference<JobServiceEngine> mService; - - JobInterface(JobServiceEngine service) { - mService = new WeakReference<>(service); - } - - @Override - public void startJob(JobParameters jobParams) throws RemoteException { - JobServiceEngine service = mService.get(); - if (service != null) { - Message m = Message.obtain(service.mHandler, MSG_EXECUTE_JOB, jobParams); - m.sendToTarget(); - } - } - - @Override - public void stopJob(JobParameters jobParams) throws RemoteException { - JobServiceEngine service = mService.get(); - if (service != null) { - Message m = Message.obtain(service.mHandler, MSG_STOP_JOB, jobParams); - m.sendToTarget(); - } - } - } - - /** - * Runs on application's main thread - callbacks are meant to offboard work to some other - * (app-specified) mechanism. - * @hide - */ - class JobHandler extends Handler { - JobHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - final JobParameters params = (JobParameters) msg.obj; - switch (msg.what) { - case MSG_EXECUTE_JOB: - try { - boolean workOngoing = JobServiceEngine.this.onStartJob(params); - ackStartMessage(params, workOngoing); - } catch (Exception e) { - Log.e(TAG, "Error while executing job: " + params.getJobId()); - throw new RuntimeException(e); - } - break; - case MSG_STOP_JOB: - try { - boolean ret = JobServiceEngine.this.onStopJob(params); - ackStopMessage(params, ret); - } catch (Exception e) { - Log.e(TAG, "Application unable to handle onStopJob.", e); - throw new RuntimeException(e); - } - break; - case MSG_JOB_FINISHED: - final boolean needsReschedule = (msg.arg2 == 1); - IJobCallback callback = params.getCallback(); - if (callback != null) { - try { - callback.jobFinished(params.getJobId(), needsReschedule); - } catch (RemoteException e) { - Log.e(TAG, "Error reporting job finish to system: binder has gone" + - "away."); - } - } else { - Log.e(TAG, "finishJob() called for a nonexistent job id."); - } - break; - default: - Log.e(TAG, "Unrecognised message received."); - break; - } - } - - private void ackStartMessage(JobParameters params, boolean workOngoing) { - final IJobCallback callback = params.getCallback(); - final int jobId = params.getJobId(); - if (callback != null) { - try { - callback.acknowledgeStartMessage(jobId, workOngoing); - } catch(RemoteException e) { - Log.e(TAG, "System unreachable for starting job."); - } - } else { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Attempting to ack a job that has already been processed."); - } - } - } - - private void ackStopMessage(JobParameters params, boolean reschedule) { - final IJobCallback callback = params.getCallback(); - final int jobId = params.getJobId(); - if (callback != null) { - try { - callback.acknowledgeStopMessage(jobId, reschedule); - } catch(RemoteException e) { - Log.e(TAG, "System unreachable for stopping job."); - } - } else { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Attempting to ack a job that has already been processed."); - } - } - } - } - - /** - * Create a new engine, ready for use. - * - * @param service The {@link Service} that is creating this engine and in which it will run. - */ - public JobServiceEngine(Service service) { - mBinder = new JobInterface(this); - mHandler = new JobHandler(service.getMainLooper()); - } - - /** - * Retrieve the engine's IPC interface that should be returned by - * {@link Service#onBind(Intent)}. - */ - public final IBinder getBinder() { - return mBinder.asBinder(); - } - - /** - * Engine's report that a job has started. See - * {@link JobService#onStartJob(JobParameters) JobService.onStartJob} for more information. - */ - public abstract boolean onStartJob(JobParameters params); - - /** - * Engine's report that a job has stopped. See - * {@link JobService#onStopJob(JobParameters) JobService.onStopJob} for more information. - */ - public abstract boolean onStopJob(JobParameters params); - - /** - * Call in to engine to report that a job has finished executing. See - * {@link JobService#jobFinished(JobParameters, boolean)} JobService.jobFinished} for more - * information. - */ - public void jobFinished(JobParameters params, boolean needsReschedule) { - if (params == null) { - throw new NullPointerException("params"); - } - Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params); - m.arg2 = needsReschedule ? 1 : 0; - m.sendToTarget(); - } -}
\ No newline at end of file diff --git a/core/java/android/app/job/JobSnapshot.aidl b/core/java/android/app/job/JobSnapshot.aidl deleted file mode 100644 index d40f4e39ea2e..000000000000 --- a/core/java/android/app/job/JobSnapshot.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (C) 2018 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 JobSnapshot; diff --git a/core/java/android/app/job/JobSnapshot.java b/core/java/android/app/job/JobSnapshot.java deleted file mode 100644 index 2c58908a6064..000000000000 --- a/core/java/android/app/job/JobSnapshot.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2018 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.os.Parcel; -import android.os.Parcelable; - -/** - * Current-state snapshot of a scheduled job. These snapshots are not used in apps; - * they exist only within the system process across the local call surface where JobStatus - * is not directly accessible at build time. - * - * Constraints that the underlying job does not require are always reported as - * being currently satisfied. - * @hide - */ -public class JobSnapshot implements Parcelable { - private final JobInfo mJob; - private final int mSatisfiedConstraints; - private final boolean mIsRunnable; - - public JobSnapshot(JobInfo info, int satisfiedMask, boolean runnable) { - mJob = info; - mSatisfiedConstraints = satisfiedMask; - mIsRunnable = runnable; - } - - public JobSnapshot(Parcel in) { - mJob = JobInfo.CREATOR.createFromParcel(in); - mSatisfiedConstraints = in.readInt(); - mIsRunnable = in.readBoolean(); - } - - private boolean satisfied(int flag) { - return (mSatisfiedConstraints & flag) != 0; - } - - /** - * Returning JobInfo bound to this snapshot - * @return JobInfo of this snapshot - */ - public JobInfo getJobInfo() { - return mJob; - } - - /** - * Is this job actually runnable at this moment? - */ - public boolean isRunnable() { - return mIsRunnable; - } - - /** - * @see JobInfo.Builder#setRequiresCharging(boolean) - */ - public boolean isChargingSatisfied() { - return !mJob.isRequireCharging() - || satisfied(JobInfo.CONSTRAINT_FLAG_CHARGING); - } - - /** - * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean) - */ - public boolean isBatteryNotLowSatisfied() { - return !mJob.isRequireBatteryNotLow() - || satisfied(JobInfo.CONSTRAINT_FLAG_BATTERY_NOT_LOW); - } - - /** - * @see JobInfo.Builder#setRequiresDeviceIdle(boolean) - */ - public boolean isRequireDeviceIdleSatisfied() { - return !mJob.isRequireDeviceIdle() - || satisfied(JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE); - } - - public boolean isRequireStorageNotLowSatisfied() { - return !mJob.isRequireStorageNotLow() - || satisfied(JobInfo.CONSTRAINT_FLAG_STORAGE_NOT_LOW); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - mJob.writeToParcel(out, flags); - out.writeInt(mSatisfiedConstraints); - out.writeBoolean(mIsRunnable); - } - - public static final @android.annotation.NonNull Creator<JobSnapshot> CREATOR = new Creator<JobSnapshot>() { - @Override - public JobSnapshot createFromParcel(Parcel in) { - return new JobSnapshot(in); - } - - @Override - public JobSnapshot[] newArray(int size) { - return new JobSnapshot[size]; - } - }; -} diff --git a/core/java/android/app/job/JobWorkItem.aidl b/core/java/android/app/job/JobWorkItem.aidl deleted file mode 100644 index e8fe47d07865..000000000000 --- a/core/java/android/app/job/JobWorkItem.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2017 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; - -/** @hide */ -parcelable JobWorkItem; diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java deleted file mode 100644 index c6631fa76494..000000000000 --- a/core/java/android/app/job/JobWorkItem.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2017 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 static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN; - -import android.annotation.BytesLong; -import android.annotation.UnsupportedAppUsage; -import android.content.Intent; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * A unit of work that can be enqueued for a job using - * {@link JobScheduler#enqueue JobScheduler.enqueue}. See - * {@link JobParameters#dequeueWork() JobParameters.dequeueWork} for more details. - */ -final public class JobWorkItem implements Parcelable { - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - final Intent mIntent; - final long mNetworkDownloadBytes; - final long mNetworkUploadBytes; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - int mDeliveryCount; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - int mWorkId; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - Object mGrants; - - /** - * Create a new piece of work, which can be submitted to - * {@link JobScheduler#enqueue JobScheduler.enqueue}. - * - * @param intent The general Intent describing this work. - */ - public JobWorkItem(Intent intent) { - mIntent = intent; - mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN; - mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN; - } - - /** - * Create a new piece of work, which can be submitted to - * {@link JobScheduler#enqueue JobScheduler.enqueue}. - * <p> - * See {@link JobInfo.Builder#setEstimatedNetworkBytes(long, long)} for - * details about how to estimate network traffic. - * - * @param intent The general Intent describing this work. - * @param downloadBytes The estimated size of network traffic that will be - * downloaded by this job work item, in bytes. - * @param uploadBytes The estimated size of network traffic that will be - * uploaded by this job work item, in bytes. - */ - public JobWorkItem(Intent intent, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { - mIntent = intent; - mNetworkDownloadBytes = downloadBytes; - mNetworkUploadBytes = uploadBytes; - } - - /** - * Return the Intent associated with this work. - */ - public Intent getIntent() { - return mIntent; - } - - /** - * Return the estimated size of download traffic that will be performed by - * this job, in bytes. - * - * @return Estimated size of download traffic, or - * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown. - */ - public @BytesLong long getEstimatedNetworkDownloadBytes() { - return mNetworkDownloadBytes; - } - - /** - * Return the estimated size of upload traffic that will be performed by - * this job work item, in bytes. - * - * @return Estimated size of upload traffic, or - * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown. - */ - public @BytesLong long getEstimatedNetworkUploadBytes() { - return mNetworkUploadBytes; - } - - /** - * Return the count of the number of times this work item has been delivered - * to the job. The value will be > 1 if it has been redelivered because the job - * was stopped or crashed while it had previously been delivered but before the - * job had called {@link JobParameters#completeWork JobParameters.completeWork} for it. - */ - public int getDeliveryCount() { - return mDeliveryCount; - } - - /** - * @hide - */ - public void bumpDeliveryCount() { - mDeliveryCount++; - } - - /** - * @hide - */ - public void setWorkId(int id) { - mWorkId = id; - } - - /** - * @hide - */ - public int getWorkId() { - return mWorkId; - } - - /** - * @hide - */ - public void setGrants(Object grants) { - mGrants = grants; - } - - /** - * @hide - */ - public Object getGrants() { - return mGrants; - } - - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append("JobWorkItem{id="); - sb.append(mWorkId); - sb.append(" intent="); - sb.append(mIntent); - if (mNetworkDownloadBytes != NETWORK_BYTES_UNKNOWN) { - sb.append(" downloadBytes="); - sb.append(mNetworkDownloadBytes); - } - if (mNetworkUploadBytes != NETWORK_BYTES_UNKNOWN) { - sb.append(" uploadBytes="); - sb.append(mNetworkUploadBytes); - } - if (mDeliveryCount != 0) { - sb.append(" dcount="); - sb.append(mDeliveryCount); - } - sb.append("}"); - return sb.toString(); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel out, int flags) { - if (mIntent != null) { - out.writeInt(1); - mIntent.writeToParcel(out, 0); - } else { - out.writeInt(0); - } - out.writeLong(mNetworkDownloadBytes); - out.writeLong(mNetworkUploadBytes); - out.writeInt(mDeliveryCount); - out.writeInt(mWorkId); - } - - public static final @android.annotation.NonNull Parcelable.Creator<JobWorkItem> CREATOR - = new Parcelable.Creator<JobWorkItem>() { - public JobWorkItem createFromParcel(Parcel in) { - return new JobWorkItem(in); - } - - public JobWorkItem[] newArray(int size) { - return new JobWorkItem[size]; - } - }; - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - JobWorkItem(Parcel in) { - if (in.readInt() != 0) { - mIntent = Intent.CREATOR.createFromParcel(in); - } else { - mIntent = null; - } - mNetworkDownloadBytes = in.readLong(); - mNetworkUploadBytes = in.readLong(); - mDeliveryCount = in.readInt(); - mWorkId = in.readInt(); - } -} |
