SyncRequest.java revision 8cf4e13e466bf7a9dc9a3bee73c8a74f3fc4bb85
1c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav/*
2c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * Copyright (C) 2013 The Android Open Source Project
3c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav *
4c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * Licensed under the Apache License, Version 2.0 (the "License");
5c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * you may not use this file except in compliance with the License.
6c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * You may obtain a copy of the License at
7c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav *
8c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav *      http://www.apache.org/licenses/LICENSE-2.0
9c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav *
10c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * Unless required by applicable law or agreed to in writing, software
11c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * distributed under the License is distributed on an "AS IS" BASIS,
12c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * See the License for the specific language governing permissions and
14c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * limitations under the License.
15c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav */
16c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
17c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslavpackage android.content;
18c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
19c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslavimport android.accounts.Account;
20c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslavimport android.os.Bundle;
21c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslavimport android.os.Parcel;
2200f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkeyimport android.os.Parcelable;
238c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganovimport android.util.Pair;
24c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
25c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslavpublic class SyncRequest implements Parcelable {
268c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov    private static final String TAG = "SyncRequest";
27c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** Account to pass to the sync adapter. Can be null. */
28c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final Account mAccountToSync;
298c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov    /** Authority string that corresponds to a ContentProvider. */
30c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final String mAuthority;
31c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** {@link SyncService} identifier. */
32c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final ComponentName mComponentInfo;
33c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** Bundle containing user info as well as sync settings. */
34c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final Bundle mExtras;
35c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** Allow this sync request on metered networks. */
36c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final boolean mAllowMetered;
37c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
38c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Anticipated upload size in bytes.
39c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * TODO: Not yet used - we put this information into the bundle for simplicity.
40c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
41c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final long mTxBytes;
42c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
43c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Anticipated download size in bytes.
44c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * TODO: Not yet used - we put this information into the bundle.
45c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
46c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final long mRxBytes;
47c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
48c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Amount of time before {@link mSyncRunTimeSecs} from which the sync may optionally be
49c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * started.
50c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
51c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final long mSyncFlexTimeSecs;
52b3f22b48bbd4e4816212e596e3cb612457d48fe5Svet Ganov    /**
53b3f22b48bbd4e4816212e596e3cb612457d48fe5Svet Ganov     * Specifies a point in the future at which the sync must have been scheduled to run.
54b3f22b48bbd4e4816212e596e3cb612457d48fe5Svet Ganov     */
55c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final long mSyncRunTimeSecs;
56b3f22b48bbd4e4816212e596e3cb612457d48fe5Svet Ganov    /** Periodic versus one-off. */
57c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final boolean mIsPeriodic;
58c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** Service versus provider. */
59b3f22b48bbd4e4816212e596e3cb612457d48fe5Svet Ganov    private final boolean mIsAuthority;
60c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** Sync should be run in lieu of other syncs. */
61c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    private final boolean mIsExpedited;
62c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
63c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
64c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
65c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * @return whether this sync is periodic or one-time. A Sync Request must be
66c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     *         either one of these or an InvalidStateException will be thrown in
67c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     *         Builder.build().
68c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
69c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public boolean isPeriodic() {
70c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mIsPeriodic;
71c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
72c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
73c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public boolean isExpedited() {
74c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mIsExpedited;
75c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
76c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
77c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
78c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
79c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * @return true if this sync uses an account/authority pair, or false if
80c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     *         this is an anonymous sync bound to an @link AnonymousSyncService.
81c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
82c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public boolean hasAuthority() {
83c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mIsAuthority;
84c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
85c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
86c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
87c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
88c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Throws a runtime IllegalArgumentException if this function is called for an
89c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * anonymous sync.
90c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     *
91c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * @return (Account, Provider) for this SyncRequest.
924f2dcfd48010a338dc9a2f5870ed12b382c30cd7Svet Ganov     */
934f2dcfd48010a338dc9a2f5870ed12b382c30cd7Svet Ganov    public Pair<Account, String> getProviderInfo() {
944f2dcfd48010a338dc9a2f5870ed12b382c30cd7Svet Ganov        if (!hasAuthority()) {
95c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            throw new IllegalArgumentException("Cannot getProviderInfo() for an anonymous sync.");
96c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
97c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return Pair.create(mAccountToSync, mAuthority);
98c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
99c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
100c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
101c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
102c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Throws a runtime IllegalArgumentException if this function is called for a
103c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * SyncRequest that is bound to an account/provider.
104c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     *
105c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * @return ComponentName for the service that this sync will bind to.
106c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
107c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public ComponentName getService() {
108c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        if (hasAuthority()) {
109c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            throw new IllegalArgumentException(
110c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                    "Cannot getAnonymousService() for a sync that has specified a provider.");
111c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
112c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mComponentInfo;
113c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
114c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
115c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
116c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
117c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Retrieve bundle for this SyncRequest. Will not be null.
118c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
119c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public Bundle getBundle() {
120c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mExtras;
121c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
122c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
123c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
124c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
125c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * @return the earliest point in time that this sync can be scheduled.
126c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
127c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public long getSyncFlexTime() {
128c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mSyncFlexTimeSecs;
129c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
130c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
131c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * {@hide}
132c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * @return the last point in time at which this sync must scheduled.
133c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
134c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public long getSyncRunTime() {
135c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return mSyncRunTimeSecs;
136c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
137c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
138c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public static final Creator<SyncRequest> CREATOR = new Creator<SyncRequest>() {
139c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
140c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        @Override
141c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public SyncRequest createFromParcel(Parcel in) {
142c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return new SyncRequest(in);
143c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
144c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
145c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        @Override
1468c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public SyncRequest[] newArray(int size) {
147c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return new SyncRequest[size];
148c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
1498c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov    };
150c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
151c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    @Override
152c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public int describeContents() {
153c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        return 0;
154c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
1558c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
156d5752bdc8fd39d4f0a508f9088c538e30e73044aSvet Ganov    @Override
157d5752bdc8fd39d4f0a508f9088c538e30e73044aSvet Ganov    public void writeToParcel(Parcel parcel, int flags) {
158d5752bdc8fd39d4f0a508f9088c538e30e73044aSvet Ganov        parcel.writeBundle(mExtras);
159c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeLong(mSyncFlexTimeSecs);
160c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeLong(mSyncRunTimeSecs);
161c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeInt((mIsPeriodic ? 1 : 0));
162c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeInt((mAllowMetered ? 1 : 0));
1638c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        parcel.writeLong(mTxBytes);
164c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeLong(mRxBytes);
165c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeInt((mIsAuthority ? 1 : 0));
166c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        parcel.writeInt((mIsExpedited? 1 : 0));
167c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        if (mIsAuthority) {
168c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            parcel.writeParcelable(mAccountToSync, flags);
169c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            parcel.writeString(mAuthority);
170c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        } else {
171c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            parcel.writeParcelable(mComponentInfo, flags);
1728c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        }
173d5752bdc8fd39d4f0a508f9088c538e30e73044aSvet Ganov    }
174d5752bdc8fd39d4f0a508f9088c538e30e73044aSvet Ganov
175d5752bdc8fd39d4f0a508f9088c538e30e73044aSvet Ganov    private SyncRequest(Parcel in) {
176c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mExtras = in.readBundle();
177c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mSyncFlexTimeSecs = in.readLong();
178c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mSyncRunTimeSecs = in.readLong();
179c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mIsPeriodic = (in.readInt() != 0);
180c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mAllowMetered = (in.readInt() != 0);
181c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mTxBytes = in.readLong();
182c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mRxBytes = in.readLong();
183c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mIsAuthority = (in.readInt() != 0);
184c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mIsExpedited = (in.readInt() != 0);
185c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        if (mIsAuthority) {
186c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mComponentInfo = null;
187c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mAccountToSync = in.readParcelable(null);
1888c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mAuthority = in.readString();
189c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        } else {
190c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mComponentInfo = in.readParcelable(null);
191c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mAccountToSync = null;
192c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mAuthority = null;
193c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
194c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
195c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
196c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /** {@hide} Protected ctor to instantiate anonymous SyncRequest. */
197c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    protected SyncRequest(SyncRequest.Builder b) {
198c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mSyncFlexTimeSecs = b.mSyncFlexTimeSecs;
199c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mSyncRunTimeSecs = b.mSyncRunTimeSecs;
200c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mAccountToSync = b.mAccount;
201c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mAuthority = b.mAuthority;
202c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mComponentInfo = b.mComponentName;
203c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
204c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
205c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mIsExpedited = b.mExpedited;
206c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mExtras = new Bundle(b.mCustomExtras);
207c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mAllowMetered = b.mAllowMetered;
208c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mTxBytes = b.mTxBytes;
209c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        mRxBytes = b.mRxBytes;
210c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
211c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
212c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    /**
213c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * Builder class for a @link SyncRequest. As you build your SyncRequest this class will also
214c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     * perform validation.
215c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav     */
216c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    public static class Builder {
217c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Unknown sync type. */
2188c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private static final int SYNC_TYPE_UNKNOWN = 0;
219c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Specify that this is a periodic sync. */
220c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private static final int SYNC_TYPE_PERIODIC = 1;
221c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Specify that this is a one-time sync. */
2228c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private static final int SYNC_TYPE_ONCE = 2;
2238c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Unknown sync target. */
224c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private static final int SYNC_TARGET_UNKNOWN = 0;
2258c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Specify that this is an anonymous sync. */
226c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private static final int SYNC_TARGET_SERVICE = 1;
227c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Specify that this is a sync with a provider. */
2288c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private static final int SYNC_TARGET_ADAPTER = 2;
2298c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
2308c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Earliest point of displacement into the future at which this sync can
2318c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * occur.
2328c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
233c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private long mSyncFlexTimeSecs;
234c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Displacement into the future at which this sync must occur. */
2358c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private long mSyncRunTimeSecs;
2368c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
2378c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Sync configuration information - custom user data explicitly provided by the developer.
2388c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * This data is handed over to the sync operation.
2398c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2408c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private Bundle mCustomExtras;
2418c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
2428c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Sync system configuration -  used to store system sync configuration. Corresponds to
2438c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * ContentResolver.SYNC_EXTRAS_* flags.
2448c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * TODO: Use this instead of dumping into one bundle. Need to decide if these flags should
2458c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * discriminate between equivalent syncs.
2468c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2478c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private Bundle mSyncConfigExtras;
2488c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Expected upload transfer in bytes. */
2498c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private long mTxBytes = -1L;
2508c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Expected download transfer in bytes. */
2518c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private long mRxBytes = -1L;
2528c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Whether or not this sync can occur on metered networks. Default false. */
253c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private boolean mAllowMetered;
254c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Priority of this sync relative to others from calling app [-2, 2]. Default 0. */
255c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private int mPriority = 0;
2568c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
257c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Whether this builder is building a periodic sync, or a one-time sync.
2588c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2598c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private int mSyncType = SYNC_TYPE_UNKNOWN;
2608c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Whether this will go to a sync adapter or to a sync service. */
2618c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private int mSyncTarget = SYNC_TARGET_UNKNOWN;
2628c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /** Whether this is a user-activated sync. */
2638c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private boolean mIsManual;
2648c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
2658c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Whether to retry this one-time sync if the sync fails. Not valid for
2668c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * periodic syncs. See {@link ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY}.
2678c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2688c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private boolean mNoRetry;
269c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
2708c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Whether to respect back-off for this one-time sync. Not valid for
271c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * periodic syncs. See
2728c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * {@link android.content.ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF};
2738c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2748c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private boolean mIgnoreBackoff;
275c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
276c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** Ignore sync system settings and perform sync anyway. */
277c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private boolean mIgnoreSettings;
2788c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
279c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** This sync will run in preference to other non-expedited syncs. */
2808c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private boolean mExpedited;
281c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
2828c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
2838c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * The @link android.content.AnonymousSyncService component that
284c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * contains the sync logic if this is a provider-less sync, otherwise
285c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * null.
286c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
2878c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private ComponentName mComponentName;
288c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
2898c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * The Account object that together with an Authority name define the SyncAdapter (if
2908c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * this sync is bound to a provider), otherwise null. This gets resolved
2918c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * against a {@link com.android.server.content.SyncStorageEngine}.
2928c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2938c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private Account mAccount;
2948c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
2958c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * The Authority name that together with an Account define the SyncAdapter (if
2968c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * this sync is bound to a provider), otherwise null. This gets resolved
2978c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * against a {@link com.android.server.content.SyncStorageEngine}.
2988c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
2998c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        private String mAuthority;
3008c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
3018c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public Builder() {
302c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
3038c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
3048c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
3058c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Developer can define timing constraints for this one-shot request.
3068c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * These values are elapsed real-time.
3078c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
3088c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @param whenSeconds The time in seconds at which you want this
3098c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *            sync to occur.
3108c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @param beforeSeconds The amount of time in advance of whenSeconds that this
3118c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *               sync may be permitted to occur. This is rounded up to a minimum of 5
3128c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *               seconds, for any sync for which whenSeconds > 5.
3138c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
3148c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Example
3158c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * <pre>
3168c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     Perform an immediate sync.
3178c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce(0, 0);
3188c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     That is, a sync 0 seconds from now with 0 seconds of flex.
3198c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
3208c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     Perform a sync in exactly 5 minutes.
3218c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     SyncRequest.Builder builder =
3228c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *       new SyncRequest.Builder().syncOnce(5 * MIN_IN_SECS, 0);
3238c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
3248c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     Perform a sync in 5 minutes, with one minute of leeway (between 4 and 5 minutes from
3258c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     now).
3268c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *     SyncRequest.Builder builder =
3278c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *       new SyncRequest.Builder().syncOnce(5 * MIN_IN_SECS, 1 * MIN_IN_SECS);
3288c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * </pre>
3298c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
3308c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public Builder syncOnce(long whenSeconds, long beforeSeconds) {
3318c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mSyncType != SYNC_TYPE_UNKNOWN) {
3328c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                throw new IllegalArgumentException("Sync type has already been defined.");
3338c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
3348c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mSyncType = SYNC_TYPE_ONCE;
3358c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            setupInterval(whenSeconds, beforeSeconds);
3368c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            return this;
3378c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        }
3388c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
3398c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
3408c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
3418c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Syncs are identified by target {@link SyncService}/{@link android.provider} and by the
3428c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * contents of the extras bundle.
3438c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * You cannot reuse the same builder for one-time syncs after having specified a periodic
3448c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * sync (by calling this function). If you do, an {@link IllegalArgumentException} will be
345c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * thrown.
346c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
3470bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * Example usage.
3480bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *
3490bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * <pre>
3500bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *     Request a periodic sync every 5 hours with 20 minutes of flex.
3510bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *     SyncRequest.Builder builder =
3520bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *         (new SyncRequest.Builder()).syncPeriodic(5 * HOUR_IN_SECS, 20 * MIN_IN_SECS);
3530bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *
3540bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *     Schedule a periodic sync every hour at any point in time during that hour.
3550bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *     SyncRequest.Builder builder =
3560bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *         (new SyncRequest.Builder()).syncPeriodic(1 * HOUR_IN_SECS, 1 * HOUR_IN_SECS);
3570bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * </pre>
3580bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         *
3590bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * N.B.: Periodic syncs are not allowed to have any of
3600bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY},
3610bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF},
3620bf8f7cc3982164a9e11ea4a25ed930e466f1dd8Amith Yamasani         * {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS},
363c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * {@link ContentResolver#SYNC_EXTRAS_INITIALIZE},
364c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * {@link ContentResolver#SYNC_EXTRAS_FORCE},
365c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * {@link ContentResolver#SYNC_EXTRAS_EXPEDITED},
366c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * {@link ContentResolver#SYNC_EXTRAS_MANUAL}
367c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * set to true. If any are supplied then an {@link IllegalArgumentException} will
368c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * be thrown.
369c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
370c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * @param pollFrequency the amount of time in seconds that you wish
371c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *            to elapse between periodic syncs.
372c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * @param beforeSeconds the amount of flex time in seconds before
373c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *            {@code pollFrequency} that you permit for the sync to take
374c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *            place. Must be less than {@code pollFrequency}.
375c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
376c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder syncPeriodic(long pollFrequency, long beforeSeconds) {
377c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            if (mSyncType != SYNC_TYPE_UNKNOWN) {
378c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                throw new IllegalArgumentException("Sync type has already been defined.");
379c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            }
380c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mSyncType = SYNC_TYPE_PERIODIC;
381c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            setupInterval(pollFrequency, beforeSeconds);
382c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
383c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
38400f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey
385c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /** {@hide} */
386c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        private void setupInterval(long at, long before) {
387c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            if (before > at) {
388c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                throw new IllegalArgumentException("Specified run time for the sync must be" +
389c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                		" after the specified flex time.");
390c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            }
391c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mSyncRunTimeSecs = at;
392c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mSyncFlexTimeSecs = before;
393c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
394c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
395c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
396c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Developer can provide insight into their payload size; optional. -1 specifies
397c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * unknown, so that you are not restricted to defining both fields.
398c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
399c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * @param rxBytes Bytes expected to be downloaded.
40091edde24ffa5d78df18bf752de88dfe2bc8c4119Jeff Sharkey         * @param txBytes Bytes expected to be uploaded.
401c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
402c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder setTransferSize(long rxBytes, long txBytes) {
40391edde24ffa5d78df18bf752de88dfe2bc8c4119Jeff Sharkey            mRxBytes = rxBytes;
404c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mTxBytes = txBytes;
405c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
406c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
407c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
408c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
409c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * @param allow false to allow this transfer on metered networks.
410c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *            Default true.
411c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
412c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder setAllowMetered(boolean allow) {
413c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mAllowMetered = true;
414c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
415c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
416c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
417c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
418c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Give ourselves a concrete way of binding. Use an explicit
4198c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * authority+account SyncAdapter for this transfer, otherwise we bind
4201b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav         * anonymously to given componentname.
4218c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
4221b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav         * @param authority
4238c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @param account Account to sync. Can be null unless this is a periodic
4248c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *            sync, for which verification by the ContentResolver will
4258c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *            fail. If a sync is performed without an account, the
4268c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
4278c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public Builder setSyncAdapter(Account account, String authority) {
4288c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
4291b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav                throw new IllegalArgumentException("Sync target has already been defined.");
4308c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
4318c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mSyncTarget = SYNC_TARGET_ADAPTER;
4328c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mAccount = account;
4338c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mAuthority = authority;
4348c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mComponentName = null;
4351b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav            return this;
4361b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav        }
4378c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
4381b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav        /**
4391b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav         * Set Service component name for anonymous sync. This is not validated
4401b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav         * until sync time so providing an incorrect component name here will
4418c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * not fail.
4421b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav         *
4438c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @param cname ComponentName to identify your Anonymous service
4448c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
4458c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public Builder setSyncAdapter(ComponentName cname) {
4461b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav            if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
4471b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav                throw new IllegalArgumentException("Sync target has already been defined.");
4481b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav            }
4498c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mSyncTarget = SYNC_TARGET_SERVICE;
4501b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav            mComponentName = cname;
4511b7025f264fd811ab27470867f8e65eeebf092e9Svetoslav            mAccount = null;
452c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mAuthority = null;
453c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
454c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
455c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
456c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
457b3a6defec84ab1d420b049c575cb37b1151e095aSvetoslav         * Developer-provided extras handed back when sync actually occurs. This bundle is copied
458c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * into the SyncRequest returned by build().
459c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
4608c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Example:
461c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <pre>
4628c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *   String[] syncItems = {"dog", "cat", "frog", "child"};
463c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *   SyncRequest.Builder builder =
464c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *     new SyncRequest.Builder()
465c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *       .setSyncAdapter(dummyAccount, dummyProvider)
466c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *       .syncOnce(5 * MINUTES_IN_SECS);
467c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
468c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *   for (String syncData : syncItems) {
469c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *     Bundle extras = new Bundle();
470c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *     extras.setString("data", syncData);
471c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *     builder.setExtras(extras);
472c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *     ContentResolver.sync(builder.build()); // Each sync() request creates a unique sync.
473c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *   }
474c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * </pre>
475c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
476c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Only values of the following types may be used in the extras bundle:
477c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <ul>
478c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>Integer</li>
479c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>Long</li>
480c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>Boolean</li>
481b3a6defec84ab1d420b049c575cb37b1151e095aSvetoslav         * <li>Float</li>
482c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>Double</li>
483c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>String</li>
484c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>Account</li>
485c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * <li>null</li>
4868c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * </ul>
487c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * If any data is present in the bundle not of this type, build() will
488c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * throw a runtime exception.
489c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
4908c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @param bundle
4918c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
492c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder setExtras(Bundle bundle) {
493c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mCustomExtras = bundle;
494c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
495c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
496c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
497c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
498c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}. A
499c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * one-off sync operation that fails will be retried at a later date unless this is
500c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * set to false. Default is true. Not valid for periodic sync and will throw an
501c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * IllegalArgumentException in Builder.build().
502c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *
503c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * @param retry false to not retry a failed sync. Default true.
504c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
505c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder setNoRetry(boolean retry) {
506c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mNoRetry = retry;
507c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
508c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
509c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
510c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
511c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}. Not valid for
512c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * periodic sync and will throw an IllegalArgumentException in
513c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Builder.build(). Default false.
514c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
515c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder setIgnoreSettings(boolean ignoreSettings) {
516c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mIgnoreSettings = ignoreSettings;
517c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            return this;
518c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
5198c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
5208c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
5218c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}.
5228c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
5238c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @param ignoreBackoff
5248c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
5258c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public Builder setIgnoreBackoff(boolean ignoreBackoff) {
5268c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mIgnoreBackoff = ignoreBackoff;
5278c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            return this;
5288c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        }
5298c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
5308c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
5318c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * {@link ContentResolver#SYNC_EXTRAS_MANUAL}. Default false.
5328c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
5338c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public Builder setManual(boolean isManual) {
5348c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mIsManual = isManual;
5358c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            return this;
5368c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        }
5378c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov
5388c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        /**
5398c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * {@link ContentResolver#SYNC_EXTRAS_EXPEDITED} Default false.
5408c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         */
541c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        public Builder setExpedited(boolean expedited) {
54200f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey            mExpedited = expedited;
5438c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            return this;
544c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
54500f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey
54600f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey        /**
547c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Priority of this request among all requests from the calling app.
548c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * Range of [-2,2] similar to {@link android.app.Notification#priority}.
549c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
55000f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey        public Builder setPriority(int priority) {
5518c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (priority < -2 || priority > 2) {
5528c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                throw new IllegalArgumentException("Priority must be within range [-2, 2]");
5538c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
5548c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mPriority = priority;
5558c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            return this;
556c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        }
557c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
558c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        /**
55900f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey         * Performs validation over the request and throws the runtime exception
56000f3904629ef89192e061c1995801ef322fc0bcfJeff Sharkey         * IllegalArgumentException if this validation fails. TODO: Add
561c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * validation of SyncRequest here. 1) Cannot specify both periodic &
562c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         * one-off (fails above). 2) Cannot specify both service and
5638c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * account/provider (fails above).
5648c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         *
5658c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov         * @return a SyncRequest with the information contained within this
566c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         *         builder.
567c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav         */
5688c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        public SyncRequest build() {
5698c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            // Validate the extras bundle
5708c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            try {
571c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                ContentResolver.validateSyncExtrasBundle(mCustomExtras);
572c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            } catch (IllegalArgumentException e) {
5738c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                throw new IllegalArgumentException(e.getMessage());
574c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            }
575c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            if (mCustomExtras == null) {
5768c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                mCustomExtras = new Bundle();
5778c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
578c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            // Combine the builder extra flags into the copy of the bundle.
579c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            if (mIgnoreBackoff) {
580c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                mCustomExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
5818c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
5828c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mAllowMetered) {
583c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                mCustomExtras.putBoolean(ContentResolver.SYNC_EXTRAS_ALLOW_METERED, true);
584c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            }
5858c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mIgnoreSettings) {
5868c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                mCustomExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
5878c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
5888c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mNoRetry) {
5898c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                mCustomExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
5908c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
5918c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mExpedited) {
592c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                mCustomExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
593c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            }
594c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            if (mIsManual) {
595c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                mCustomExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
5968c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
5978c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            // Upload/download expectations.
598c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mCustomExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD, mTxBytes);
599c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            mCustomExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD, mRxBytes);
600c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav            // Priority.
6018c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            mCustomExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
6028c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mSyncType == SYNC_TYPE_PERIODIC) {
603c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                // If this is a periodic sync ensure than invalid extras were
604c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                // not set.
6058c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                if (mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
6068c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                        || mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
607c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                        || mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
6088c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                        || mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
6098c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                        || mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
610c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                        || mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
611c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                        || mCustomExtras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
612c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                    throw new IllegalArgumentException("Illegal extras were set");
613c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav                }
6148c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
6158c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
6168c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
6178c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            // Ensure that a target for the sync has been set.
6188c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
6198c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                throw new IllegalArgumentException("Must specify an adapter with one of"
6208c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                    + "setSyncAdapter(ComponentName) or setSyncAdapter(Account, String");
6218c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            }
6228c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov            return new SyncRequest(this);
6238c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov        }
6248c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov    }
6258c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov}
6268c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov