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; |
Mathew Inwood | 5c0d354 | 2018-08-14 13:54:31 +0100 | [diff] [blame] | 20 | import android.annotation.UnsupportedAppUsage; |
Mathew Inwood | 8c854f8 | 2018-09-14 12:35:36 +0100 | [diff] [blame] | 21 | import android.os.Build; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 22 | import android.os.Bundle; |
| 23 | import android.os.Parcel; |
| 24 | import android.os.Parcelable; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 25 | |
Matthew Williams | 2368014 | 2014-06-09 20:06:03 -0700 | [diff] [blame] | 26 | /** |
| 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 31 | public class SyncRequest implements Parcelable { |
| 32 | private static final String TAG = "SyncRequest"; |
| 33 | /** Account to pass to the sync adapter. Can be null. */ |
Mathew Inwood | 5c0d354 | 2018-08-14 13:54:31 +0100 | [diff] [blame] | 34 | @UnsupportedAppUsage |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 35 | private final Account mAccountToSync; |
| 36 | /** Authority string that corresponds to a ContentProvider. */ |
Mathew Inwood | 8c854f8 | 2018-09-14 12:35:36 +0100 | [diff] [blame] | 37 | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 38 | private final String mAuthority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 39 | /** Bundle containing user info as well as sync settings. */ |
Mathew Inwood | 8c854f8 | 2018-09-14 12:35:36 +0100 | [diff] [blame] | 40 | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 41 | private final Bundle mExtras; |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 42 | /** Don't allow this sync request on metered networks. */ |
| 43 | private final boolean mDisallowMetered; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 44 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 45 | * 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] | 46 | * 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 Inwood | 5c0d354 | 2018-08-14 13:54:31 +0100 | [diff] [blame] | 52 | @UnsupportedAppUsage |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 53 | private final long mSyncRunTimeSecs; |
| 54 | /** Periodic versus one-off. */ |
Mathew Inwood | 5c0d354 | 2018-08-14 13:54:31 +0100 | [diff] [blame] | 55 | @UnsupportedAppUsage |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 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 | */ |
| 68 | public boolean isPeriodic() { |
| 69 | return mIsPeriodic; |
| 70 | } |
| 71 | |
Matthew Williams | 2368014 | 2014-06-09 20:06:03 -0700 | [diff] [blame] | 72 | /** |
| 73 | * {@hide} |
| 74 | * @return whether this sync is expedited. |
| 75 | */ |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 76 | public boolean isExpedited() { |
| 77 | return mIsExpedited; |
| 78 | } |
| 79 | |
| 80 | /** |
| 81 | * {@hide} |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 82 | * |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 83 | * @return account object for this sync. |
| 84 | * @throws IllegalArgumentException if this function is called for a request that targets a |
| 85 | * sync service. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 86 | */ |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 87 | public Account getAccount() { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 88 | 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 Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 99 | return mAuthority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | /** |
| 103 | * {@hide} |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 104 | * 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 | |
| 125 | public static final Creator<SyncRequest> CREATOR = new Creator<SyncRequest>() { |
| 126 | |
| 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 Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 149 | parcel.writeInt((mDisallowMetered ? 1 : 0)); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 150 | parcel.writeInt((mIsAuthority ? 1 : 0)); |
| 151 | parcel.writeInt((mIsExpedited? 1 : 0)); |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 152 | parcel.writeParcelable(mAccountToSync, flags); |
| 153 | parcel.writeString(mAuthority); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | private SyncRequest(Parcel in) { |
Jeff Sharkey | a04c7a7 | 2016-03-18 12:20:36 -0600 | [diff] [blame] | 157 | mExtras = Bundle.setDefusable(in.readBundle(), true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 158 | mSyncFlexTimeSecs = in.readLong(); |
| 159 | mSyncRunTimeSecs = in.readLong(); |
| 160 | mIsPeriodic = (in.readInt() != 0); |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 161 | mDisallowMetered = (in.readInt() != 0); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 162 | mIsAuthority = (in.readInt() != 0); |
| 163 | mIsExpedited = (in.readInt() != 0); |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 164 | mAccountToSync = in.readParcelable(null); |
| 165 | mAuthority = in.readString(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 166 | } |
| 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 174 | 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 Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 178 | // 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 Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 181 | mDisallowMetered = b.mDisallowMetered; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | /** |
Elliot Waite | 54de774 | 2017-01-11 15:30:35 -0800 | [diff] [blame] | 185 | * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 186 | * 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 197 | /** 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 218 | /** Whether or not this sync can occur on metered networks. Default false. */ |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 219 | private boolean mDisallowMetered; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 220 | /** |
| 221 | * Whether this builder is building a periodic sync, or a one-time sync. |
| 222 | */ |
| 223 | private int mSyncType = SYNC_TYPE_UNKNOWN; |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 224 | /** Whether this will go to a sync adapter. */ |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 225 | 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 Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 230 | * periodic syncs. See {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 231 | */ |
| 232 | private boolean mNoRetry; |
| 233 | /** |
| 234 | * Whether to respect back-off for this one-time sync. Not valid for |
| 235 | * periodic syncs. See |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 236 | * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 237 | */ |
| 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 247 | * 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] | 248 | * this sync is bound to a provider), otherwise null. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 249 | */ |
| 250 | private Account mAccount; |
| 251 | /** |
| 252 | * The Authority name that together with an Account define the SyncAdapter (if |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 253 | * this sync is bound to a provider), otherwise null. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 254 | */ |
| 255 | private String mAuthority; |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 256 | /** |
| 257 | * Whether the sync requires the phone to be plugged in. |
| 258 | */ |
| 259 | private boolean mRequiresCharging; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 260 | |
| 261 | public Builder() { |
| 262 | } |
| 263 | |
| 264 | /** |
Nick Kralevich | 47d2b61 | 2013-10-19 10:43:55 -0700 | [diff] [blame] | 265 | * Request that a sync occur immediately. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 266 | * |
| 267 | * Example |
| 268 | * <pre> |
Nick Kralevich | 69002ae | 2013-10-19 08:43:08 -0700 | [diff] [blame] | 269 | * SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 270 | * </pre> |
| 271 | */ |
Nick Kralevich | 69002ae | 2013-10-19 08:43:08 -0700 | [diff] [blame] | 272 | public Builder syncOnce() { |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 273 | if (mSyncType != SYNC_TYPE_UNKNOWN) { |
| 274 | throw new IllegalArgumentException("Sync type has already been defined."); |
| 275 | } |
| 276 | mSyncType = SYNC_TYPE_ONCE; |
Nick Kralevich | 69002ae | 2013-10-19 08:43:08 -0700 | [diff] [blame] | 277 | setupInterval(0, 0); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 278 | return this; |
| 279 | } |
| 280 | |
| 281 | /** |
| 282 | * 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] | 283 | * Syncs are identified by target {@link android.provider} and by the |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 284 | * contents of the extras bundle. |
| 285 | * 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] | 286 | * sync (by calling this function). If you do, an <code>IllegalArgumentException</code> |
| 287 | * will be thrown. |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 288 | * <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 Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 292 | * |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 293 | * 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 Wang | 8cf4e13 | 2013-07-24 20:47:19 -0700 | [diff] [blame] | 306 | * {@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 Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 313 | * 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] | 314 | * be thrown. |
| 315 | * |
| 316 | * @param pollFrequency the amount of time in seconds that you wish |
Shreyas Basarge | e96c3b7 | 2016-01-29 19:25:51 +0000 | [diff] [blame] | 317 | * 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] | 318 | * @param beforeSeconds the amount of flex time in seconds before |
| 319 | * {@code pollFrequency} that you permit for the sync to take |
Shreyas Basarge | e96c3b7 | 2016-01-29 19:25:51 +0000 | [diff] [blame] | 320 | * place. Must be less than {@code pollFrequency} and greater than |
| 321 | * MAX(5% of {@code pollFrequency}, 5 minutes) |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 322 | */ |
| 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 332 | private void setupInterval(long at, long before) { |
| 333 | if (before > at) { |
| 334 | throw new IllegalArgumentException("Specified run time for the sync must be" + |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 335 | " after the specified flex time."); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 336 | } |
| 337 | mSyncRunTimeSecs = at; |
| 338 | mSyncFlexTimeSecs = before; |
| 339 | } |
| 340 | |
| 341 | /** |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 342 | * 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 Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 345 | * |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 346 | */ |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 347 | public Builder setDisallowMetered(boolean disallow) { |
| 348 | if (mIgnoreSettings && disallow) { |
| 349 | throw new IllegalArgumentException("setDisallowMetered(true) after having" |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 350 | + " specified that settings are ignored."); |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 351 | } |
| 352 | mDisallowMetered = disallow; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 353 | return this; |
| 354 | } |
| 355 | |
| 356 | /** |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 357 | * 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 Basarge | 3a14723 | 2017-02-06 17:46:26 +0000 | [diff] [blame] | 361 | mRequiresCharging = requiresCharging; |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 362 | return this; |
| 363 | } |
| 364 | |
| 365 | /** |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 366 | * Specify an authority and account for this transfer. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 367 | * |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 368 | * @param authority A String identifying the content provider to be synced. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 369 | * @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 Williams | 632515b | 2013-10-10 15:51:00 -0700 | [diff] [blame] | 377 | if (authority != null && authority.length() == 0) { |
| 378 | throw new IllegalArgumentException("Authority must be non-empty"); |
| 379 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 380 | mSyncTarget = SYNC_TARGET_ADAPTER; |
| 381 | mAccount = account; |
| 382 | mAuthority = authority; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 383 | return this; |
| 384 | } |
| 385 | |
| 386 | /** |
| 387 | * 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] | 388 | * into the SyncRequest returned by {@link #build()}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 389 | * |
| 390 | * Example: |
| 391 | * <pre> |
| 392 | * String[] syncItems = {"dog", "cat", "frog", "child"}; |
| 393 | * SyncRequest.Builder builder = |
| 394 | * new SyncRequest.Builder() |
| 395 | * .setSyncAdapter(dummyAccount, dummyProvider) |
Russ Schnapp | c43a6bb | 2014-05-07 12:56:13 -0700 | [diff] [blame] | 396 | * .syncOnce(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 397 | * |
| 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 405 | * 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 Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 419 | * @param bundle extras bundle to set. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 420 | */ |
| 421 | public Builder setExtras(Bundle bundle) { |
| 422 | mCustomExtras = bundle; |
| 423 | return this; |
| 424 | } |
| 425 | |
| 426 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 427 | * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 428 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 429 | * 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 434 | */ |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 435 | public Builder setNoRetry(boolean noRetry) { |
| 436 | mNoRetry = noRetry; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 437 | return this; |
| 438 | } |
| 439 | |
| 440 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 441 | * 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 Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 445 | * <p>Throws <code>IllegalArgumentException</code> if called and |
| 446 | * {@link #setDisallowMetered(boolean)} has been set. |
| 447 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 448 | * |
| 449 | * @param ignoreSettings true to ignore the sync automatically settings. Default false. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 450 | */ |
| 451 | public Builder setIgnoreSettings(boolean ignoreSettings) { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 452 | if (mDisallowMetered && ignoreSettings) { |
| 453 | throw new IllegalArgumentException("setIgnoreSettings(true) after having specified" |
| 454 | + " sync settings with this builder."); |
| 455 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 456 | mIgnoreSettings = ignoreSettings; |
| 457 | return this; |
| 458 | } |
| 459 | |
| 460 | /** |
Ying Wang | 8cf4e13 | 2013-07-24 20:47:19 -0700 | [diff] [blame] | 461 | * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 462 | * |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 463 | * 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 470 | */ |
| 471 | public Builder setIgnoreBackoff(boolean ignoreBackoff) { |
| 472 | mIgnoreBackoff = ignoreBackoff; |
| 473 | return this; |
| 474 | } |
| 475 | |
| 476 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 477 | * 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 483 | */ |
| 484 | public Builder setManual(boolean isManual) { |
| 485 | mIsManual = isManual; |
| 486 | return this; |
| 487 | } |
| 488 | |
| 489 | /** |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 490 | * 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 Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 496 | */ |
| 497 | public Builder setExpedited(boolean expedited) { |
| 498 | mExpedited = expedited; |
| 499 | return this; |
| 500 | } |
| 501 | |
| 502 | /** |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 503 | * Performs validation over the request and throws the runtime exception |
Matthew Williams | c81891c | 2013-07-24 19:09:30 -0700 | [diff] [blame] | 504 | * <code>IllegalArgumentException</code> if this validation fails. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 505 | * |
| 506 | * @return a SyncRequest with the information contained within this |
| 507 | * builder. |
| 508 | */ |
| 509 | public SyncRequest build() { |
| 510 | // Validate the extras bundle |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 511 | ContentResolver.validateSyncExtrasBundle(mCustomExtras); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 512 | if (mCustomExtras == null) { |
| 513 | mCustomExtras = new Bundle(); |
| 514 | } |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 515 | // Combine builder extra flags into the config bundle. |
| 516 | mSyncConfigExtras = new Bundle(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 517 | if (mIgnoreBackoff) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 518 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 519 | } |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 520 | if (mDisallowMetered) { |
| 521 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 522 | } |
Shreyas Basarge | 8c834c0 | 2016-01-07 13:53:16 +0000 | [diff] [blame] | 523 | if (mRequiresCharging) { |
| 524 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_REQUIRE_CHARGING, true); |
| 525 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 526 | if (mIgnoreSettings) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 527 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 528 | } |
| 529 | if (mNoRetry) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 530 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 531 | } |
| 532 | if (mExpedited) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 533 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 534 | } |
| 535 | if (mIsManual) { |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 536 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true); |
| 537 | mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 538 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 539 | if (mSyncType == SYNC_TYPE_PERIODIC) { |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 540 | // 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] | 541 | if (ContentResolver.invalidPeriodicExtras(mCustomExtras) || |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 542 | ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) { |
| 543 | throw new IllegalArgumentException("Illegal extras were set"); |
| 544 | } |
Matthew Williams | 56dbf8f | 2013-07-26 12:56:39 -0700 | [diff] [blame] | 545 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 546 | // Ensure that a target for the sync has been set. |
| 547 | if (mSyncTarget == SYNC_TARGET_UNKNOWN) { |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 548 | throw new IllegalArgumentException("Must specify an adapter with" + |
| 549 | " setSyncAdapter(Account, String"); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 550 | } |
| 551 | return new SyncRequest(this); |
| 552 | } |
Matthew Williams | 64939ae | 2014-06-04 09:25:11 -0700 | [diff] [blame] | 553 | } |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 554 | } |