Merge "Prevent apps from setting negative estimated bytes."
This commit is contained in:
committed by
Android (Google) Code Review
commit
901ade8636
@@ -32,6 +32,7 @@ import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.compat.Compatibility;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledAfter;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.ClipData;
|
||||
@@ -97,6 +98,15 @@ public class JobInfo implements Parcelable {
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
|
||||
public static final long THROW_ON_INVALID_PRIORITY_VALUE = 140852299L;
|
||||
|
||||
/**
|
||||
* Require that estimated network bytes are nonnegative.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
|
||||
public static final long REJECT_NEGATIVE_NETWORK_ESTIMATES = 253665015L;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "NETWORK_TYPE_" }, value = {
|
||||
NETWORK_TYPE_NONE,
|
||||
@@ -1890,11 +1900,13 @@ public class JobInfo implements Parcelable {
|
||||
* @return The job object to hand to the JobScheduler. This object is immutable.
|
||||
*/
|
||||
public JobInfo build() {
|
||||
return build(Compatibility.isChangeEnabled(DISALLOW_DEADLINES_FOR_PREFETCH_JOBS));
|
||||
return build(Compatibility.isChangeEnabled(DISALLOW_DEADLINES_FOR_PREFETCH_JOBS),
|
||||
Compatibility.isChangeEnabled(REJECT_NEGATIVE_NETWORK_ESTIMATES));
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public JobInfo build(boolean disallowPrefetchDeadlines) {
|
||||
public JobInfo build(boolean disallowPrefetchDeadlines,
|
||||
boolean rejectNegativeNetworkEstimates) {
|
||||
// This check doesn't need to be inside enforceValidity. It's an unnecessary legacy
|
||||
// check that would ideally be phased out instead.
|
||||
if (mBackoffPolicySet && (mConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) {
|
||||
@@ -1903,7 +1915,7 @@ public class JobInfo implements Parcelable {
|
||||
" setRequiresDeviceIdle is an error.");
|
||||
}
|
||||
JobInfo jobInfo = new JobInfo(this);
|
||||
jobInfo.enforceValidity(disallowPrefetchDeadlines);
|
||||
jobInfo.enforceValidity(disallowPrefetchDeadlines, rejectNegativeNetworkEstimates);
|
||||
return jobInfo;
|
||||
}
|
||||
|
||||
@@ -1921,13 +1933,24 @@ public class JobInfo implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final void enforceValidity(boolean disallowPrefetchDeadlines) {
|
||||
public final void enforceValidity(boolean disallowPrefetchDeadlines,
|
||||
boolean rejectNegativeNetworkEstimates) {
|
||||
// Check that network estimates require network type and are reasonable values.
|
||||
if ((networkDownloadBytes > 0 || networkUploadBytes > 0 || minimumNetworkChunkBytes > 0)
|
||||
&& networkRequest == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't provide estimated network usage without requiring a network");
|
||||
}
|
||||
if (networkRequest != null && rejectNegativeNetworkEstimates) {
|
||||
if (networkUploadBytes != NETWORK_BYTES_UNKNOWN && networkUploadBytes < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid network upload bytes: " + networkUploadBytes);
|
||||
}
|
||||
if (networkDownloadBytes != NETWORK_BYTES_UNKNOWN && networkDownloadBytes < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid network download bytes: " + networkDownloadBytes);
|
||||
}
|
||||
}
|
||||
final long estimatedTransfer;
|
||||
if (networkUploadBytes == NETWORK_BYTES_UNKNOWN) {
|
||||
estimatedTransfer = networkDownloadBytes;
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN;
|
||||
|
||||
import android.annotation.BytesLong;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.Compatibility;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
@@ -88,25 +89,11 @@ final public class JobWorkItem implements Parcelable {
|
||||
*/
|
||||
public JobWorkItem(@Nullable Intent intent, @BytesLong long downloadBytes,
|
||||
@BytesLong long uploadBytes, @BytesLong long minimumChunkBytes) {
|
||||
if (minimumChunkBytes != NETWORK_BYTES_UNKNOWN && minimumChunkBytes <= 0) {
|
||||
throw new IllegalArgumentException("Minimum chunk size must be positive");
|
||||
}
|
||||
final long estimatedTransfer;
|
||||
if (uploadBytes == NETWORK_BYTES_UNKNOWN) {
|
||||
estimatedTransfer = downloadBytes;
|
||||
} else {
|
||||
estimatedTransfer = uploadBytes
|
||||
+ (downloadBytes == NETWORK_BYTES_UNKNOWN ? 0 : downloadBytes);
|
||||
}
|
||||
if (minimumChunkBytes != NETWORK_BYTES_UNKNOWN && estimatedTransfer != NETWORK_BYTES_UNKNOWN
|
||||
&& minimumChunkBytes > estimatedTransfer) {
|
||||
throw new IllegalArgumentException(
|
||||
"Minimum chunk size can't be greater than estimated network usage");
|
||||
}
|
||||
mIntent = intent;
|
||||
mNetworkDownloadBytes = downloadBytes;
|
||||
mNetworkUploadBytes = uploadBytes;
|
||||
mMinimumChunkBytes = minimumChunkBytes;
|
||||
enforceValidity(Compatibility.isChangeEnabled(JobInfo.REJECT_NEGATIVE_NETWORK_ESTIMATES));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +209,17 @@ final public class JobWorkItem implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void enforceValidity() {
|
||||
public void enforceValidity(boolean rejectNegativeNetworkEstimates) {
|
||||
if (rejectNegativeNetworkEstimates) {
|
||||
if (mNetworkUploadBytes != NETWORK_BYTES_UNKNOWN && mNetworkUploadBytes < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid network upload bytes: " + mNetworkUploadBytes);
|
||||
}
|
||||
if (mNetworkDownloadBytes != NETWORK_BYTES_UNKNOWN && mNetworkDownloadBytes < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid network download bytes: " + mNetworkDownloadBytes);
|
||||
}
|
||||
}
|
||||
final long estimatedTransfer;
|
||||
if (mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) {
|
||||
estimatedTransfer = mNetworkDownloadBytes;
|
||||
|
||||
@@ -3163,9 +3163,12 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
}
|
||||
|
||||
private void validateJob(JobInfo job, int callingUid, @Nullable JobWorkItem jobWorkItem) {
|
||||
final boolean rejectNegativeNetworkEstimates = CompatChanges.isChangeEnabled(
|
||||
JobInfo.REJECT_NEGATIVE_NETWORK_ESTIMATES, callingUid);
|
||||
job.enforceValidity(
|
||||
CompatChanges.isChangeEnabled(
|
||||
JobInfo.DISALLOW_DEADLINES_FOR_PREFETCH_JOBS, callingUid));
|
||||
JobInfo.DISALLOW_DEADLINES_FOR_PREFETCH_JOBS, callingUid),
|
||||
rejectNegativeNetworkEstimates);
|
||||
if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
|
||||
getContext().enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
|
||||
@@ -3180,7 +3183,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
}
|
||||
}
|
||||
if (jobWorkItem != null) {
|
||||
jobWorkItem.enforceValidity();
|
||||
jobWorkItem.enforceValidity(rejectNegativeNetworkEstimates);
|
||||
if (jobWorkItem.getEstimatedNetworkDownloadBytes() != JobInfo.NETWORK_BYTES_UNKNOWN
|
||||
|| jobWorkItem.getEstimatedNetworkUploadBytes()
|
||||
!= JobInfo.NETWORK_BYTES_UNKNOWN
|
||||
|
||||
@@ -1024,7 +1024,8 @@ public final class JobStore {
|
||||
// have a deadline. If a job is rescheduled (via jobFinished(true) or onStopJob()'s
|
||||
// return value), the deadline is dropped. Periodic jobs require all constraints
|
||||
// to be met, so there's no issue with their deadlines.
|
||||
builtJob = jobBuilder.build(false);
|
||||
// The same logic applies for other target SDK-based validation checks.
|
||||
builtJob = jobBuilder.build(false, false);
|
||||
} catch (Exception e) {
|
||||
Slog.w(TAG, "Unable to build job from XML, ignoring: " + jobBuilder.summarize(), e);
|
||||
return null;
|
||||
|
||||
@@ -612,9 +612,9 @@ public final class JobStatus {
|
||||
requestBuilder.setUids(
|
||||
Collections.singleton(new Range<Integer>(this.sourceUid, this.sourceUid)));
|
||||
builder.setRequiredNetwork(requestBuilder.build());
|
||||
// Don't perform prefetch-deadline check at this point. We've already passed the
|
||||
// Don't perform validation checks at this point since we've already passed the
|
||||
// initial validation check.
|
||||
job = builder.build(false);
|
||||
job = builder.build(false, false);
|
||||
}
|
||||
|
||||
updateMediaBackupExemptionStatus();
|
||||
|
||||
Reference in New Issue
Block a user