Merge "Allow syncs to be scheduled as EJs." into sc-dev am: 5c9a0355f8
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13593463 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Ie51db0996d7d1a09ec9b5c4f0f77b56b2caa7b6d
This commit is contained in:
@@ -182,6 +182,8 @@ public class RequestSync {
|
|||||||
mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
|
mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
|
||||||
} else if (opt.equals("--rc") || opt.equals("--require-charging")) {
|
} else if (opt.equals("--rc") || opt.equals("--require-charging")) {
|
||||||
mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, true);
|
mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, true);
|
||||||
|
} else if (opt.equals("--ej") || opt.equals("--schedule-as-ej")) {
|
||||||
|
mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, true);
|
||||||
} else if (opt.equals("-e") || opt.equals("--es") || opt.equals("--extra-string")) {
|
} else if (opt.equals("-e") || opt.equals("--es") || opt.equals("--extra-string")) {
|
||||||
final String key = nextArgRequired();
|
final String key = nextArgRequired();
|
||||||
final String value = nextArgRequired();
|
final String value = nextArgRequired();
|
||||||
|
|||||||
@@ -10238,6 +10238,7 @@ package android.content {
|
|||||||
field public static final String SYNC_EXTRAS_MANUAL = "force";
|
field public static final String SYNC_EXTRAS_MANUAL = "force";
|
||||||
field public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
|
field public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
|
||||||
field public static final String SYNC_EXTRAS_REQUIRE_CHARGING = "require_charging";
|
field public static final String SYNC_EXTRAS_REQUIRE_CHARGING = "require_charging";
|
||||||
|
field public static final String SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB = "schedule_as_expedited_job";
|
||||||
field public static final String SYNC_EXTRAS_UPLOAD = "upload";
|
field public static final String SYNC_EXTRAS_UPLOAD = "upload";
|
||||||
field public static final int SYNC_OBSERVER_TYPE_ACTIVE = 4; // 0x4
|
field public static final int SYNC_OBSERVER_TYPE_ACTIVE = 4; // 0x4
|
||||||
field public static final int SYNC_OBSERVER_TYPE_PENDING = 2; // 0x2
|
field public static final int SYNC_OBSERVER_TYPE_PENDING = 2; // 0x2
|
||||||
@@ -11560,6 +11561,7 @@ package android.content {
|
|||||||
method public android.content.SyncRequest.Builder setManual(boolean);
|
method public android.content.SyncRequest.Builder setManual(boolean);
|
||||||
method public android.content.SyncRequest.Builder setNoRetry(boolean);
|
method public android.content.SyncRequest.Builder setNoRetry(boolean);
|
||||||
method public android.content.SyncRequest.Builder setRequiresCharging(boolean);
|
method public android.content.SyncRequest.Builder setRequiresCharging(boolean);
|
||||||
|
method @NonNull public android.content.SyncRequest.Builder setScheduleAsExpeditedJob(boolean);
|
||||||
method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, String);
|
method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, String);
|
||||||
method public android.content.SyncRequest.Builder syncOnce();
|
method public android.content.SyncRequest.Builder syncOnce();
|
||||||
method public android.content.SyncRequest.Builder syncPeriodic(long, long);
|
method public android.content.SyncRequest.Builder syncPeriodic(long, long);
|
||||||
|
|||||||
@@ -132,8 +132,11 @@ public abstract class ContentResolver implements ContentInterface {
|
|||||||
public static final String SYNC_EXTRAS_ACCOUNT = "account";
|
public static final String SYNC_EXTRAS_ACCOUNT = "account";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this extra is set to true, the sync request will be scheduled
|
* If this extra is set to true, the sync request will be scheduled at the front of the
|
||||||
* at the front of the sync request queue and without any delay
|
* sync request queue, but it is still subject to JobScheduler quota and throttling due to
|
||||||
|
* App Standby buckets.
|
||||||
|
*
|
||||||
|
* <p>This is different from {@link #SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB}.
|
||||||
*/
|
*/
|
||||||
public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
|
public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
|
||||||
|
|
||||||
@@ -144,6 +147,29 @@ public abstract class ContentResolver implements ContentInterface {
|
|||||||
*/
|
*/
|
||||||
public static final String SYNC_EXTRAS_REQUIRE_CHARGING = "require_charging";
|
public static final String SYNC_EXTRAS_REQUIRE_CHARGING = "require_charging";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run this sync operation as an "expedited job"
|
||||||
|
* (see {@link android.app.job.JobInfo.Builder#setExpedited(boolean)}).
|
||||||
|
* Normally (if this flag isn't specified), sync operations are executed as regular
|
||||||
|
* {@link android.app.job.JobService} jobs.
|
||||||
|
*
|
||||||
|
* <p> Because Expedited Jobs have various restrictions compared to regular jobs, this flag
|
||||||
|
* cannot be combined with certain other flags, otherwise an
|
||||||
|
* <code>IllegalArgumentException</code> will be thrown. Notably, because Expedited Jobs do not
|
||||||
|
* support various constraints, the following restriction apply:
|
||||||
|
* <ul>
|
||||||
|
* <li>Can't be used with {@link #SYNC_EXTRAS_REQUIRE_CHARGING}
|
||||||
|
* <li>Can't be used with {@link #SYNC_EXTRAS_EXPEDITED}
|
||||||
|
* <li>Can't be used on periodic syncs.
|
||||||
|
* <li>When an expedited-job-sync fails and a retry is scheduled, the retried sync will be
|
||||||
|
* scheduled as a regular job unless {@link #SYNC_EXTRAS_IGNORE_BACKOFF} is set.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>This is different from {@link #SYNC_EXTRAS_EXPEDITED}.
|
||||||
|
*/
|
||||||
|
@SuppressLint("IntentName")
|
||||||
|
public static final String SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB = "schedule_as_expedited_job";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated instead use
|
* @deprecated instead use
|
||||||
* {@link #SYNC_EXTRAS_MANUAL}
|
* {@link #SYNC_EXTRAS_MANUAL}
|
||||||
@@ -3219,6 +3245,18 @@ public abstract class ContentResolver implements ContentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@hide}
|
||||||
|
* Helper function to throw an <code>IllegalArgumentException</code> if any illegal
|
||||||
|
* extras were set for a sync scheduled as an expedited job.
|
||||||
|
*
|
||||||
|
* @param extras bundle to validate.
|
||||||
|
*/
|
||||||
|
public static boolean hasInvalidScheduleAsEjExtras(Bundle extras) {
|
||||||
|
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING)
|
||||||
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies that a sync should be requested with the specified the account, authority,
|
* Specifies that a sync should be requested with the specified the account, authority,
|
||||||
* and extras at the given frequency. If there is already another periodic sync scheduled
|
* and extras at the given frequency. If there is already another periodic sync scheduled
|
||||||
@@ -3233,7 +3271,8 @@ public abstract class ContentResolver implements ContentInterface {
|
|||||||
* Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY},
|
* Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY},
|
||||||
* {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS},
|
* {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS},
|
||||||
* {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE},
|
* {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE},
|
||||||
* {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true.
|
* {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL},
|
||||||
|
* {@link #SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB} set to true.
|
||||||
* If any are supplied then an {@link IllegalArgumentException} will be thrown.
|
* If any are supplied then an {@link IllegalArgumentException} will be thrown.
|
||||||
*
|
*
|
||||||
* <p>This method requires the caller to hold the permission
|
* <p>This method requires the caller to hold the permission
|
||||||
@@ -3273,16 +3312,14 @@ public abstract class ContentResolver implements ContentInterface {
|
|||||||
* @param extras bundle to validate.
|
* @param extras bundle to validate.
|
||||||
*/
|
*/
|
||||||
public static boolean invalidPeriodicExtras(Bundle extras) {
|
public static boolean invalidPeriodicExtras(Bundle extras) {
|
||||||
if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
|
return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
|
||||||
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
|
||||||
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
|
||||||
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
|
||||||
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
|
||||||
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
|
||||||
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)
|
||||||
return true;
|
|| extras.getBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, false);
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package android.content;
|
package android.content;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -58,6 +59,8 @@ public class SyncRequest implements Parcelable {
|
|||||||
private final boolean mIsAuthority;
|
private final boolean mIsAuthority;
|
||||||
/** Sync should be run in lieu of other syncs. */
|
/** Sync should be run in lieu of other syncs. */
|
||||||
private final boolean mIsExpedited;
|
private final boolean mIsExpedited;
|
||||||
|
/** Sync sound be ran as an expedited job. */
|
||||||
|
private final boolean mIsScheduledAsExpeditedJob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
@@ -77,6 +80,14 @@ public class SyncRequest implements Parcelable {
|
|||||||
return mIsExpedited;
|
return mIsExpedited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@hide}
|
||||||
|
* @return whether this sync is scheduled as an expedited job.
|
||||||
|
*/
|
||||||
|
public boolean isScheduledAsExpeditedJob() {
|
||||||
|
return mIsScheduledAsExpeditedJob;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*
|
*
|
||||||
@@ -149,6 +160,7 @@ public class SyncRequest implements Parcelable {
|
|||||||
parcel.writeInt((mDisallowMetered ? 1 : 0));
|
parcel.writeInt((mDisallowMetered ? 1 : 0));
|
||||||
parcel.writeInt((mIsAuthority ? 1 : 0));
|
parcel.writeInt((mIsAuthority ? 1 : 0));
|
||||||
parcel.writeInt((mIsExpedited? 1 : 0));
|
parcel.writeInt((mIsExpedited? 1 : 0));
|
||||||
|
parcel.writeInt(mIsScheduledAsExpeditedJob ? 1 : 0);
|
||||||
parcel.writeParcelable(mAccountToSync, flags);
|
parcel.writeParcelable(mAccountToSync, flags);
|
||||||
parcel.writeString(mAuthority);
|
parcel.writeString(mAuthority);
|
||||||
}
|
}
|
||||||
@@ -161,6 +173,7 @@ public class SyncRequest implements Parcelable {
|
|||||||
mDisallowMetered = (in.readInt() != 0);
|
mDisallowMetered = (in.readInt() != 0);
|
||||||
mIsAuthority = (in.readInt() != 0);
|
mIsAuthority = (in.readInt() != 0);
|
||||||
mIsExpedited = (in.readInt() != 0);
|
mIsExpedited = (in.readInt() != 0);
|
||||||
|
mIsScheduledAsExpeditedJob = (in.readInt() != 0);
|
||||||
mAccountToSync = in.readParcelable(null);
|
mAccountToSync = in.readParcelable(null);
|
||||||
mAuthority = in.readString();
|
mAuthority = in.readString();
|
||||||
}
|
}
|
||||||
@@ -174,6 +187,7 @@ public class SyncRequest implements Parcelable {
|
|||||||
mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
|
mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
|
||||||
mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
|
mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
|
||||||
mIsExpedited = b.mExpedited;
|
mIsExpedited = b.mExpedited;
|
||||||
|
mIsScheduledAsExpeditedJob = b.mScheduleAsExpeditedJob;
|
||||||
mExtras = new Bundle(b.mCustomExtras);
|
mExtras = new Bundle(b.mCustomExtras);
|
||||||
// For now we merge the sync config extras & the custom extras into one bundle.
|
// For now we merge the sync config extras & the custom extras into one bundle.
|
||||||
// TODO: pass the configuration extras through separately.
|
// TODO: pass the configuration extras through separately.
|
||||||
@@ -258,6 +272,11 @@ public class SyncRequest implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
private boolean mRequiresCharging;
|
private boolean mRequiresCharging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the sync should be scheduled as an expedited job.
|
||||||
|
*/
|
||||||
|
private boolean mScheduleAsExpeditedJob;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +328,8 @@ public class SyncRequest implements Parcelable {
|
|||||||
* {@link ContentResolver#SYNC_EXTRAS_INITIALIZE},
|
* {@link ContentResolver#SYNC_EXTRAS_INITIALIZE},
|
||||||
* {@link ContentResolver#SYNC_EXTRAS_FORCE},
|
* {@link ContentResolver#SYNC_EXTRAS_FORCE},
|
||||||
* {@link ContentResolver#SYNC_EXTRAS_EXPEDITED},
|
* {@link ContentResolver#SYNC_EXTRAS_EXPEDITED},
|
||||||
* {@link ContentResolver#SYNC_EXTRAS_MANUAL}
|
* {@link ContentResolver#SYNC_EXTRAS_MANUAL},
|
||||||
|
* {@link ContentResolver#SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB}
|
||||||
* set to true. If any are supplied then an <code>IllegalArgumentException</code> will
|
* set to true. If any are supplied then an <code>IllegalArgumentException</code> will
|
||||||
* be thrown.
|
* be thrown.
|
||||||
*
|
*
|
||||||
@@ -499,6 +519,22 @@ public class SyncRequest implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function for setting
|
||||||
|
* {@link ContentResolver#SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB}.
|
||||||
|
*
|
||||||
|
* <p> Not to be confused with {@link ContentResolver#SYNC_EXTRAS_EXPEDITED}.
|
||||||
|
*
|
||||||
|
* <p> Not valid for periodic syncs, expedited syncs, and syncs that require charging - an
|
||||||
|
* <code>IllegalArgumentException</code> will be thrown in {@link #build()}.
|
||||||
|
*
|
||||||
|
* @param scheduleAsExpeditedJob whether to schedule as an expedited job. Default false.
|
||||||
|
*/
|
||||||
|
public @NonNull Builder setScheduleAsExpeditedJob(boolean scheduleAsExpeditedJob) {
|
||||||
|
mScheduleAsExpeditedJob = scheduleAsExpeditedJob;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs validation over the request and throws the runtime exception
|
* Performs validation over the request and throws the runtime exception
|
||||||
* <code>IllegalArgumentException</code> if this validation fails.
|
* <code>IllegalArgumentException</code> if this validation fails.
|
||||||
@@ -507,11 +543,6 @@ public class SyncRequest implements Parcelable {
|
|||||||
* builder.
|
* builder.
|
||||||
*/
|
*/
|
||||||
public SyncRequest build() {
|
public SyncRequest build() {
|
||||||
// Validate the extras bundle
|
|
||||||
ContentResolver.validateSyncExtrasBundle(mCustomExtras);
|
|
||||||
if (mCustomExtras == null) {
|
|
||||||
mCustomExtras = new Bundle();
|
|
||||||
}
|
|
||||||
// Combine builder extra flags into the config bundle.
|
// Combine builder extra flags into the config bundle.
|
||||||
mSyncConfigExtras = new Bundle();
|
mSyncConfigExtras = new Bundle();
|
||||||
if (mIgnoreBackoff) {
|
if (mIgnoreBackoff) {
|
||||||
@@ -532,17 +563,35 @@ public class SyncRequest implements Parcelable {
|
|||||||
if (mExpedited) {
|
if (mExpedited) {
|
||||||
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
|
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
|
||||||
}
|
}
|
||||||
|
if (mScheduleAsExpeditedJob) {
|
||||||
|
mSyncConfigExtras.putBoolean(
|
||||||
|
ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, true);
|
||||||
|
}
|
||||||
if (mIsManual) {
|
if (mIsManual) {
|
||||||
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
|
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
|
||||||
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
|
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCustomExtras == null) {
|
||||||
|
mCustomExtras = new Bundle();
|
||||||
|
}
|
||||||
|
// Validate the extras bundles
|
||||||
|
ContentResolver.validateSyncExtrasBundle(mCustomExtras);
|
||||||
|
// If this is a periodic sync ensure than invalid extras were not set.
|
||||||
if (mSyncType == SYNC_TYPE_PERIODIC) {
|
if (mSyncType == SYNC_TYPE_PERIODIC) {
|
||||||
// If this is a periodic sync ensure than invalid extras were not set.
|
|
||||||
if (ContentResolver.invalidPeriodicExtras(mCustomExtras) ||
|
if (ContentResolver.invalidPeriodicExtras(mCustomExtras) ||
|
||||||
ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
|
ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
|
||||||
throw new IllegalArgumentException("Illegal extras were set");
|
throw new IllegalArgumentException("Illegal extras were set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If this sync is scheduled as an EJ, ensure that invalid extras were not set.
|
||||||
|
if (mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB)
|
||||||
|
|| mScheduleAsExpeditedJob) {
|
||||||
|
if (ContentResolver.hasInvalidScheduleAsEjExtras(mCustomExtras)
|
||||||
|
|| ContentResolver.hasInvalidScheduleAsEjExtras(mSyncConfigExtras)) {
|
||||||
|
throw new IllegalArgumentException("Illegal extras were set");
|
||||||
|
}
|
||||||
|
}
|
||||||
// Ensure that a target for the sync has been set.
|
// Ensure that a target for the sync has been set.
|
||||||
if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
|
if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
|
||||||
throw new IllegalArgumentException("Must specify an adapter with" +
|
throw new IllegalArgumentException("Must specify an adapter with" +
|
||||||
|
|||||||
@@ -264,6 +264,10 @@ public class SyncManager {
|
|||||||
|
|
||||||
private final SyncLogger mLogger;
|
private final SyncLogger mLogger;
|
||||||
|
|
||||||
|
// NOTE: this is a temporary allow-list for testing purposes; it will be removed before release.
|
||||||
|
private final String[] mEjSyncAllowedPackages = new String[]{
|
||||||
|
"com.google.android.google", "com.android.frameworks.servicestests"};
|
||||||
|
|
||||||
private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
|
private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
|
||||||
for (JobInfo job: pendingJobs) {
|
for (JobInfo job: pendingJobs) {
|
||||||
if (job.getId() == jobId) {
|
if (job.getId() == jobId) {
|
||||||
@@ -983,6 +987,14 @@ public class SyncManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean scheduleAsEj =
|
||||||
|
extras.getBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, false);
|
||||||
|
// NOTE: this is a temporary check for internal testing - to be removed before release.
|
||||||
|
if (scheduleAsEj && !ArrayUtils.contains(mEjSyncAllowedPackages, callingPackage)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
callingPackage + " is not allowed to schedule a sync as an EJ yet.");
|
||||||
|
}
|
||||||
|
|
||||||
for (AccountAndUser account : accounts) {
|
for (AccountAndUser account : accounts) {
|
||||||
// If userId is specified, do not sync accounts of other users
|
// If userId is specified, do not sync accounts of other users
|
||||||
if (userId >= UserHandle.USER_SYSTEM && account.userId >= UserHandle.USER_SYSTEM
|
if (userId >= UserHandle.USER_SYSTEM && account.userId >= UserHandle.USER_SYSTEM
|
||||||
@@ -1490,6 +1502,12 @@ public class SyncManager {
|
|||||||
+ logSafe(syncOperation.target));
|
+ logSafe(syncOperation.target));
|
||||||
backoff = new Pair<Long, Long>(SyncStorageEngine.NOT_IN_BACKOFF_MODE,
|
backoff = new Pair<Long, Long>(SyncStorageEngine.NOT_IN_BACKOFF_MODE,
|
||||||
SyncStorageEngine.NOT_IN_BACKOFF_MODE);
|
SyncStorageEngine.NOT_IN_BACKOFF_MODE);
|
||||||
|
} else {
|
||||||
|
// if an EJ is being backed-off but doesn't have SYNC_EXTRAS_IGNORE_BACKOFF set,
|
||||||
|
// reschedule it as a regular job
|
||||||
|
if (syncOperation.isScheduledAsExpeditedJob()) {
|
||||||
|
syncOperation.scheduleEjAsRegularJob = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
long now = SystemClock.elapsedRealtime();
|
long now = SystemClock.elapsedRealtime();
|
||||||
long backoffDelay = backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE ? 0
|
long backoffDelay = backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE ? 0
|
||||||
@@ -1640,6 +1658,10 @@ public class SyncManager {
|
|||||||
b.setRequiresCharging(true);
|
b.setRequiresCharging(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (syncOperation.isScheduledAsExpeditedJob() && !syncOperation.scheduleEjAsRegularJob) {
|
||||||
|
b.setExpedited(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (syncOperation.syncExemptionFlag
|
if (syncOperation.syncExemptionFlag
|
||||||
== ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP) {
|
== ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP) {
|
||||||
DeviceIdleInternal dic =
|
DeviceIdleInternal dic =
|
||||||
@@ -3951,6 +3973,9 @@ public class SyncManager {
|
|||||||
if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) {
|
if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (key.equals(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS)) {
|
if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,13 @@ public class SyncOperation {
|
|||||||
/** Stores the number of times this sync operation failed and had to be retried. */
|
/** Stores the number of times this sync operation failed and had to be retried. */
|
||||||
int retries;
|
int retries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if a sync that was originally scheduled as an EJ is being re-scheduled as a
|
||||||
|
* regular job. Specifically, this will be {@code true} if a sync is being backed-off but
|
||||||
|
* {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF} is not set.
|
||||||
|
*/
|
||||||
|
boolean scheduleEjAsRegularJob;
|
||||||
|
|
||||||
/** jobId of the JobScheduler job corresponding to this sync */
|
/** jobId of the JobScheduler job corresponding to this sync */
|
||||||
public int jobId;
|
public int jobId;
|
||||||
|
|
||||||
@@ -408,6 +415,12 @@ public class SyncOperation {
|
|||||||
if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
|
if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
|
||||||
sb.append(" EXPEDITED");
|
sb.append(" EXPEDITED");
|
||||||
}
|
}
|
||||||
|
if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, false)) {
|
||||||
|
sb.append(" EXPEDITED-JOB");
|
||||||
|
if (scheduleEjAsRegularJob) {
|
||||||
|
sb.append("(scheduled-as-regular)");
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (syncExemptionFlag) {
|
switch (syncExemptionFlag) {
|
||||||
case ContentResolver.SYNC_EXEMPTION_NONE:
|
case ContentResolver.SYNC_EXEMPTION_NONE:
|
||||||
break;
|
break;
|
||||||
@@ -537,6 +550,11 @@ public class SyncOperation {
|
|||||||
return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, false);
|
return mImmutableExtras.getBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isScheduledAsExpeditedJob() {
|
||||||
|
return mImmutableExtras.getBoolean(
|
||||||
|
ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, false);
|
||||||
|
}
|
||||||
|
|
||||||
boolean isAppStandbyExempted() {
|
boolean isAppStandbyExempted() {
|
||||||
return syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE;
|
return syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,4 +153,25 @@ public class SyncOperationTest extends AndroidTestCase {
|
|||||||
assertEquals("Period not restored", periodic.periodMillis, oneoff.periodMillis);
|
assertEquals("Period not restored", periodic.periodMillis, oneoff.periodMillis);
|
||||||
assertEquals("Flex not restored", periodic.flexMillis, oneoff.flexMillis);
|
assertEquals("Flex not restored", periodic.flexMillis, oneoff.flexMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
public void testScheduleAsEjIsInExtras() {
|
||||||
|
Account account1 = new Account("account1", "type1");
|
||||||
|
Bundle b1 = new Bundle();
|
||||||
|
b1.putBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB, true);
|
||||||
|
|
||||||
|
SyncOperation op1 = new SyncOperation(account1, 0, 1, "foo", 0,
|
||||||
|
SyncOperation.REASON_USER_START, "authority1", b1, false,
|
||||||
|
ContentResolver.SYNC_EXEMPTION_NONE);
|
||||||
|
assertTrue(op1.isScheduledAsExpeditedJob());
|
||||||
|
|
||||||
|
PersistableBundle pb = op1.toJobInfoExtras();
|
||||||
|
assertTrue("EJ extra not found in job extras",
|
||||||
|
((PersistableBundle) pb.get("syncExtras"))
|
||||||
|
.containsKey(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB));
|
||||||
|
|
||||||
|
SyncOperation op2 = SyncOperation.maybeCreateFromJobExtras(pb);
|
||||||
|
assertTrue("EJ extra not found in extras", op2.getClonedExtras()
|
||||||
|
.getBoolean(ContentResolver.SYNC_EXTRAS_SCHEDULE_AS_EXPEDITED_JOB));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user