1 /*
2  * Copyright (C) 2009 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.annotation.Nullable;
20 import android.text.TextUtils;
21 import android.os.Parcelable;
22 import android.os.Parcel;
23 
24 /**
25  * Value type that represents a SyncAdapterType. This object overrides {@link #equals} and
26  * {@link #hashCode}, making it suitable for use as the key of a {@link java.util.Map}
27  */
28 public class SyncAdapterType implements Parcelable {
29     public final String authority;
30     public final String accountType;
31     public final boolean isKey;
32     private final boolean userVisible;
33     private final boolean supportsUploading;
34     private final boolean isAlwaysSyncable;
35     private final boolean allowParallelSyncs;
36     private final String settingsActivity;
37     private final String packageName;
38 
SyncAdapterType(String authority, String accountType, boolean userVisible, boolean supportsUploading)39     public SyncAdapterType(String authority, String accountType, boolean userVisible,
40             boolean supportsUploading) {
41         if (TextUtils.isEmpty(authority)) {
42             throw new IllegalArgumentException("the authority must not be empty: " + authority);
43         }
44         if (TextUtils.isEmpty(accountType)) {
45             throw new IllegalArgumentException("the accountType must not be empty: " + accountType);
46         }
47         this.authority = authority;
48         this.accountType = accountType;
49         this.userVisible = userVisible;
50         this.supportsUploading = supportsUploading;
51         this.isAlwaysSyncable = false;
52         this.allowParallelSyncs = false;
53         this.settingsActivity = null;
54         this.isKey = false;
55         this.packageName = null;
56     }
57 
58     /** @hide */
SyncAdapterType(String authority, String accountType, boolean userVisible, boolean supportsUploading, boolean isAlwaysSyncable, boolean allowParallelSyncs, String settingsActivity, String packageName)59     public SyncAdapterType(String authority, String accountType, boolean userVisible,
60             boolean supportsUploading,
61             boolean isAlwaysSyncable,
62             boolean allowParallelSyncs,
63             String settingsActivity,
64             String packageName) {
65         if (TextUtils.isEmpty(authority)) {
66             throw new IllegalArgumentException("the authority must not be empty: " + authority);
67         }
68         if (TextUtils.isEmpty(accountType)) {
69             throw new IllegalArgumentException("the accountType must not be empty: " + accountType);
70         }
71         this.authority = authority;
72         this.accountType = accountType;
73         this.userVisible = userVisible;
74         this.supportsUploading = supportsUploading;
75         this.isAlwaysSyncable = isAlwaysSyncable;
76         this.allowParallelSyncs = allowParallelSyncs;
77         this.settingsActivity = settingsActivity;
78         this.isKey = false;
79         this.packageName = packageName;
80     }
81 
SyncAdapterType(String authority, String accountType)82     private SyncAdapterType(String authority, String accountType) {
83         if (TextUtils.isEmpty(authority)) {
84             throw new IllegalArgumentException("the authority must not be empty: " + authority);
85         }
86         if (TextUtils.isEmpty(accountType)) {
87             throw new IllegalArgumentException("the accountType must not be empty: " + accountType);
88         }
89         this.authority = authority;
90         this.accountType = accountType;
91         this.userVisible = true;
92         this.supportsUploading = true;
93         this.isAlwaysSyncable = false;
94         this.allowParallelSyncs = false;
95         this.settingsActivity = null;
96         this.isKey = true;
97         this.packageName = null;
98     }
99 
supportsUploading()100     public boolean supportsUploading() {
101         if (isKey) {
102             throw new IllegalStateException(
103                     "this method is not allowed to be called when this is a key");
104         }
105         return supportsUploading;
106     }
107 
isUserVisible()108     public boolean isUserVisible() {
109         if (isKey) {
110             throw new IllegalStateException(
111                     "this method is not allowed to be called when this is a key");
112         }
113         return userVisible;
114     }
115 
116     /**
117      * @return True if this SyncAdapter supports syncing multiple accounts simultaneously.
118      * If false then the SyncManager will take care to only start one sync at a time
119      * using this SyncAdapter.
120      */
allowParallelSyncs()121     public boolean allowParallelSyncs() {
122         if (isKey) {
123             throw new IllegalStateException(
124                     "this method is not allowed to be called when this is a key");
125         }
126         return allowParallelSyncs;
127     }
128 
129     /**
130      * If true then the SyncManager will never issue an initialization sync to the SyncAdapter
131      * and will instead automatically call
132      * {@link ContentResolver#setIsSyncable(android.accounts.Account, String, int)} with a
133      * value of 1 for each account and provider that this sync adapter supports.
134      * @return true if the SyncAdapter does not require initialization and if it is ok for the
135      * SyncAdapter to treat it as syncable automatically.
136      */
isAlwaysSyncable()137     public boolean isAlwaysSyncable() {
138         if (isKey) {
139             throw new IllegalStateException(
140                     "this method is not allowed to be called when this is a key");
141         }
142         return isAlwaysSyncable;
143     }
144 
145     /**
146      * @return The activity to use to invoke this SyncAdapter's settings activity.
147      * May be null.
148      */
getSettingsActivity()149     public String getSettingsActivity() {
150         if (isKey) {
151             throw new IllegalStateException(
152                     "this method is not allowed to be called when this is a key");
153         }
154         return settingsActivity;
155     }
156 
157     /**
158      * The package hosting the sync adapter.
159      * @return The package name.
160      *
161      * @hide
162      */
getPackageName()163     public @Nullable String getPackageName() {
164         return packageName;
165     }
166 
newKey(String authority, String accountType)167     public static SyncAdapterType newKey(String authority, String accountType) {
168         return new SyncAdapterType(authority, accountType);
169     }
170 
equals(Object o)171     public boolean equals(Object o) {
172         if (o == this) return true;
173         if (!(o instanceof SyncAdapterType)) return false;
174         final SyncAdapterType other = (SyncAdapterType)o;
175         // don't include userVisible or supportsUploading in the equality check
176         return authority.equals(other.authority) && accountType.equals(other.accountType);
177     }
178 
hashCode()179     public int hashCode() {
180         int result = 17;
181         result = 31 * result + authority.hashCode();
182         result = 31 * result + accountType.hashCode();
183         // don't include userVisible or supportsUploading  the hash
184         return result;
185     }
186 
toString()187     public String toString() {
188         if (isKey) {
189             return "SyncAdapterType Key {name=" + authority
190                     + ", type=" + accountType
191                     + "}";
192         } else {
193             return "SyncAdapterType {name=" + authority
194                     + ", type=" + accountType
195                     + ", userVisible=" + userVisible
196                     + ", supportsUploading=" + supportsUploading
197                     + ", isAlwaysSyncable=" + isAlwaysSyncable
198                     + ", allowParallelSyncs=" + allowParallelSyncs
199                     + ", settingsActivity=" + settingsActivity
200                     + ", packageName=" + packageName
201                     + "}";
202         }
203     }
204 
describeContents()205     public int describeContents() {
206         return 0;
207     }
208 
writeToParcel(Parcel dest, int flags)209     public void writeToParcel(Parcel dest, int flags) {
210         if (isKey) {
211             throw new IllegalStateException("keys aren't parcelable");
212         }
213 
214         dest.writeString(authority);
215         dest.writeString(accountType);
216         dest.writeInt(userVisible ? 1 : 0);
217         dest.writeInt(supportsUploading ? 1 : 0);
218         dest.writeInt(isAlwaysSyncable ? 1 : 0);
219         dest.writeInt(allowParallelSyncs ? 1 : 0);
220         dest.writeString(settingsActivity);
221         dest.writeString(packageName);
222     }
223 
SyncAdapterType(Parcel source)224     public SyncAdapterType(Parcel source) {
225         this(
226                 source.readString(),
227                 source.readString(),
228                 source.readInt() != 0,
229                 source.readInt() != 0,
230                 source.readInt() != 0,
231                 source.readInt() != 0,
232                 source.readString(),
233                 source.readString());
234     }
235 
236     public static final Creator<SyncAdapterType> CREATOR = new Creator<SyncAdapterType>() {
237         public SyncAdapterType createFromParcel(Parcel source) {
238             return new SyncAdapterType(source);
239         }
240 
241         public SyncAdapterType[] newArray(int size) {
242             return new SyncAdapterType[size];
243         }
244     };
245 }
246