diff --git a/api/current.txt b/api/current.txt
index 5e7fa591385e0..38f37a198c7d6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7041,7 +7041,8 @@ package android.app.job {
method public int getBackoffPolicy();
method public android.content.ClipData getClipData();
method public int getClipGrantFlags();
- method public long getEstimatedNetworkBytes();
+ method public long getEstimatedNetworkDownloadBytes();
+ method public long getEstimatedNetworkUploadBytes();
method public android.os.PersistableBundle getExtras();
method public long getFlexMillis();
method public int getId();
@@ -7058,8 +7059,10 @@ package android.app.job {
method public long getTriggerContentMaxDelay();
method public long getTriggerContentUpdateDelay();
method public android.app.job.JobInfo.TriggerContentUri[] getTriggerContentUris();
+ method public boolean isImportantWhileForeground();
method public boolean isPeriodic();
method public boolean isPersisted();
+ method public boolean isPrefetch();
method public boolean isRequireBatteryNotLow();
method public boolean isRequireCharging();
method public boolean isRequireDeviceIdle();
@@ -7085,15 +7088,15 @@ package android.app.job {
method public android.app.job.JobInfo build();
method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
method public android.app.job.JobInfo.Builder setClipData(android.content.ClipData, int);
- method public android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long);
+ method public android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long, long);
method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
method public android.app.job.JobInfo.Builder setImportantWhileForeground(boolean);
- method public android.app.job.JobInfo.Builder setIsPrefetch(boolean);
method public android.app.job.JobInfo.Builder setMinimumLatency(long);
method public android.app.job.JobInfo.Builder setOverrideDeadline(long);
method public android.app.job.JobInfo.Builder setPeriodic(long);
method public android.app.job.JobInfo.Builder setPeriodic(long, long);
method public android.app.job.JobInfo.Builder setPersisted(boolean);
+ method public android.app.job.JobInfo.Builder setPrefetch(boolean);
method public android.app.job.JobInfo.Builder setRequiredNetwork(android.net.NetworkRequest);
method public android.app.job.JobInfo.Builder setRequiredNetworkType(int);
method public android.app.job.JobInfo.Builder setRequiresBatteryNotLow(boolean);
@@ -7163,10 +7166,11 @@ package android.app.job {
public final class JobWorkItem implements android.os.Parcelable {
ctor public JobWorkItem(android.content.Intent);
- ctor public JobWorkItem(android.content.Intent, long);
+ ctor public JobWorkItem(android.content.Intent, long, long);
method public int describeContents();
method public int getDeliveryCount();
- method public long getEstimatedNetworkBytes();
+ method public long getEstimatedNetworkDownloadBytes();
+ method public long getEstimatedNetworkUploadBytes();
method public android.content.Intent getIntent();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator This is not the same as "doze" or "device idle";
- * it is purely about the user's direct interactions.
+ * 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 networkBytes The estimated size of network traffic that will - * be performed by this job, in bytes. This value only - * reflects 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. - * @see JobInfo#getEstimatedNetworkBytes() - * @see JobWorkItem#JobWorkItem(android.content.Intent, long) + * @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 networkBytes) { - mNetworkBytes = networkBytes; + public Builder setEstimatedNetworkBytes(@BytesLong long downloadBytes, + @BytesLong long uploadBytes) { + mNetworkDownloadBytes = downloadBytes; + mNetworkUploadBytes = uploadBytes; return this; } @@ -1146,6 +1225,7 @@ public class JobInfo implements Parcelable { * * @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) @@ -1159,6 +1239,7 @@ public class JobInfo implements Parcelable { * 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) @@ -1183,6 +1264,7 @@ public class JobInfo implements Parcelable { * * @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) @@ -1196,6 +1278,7 @@ public class JobInfo implements Parcelable { * 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) @@ -1228,6 +1311,7 @@ public class JobInfo implements Parcelable { * job} * * @param uri The content: URI to monitor. + * @see JobInfo#getTriggerContentUris() */ public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) { if (mTriggerContentUris == null) { @@ -1242,6 +1326,7 @@ public class JobInfo implements Parcelable { * 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; @@ -1252,6 +1337,7 @@ public class JobInfo implements Parcelable { * 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; @@ -1265,6 +1351,8 @@ public class JobInfo implements Parcelable { * 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); @@ -1278,6 +1366,8 @@ public class JobInfo implements Parcelable { * @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(); @@ -1309,6 +1399,7 @@ public class JobInfo implements Parcelable { * {@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; @@ -1322,6 +1413,7 @@ public class JobInfo implements Parcelable { * 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; @@ -1341,6 +1433,8 @@ public class JobInfo implements Parcelable { * 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) { @@ -1371,6 +1465,7 @@ public class JobInfo implements Parcelable { * * @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) { @@ -1381,6 +1476,15 @@ public class JobInfo implements Parcelable { return this; } + /** + * @removed + * @deprecated replaced with {@link #setPrefetch(boolean)} + */ + @Deprecated + public Builder setIsPrefetch(boolean isPrefetch) { + return setPrefetch(isPrefetch); + } + /** * Setting this to true indicates that this job is designed to prefetch * content that will make a material improvement to the experience of @@ -1393,12 +1497,13 @@ public class JobInfo implements Parcelable { * 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 setIsPrefetch(boolean isPrefetch) { - if (isPrefetch) { - mFlags |= FLAG_IS_PREFETCH; + public Builder setPrefetch(boolean prefetch) { + if (prefetch) { + mFlags |= FLAG_PREFETCH; } else { - mFlags &= (~FLAG_IS_PREFETCH); + mFlags &= (~FLAG_PREFETCH); } return this; } @@ -1408,6 +1513,7 @@ public class JobInfo implements Parcelable { * * @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) { @@ -1427,7 +1533,7 @@ public class JobInfo implements Parcelable { "constraints, this is not allowed."); } // Check that network estimates require network type - if (mNetworkBytes > 0 && mNetworkRequest == null) { + if ((mNetworkDownloadBytes > 0 || mNetworkUploadBytes > 0) && mNetworkRequest == null) { throw new IllegalArgumentException( "Can't provide estimated network usage without requiring a network"); } diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java index 1c46e8ecbe526..995f5226d5a39 100644 --- a/core/java/android/app/job/JobWorkItem.java +++ b/core/java/android/app/job/JobWorkItem.java @@ -16,6 +16,8 @@ package android.app.job; +import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN; + import android.annotation.BytesLong; import android.content.Intent; import android.os.Parcel; @@ -28,7 +30,8 @@ import android.os.Parcelable; */ final public class JobWorkItem implements Parcelable { final Intent mIntent; - final long mNetworkBytes; + final long mNetworkDownloadBytes; + final long mNetworkUploadBytes; int mDeliveryCount; int mWorkId; Object mGrants; @@ -41,22 +44,36 @@ final public class JobWorkItem implements Parcelable { */ public JobWorkItem(Intent intent) { mIntent = intent; - mNetworkBytes = JobInfo.NETWORK_BYTES_UNKNOWN; + mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN; + mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN; + } + + /** + * @deprecated replaced by {@link #JobWorkItem(Intent, long, long)} + * @removed + */ + @Deprecated + public JobWorkItem(Intent intent, @BytesLong long networkBytes) { + this(intent, networkBytes, NETWORK_BYTES_UNKNOWN); } /** * Create a new piece of work, which can be submitted to * {@link JobScheduler#enqueue JobScheduler.enqueue}. + *
+ * See {@link JobInfo.Builder#setEstimatedNetworkBytes(long, long)} for + * details about how to estimate network traffic. * * @param intent The general Intent describing this work. - * @param networkBytes The estimated size of network traffic that will be - * performed by this job work item, in bytes. See - * {@link JobInfo.Builder#setEstimatedNetworkBytes(long)} for - * details about how to estimate. + * @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 networkBytes) { + public JobWorkItem(Intent intent, @BytesLong long downloadBytes, @BytesLong long uploadBytes) { mIntent = intent; - mNetworkBytes = networkBytes; + mNetworkDownloadBytes = downloadBytes; + mNetworkUploadBytes = uploadBytes; } /** @@ -67,14 +84,44 @@ final public class JobWorkItem implements Parcelable { } /** - * Return the estimated size of network traffic that will be performed by + * @deprecated replaced by {@link #getEstimatedNetworkDownloadBytes()} and + * {@link #getEstimatedNetworkUploadBytes()}. + * @removed + */ + @Deprecated + public @BytesLong long getEstimatedNetworkBytes() { + if (mNetworkDownloadBytes == NETWORK_BYTES_UNKNOWN + && mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) { + return NETWORK_BYTES_UNKNOWN; + } else if (mNetworkDownloadBytes == NETWORK_BYTES_UNKNOWN) { + return mNetworkUploadBytes; + } else if (mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) { + return mNetworkDownloadBytes; + } else { + return mNetworkDownloadBytes + mNetworkUploadBytes; + } + } + + /** + * 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, or {@link JobInfo#NETWORK_BYTES_UNKNOWN} when - * unknown. + * @return Estimated size of upload traffic, or + * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown. */ - public @BytesLong long getEstimatedNetworkBytes() { - return mNetworkBytes; + public @BytesLong long getEstimatedNetworkUploadBytes() { + return mNetworkUploadBytes; } /** @@ -128,9 +175,13 @@ final public class JobWorkItem implements Parcelable { sb.append(mWorkId); sb.append(" intent="); sb.append(mIntent); - if (mNetworkBytes != JobInfo.NETWORK_BYTES_UNKNOWN) { - sb.append(" networkBytes="); - sb.append(mNetworkBytes); + 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="); @@ -151,7 +202,8 @@ final public class JobWorkItem implements Parcelable { } else { out.writeInt(0); } - out.writeLong(mNetworkBytes); + out.writeLong(mNetworkDownloadBytes); + out.writeLong(mNetworkUploadBytes); out.writeInt(mDeliveryCount); out.writeInt(mWorkId); } @@ -173,7 +225,8 @@ final public class JobWorkItem implements Parcelable { } else { mIntent = null; } - mNetworkBytes = in.readLong(); + mNetworkDownloadBytes = in.readLong(); + mNetworkUploadBytes = in.readLong(); mDeliveryCount = in.readInt(); mWorkId = in.readInt(); } diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java index abe55bbfb7290..8365fd2e5427b 100644 --- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java +++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java @@ -160,7 +160,7 @@ public final class ConnectivityController extends StateController implements private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network, NetworkCapabilities capabilities, Constants constants) { // Only consider doing this for prefetching jobs - if ((jobStatus.getJob().getFlags() & JobInfo.FLAG_IS_PREFETCH) == 0) { + if (!jobStatus.getJob().isPrefetch()) { return false; }