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 17package android.content; 18 19import android.annotation.Nullable; 20import android.text.TextUtils; 21import android.os.Parcelable; 22import 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 */ 28public 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 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 */ 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 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 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 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 */ 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 */ 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 */ 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 */ 163 public @Nullable String getPackageName() { 164 return packageName; 165 } 166 167 public static SyncAdapterType newKey(String authority, String accountType) { 168 return new SyncAdapterType(authority, accountType); 169 } 170 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 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 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 205 public int describeContents() { 206 return 0; 207 } 208 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 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