• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.content;
18 
19 import android.accounts.Account;
20 import android.os.Bundle;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 public class SyncRequest implements Parcelable {
25     private static final String TAG = "SyncRequest";
26     /** Account to pass to the sync adapter. May be null. */
27     private final Account mAccountToSync;
28     /** Authority string that corresponds to a ContentProvider. */
29     private final String mAuthority;
30     /** Sync service identifier. May be null.*/
31     private final ComponentName mComponentInfo;
32     /** Bundle containing user info as well as sync settings. */
33     private final Bundle mExtras;
34     /** Disallow this sync request on metered networks. */
35     private final boolean mDisallowMetered;
36     /**
37      * Anticipated upload size in bytes.
38      * TODO: Not yet used - we put this information into the bundle for simplicity.
39      */
40     private final long mTxBytes;
41     /**
42      * Anticipated download size in bytes.
43      * TODO: Not yet used - we put this information into the bundle.
44      */
45     private final long mRxBytes;
46     /**
47      * Amount of time before {@link #mSyncRunTimeSecs} from which the sync may optionally be
48      * started.
49      */
50     private final long mSyncFlexTimeSecs;
51     /**
52      * Specifies a point in the future at which the sync must have been scheduled to run.
53      */
54     private final long mSyncRunTimeSecs;
55     /** Periodic versus one-off. */
56     private final boolean mIsPeriodic;
57     /** Service versus provider. */
58     private final boolean mIsAuthority;
59     /** Sync should be run in lieu of other syncs. */
60     private final boolean mIsExpedited;
61 
62     /**
63      * {@hide}
64      * @return whether this sync is periodic or one-time. A Sync Request must be
65      *         either one of these or an InvalidStateException will be thrown in
66      *         Builder.build().
67      */
isPeriodic()68     public boolean isPeriodic() {
69         return mIsPeriodic;
70     }
71 
72     /**
73      * {@hide}
74      * @return whether this is an expedited sync.
75      */
isExpedited()76     public boolean isExpedited() {
77         return mIsExpedited;
78     }
79 
80     /**
81      * {@hide}
82      * @return true if this sync uses an account/authority pair, or false if this sync is bound to
83      * a Sync Service.
84      */
hasAuthority()85     public boolean hasAuthority() {
86         return mIsAuthority;
87     }
88 
89     /**
90      * {@hide}
91      * @return account object for this sync.
92      * @throws IllegalArgumentException if this function is called for a request that does not
93      * specify an account/provider authority.
94      */
getAccount()95     public Account getAccount() {
96         if (!hasAuthority()) {
97             throw new IllegalArgumentException("Cannot getAccount() for a sync that does not"
98                     + "specify an authority.");
99         }
100         return mAccountToSync;
101     }
102 
103     /**
104      * {@hide}
105      * @return provider for this sync.
106      * @throws IllegalArgumentException if this function is called for a request that does not
107      * specify an account/provider authority.
108      */
getProvider()109     public String getProvider() {
110         if (!hasAuthority()) {
111             throw new IllegalArgumentException("Cannot getProvider() for a sync that does not"
112                     + "specify a provider.");
113         }
114         return mAuthority;
115     }
116 
117     /**
118      * {@hide}
119      * Retrieve bundle for this SyncRequest. Will not be null.
120      */
getBundle()121     public Bundle getBundle() {
122         return mExtras;
123     }
124 
125     /**
126      * {@hide}
127      * @return the earliest point in time that this sync can be scheduled.
128      */
getSyncFlexTime()129     public long getSyncFlexTime() {
130         return mSyncFlexTimeSecs;
131     }
132 
133     /**
134      * {@hide}
135      * @return the last point in time at which this sync must scheduled.
136      */
getSyncRunTime()137     public long getSyncRunTime() {
138         return mSyncRunTimeSecs;
139     }
140 
141     public static final Creator<SyncRequest> CREATOR = new Creator<SyncRequest>() {
142 
143         @Override
144         public SyncRequest createFromParcel(Parcel in) {
145             return new SyncRequest(in);
146         }
147 
148         @Override
149         public SyncRequest[] newArray(int size) {
150             return new SyncRequest[size];
151         }
152     };
153 
154     @Override
describeContents()155     public int describeContents() {
156         return 0;
157     }
158 
159     @Override
writeToParcel(Parcel parcel, int flags)160     public void writeToParcel(Parcel parcel, int flags) {
161         parcel.writeBundle(mExtras);
162         parcel.writeLong(mSyncFlexTimeSecs);
163         parcel.writeLong(mSyncRunTimeSecs);
164         parcel.writeInt((mIsPeriodic ? 1 : 0));
165         parcel.writeInt((mDisallowMetered ? 1 : 0));
166         parcel.writeLong(mTxBytes);
167         parcel.writeLong(mRxBytes);
168         parcel.writeInt((mIsAuthority ? 1 : 0));
169         parcel.writeInt((mIsExpedited? 1 : 0));
170         if (mIsAuthority) {
171             parcel.writeParcelable(mAccountToSync, flags);
172             parcel.writeString(mAuthority);
173         } else {
174             parcel.writeParcelable(mComponentInfo, flags);
175         }
176     }
177 
SyncRequest(Parcel in)178     private SyncRequest(Parcel in) {
179         mExtras = in.readBundle();
180         mSyncFlexTimeSecs = in.readLong();
181         mSyncRunTimeSecs = in.readLong();
182         mIsPeriodic = (in.readInt() != 0);
183         mDisallowMetered = (in.readInt() != 0);
184         mTxBytes = in.readLong();
185         mRxBytes = in.readLong();
186         mIsAuthority = (in.readInt() != 0);
187         mIsExpedited = (in.readInt() != 0);
188         if (mIsAuthority) {
189             mComponentInfo = null;
190             mAccountToSync = in.readParcelable(null);
191             mAuthority = in.readString();
192         } else {
193             mComponentInfo = in.readParcelable(null);
194             mAccountToSync = null;
195             mAuthority = null;
196         }
197     }
198 
199     /** {@hide} Protected ctor to instantiate anonymous SyncRequest. */
SyncRequest(SyncRequest.Builder b)200     protected SyncRequest(SyncRequest.Builder b) {
201         mSyncFlexTimeSecs = b.mSyncFlexTimeSecs;
202         mSyncRunTimeSecs = b.mSyncRunTimeSecs;
203         mAccountToSync = b.mAccount;
204         mAuthority = b.mAuthority;
205         mComponentInfo = b.mComponentName;
206         mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
207         mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
208         mIsExpedited = b.mExpedited;
209         mExtras = new Bundle(b.mCustomExtras);
210         // For now we merge the sync config extras & the custom extras into one bundle.
211         // TODO: pass the configuration extras through separately.
212         mExtras.putAll(b.mSyncConfigExtras);
213         mDisallowMetered = b.mDisallowMetered;
214         mTxBytes = b.mTxBytes;
215         mRxBytes = b.mRxBytes;
216     }
217 
218     /**
219      * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also
220      * perform validation.
221      */
222     public static class Builder {
223         /** Unknown sync type. */
224         private static final int SYNC_TYPE_UNKNOWN = 0;
225         /** Specify that this is a periodic sync. */
226         private static final int SYNC_TYPE_PERIODIC = 1;
227         /** Specify that this is a one-time sync. */
228         private static final int SYNC_TYPE_ONCE = 2;
229         /** Unknown sync target. */
230         private static final int SYNC_TARGET_UNKNOWN = 0;
231         /** Specify that this is an anonymous sync. */
232         private static final int SYNC_TARGET_SERVICE = 1;
233         /** Specify that this is a sync with a provider. */
234         private static final int SYNC_TARGET_ADAPTER = 2;
235         /** Earliest point of displacement into the future at which this sync can occur. */
236         private long mSyncFlexTimeSecs;
237         /** Latest point of displacement into the future at which this sync must occur. */
238         private long mSyncRunTimeSecs;
239         /**
240          * Sync configuration information - custom user data explicitly provided by the developer.
241          * This data is handed over to the sync operation.
242          */
243         private Bundle mCustomExtras;
244         /**
245          * Sync system configuration -  used to store system sync configuration. Corresponds to
246          * ContentResolver.SYNC_EXTRAS_* flags.
247          * TODO: Use this instead of dumping into one bundle. Need to decide if these flags should
248          * discriminate between equivalent syncs.
249          */
250         private Bundle mSyncConfigExtras;
251         /** Expected upload transfer in bytes. */
252         private long mTxBytes = -1L;
253         /** Expected download transfer in bytes. */
254         private long mRxBytes = -1L;
255         /** Whether or not this sync can occur on metered networks. Default false. */
256         private boolean mDisallowMetered;
257         /** Priority of this sync relative to others from calling app [-2, 2]. Default 0. */
258         private int mPriority = 0;
259         /**
260          * Whether this builder is building a periodic sync, or a one-time sync.
261          */
262         private int mSyncType = SYNC_TYPE_UNKNOWN;
263         /** Whether this will go to a sync adapter or to a sync service. */
264         private int mSyncTarget = SYNC_TARGET_UNKNOWN;
265         /** Whether this is a user-activated sync. */
266         private boolean mIsManual;
267         /**
268          * Whether to retry this one-time sync if the sync fails. Not valid for
269          * periodic syncs. See {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}.
270          */
271         private boolean mNoRetry;
272         /**
273          * Whether to respect back-off for this one-time sync. Not valid for
274          * periodic syncs. See
275          * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF};
276          */
277         private boolean mIgnoreBackoff;
278 
279         /** Ignore sync system settings and perform sync anyway. */
280         private boolean mIgnoreSettings;
281 
282         /** This sync will run in preference to other non-expedited syncs. */
283         private boolean mExpedited;
284 
285         /**
286          * The sync component that contains the sync logic if this is a provider-less sync,
287          * otherwise null.
288          */
289         private ComponentName mComponentName;
290         /**
291          * The Account object that together with an Authority name define the SyncAdapter (if
292          * this sync is bound to a provider), otherwise null.
293          */
294         private Account mAccount;
295         /**
296          * The Authority name that together with an Account define the SyncAdapter (if
297          * this sync is bound to a provider), otherwise null.
298          */
299         private String mAuthority;
300 
Builder()301         public Builder() {
302         }
303 
304         /**
305          * Request that a sync occur immediately.
306          *
307          * Example
308          * <pre>
309          *     SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce();
310          * </pre>
311          */
syncOnce()312         public Builder syncOnce() {
313             if (mSyncType != SYNC_TYPE_UNKNOWN) {
314                 throw new IllegalArgumentException("Sync type has already been defined.");
315             }
316             mSyncType = SYNC_TYPE_ONCE;
317             setupInterval(0, 0);
318             return this;
319         }
320 
321         /**
322          * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
323          * Syncs are identified by target {@link android.provider}/{@link android.accounts.Account}
324          * and by the contents of the extras bundle.
325          * You cannot reuse the same builder for one-time syncs (by calling this function) after
326          * having specified a periodic sync. If you do, an <code>IllegalArgumentException</code>
327          * will be thrown.
328          *
329          * Example usage.
330          *
331          * <pre>
332          *     Request a periodic sync every 5 hours with 20 minutes of flex.
333          *     SyncRequest.Builder builder =
334          *         (new SyncRequest.Builder()).syncPeriodic(5 * HOUR_IN_SECS, 20 * MIN_IN_SECS);
335          *
336          *     Schedule a periodic sync every hour at any point in time during that hour.
337          *     SyncRequest.Builder builder =
338          *         (new SyncRequest.Builder()).syncPeriodic(1 * HOUR_IN_SECS, 1 * HOUR_IN_SECS);
339          * </pre>
340          *
341          * N.B.: Periodic syncs are not allowed to have any of
342          * {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY},
343          * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF},
344          * {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS},
345          * {@link ContentResolver#SYNC_EXTRAS_INITIALIZE},
346          * {@link ContentResolver#SYNC_EXTRAS_FORCE},
347          * {@link ContentResolver#SYNC_EXTRAS_EXPEDITED},
348          * {@link ContentResolver#SYNC_EXTRAS_MANUAL}
349          * set to true. If any are supplied then an <code>IllegalArgumentException</code> will
350          * be thrown.
351          *
352          * @param pollFrequency the amount of time in seconds that you wish
353          *            to elapse between periodic syncs.
354          * @param beforeSeconds the amount of flex time in seconds before
355          *            {@code pollFrequency} that you permit for the sync to take
356          *            place. Must be less than {@code pollFrequency}.
357          */
syncPeriodic(long pollFrequency, long beforeSeconds)358         public Builder syncPeriodic(long pollFrequency, long beforeSeconds) {
359             if (mSyncType != SYNC_TYPE_UNKNOWN) {
360                 throw new IllegalArgumentException("Sync type has already been defined.");
361             }
362             mSyncType = SYNC_TYPE_PERIODIC;
363             setupInterval(pollFrequency, beforeSeconds);
364             return this;
365         }
366 
367         /** {@hide} */
setupInterval(long at, long before)368         private void setupInterval(long at, long before) {
369             if (before > at) {
370                 throw new IllegalArgumentException("Specified run time for the sync must be" +
371                     " after the specified flex time.");
372             }
373             mSyncRunTimeSecs = at;
374             mSyncFlexTimeSecs = before;
375         }
376 
377         /**
378          * {@hide}
379          * Developer can provide insight into their payload size; optional. -1 specifies unknown,
380          * so that you are not restricted to defining both fields.
381          *
382          * @param rxBytes Bytes expected to be downloaded.
383          * @param txBytes Bytes expected to be uploaded.
384          */
setTransferSize(long rxBytes, long txBytes)385         public Builder setTransferSize(long rxBytes, long txBytes) {
386             mRxBytes = rxBytes;
387             mTxBytes = txBytes;
388             return this;
389         }
390 
391         /**
392          * @see android.net.ConnectivityManager#isActiveNetworkMetered()
393          * @param disallow true to enforce that this transfer not occur on metered networks.
394          *                 Default false.
395          */
setDisallowMetered(boolean disallow)396         public Builder setDisallowMetered(boolean disallow) {
397             mDisallowMetered = disallow;
398             return this;
399         }
400 
401         /**
402          * Specify an authority and account for this transfer.
403          *
404          * @param authority String identifying which content provider to sync.
405          * @param account Account to sync. Can be null unless this is a periodic sync.
406          */
setSyncAdapter(Account account, String authority)407         public Builder setSyncAdapter(Account account, String authority) {
408             if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
409                 throw new IllegalArgumentException("Sync target has already been defined.");
410             }
411             if (authority != null && authority.length() == 0) {
412                 throw new IllegalArgumentException("Authority must be non-empty");
413             }
414             mSyncTarget = SYNC_TARGET_ADAPTER;
415             mAccount = account;
416             mAuthority = authority;
417             mComponentName = null;
418             return this;
419         }
420 
421         /**
422          * Optional developer-provided extras handed back in
423          * {@link AbstractThreadedSyncAdapter#onPerformSync(Account, Bundle, String,
424          * ContentProviderClient, SyncResult)} occurs. This bundle is copied into the SyncRequest
425          * returned by {@link #build()}.
426          *
427          * Example:
428          * <pre>
429          *   String[] syncItems = {"dog", "cat", "frog", "child"};
430          *   SyncRequest.Builder builder =
431          *     new SyncRequest.Builder()
432          *       .setSyncAdapter(dummyAccount, dummyProvider)
433          *       .syncOnce(5 * MINUTES_IN_SECS);
434          *
435          *   for (String syncData : syncItems) {
436          *     Bundle extras = new Bundle();
437          *     extras.setString("data", syncData);
438          *     builder.setExtras(extras);
439          *     ContentResolver.sync(builder.build()); // Each sync() request is for a unique sync.
440          *   }
441          * </pre>
442          * Only values of the following types may be used in the extras bundle:
443          * <ul>
444          * <li>Integer</li>
445          * <li>Long</li>
446          * <li>Boolean</li>
447          * <li>Float</li>
448          * <li>Double</li>
449          * <li>String</li>
450          * <li>Account</li>
451          * <li>null</li>
452          * </ul>
453          * If any data is present in the bundle not of this type, build() will
454          * throw a runtime exception.
455          *
456          * @param bundle extras bundle to set.
457          */
setExtras(Bundle bundle)458         public Builder setExtras(Bundle bundle) {
459             mCustomExtras = bundle;
460             return this;
461         }
462 
463         /**
464          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}.
465          *
466          * A one-off sync operation that fails will be retried with exponential back-off unless
467          * this is set to false. Not valid for periodic sync and will throw an
468          * <code>IllegalArgumentException</code> in build().
469          *
470          * @param noRetry true to not retry a failed sync. Default false.
471          */
setNoRetry(boolean noRetry)472         public Builder setNoRetry(boolean noRetry) {
473             mNoRetry = noRetry;
474             return this;
475         }
476 
477         /**
478          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}.
479          *
480          * A sync can specify that system sync settings be ignored (user has turned sync off). Not
481          * valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
482          * {@link #build()}.
483          *
484          * @param ignoreSettings true to ignore the sync automatically settings. Default false.
485          */
setIgnoreSettings(boolean ignoreSettings)486         public Builder setIgnoreSettings(boolean ignoreSettings) {
487             mIgnoreSettings = ignoreSettings;
488             return this;
489         }
490 
491         /**
492          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}.
493          *
494          * Force the sync scheduling process to ignore any back-off that was the result of a failed
495          * sync, as well as to invalidate any {@link SyncResult#delayUntil} value that may have
496          * been set by the adapter. Successive failures will not honor this flag. Not valid for
497          * periodic sync and will throw an <code>IllegalArgumentException</code> in
498          * {@link #build()}.
499          *
500          * @param ignoreBackoff ignore back-off settings. Default false.
501          */
setIgnoreBackoff(boolean ignoreBackoff)502         public Builder setIgnoreBackoff(boolean ignoreBackoff) {
503             mIgnoreBackoff = ignoreBackoff;
504             return this;
505         }
506 
507         /**
508          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_MANUAL}.
509          *
510          * A manual sync is functionally equivalent to calling {@link #setIgnoreBackoff(boolean)}
511          * and {@link #setIgnoreSettings(boolean)}. Not valid for periodic sync and will throw an
512          * <code>IllegalArgumentException</code> in {@link #build()}.
513          *
514          * @param isManual User-initiated sync or not. Default false.
515          */
setManual(boolean isManual)516         public Builder setManual(boolean isManual) {
517             mIsManual = isManual;
518             return this;
519         }
520 
521         /**
522          * An expedited sync runs immediately and will preempt another non-expedited running sync.
523          *
524          * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
525          * {@link #build()}.
526          *
527          * @param expedited whether to run expedited. Default false.
528          */
setExpedited(boolean expedited)529         public Builder setExpedited(boolean expedited) {
530             mExpedited = expedited;
531             return this;
532         }
533 
534         /**
535          * {@hide}
536          * @param priority the priority of this request among all requests from the calling app.
537          * Range of [-2,2] similar to how this is done with notifications.
538          */
setPriority(int priority)539         public Builder setPriority(int priority) {
540             if (priority < -2 || priority > 2) {
541                 throw new IllegalArgumentException("Priority must be within range [-2, 2]");
542             }
543             mPriority = priority;
544             return this;
545         }
546 
547         /**
548          * Performs validation over the request and throws the runtime exception
549          * <code>IllegalArgumentException</code> if this validation fails.
550          *
551          * @return a SyncRequest with the information contained within this
552          *         builder.
553          */
build()554         public SyncRequest build() {
555             if (mCustomExtras == null) {
556                 mCustomExtras = new Bundle();
557             }
558             // Validate the extras bundle
559             ContentResolver.validateSyncExtrasBundle(mCustomExtras);
560             // Combine builder extra flags into the config bundle.
561             mSyncConfigExtras = new Bundle();
562             if (mIgnoreBackoff) {
563                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
564             }
565             if (mDisallowMetered) {
566                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true);
567             }
568             if (mIgnoreSettings) {
569                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
570             }
571             if (mNoRetry) {
572                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
573             }
574             if (mExpedited) {
575                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
576             }
577             if (mIsManual) {
578                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
579             }
580             mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD, mTxBytes);
581             mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD, mRxBytes);
582             mSyncConfigExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
583             if (mSyncType == SYNC_TYPE_PERIODIC) {
584                 // If this is a periodic sync ensure than invalid extras were not set.
585                 validatePeriodicExtras(mCustomExtras);
586                 validatePeriodicExtras(mSyncConfigExtras);
587                 // Verify that account and provider are not null.
588                 if (mAccount == null) {
589                     throw new IllegalArgumentException("Account must not be null for periodic"
590                             + " sync.");
591                 }
592                 if (mAuthority == null) {
593                     throw new IllegalArgumentException("Authority must not be null for periodic"
594                             + " sync.");
595                 }
596             } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
597                 throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
598             }
599             // Ensure that a target for the sync has been set.
600             if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
601                 throw new IllegalArgumentException("Must specify an adapter with "
602                         + "setSyncAdapter(Account, String");
603             }
604             return new SyncRequest(this);
605         }
606 
607         /**
608          * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
609          * extras were set for a periodic sync.
610          *
611          * @param extras bundle to validate.
612          */
validatePeriodicExtras(Bundle extras)613         private void validatePeriodicExtras(Bundle extras) {
614             if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
615                     || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
616                     || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
617                     || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
618                     || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
619                     || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
620                     || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
621                 throw new IllegalArgumentException("Illegal extras were set");
622             }
623         }
624     }
625 }
626