Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 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; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 23 | |
Matthew Williams | 2368014 | 2014-06-09 20:06:03 -0700 | [diff] [blame] | 24 | /** |
| 25 | * Convenience class to construct sync requests. See {@link android.content.SyncRequest.Builder} |
| 26 | * for an explanation of the various functions. The resulting object is passed through to the |
| 27 | * framework via {@link android.content.ContentResolver#requestSync(SyncRequest)}. |
| 28 | */ |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 29 | public class SyncRequest implements Parcelable { |
| 30 | private static final String TAG = "SyncRequest"; |
| 31 | /** Account to pass to the sync adapter. Can be null. */ |
| 32 | private final Account mAccountToSync; |
| 33 | /** Authority string that corresponds to a ContentProvider. */ |
| 34 | private final String mAuthority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 35 | /** Bundle containing user info as well as sync settings. */ |
| 36 | private final Bundle mExtras; |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 37 | /** Don't allow this sync request on metered networks. */ |
| 38 | private final boolean mDisallowMetered; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 39 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 40 | * Amount of time before {@link #mSyncRunTimeSecs} from which the sync may optionally be |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 41 | * started. |
| 42 | */ |
| 43 | private final long mSyncFlexTimeSecs; |
| 44 | /** |
| 45 | * Specifies a point in the future at which the sync must have been scheduled to run. |
| 46 | */ |
| 47 | private final long mSyncRunTimeSecs; |
| 48 | /** Periodic versus one-off. */ |
| 49 | private final boolean mIsPeriodic; |
| 50 | /** Service versus provider. */ |
| 51 | private final boolean mIsAuthority; |
| 52 | /** Sync should be run in lieu of other syncs. */ |
| 53 | private final boolean mIsExpedited; |
| 54 | |
| 55 | /** |
| 56 | * {@hide} |
| 57 | * @return whether this sync is periodic or one-time. A Sync Request must be |
| 58 | * either one of these or an InvalidStateException will be thrown in |
| 59 | * Builder.build(). |
| 60 | */ |
| 61 | public boolean isPeriodic() { |
| 62 | return mIsPeriodic; |
| 63 | } |
| 64 | |
Matthew Williams | 2368014 | 2014-06-09 20:06:03 -0700 | [diff] [blame] | 65 | /** |
| 66 | * {@hide} |
| 67 | * @return whether this sync is expedited. |
| 68 | */ |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 69 | public boolean isExpedited() { |
| 70 | return mIsExpedited; |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | * {@hide} |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 75 | * |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 76 | * @return account object for this sync. |
| 77 | * @throws IllegalArgumentException if this function is called for a request that targets a |
| 78 | * sync service. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 79 | */ |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 80 | public Account getAccount() { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 81 | return mAccountToSync; |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * {@hide} |
| 86 | * |
| 87 | * @return provider for this sync. |
| 88 | * @throws IllegalArgumentException if this function is called for a request that targets a |
| 89 | * sync service. |
| 90 | */ |
| 91 | public String getProvider() { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 92 | return mAuthority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | /** |
| 96 | * {@hide} |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 97 | * Retrieve bundle for this SyncRequest. Will not be null. |
| 98 | */ |
| 99 | public Bundle getBundle() { |
| 100 | return mExtras; |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * {@hide} |
| 105 | * @return the earliest point in time that this sync can be scheduled. |
| 106 | */ |
| 107 | public long getSyncFlexTime() { |
| 108 | return mSyncFlexTimeSecs; |
| 109 | } |
| 110 | /** |
| 111 | * {@hide} |
| 112 | * @return the last point in time at which this sync must scheduled. |
| 113 | */ |
| 114 | public long getSyncRunTime() { |
| 115 | return mSyncRunTimeSecs; |
| 116 | } |
| 117 | |
| 118 | public static final Creator<SyncRequest> CREATOR = new Creator<SyncRequest>() { |
| 119 | |
| 120 | @Override |
| 121 | public SyncRequest createFromParcel(Parcel in) { |
| 122 | return new SyncRequest(in); |
| 123 | } |
| 124 | |
| 125 | @Override |
| 126 | public SyncRequest[] newArray(int size) { |
| 127 | return new SyncRequest[size]; |
| 128 | } |
| 129 | }; |
| 130 | |
| 131 | @Override |
| 132 | public int describeContents() { |
| 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | @Override |
| 137 | public void writeToParcel(Parcel parcel, int flags) { |
| 138 | parcel.writeBundle(mExtras); |
| 139 | parcel.writeLong(mSyncFlexTimeSecs); |
| 140 | parcel.writeLong(mSyncRunTimeSecs); |
| 141 | parcel.writeInt((mIsPeriodic ? 1 : 0)); |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 142 | parcel.writeInt((mDisallowMetered ? 1 : 0)); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 143 | parcel.writeInt((mIsAuthority ? 1 : 0)); |
| 144 | parcel.writeInt((mIsExpedited? 1 : 0)); |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 145 | parcel.writeParcelable(mAccountToSync, flags); |
| 146 | parcel.writeString(mAuthority); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | private SyncRequest(Parcel in) { |
Jeff Sharkey | a04c7a7 | 2016-03-18 12:20:36 -0600 | [diff] [blame] | 150 | mExtras = Bundle.setDefusable(in.readBundle(), true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 151 | mSyncFlexTimeSecs = in.readLong(); |
| 152 | mSyncRunTimeSecs = in.readLong(); |
| 153 | mIsPeriodic = (in.readInt() != 0); |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 154 | mDisallowMetered = (in.readInt() != 0); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 155 | mIsAuthority = (in.readInt() != 0); |
| 156 | mIsExpedited = (in.readInt() != 0); |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 157 | mAccountToSync = in.readParcelable(null); |
| 158 | mAuthority = in.readString(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | /** {@hide} Protected ctor to instantiate anonymous SyncRequest. */ |
| 162 | protected SyncRequest(SyncRequest.Builder b) { |
| 163 | mSyncFlexTimeSecs = b.mSyncFlexTimeSecs; |
| 164 | mSyncRunTimeSecs = b.mSyncRunTimeSecs; |
| 165 | mAccountToSync = b.mAccount; |
| 166 | mAuthority = b.mAuthority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 167 | mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC); |
| 168 | mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER); |
| 169 | mIsExpedited = b.mExpedited; |
| 170 | mExtras = new Bundle(b.mCustomExtras); |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 171 | // For now we merge the sync config extras & the custom extras into one bundle. |
| 172 | // TODO: pass the configuration extras through separately. |
| 173 | mExtras.putAll(b.mSyncConfigExtras); |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 174 | mDisallowMetered = b.mDisallowMetered; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | /** |
| 178 | * Builder class for a @link SyncRequest. As you build your SyncRequest this class will also |
| 179 | * perform validation. |
| 180 | */ |
| 181 | public static class Builder { |
| 182 | /** Unknown sync type. */ |
| 183 | private static final int SYNC_TYPE_UNKNOWN = 0; |
| 184 | /** Specify that this is a periodic sync. */ |
| 185 | private static final int SYNC_TYPE_PERIODIC = 1; |
| 186 | /** Specify that this is a one-time sync. */ |
| 187 | private static final int SYNC_TYPE_ONCE = 2; |
| 188 | /** Unknown sync target. */ |
| 189 | private static final int SYNC_TARGET_UNKNOWN = 0; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 190 | /** Specify that this is a sync with a provider. */ |
| 191 | private static final int SYNC_TARGET_ADAPTER = 2; |
| 192 | /** |
| 193 | * Earliest point of displacement into the future at which this sync can |
| 194 | * occur. |
| 195 | */ |
| 196 | private long mSyncFlexTimeSecs; |
| 197 | /** Displacement into the future at which this sync must occur. */ |
| 198 | private long mSyncRunTimeSecs; |
| 199 | /** |
| 200 | * Sync configuration information - custom user data explicitly provided by the developer. |
| 201 | * This data is handed over to the sync operation. |
| 202 | */ |
| 203 | private Bundle mCustomExtras; |
| 204 | /** |
| 205 | * Sync system configuration - used to store system sync configuration. Corresponds to |
| 206 | * ContentResolver.SYNC_EXTRAS_* flags. |
| 207 | * TODO: Use this instead of dumping into one bundle. Need to decide if these flags should |
| 208 | * discriminate between equivalent syncs. |
| 209 | */ |
| 210 | private Bundle mSyncConfigExtras; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 211 | /** Whether or not this sync can occur on metered networks. Default false. */ |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 212 | private boolean mDisallowMetered; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 213 | /** |
| 214 | * Whether this builder is building a periodic sync, or a one-time sync. |
| 215 | */ |
| 216 | private int mSyncType = SYNC_TYPE_UNKNOWN; |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 217 | /** Whether this will go to a sync adapter. */ |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 218 | private int mSyncTarget = SYNC_TARGET_UNKNOWN; |
| 219 | /** Whether this is a user-activated sync. */ |
| 220 | private boolean mIsManual; |
| 221 | /** |
| 222 | * Whether to retry this one-time sync if the sync fails. Not valid for |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 223 | * periodic syncs. See {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 224 | */ |
| 225 | private boolean mNoRetry; |
| 226 | /** |
| 227 | * Whether to respect back-off for this one-time sync. Not valid for |
| 228 | * periodic syncs. See |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 229 | * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 230 | */ |
| 231 | private boolean mIgnoreBackoff; |
| 232 | |
| 233 | /** Ignore sync system settings and perform sync anyway. */ |
| 234 | private boolean mIgnoreSettings; |
| 235 | |
| 236 | /** This sync will run in preference to other non-expedited syncs. */ |
| 237 | private boolean mExpedited; |
| 238 | |
| 239 | /** |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 240 | * The Account object that together with an Authority name define the SyncAdapter (if |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 241 | * this sync is bound to a provider), otherwise null. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 242 | */ |
| 243 | private Account mAccount; |
| 244 | /** |
| 245 | * The Authority name that together with an Account define the SyncAdapter (if |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 246 | * this sync is bound to a provider), otherwise null. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 247 | */ |
| 248 | private String mAuthority; |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 249 | /** |
| 250 | * Whether the sync requires the phone to be plugged in. |
| 251 | */ |
| 252 | private boolean mRequiresCharging; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 253 | |
| 254 | public Builder() { |
| 255 | } |
| 256 | |
| 257 | /** |
Nick Kralevich | 47d2b61 | 2013-10-19 10:43:55 -0700 | [diff] [blame] | 258 | * Request that a sync occur immediately. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 259 | * |
| 260 | * Example |
| 261 | * <pre> |
Nick Kralevich | 69002ae | 2013-10-19 08:43:08 -0700 | [diff] [blame] | 262 | * SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 263 | * </pre> |
| 264 | */ |
Nick Kralevich | 69002ae | 2013-10-19 08:43:08 -0700 | [diff] [blame] | 265 | public Builder syncOnce() { |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 266 | if (mSyncType != SYNC_TYPE_UNKNOWN) { |
| 267 | throw new IllegalArgumentException("Sync type has already been defined."); |
| 268 | } |
| 269 | mSyncType = SYNC_TYPE_ONCE; |
Nick Kralevich | 69002ae | 2013-10-19 08:43:08 -0700 | [diff] [blame] | 270 | setupInterval(0, 0); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 271 | return this; |
| 272 | } |
| 273 | |
| 274 | /** |
| 275 | * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder. |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 276 | * Syncs are identified by target {@link android.provider} and by the |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 277 | * contents of the extras bundle. |
| 278 | * You cannot reuse the same builder for one-time syncs after having specified a periodic |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 279 | * sync (by calling this function). If you do, an <code>IllegalArgumentException</code> |
| 280 | * will be thrown. |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 281 | * <p>The bundle for a periodic sync can be queried by applications with the correct |
| 282 | * permissions using |
| 283 | * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no |
| 284 | * sensitive data should be transferred here. |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 285 | * |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 286 | * Example usage. |
| 287 | * |
| 288 | * <pre> |
| 289 | * Request a periodic sync every 5 hours with 20 minutes of flex. |
| 290 | * SyncRequest.Builder builder = |
| 291 | * (new SyncRequest.Builder()).syncPeriodic(5 * HOUR_IN_SECS, 20 * MIN_IN_SECS); |
| 292 | * |
| 293 | * Schedule a periodic sync every hour at any point in time during that hour. |
| 294 | * SyncRequest.Builder builder = |
| 295 | * (new SyncRequest.Builder()).syncPeriodic(1 * HOUR_IN_SECS, 1 * HOUR_IN_SECS); |
| 296 | * </pre> |
| 297 | * |
| 298 | * N.B.: Periodic syncs are not allowed to have any of |
Ying Wang | 8cf4e13 | 2013-07-24 20:47:19 -0700 | [diff] [blame] | 299 | * {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}, |
| 300 | * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}, |
| 301 | * {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}, |
| 302 | * {@link ContentResolver#SYNC_EXTRAS_INITIALIZE}, |
| 303 | * {@link ContentResolver#SYNC_EXTRAS_FORCE}, |
| 304 | * {@link ContentResolver#SYNC_EXTRAS_EXPEDITED}, |
| 305 | * {@link ContentResolver#SYNC_EXTRAS_MANUAL} |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 306 | * set to true. If any are supplied then an <code>IllegalArgumentException</code> will |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 307 | * be thrown. |
| 308 | * |
| 309 | * @param pollFrequency the amount of time in seconds that you wish |
Shreyas Basarge | e96c3b7 | 2016-01-29 19:25:51 +0000 | [diff] [blame] | 310 | * to elapse between periodic syncs. A minimum period of 1 hour is enforced. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 311 | * @param beforeSeconds the amount of flex time in seconds before |
| 312 | * {@code pollFrequency} that you permit for the sync to take |
Shreyas Basarge | e96c3b7 | 2016-01-29 19:25:51 +0000 | [diff] [blame] | 313 | * place. Must be less than {@code pollFrequency} and greater than |
| 314 | * MAX(5% of {@code pollFrequency}, 5 minutes) |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 315 | */ |
| 316 | public Builder syncPeriodic(long pollFrequency, long beforeSeconds) { |
| 317 | if (mSyncType != SYNC_TYPE_UNKNOWN) { |
| 318 | throw new IllegalArgumentException("Sync type has already been defined."); |
| 319 | } |
| 320 | mSyncType = SYNC_TYPE_PERIODIC; |
| 321 | setupInterval(pollFrequency, beforeSeconds); |
| 322 | return this; |
| 323 | } |
| 324 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 325 | private void setupInterval(long at, long before) { |
| 326 | if (before > at) { |
| 327 | throw new IllegalArgumentException("Specified run time for the sync must be" + |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 328 | " after the specified flex time."); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 329 | } |
| 330 | mSyncRunTimeSecs = at; |
| 331 | mSyncFlexTimeSecs = before; |
| 332 | } |
| 333 | |
| 334 | /** |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 335 | * Will throw an <code>IllegalArgumentException</code> if called and |
| 336 | * {@link #setIgnoreSettings(boolean ignoreSettings)} has already been called. |
| 337 | * @param disallow true to allow this transfer on metered networks. Default false. |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 338 | * |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 339 | */ |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 340 | public Builder setDisallowMetered(boolean disallow) { |
| 341 | if (mIgnoreSettings && disallow) { |
| 342 | throw new IllegalArgumentException("setDisallowMetered(true) after having" |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 343 | + " specified that settings are ignored."); |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 344 | } |
| 345 | mDisallowMetered = disallow; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 346 | return this; |
| 347 | } |
| 348 | |
| 349 | /** |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 350 | * Specify whether the sync requires the phone to be plugged in. |
| 351 | * @param requiresCharging true if sync requires the phone to be plugged in. Default false. |
| 352 | */ |
| 353 | public Builder setRequiresCharging(boolean requiresCharging) { |
| 354 | mRequiresCharging = true; |
| 355 | return this; |
| 356 | } |
| 357 | |
| 358 | /** |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 359 | * Specify an authority and account for this transfer. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 360 | * |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 361 | * @param authority A String identifying the content provider to be synced. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 362 | * @param account Account to sync. Can be null unless this is a periodic |
| 363 | * sync, for which verification by the ContentResolver will |
| 364 | * fail. If a sync is performed without an account, the |
| 365 | */ |
| 366 | public Builder setSyncAdapter(Account account, String authority) { |
| 367 | if (mSyncTarget != SYNC_TARGET_UNKNOWN) { |
| 368 | throw new IllegalArgumentException("Sync target has already been defined."); |
| 369 | } |
Matthew Williams | 632515b | 2013-10-10 15:51:00 -0700 | [diff] [blame] | 370 | if (authority != null && authority.length() == 0) { |
| 371 | throw new IllegalArgumentException("Authority must be non-empty"); |
| 372 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 373 | mSyncTarget = SYNC_TARGET_ADAPTER; |
| 374 | mAccount = account; |
| 375 | mAuthority = authority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 376 | return this; |
| 377 | } |
| 378 | |
| 379 | /** |
| 380 | * Developer-provided extras handed back when sync actually occurs. This bundle is copied |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 381 | * into the SyncRequest returned by {@link #build()}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 382 | * |
| 383 | * Example: |
| 384 | * <pre> |
| 385 | * String[] syncItems = {"dog", "cat", "frog", "child"}; |
| 386 | * SyncRequest.Builder builder = |
| 387 | * new SyncRequest.Builder() |
| 388 | * .setSyncAdapter(dummyAccount, dummyProvider) |
Russ Schnapp | c43a6bb | 2014-05-07 12:56:13 -0700 | [diff] [blame] | 389 | * .syncOnce(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 390 | * |
| 391 | * for (String syncData : syncItems) { |
| 392 | * Bundle extras = new Bundle(); |
| 393 | * extras.setString("data", syncData); |
| 394 | * builder.setExtras(extras); |
| 395 | * ContentResolver.sync(builder.build()); // Each sync() request creates a unique sync. |
| 396 | * } |
| 397 | * </pre> |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 398 | * Only values of the following types may be used in the extras bundle: |
| 399 | * <ul> |
| 400 | * <li>Integer</li> |
| 401 | * <li>Long</li> |
| 402 | * <li>Boolean</li> |
| 403 | * <li>Float</li> |
| 404 | * <li>Double</li> |
| 405 | * <li>String</li> |
| 406 | * <li>Account</li> |
| 407 | * <li>null</li> |
| 408 | * </ul> |
| 409 | * If any data is present in the bundle not of this type, build() will |
| 410 | * throw a runtime exception. |
| 411 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 412 | * @param bundle extras bundle to set. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 413 | */ |
| 414 | public Builder setExtras(Bundle bundle) { |
| 415 | mCustomExtras = bundle; |
| 416 | return this; |
| 417 | } |
| 418 | |
| 419 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 420 | * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 421 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 422 | * A one-off sync operation that fails will be retried with exponential back-off unless |
| 423 | * this is set to false. Not valid for periodic sync and will throw an |
| 424 | * <code>IllegalArgumentException</code> in build(). |
| 425 | * |
| 426 | * @param noRetry true to not retry a failed sync. Default false. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 427 | */ |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 428 | public Builder setNoRetry(boolean noRetry) { |
| 429 | mNoRetry = noRetry; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 430 | return this; |
| 431 | } |
| 432 | |
| 433 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 434 | * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}. |
| 435 | * |
| 436 | * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in |
| 437 | * {@link #build()}. |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 438 | * <p>Throws <code>IllegalArgumentException</code> if called and |
| 439 | * {@link #setDisallowMetered(boolean)} has been set. |
| 440 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 441 | * |
| 442 | * @param ignoreSettings true to ignore the sync automatically settings. Default false. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 443 | */ |
| 444 | public Builder setIgnoreSettings(boolean ignoreSettings) { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 445 | if (mDisallowMetered && ignoreSettings) { |
| 446 | throw new IllegalArgumentException("setIgnoreSettings(true) after having specified" |
| 447 | + " sync settings with this builder."); |
| 448 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 449 | mIgnoreSettings = ignoreSettings; |
| 450 | return this; |
| 451 | } |
| 452 | |
| 453 | /** |
Ying Wang | 8cf4e13 | 2013-07-24 20:47:19 -0700 | [diff] [blame] | 454 | * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 455 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 456 | * Ignoring back-off will force the sync scheduling process to ignore any back-off that was |
| 457 | * the result of a failed sync, as well as to invalidate any {@link SyncResult#delayUntil} |
| 458 | * value that may have been set by the adapter. Successive failures will not honor this |
| 459 | * flag. Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> |
| 460 | * in {@link #build()}. |
| 461 | * |
| 462 | * @param ignoreBackoff ignore back off settings. Default false. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 463 | */ |
| 464 | public Builder setIgnoreBackoff(boolean ignoreBackoff) { |
| 465 | mIgnoreBackoff = ignoreBackoff; |
| 466 | return this; |
| 467 | } |
| 468 | |
| 469 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 470 | * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_MANUAL}. |
| 471 | * |
| 472 | * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in |
| 473 | * {@link #build()}. |
| 474 | * |
| 475 | * @param isManual User-initiated sync or not. Default false. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 476 | */ |
| 477 | public Builder setManual(boolean isManual) { |
| 478 | mIsManual = isManual; |
| 479 | return this; |
| 480 | } |
| 481 | |
| 482 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 483 | * An expedited sync runs immediately and can preempt other non-expedited running syncs. |
| 484 | * |
| 485 | * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in |
| 486 | * {@link #build()}. |
| 487 | * |
| 488 | * @param expedited whether to run expedited. Default false. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 489 | */ |
| 490 | public Builder setExpedited(boolean expedited) { |
| 491 | mExpedited = expedited; |
| 492 | return this; |
| 493 | } |
| 494 | |
| 495 | /** |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 496 | * Performs validation over the request and throws the runtime exception |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 497 | * <code>IllegalArgumentException</code> if this validation fails. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 498 | * |
| 499 | * @return a SyncRequest with the information contained within this |
| 500 | * builder. |
| 501 | */ |
| 502 | public SyncRequest build() { |
| 503 | // Validate the extras bundle |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 504 | ContentResolver.validateSyncExtrasBundle(mCustomExtras); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 505 | if (mCustomExtras == null) { |
| 506 | mCustomExtras = new Bundle(); |
| 507 | } |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 508 | // Combine builder extra flags into the config bundle. |
| 509 | mSyncConfigExtras = new Bundle(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 510 | if (mIgnoreBackoff) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 511 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 512 | } |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 513 | if (mDisallowMetered) { |
| 514 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 515 | } |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 516 | if (mRequiresCharging) { |
| 517 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, true); |
| 518 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 519 | if (mIgnoreSettings) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 520 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 521 | } |
| 522 | if (mNoRetry) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 523 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 524 | } |
| 525 | if (mExpedited) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 526 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 527 | } |
| 528 | if (mIsManual) { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 529 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true); |
| 530 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 531 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 532 | if (mSyncType == SYNC_TYPE_PERIODIC) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 533 | // If this is a periodic sync ensure than invalid extras were not set. |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 534 | if (ContentResolver.invalidPeriodicExtras(mCustomExtras) || |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 535 | ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) { |
| 536 | throw new IllegalArgumentException("Illegal extras were set"); |
| 537 | } |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 538 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 539 | // Ensure that a target for the sync has been set. |
| 540 | if (mSyncTarget == SYNC_TARGET_UNKNOWN) { |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 541 | throw new IllegalArgumentException("Must specify an adapter with" + |
| 542 | " setSyncAdapter(Account, String"); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 543 | } |
| 544 | return new SyncRequest(this); |
| 545 | } |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 546 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 547 | } |