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