blob: 5f1f18016e0d4f3d546476e01d1872036b5f8405 [file] [log] [blame]
Matthew Williamsfa774182013-06-18 15:44:11 -07001/*
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
17package android.content;
18
19import android.accounts.Account;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010020import android.annotation.UnsupportedAppUsage;
Mathew Inwood8c854f82018-09-14 12:35:36 +010021import android.os.Build;
Matthew Williamsfa774182013-06-18 15:44:11 -070022import android.os.Bundle;
23import android.os.Parcel;
24import android.os.Parcelable;
Matthew Williamsfa774182013-06-18 15:44:11 -070025
Matthew Williams23680142014-06-09 20:06:03 -070026/**
27 * Convenience class to construct sync requests. See {@link android.content.SyncRequest.Builder}
28 * for an explanation of the various functions. The resulting object is passed through to the
29 * framework via {@link android.content.ContentResolver#requestSync(SyncRequest)}.
30 */
Matthew Williamsfa774182013-06-18 15:44:11 -070031public class SyncRequest implements Parcelable {
32 private static final String TAG = "SyncRequest";
33 /** Account to pass to the sync adapter. Can be null. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +010034 @UnsupportedAppUsage
Matthew Williamsfa774182013-06-18 15:44:11 -070035 private final Account mAccountToSync;
36 /** Authority string that corresponds to a ContentProvider. */
Mathew Inwood8c854f82018-09-14 12:35:36 +010037 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Matthew Williamsfa774182013-06-18 15:44:11 -070038 private final String mAuthority;
Matthew Williamsfa774182013-06-18 15:44:11 -070039 /** Bundle containing user info as well as sync settings. */
Mathew Inwood8c854f82018-09-14 12:35:36 +010040 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Matthew Williamsfa774182013-06-18 15:44:11 -070041 private final Bundle mExtras;
Matthew Williams56dbf8f2013-07-26 12:56:39 -070042 /** Don't allow this sync request on metered networks. */
43 private final boolean mDisallowMetered;
Matthew Williamsfa774182013-06-18 15:44:11 -070044 /**
Matthew Williamsc81891c2013-07-24 19:09:30 -070045 * Amount of time before {@link #mSyncRunTimeSecs} from which the sync may optionally be
Matthew Williamsfa774182013-06-18 15:44:11 -070046 * started.
47 */
48 private final long mSyncFlexTimeSecs;
49 /**
50 * Specifies a point in the future at which the sync must have been scheduled to run.
51 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +010052 @UnsupportedAppUsage
Matthew Williamsfa774182013-06-18 15:44:11 -070053 private final long mSyncRunTimeSecs;
54 /** Periodic versus one-off. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +010055 @UnsupportedAppUsage
Matthew Williamsfa774182013-06-18 15:44:11 -070056 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 */
68 public boolean isPeriodic() {
69 return mIsPeriodic;
70 }
71
Matthew Williams23680142014-06-09 20:06:03 -070072 /**
73 * {@hide}
74 * @return whether this sync is expedited.
75 */
Matthew Williamsfa774182013-06-18 15:44:11 -070076 public boolean isExpedited() {
77 return mIsExpedited;
78 }
79
80 /**
81 * {@hide}
Matthew Williamsfa774182013-06-18 15:44:11 -070082 *
Matthew Williams56dbf8f2013-07-26 12:56:39 -070083 * @return account object for this sync.
84 * @throws IllegalArgumentException if this function is called for a request that targets a
85 * sync service.
Matthew Williamsfa774182013-06-18 15:44:11 -070086 */
Matthew Williams56dbf8f2013-07-26 12:56:39 -070087 public Account getAccount() {
Matthew Williams56dbf8f2013-07-26 12:56:39 -070088 return mAccountToSync;
89 }
90
91 /**
92 * {@hide}
93 *
94 * @return provider for this sync.
95 * @throws IllegalArgumentException if this function is called for a request that targets a
96 * sync service.
97 */
98 public String getProvider() {
Matthew Williams56dbf8f2013-07-26 12:56:39 -070099 return mAuthority;
Matthew Williamsfa774182013-06-18 15:44:11 -0700100 }
101
102 /**
103 * {@hide}
Matthew Williamsfa774182013-06-18 15:44:11 -0700104 * Retrieve bundle for this SyncRequest. Will not be null.
105 */
106 public Bundle getBundle() {
107 return mExtras;
108 }
109
110 /**
111 * {@hide}
112 * @return the earliest point in time that this sync can be scheduled.
113 */
114 public long getSyncFlexTime() {
115 return mSyncFlexTimeSecs;
116 }
117 /**
118 * {@hide}
119 * @return the last point in time at which this sync must scheduled.
120 */
121 public long getSyncRunTime() {
122 return mSyncRunTimeSecs;
123 }
124
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700125 public static final @android.annotation.NonNull Creator<SyncRequest> CREATOR = new Creator<SyncRequest>() {
Matthew Williamsfa774182013-06-18 15:44:11 -0700126
127 @Override
128 public SyncRequest createFromParcel(Parcel in) {
129 return new SyncRequest(in);
130 }
131
132 @Override
133 public SyncRequest[] newArray(int size) {
134 return new SyncRequest[size];
135 }
136 };
137
138 @Override
139 public int describeContents() {
140 return 0;
141 }
142
143 @Override
144 public void writeToParcel(Parcel parcel, int flags) {
145 parcel.writeBundle(mExtras);
146 parcel.writeLong(mSyncFlexTimeSecs);
147 parcel.writeLong(mSyncRunTimeSecs);
148 parcel.writeInt((mIsPeriodic ? 1 : 0));
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700149 parcel.writeInt((mDisallowMetered ? 1 : 0));
Matthew Williamsfa774182013-06-18 15:44:11 -0700150 parcel.writeInt((mIsAuthority ? 1 : 0));
151 parcel.writeInt((mIsExpedited? 1 : 0));
Matthew Williams64939ae2014-06-04 09:25:11 -0700152 parcel.writeParcelable(mAccountToSync, flags);
153 parcel.writeString(mAuthority);
Matthew Williamsfa774182013-06-18 15:44:11 -0700154 }
155
156 private SyncRequest(Parcel in) {
Jeff Sharkeya04c7a72016-03-18 12:20:36 -0600157 mExtras = Bundle.setDefusable(in.readBundle(), true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700158 mSyncFlexTimeSecs = in.readLong();
159 mSyncRunTimeSecs = in.readLong();
160 mIsPeriodic = (in.readInt() != 0);
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700161 mDisallowMetered = (in.readInt() != 0);
Matthew Williamsfa774182013-06-18 15:44:11 -0700162 mIsAuthority = (in.readInt() != 0);
163 mIsExpedited = (in.readInt() != 0);
Matthew Williams64939ae2014-06-04 09:25:11 -0700164 mAccountToSync = in.readParcelable(null);
165 mAuthority = in.readString();
Matthew Williamsfa774182013-06-18 15:44:11 -0700166 }
167
168 /** {@hide} Protected ctor to instantiate anonymous SyncRequest. */
169 protected SyncRequest(SyncRequest.Builder b) {
170 mSyncFlexTimeSecs = b.mSyncFlexTimeSecs;
171 mSyncRunTimeSecs = b.mSyncRunTimeSecs;
172 mAccountToSync = b.mAccount;
173 mAuthority = b.mAuthority;
Matthew Williamsfa774182013-06-18 15:44:11 -0700174 mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
175 mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
176 mIsExpedited = b.mExpedited;
177 mExtras = new Bundle(b.mCustomExtras);
Matthew Williams68e39c32013-07-25 16:40:23 -0700178 // For now we merge the sync config extras & the custom extras into one bundle.
179 // TODO: pass the configuration extras through separately.
180 mExtras.putAll(b.mSyncConfigExtras);
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700181 mDisallowMetered = b.mDisallowMetered;
Matthew Williamsfa774182013-06-18 15:44:11 -0700182 }
183
184 /**
Elliot Waite54de7742017-01-11 15:30:35 -0800185 * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also
Matthew Williamsfa774182013-06-18 15:44:11 -0700186 * perform validation.
187 */
188 public static class Builder {
189 /** Unknown sync type. */
190 private static final int SYNC_TYPE_UNKNOWN = 0;
191 /** Specify that this is a periodic sync. */
192 private static final int SYNC_TYPE_PERIODIC = 1;
193 /** Specify that this is a one-time sync. */
194 private static final int SYNC_TYPE_ONCE = 2;
195 /** Unknown sync target. */
196 private static final int SYNC_TARGET_UNKNOWN = 0;
Matthew Williamsfa774182013-06-18 15:44:11 -0700197 /** Specify that this is a sync with a provider. */
198 private static final int SYNC_TARGET_ADAPTER = 2;
199 /**
200 * Earliest point of displacement into the future at which this sync can
201 * occur.
202 */
203 private long mSyncFlexTimeSecs;
204 /** Displacement into the future at which this sync must occur. */
205 private long mSyncRunTimeSecs;
206 /**
207 * Sync configuration information - custom user data explicitly provided by the developer.
208 * This data is handed over to the sync operation.
209 */
210 private Bundle mCustomExtras;
211 /**
212 * Sync system configuration - used to store system sync configuration. Corresponds to
213 * ContentResolver.SYNC_EXTRAS_* flags.
214 * TODO: Use this instead of dumping into one bundle. Need to decide if these flags should
215 * discriminate between equivalent syncs.
216 */
217 private Bundle mSyncConfigExtras;
Matthew Williamsfa774182013-06-18 15:44:11 -0700218 /** Whether or not this sync can occur on metered networks. Default false. */
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700219 private boolean mDisallowMetered;
Matthew Williamsfa774182013-06-18 15:44:11 -0700220 /**
221 * Whether this builder is building a periodic sync, or a one-time sync.
222 */
223 private int mSyncType = SYNC_TYPE_UNKNOWN;
Matthew Williams64939ae2014-06-04 09:25:11 -0700224 /** Whether this will go to a sync adapter. */
Matthew Williamsfa774182013-06-18 15:44:11 -0700225 private int mSyncTarget = SYNC_TARGET_UNKNOWN;
226 /** Whether this is a user-activated sync. */
227 private boolean mIsManual;
228 /**
229 * Whether to retry this one-time sync if the sync fails. Not valid for
Matthew Williamsc81891c2013-07-24 19:09:30 -0700230 * periodic syncs. See {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}.
Matthew Williamsfa774182013-06-18 15:44:11 -0700231 */
232 private boolean mNoRetry;
233 /**
234 * Whether to respect back-off for this one-time sync. Not valid for
235 * periodic syncs. See
Matthew Williamsc81891c2013-07-24 19:09:30 -0700236 * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF};
Matthew Williamsfa774182013-06-18 15:44:11 -0700237 */
238 private boolean mIgnoreBackoff;
239
240 /** Ignore sync system settings and perform sync anyway. */
241 private boolean mIgnoreSettings;
242
243 /** This sync will run in preference to other non-expedited syncs. */
244 private boolean mExpedited;
245
246 /**
Matthew Williamsfa774182013-06-18 15:44:11 -0700247 * The Account object that together with an Authority name define the SyncAdapter (if
Matthew Williamsc81891c2013-07-24 19:09:30 -0700248 * this sync is bound to a provider), otherwise null.
Matthew Williamsfa774182013-06-18 15:44:11 -0700249 */
250 private Account mAccount;
251 /**
252 * The Authority name that together with an Account define the SyncAdapter (if
Matthew Williamsc81891c2013-07-24 19:09:30 -0700253 * this sync is bound to a provider), otherwise null.
Matthew Williamsfa774182013-06-18 15:44:11 -0700254 */
255 private String mAuthority;
Shreyas Basarge8c834c02016-01-07 13:53:16 +0000256 /**
257 * Whether the sync requires the phone to be plugged in.
258 */
259 private boolean mRequiresCharging;
Matthew Williamsfa774182013-06-18 15:44:11 -0700260
261 public Builder() {
262 }
263
264 /**
Nick Kralevich47d2b612013-10-19 10:43:55 -0700265 * Request that a sync occur immediately.
Matthew Williamsfa774182013-06-18 15:44:11 -0700266 *
267 * Example
268 * <pre>
Nick Kralevich69002ae2013-10-19 08:43:08 -0700269 * SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce();
Matthew Williamsfa774182013-06-18 15:44:11 -0700270 * </pre>
271 */
Nick Kralevich69002ae2013-10-19 08:43:08 -0700272 public Builder syncOnce() {
Matthew Williamsfa774182013-06-18 15:44:11 -0700273 if (mSyncType != SYNC_TYPE_UNKNOWN) {
274 throw new IllegalArgumentException("Sync type has already been defined.");
275 }
276 mSyncType = SYNC_TYPE_ONCE;
Nick Kralevich69002ae2013-10-19 08:43:08 -0700277 setupInterval(0, 0);
Matthew Williamsfa774182013-06-18 15:44:11 -0700278 return this;
279 }
280
281 /**
282 * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
Matthew Williams64939ae2014-06-04 09:25:11 -0700283 * Syncs are identified by target {@link android.provider} and by the
Matthew Williamsfa774182013-06-18 15:44:11 -0700284 * contents of the extras bundle.
285 * You cannot reuse the same builder for one-time syncs after having specified a periodic
Matthew Williamsc81891c2013-07-24 19:09:30 -0700286 * sync (by calling this function). If you do, an <code>IllegalArgumentException</code>
287 * will be thrown.
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700288 * <p>The bundle for a periodic sync can be queried by applications with the correct
289 * permissions using
290 * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
291 * sensitive data should be transferred here.
Matthew Williamsc81891c2013-07-24 19:09:30 -0700292 *
Matthew Williamsfa774182013-06-18 15:44:11 -0700293 * Example usage.
294 *
295 * <pre>
296 * Request a periodic sync every 5 hours with 20 minutes of flex.
297 * SyncRequest.Builder builder =
298 * (new SyncRequest.Builder()).syncPeriodic(5 * HOUR_IN_SECS, 20 * MIN_IN_SECS);
299 *
300 * Schedule a periodic sync every hour at any point in time during that hour.
301 * SyncRequest.Builder builder =
302 * (new SyncRequest.Builder()).syncPeriodic(1 * HOUR_IN_SECS, 1 * HOUR_IN_SECS);
303 * </pre>
304 *
305 * N.B.: Periodic syncs are not allowed to have any of
Ying Wang8cf4e132013-07-24 20:47:19 -0700306 * {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY},
307 * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF},
308 * {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS},
309 * {@link ContentResolver#SYNC_EXTRAS_INITIALIZE},
310 * {@link ContentResolver#SYNC_EXTRAS_FORCE},
311 * {@link ContentResolver#SYNC_EXTRAS_EXPEDITED},
312 * {@link ContentResolver#SYNC_EXTRAS_MANUAL}
Matthew Williamsc81891c2013-07-24 19:09:30 -0700313 * set to true. If any are supplied then an <code>IllegalArgumentException</code> will
Matthew Williamsfa774182013-06-18 15:44:11 -0700314 * be thrown.
315 *
316 * @param pollFrequency the amount of time in seconds that you wish
Shreyas Basargee96c3b72016-01-29 19:25:51 +0000317 * to elapse between periodic syncs. A minimum period of 1 hour is enforced.
Matthew Williamsfa774182013-06-18 15:44:11 -0700318 * @param beforeSeconds the amount of flex time in seconds before
319 * {@code pollFrequency} that you permit for the sync to take
Shreyas Basargee96c3b72016-01-29 19:25:51 +0000320 * place. Must be less than {@code pollFrequency} and greater than
321 * MAX(5% of {@code pollFrequency}, 5 minutes)
Matthew Williamsfa774182013-06-18 15:44:11 -0700322 */
323 public Builder syncPeriodic(long pollFrequency, long beforeSeconds) {
324 if (mSyncType != SYNC_TYPE_UNKNOWN) {
325 throw new IllegalArgumentException("Sync type has already been defined.");
326 }
327 mSyncType = SYNC_TYPE_PERIODIC;
328 setupInterval(pollFrequency, beforeSeconds);
329 return this;
330 }
331
Matthew Williamsfa774182013-06-18 15:44:11 -0700332 private void setupInterval(long at, long before) {
333 if (before > at) {
334 throw new IllegalArgumentException("Specified run time for the sync must be" +
Matthew Williamsc81891c2013-07-24 19:09:30 -0700335 " after the specified flex time.");
Matthew Williamsfa774182013-06-18 15:44:11 -0700336 }
337 mSyncRunTimeSecs = at;
338 mSyncFlexTimeSecs = before;
339 }
340
341 /**
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700342 * Will throw an <code>IllegalArgumentException</code> if called and
343 * {@link #setIgnoreSettings(boolean ignoreSettings)} has already been called.
344 * @param disallow true to allow this transfer on metered networks. Default false.
Matthew Williams64939ae2014-06-04 09:25:11 -0700345 *
Matthew Williamsfa774182013-06-18 15:44:11 -0700346 */
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700347 public Builder setDisallowMetered(boolean disallow) {
348 if (mIgnoreSettings && disallow) {
349 throw new IllegalArgumentException("setDisallowMetered(true) after having"
Shreyas Basarge8c834c02016-01-07 13:53:16 +0000350 + " specified that settings are ignored.");
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700351 }
352 mDisallowMetered = disallow;
Matthew Williamsfa774182013-06-18 15:44:11 -0700353 return this;
354 }
355
356 /**
Shreyas Basarge8c834c02016-01-07 13:53:16 +0000357 * Specify whether the sync requires the phone to be plugged in.
358 * @param requiresCharging true if sync requires the phone to be plugged in. Default false.
359 */
360 public Builder setRequiresCharging(boolean requiresCharging) {
Shreyas Basarge3a147232017-02-06 17:46:26 +0000361 mRequiresCharging = requiresCharging;
Shreyas Basarge8c834c02016-01-07 13:53:16 +0000362 return this;
363 }
364
365 /**
Matthew Williams64939ae2014-06-04 09:25:11 -0700366 * Specify an authority and account for this transfer.
Matthew Williamsfa774182013-06-18 15:44:11 -0700367 *
Matthew Williams64939ae2014-06-04 09:25:11 -0700368 * @param authority A String identifying the content provider to be synced.
Matthew Williamsfa774182013-06-18 15:44:11 -0700369 * @param account Account to sync. Can be null unless this is a periodic
370 * sync, for which verification by the ContentResolver will
371 * fail. If a sync is performed without an account, the
372 */
373 public Builder setSyncAdapter(Account account, String authority) {
374 if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
375 throw new IllegalArgumentException("Sync target has already been defined.");
376 }
Matthew Williams632515b2013-10-10 15:51:00 -0700377 if (authority != null && authority.length() == 0) {
378 throw new IllegalArgumentException("Authority must be non-empty");
379 }
Matthew Williamsfa774182013-06-18 15:44:11 -0700380 mSyncTarget = SYNC_TARGET_ADAPTER;
381 mAccount = account;
382 mAuthority = authority;
Matthew Williamsfa774182013-06-18 15:44:11 -0700383 return this;
384 }
385
386 /**
387 * Developer-provided extras handed back when sync actually occurs. This bundle is copied
Matthew Williamsc81891c2013-07-24 19:09:30 -0700388 * into the SyncRequest returned by {@link #build()}.
Matthew Williamsfa774182013-06-18 15:44:11 -0700389 *
390 * Example:
391 * <pre>
392 * String[] syncItems = {"dog", "cat", "frog", "child"};
393 * SyncRequest.Builder builder =
394 * new SyncRequest.Builder()
395 * .setSyncAdapter(dummyAccount, dummyProvider)
Russ Schnappc43a6bb2014-05-07 12:56:13 -0700396 * .syncOnce();
Matthew Williamsfa774182013-06-18 15:44:11 -0700397 *
398 * for (String syncData : syncItems) {
399 * Bundle extras = new Bundle();
400 * extras.setString("data", syncData);
401 * builder.setExtras(extras);
402 * ContentResolver.sync(builder.build()); // Each sync() request creates a unique sync.
403 * }
404 * </pre>
Matthew Williamsfa774182013-06-18 15:44:11 -0700405 * Only values of the following types may be used in the extras bundle:
406 * <ul>
407 * <li>Integer</li>
408 * <li>Long</li>
409 * <li>Boolean</li>
410 * <li>Float</li>
411 * <li>Double</li>
412 * <li>String</li>
413 * <li>Account</li>
414 * <li>null</li>
415 * </ul>
416 * If any data is present in the bundle not of this type, build() will
417 * throw a runtime exception.
418 *
Matthew Williamsc81891c2013-07-24 19:09:30 -0700419 * @param bundle extras bundle to set.
Matthew Williamsfa774182013-06-18 15:44:11 -0700420 */
421 public Builder setExtras(Bundle bundle) {
422 mCustomExtras = bundle;
423 return this;
424 }
425
426 /**
Matthew Williamsc81891c2013-07-24 19:09:30 -0700427 * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}.
Matthew Williamsfa774182013-06-18 15:44:11 -0700428 *
Matthew Williamsc81891c2013-07-24 19:09:30 -0700429 * A one-off sync operation that fails will be retried with exponential back-off unless
430 * this is set to false. Not valid for periodic sync and will throw an
431 * <code>IllegalArgumentException</code> in build().
432 *
433 * @param noRetry true to not retry a failed sync. Default false.
Matthew Williamsfa774182013-06-18 15:44:11 -0700434 */
Matthew Williamsc81891c2013-07-24 19:09:30 -0700435 public Builder setNoRetry(boolean noRetry) {
436 mNoRetry = noRetry;
Matthew Williamsfa774182013-06-18 15:44:11 -0700437 return this;
438 }
439
440 /**
Matthew Williamsc81891c2013-07-24 19:09:30 -0700441 * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}.
442 *
443 * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
444 * {@link #build()}.
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700445 * <p>Throws <code>IllegalArgumentException</code> if called and
446 * {@link #setDisallowMetered(boolean)} has been set.
447 *
Matthew Williamsc81891c2013-07-24 19:09:30 -0700448 *
449 * @param ignoreSettings true to ignore the sync automatically settings. Default false.
Matthew Williamsfa774182013-06-18 15:44:11 -0700450 */
451 public Builder setIgnoreSettings(boolean ignoreSettings) {
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700452 if (mDisallowMetered && ignoreSettings) {
453 throw new IllegalArgumentException("setIgnoreSettings(true) after having specified"
454 + " sync settings with this builder.");
455 }
Matthew Williamsfa774182013-06-18 15:44:11 -0700456 mIgnoreSettings = ignoreSettings;
457 return this;
458 }
459
460 /**
Ying Wang8cf4e132013-07-24 20:47:19 -0700461 * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}.
Matthew Williamsfa774182013-06-18 15:44:11 -0700462 *
Matthew Williamsc81891c2013-07-24 19:09:30 -0700463 * Ignoring back-off will force the sync scheduling process to ignore any back-off that was
464 * the result of a failed sync, as well as to invalidate any {@link SyncResult#delayUntil}
465 * value that may have been set by the adapter. Successive failures will not honor this
466 * flag. Not valid for periodic sync and will throw an <code>IllegalArgumentException</code>
467 * in {@link #build()}.
468 *
469 * @param ignoreBackoff ignore back off settings. Default false.
Matthew Williamsfa774182013-06-18 15:44:11 -0700470 */
471 public Builder setIgnoreBackoff(boolean ignoreBackoff) {
472 mIgnoreBackoff = ignoreBackoff;
473 return this;
474 }
475
476 /**
Matthew Williamsc81891c2013-07-24 19:09:30 -0700477 * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_MANUAL}.
478 *
479 * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
480 * {@link #build()}.
481 *
482 * @param isManual User-initiated sync or not. Default false.
Matthew Williamsfa774182013-06-18 15:44:11 -0700483 */
484 public Builder setManual(boolean isManual) {
485 mIsManual = isManual;
486 return this;
487 }
488
489 /**
Matthew Williamsc81891c2013-07-24 19:09:30 -0700490 * An expedited sync runs immediately and can preempt other non-expedited running syncs.
491 *
492 * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
493 * {@link #build()}.
494 *
495 * @param expedited whether to run expedited. Default false.
Matthew Williamsfa774182013-06-18 15:44:11 -0700496 */
497 public Builder setExpedited(boolean expedited) {
498 mExpedited = expedited;
499 return this;
500 }
501
502 /**
Matthew Williamsfa774182013-06-18 15:44:11 -0700503 * Performs validation over the request and throws the runtime exception
Matthew Williamsc81891c2013-07-24 19:09:30 -0700504 * <code>IllegalArgumentException</code> if this validation fails.
Matthew Williamsfa774182013-06-18 15:44:11 -0700505 *
506 * @return a SyncRequest with the information contained within this
507 * builder.
508 */
509 public SyncRequest build() {
510 // Validate the extras bundle
Matthew Williams68e39c32013-07-25 16:40:23 -0700511 ContentResolver.validateSyncExtrasBundle(mCustomExtras);
Matthew Williamsfa774182013-06-18 15:44:11 -0700512 if (mCustomExtras == null) {
513 mCustomExtras = new Bundle();
514 }
Matthew Williams68e39c32013-07-25 16:40:23 -0700515 // Combine builder extra flags into the config bundle.
516 mSyncConfigExtras = new Bundle();
Matthew Williamsfa774182013-06-18 15:44:11 -0700517 if (mIgnoreBackoff) {
Matthew Williams68e39c32013-07-25 16:40:23 -0700518 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700519 }
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700520 if (mDisallowMetered) {
521 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700522 }
Shreyas Basarge8c834c02016-01-07 13:53:16 +0000523 if (mRequiresCharging) {
524 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, true);
525 }
Matthew Williamsfa774182013-06-18 15:44:11 -0700526 if (mIgnoreSettings) {
Matthew Williams68e39c32013-07-25 16:40:23 -0700527 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700528 }
529 if (mNoRetry) {
Matthew Williams68e39c32013-07-25 16:40:23 -0700530 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700531 }
532 if (mExpedited) {
Matthew Williams68e39c32013-07-25 16:40:23 -0700533 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700534 }
535 if (mIsManual) {
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700536 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
537 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
Matthew Williamsfa774182013-06-18 15:44:11 -0700538 }
Matthew Williamsfa774182013-06-18 15:44:11 -0700539 if (mSyncType == SYNC_TYPE_PERIODIC) {
Matthew Williams68e39c32013-07-25 16:40:23 -0700540 // If this is a periodic sync ensure than invalid extras were not set.
Matthew Williams64939ae2014-06-04 09:25:11 -0700541 if (ContentResolver.invalidPeriodicExtras(mCustomExtras) ||
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700542 ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
543 throw new IllegalArgumentException("Illegal extras were set");
544 }
Matthew Williams56dbf8f2013-07-26 12:56:39 -0700545 }
Matthew Williamsfa774182013-06-18 15:44:11 -0700546 // Ensure that a target for the sync has been set.
547 if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
Matthew Williams64939ae2014-06-04 09:25:11 -0700548 throw new IllegalArgumentException("Must specify an adapter with" +
549 " setSyncAdapter(Account, String");
Matthew Williamsfa774182013-06-18 15:44:11 -0700550 }
551 return new SyncRequest(this);
552 }
Matthew Williams64939ae2014-06-04 09:25:11 -0700553 }
Matthew Williamsfa774182013-06-18 15:44:11 -0700554}