1273399bf829133a8385332ad43add3c34c889102Chiao Cheng/* 2273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Copyright (C) 2009 The Android Open Source Project 3273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 4273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5273399bf829133a8385332ad43add3c34c889102Chiao Cheng * you may not use this file except in compliance with the License. 6273399bf829133a8385332ad43add3c34c889102Chiao Cheng * You may obtain a copy of the License at 7273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 8273399bf829133a8385332ad43add3c34c889102Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 9273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 10273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Unless required by applicable law or agreed to in writing, software 11273399bf829133a8385332ad43add3c34c889102Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12273399bf829133a8385332ad43add3c34c889102Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13273399bf829133a8385332ad43add3c34c889102Chiao Cheng * See the License for the specific language governing permissions and 14273399bf829133a8385332ad43add3c34c889102Chiao Cheng * limitations under the License. 15273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 16273399bf829133a8385332ad43add3c34c889102Chiao Cheng 17273399bf829133a8385332ad43add3c34c889102Chiao Chengpackage com.android.contacts.common.model.account; 18273399bf829133a8385332ad43add3c34c889102Chiao Cheng 19273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.content.ContentValues; 20273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.content.Context; 21273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.content.pm.PackageManager; 22273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.graphics.drawable.Drawable; 23273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.provider.ContactsContract.CommonDataKinds.Phone; 24273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 25273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.provider.ContactsContract.Contacts; 26273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.provider.ContactsContract.RawContacts; 27273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.view.inputmethod.EditorInfo; 28273399bf829133a8385332ad43add3c34c889102Chiao Chengimport android.widget.EditText; 29273399bf829133a8385332ad43add3c34c889102Chiao Cheng 30273399bf829133a8385332ad43add3c34c889102Chiao Chengimport com.android.contacts.common.R; 31273399bf829133a8385332ad43add3c34c889102Chiao Chengimport com.android.contacts.common.model.dataitem.DataKind; 32273399bf829133a8385332ad43add3c34c889102Chiao Chengimport com.google.common.annotations.VisibleForTesting; 33273399bf829133a8385332ad43add3c34c889102Chiao Chengimport com.google.common.collect.Lists; 34273399bf829133a8385332ad43add3c34c889102Chiao Chengimport com.google.common.collect.Maps; 35273399bf829133a8385332ad43add3c34c889102Chiao Cheng 36273399bf829133a8385332ad43add3c34c889102Chiao Chengimport java.text.Collator; 37273399bf829133a8385332ad43add3c34c889102Chiao Chengimport java.util.ArrayList; 38273399bf829133a8385332ad43add3c34c889102Chiao Chengimport java.util.Collections; 39273399bf829133a8385332ad43add3c34c889102Chiao Chengimport java.util.Comparator; 40273399bf829133a8385332ad43add3c34c889102Chiao Chengimport java.util.HashMap; 41273399bf829133a8385332ad43add3c34c889102Chiao Chengimport java.util.List; 42273399bf829133a8385332ad43add3c34c889102Chiao Cheng 43273399bf829133a8385332ad43add3c34c889102Chiao Cheng/** 44273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Internal structure that represents constraints and styles for a specific data 45273399bf829133a8385332ad43add3c34c889102Chiao Cheng * source, such as the various data types they support, including details on how 46273399bf829133a8385332ad43add3c34c889102Chiao Cheng * those types should be rendered and edited. 47273399bf829133a8385332ad43add3c34c889102Chiao Cheng * <p> 48273399bf829133a8385332ad43add3c34c889102Chiao Cheng * In the future this may be inflated from XML defined by a data source. 49273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 50273399bf829133a8385332ad43add3c34c889102Chiao Chengpublic abstract class AccountType { 51273399bf829133a8385332ad43add3c34c889102Chiao Cheng private static final String TAG = "AccountType"; 52273399bf829133a8385332ad43add3c34c889102Chiao Cheng 53273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 54273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The {@link RawContacts#ACCOUNT_TYPE} these constraints apply to. 55273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 56273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String accountType = null; 57273399bf829133a8385332ad43add3c34c889102Chiao Cheng 58273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 59273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The {@link RawContacts#DATA_SET} these constraints apply to. 60273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 61273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String dataSet = null; 62273399bf829133a8385332ad43add3c34c889102Chiao Cheng 63273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 64273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Package that resources should be loaded from. Will be null for embedded types, in which 65273399bf829133a8385332ad43add3c34c889102Chiao Cheng * case resources are stored in this package itself. 66273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 67273399bf829133a8385332ad43add3c34c889102Chiao Cheng * TODO Clean up {@link #resourcePackageName}, {@link #syncAdapterPackageName} and 68273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #getViewContactNotifyServicePackageName()}. 69273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 70273399bf829133a8385332ad43add3c34c889102Chiao Cheng * There's the following invariants: 71273399bf829133a8385332ad43add3c34c889102Chiao Cheng * - {@link #syncAdapterPackageName} is always set to the actual sync adapter package name. 72273399bf829133a8385332ad43add3c34c889102Chiao Cheng * - {@link #resourcePackageName} too is set to the same value, unless {@link #isEmbedded()}, 73273399bf829133a8385332ad43add3c34c889102Chiao Cheng * in which case it'll be null. 74273399bf829133a8385332ad43add3c34c889102Chiao Cheng * There's an unfortunate exception of {@link FallbackAccountType}. Even though it 75273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #isEmbedded()}, but we set non-null to {@link #resourcePackageName} for unit tests. 76273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 77273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String resourcePackageName; 78273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 79273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The package name for the authenticator (for the embedded types, i.e. Google and Exchange) 80273399bf829133a8385332ad43add3c34c889102Chiao Cheng * or the sync adapter (for external type, including extensions). 81273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 82273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String syncAdapterPackageName; 83273399bf829133a8385332ad43add3c34c889102Chiao Cheng 84273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int titleRes; 85273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int iconRes; 86273399bf829133a8385332ad43add3c34c889102Chiao Cheng 87273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 88273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Set of {@link DataKind} supported by this source. 89273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 90273399bf829133a8385332ad43add3c34c889102Chiao Cheng private ArrayList<DataKind> mKinds = Lists.newArrayList(); 91273399bf829133a8385332ad43add3c34c889102Chiao Cheng 92273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 93273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Lookup map of {@link #mKinds} on {@link DataKind#mimeType}. 94273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 95273399bf829133a8385332ad43add3c34c889102Chiao Cheng private HashMap<String, DataKind> mMimeKinds = Maps.newHashMap(); 96273399bf829133a8385332ad43add3c34c889102Chiao Cheng 97273399bf829133a8385332ad43add3c34c889102Chiao Cheng protected boolean mIsInitialized; 98273399bf829133a8385332ad43add3c34c889102Chiao Cheng 99273399bf829133a8385332ad43add3c34c889102Chiao Cheng protected static class DefinitionException extends Exception { 100273399bf829133a8385332ad43add3c34c889102Chiao Cheng public DefinitionException(String message) { 101273399bf829133a8385332ad43add3c34c889102Chiao Cheng super(message); 102273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 103273399bf829133a8385332ad43add3c34c889102Chiao Cheng 104273399bf829133a8385332ad43add3c34c889102Chiao Cheng public DefinitionException(String message, Exception inner) { 105273399bf829133a8385332ad43add3c34c889102Chiao Cheng super(message, inner); 106273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 107273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 108273399bf829133a8385332ad43add3c34c889102Chiao Cheng 109273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 110273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Whether this account type was able to be fully initialized. This may be false if 111273399bf829133a8385332ad43add3c34c889102Chiao Cheng * (for example) the package name associated with the account type could not be found. 112273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 113273399bf829133a8385332ad43add3c34c889102Chiao Cheng public final boolean isInitialized() { 114273399bf829133a8385332ad43add3c34c889102Chiao Cheng return mIsInitialized; 115273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 116273399bf829133a8385332ad43add3c34c889102Chiao Cheng 117273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 118273399bf829133a8385332ad43add3c34c889102Chiao Cheng * @return Whether this type is an "embedded" type. i.e. any of {@link FallbackAccountType}, 119273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link GoogleAccountType} or {@link ExternalAccountType}. 120273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 121273399bf829133a8385332ad43add3c34c889102Chiao Cheng * If an embedded type cannot be initialized (i.e. if {@link #isInitialized()} returns 122273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@code false}) it's considered critical, and the application will crash. On the other 123273399bf829133a8385332ad43add3c34c889102Chiao Cheng * hand if it's not an embedded type, we just skip loading the type. 124273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 125273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean isEmbedded() { 126273399bf829133a8385332ad43add3c34c889102Chiao Cheng return true; 127273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 128273399bf829133a8385332ad43add3c34c889102Chiao Cheng 129273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean isExtension() { 130273399bf829133a8385332ad43add3c34c889102Chiao Cheng return false; 131273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 132273399bf829133a8385332ad43add3c34c889102Chiao Cheng 133273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 134273399bf829133a8385332ad43add3c34c889102Chiao Cheng * @return True if contacts can be created and edited using this app. If false, 135273399bf829133a8385332ad43add3c34c889102Chiao Cheng * there could still be an external editor as provided by 136273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #getEditContactActivityClassName()} or {@link #getCreateContactActivityClassName()} 137273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 138273399bf829133a8385332ad43add3c34c889102Chiao Cheng public abstract boolean areContactsWritable(); 139273399bf829133a8385332ad43add3c34c889102Chiao Cheng 140273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 141273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns an optional custom edit activity. 142273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 143273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Only makes sense for non-embedded account types. 144273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The activity class should reside in the sync adapter package as determined by 145273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #syncAdapterPackageName}. 146273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 147273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getEditContactActivityClassName() { 148273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 149273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 150273399bf829133a8385332ad43add3c34c889102Chiao Cheng 151273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 152273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns an optional custom new contact activity. 153273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 154273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Only makes sense for non-embedded account types. 155273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The activity class should reside in the sync adapter package as determined by 156273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #syncAdapterPackageName}. 157273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 158273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getCreateContactActivityClassName() { 159273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 160273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 161273399bf829133a8385332ad43add3c34c889102Chiao Cheng 162273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 163273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns an optional custom invite contact activity. 164273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 165273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Only makes sense for non-embedded account types. 166273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The activity class should reside in the sync adapter package as determined by 167273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #syncAdapterPackageName}. 168273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 169273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getInviteContactActivityClassName() { 170273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 171273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 172273399bf829133a8385332ad43add3c34c889102Chiao Cheng 173273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 174273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns an optional service that can be launched whenever a contact is being looked at. 175273399bf829133a8385332ad43add3c34c889102Chiao Cheng * This allows the sync adapter to provide more up-to-date information. 176273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 177273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The service class should reside in the sync adapter package as determined by 178273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link #getViewContactNotifyServicePackageName()}. 179273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 180273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getViewContactNotifyServiceClassName() { 181273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 182273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 183273399bf829133a8385332ad43add3c34c889102Chiao Cheng 184273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 185273399bf829133a8385332ad43add3c34c889102Chiao Cheng * TODO This is way too hacky should be removed. 186273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 187273399bf829133a8385332ad43add3c34c889102Chiao Cheng * This is introduced for {@link GoogleAccountType} where {@link #syncAdapterPackageName} 188273399bf829133a8385332ad43add3c34c889102Chiao Cheng * is the authenticator package name but the notification service is in the sync adapter 189273399bf829133a8385332ad43add3c34c889102Chiao Cheng * package. See {@link #resourcePackageName} -- we should clean up those. 190273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 191273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getViewContactNotifyServicePackageName() { 192273399bf829133a8385332ad43add3c34c889102Chiao Cheng return syncAdapterPackageName; 193273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 194273399bf829133a8385332ad43add3c34c889102Chiao Cheng 195273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** Returns an optional Activity string that can be used to view the group. */ 196273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getViewGroupActivity() { 197273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 198273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 199273399bf829133a8385332ad43add3c34c889102Chiao Cheng 200273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** Returns an optional Activity string that can be used to view the stream item. */ 201273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getViewStreamItemActivity() { 202273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 203273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 204273399bf829133a8385332ad43add3c34c889102Chiao Cheng 205273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** Returns an optional Activity string that can be used to view the stream item photo. */ 206273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String getViewStreamItemPhotoActivity() { 207273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 208273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 209273399bf829133a8385332ad43add3c34c889102Chiao Cheng 210273399bf829133a8385332ad43add3c34c889102Chiao Cheng public CharSequence getDisplayLabel(Context context) { 211273399bf829133a8385332ad43add3c34c889102Chiao Cheng // Note this resource is defined in the sync adapter package, not resourcePackageName. 212273399bf829133a8385332ad43add3c34c889102Chiao Cheng return getResourceText(context, syncAdapterPackageName, titleRes, accountType); 213273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 214273399bf829133a8385332ad43add3c34c889102Chiao Cheng 215273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 216273399bf829133a8385332ad43add3c34c889102Chiao Cheng * @return resource ID for the "invite contact" action label, or -1 if not defined. 217273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 218273399bf829133a8385332ad43add3c34c889102Chiao Cheng protected int getInviteContactActionResId() { 219273399bf829133a8385332ad43add3c34c889102Chiao Cheng return -1; 220273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 221273399bf829133a8385332ad43add3c34c889102Chiao Cheng 222273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 223273399bf829133a8385332ad43add3c34c889102Chiao Cheng * @return resource ID for the "view group" label, or -1 if not defined. 224273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 225273399bf829133a8385332ad43add3c34c889102Chiao Cheng protected int getViewGroupLabelResId() { 226273399bf829133a8385332ad43add3c34c889102Chiao Cheng return -1; 227273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 228273399bf829133a8385332ad43add3c34c889102Chiao Cheng 229273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 230273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns {@link AccountTypeWithDataSet} for this type. 231273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 232273399bf829133a8385332ad43add3c34c889102Chiao Cheng public AccountTypeWithDataSet getAccountTypeAndDataSet() { 233273399bf829133a8385332ad43add3c34c889102Chiao Cheng return AccountTypeWithDataSet.get(accountType, dataSet); 234273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 235273399bf829133a8385332ad43add3c34c889102Chiao Cheng 236273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 237273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns a list of additional package names that should be inspected as additional 238273399bf829133a8385332ad43add3c34c889102Chiao Cheng * external account types. This allows for a primary account type to indicate other packages 239273399bf829133a8385332ad43add3c34c889102Chiao Cheng * that may not be sync adapters but which still provide contact data, perhaps under a 240273399bf829133a8385332ad43add3c34c889102Chiao Cheng * separate data set within the account. 241273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 242273399bf829133a8385332ad43add3c34c889102Chiao Cheng public List<String> getExtensionPackageNames() { 243273399bf829133a8385332ad43add3c34c889102Chiao Cheng return new ArrayList<String>(); 244273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 245273399bf829133a8385332ad43add3c34c889102Chiao Cheng 246273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 247273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns an optional custom label for the "invite contact" action, which will be shown on 248273399bf829133a8385332ad43add3c34c889102Chiao Cheng * the contact card. (If not defined, returns null.) 249273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 250273399bf829133a8385332ad43add3c34c889102Chiao Cheng public CharSequence getInviteContactActionLabel(Context context) { 251273399bf829133a8385332ad43add3c34c889102Chiao Cheng // Note this resource is defined in the sync adapter package, not resourcePackageName. 252273399bf829133a8385332ad43add3c34c889102Chiao Cheng return getResourceText(context, syncAdapterPackageName, getInviteContactActionResId(), ""); 253273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 254273399bf829133a8385332ad43add3c34c889102Chiao Cheng 255273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 256273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Returns a label for the "view group" action. If not defined, this falls back to our 257273399bf829133a8385332ad43add3c34c889102Chiao Cheng * own "View Updates" string 258273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 259273399bf829133a8385332ad43add3c34c889102Chiao Cheng public CharSequence getViewGroupLabel(Context context) { 260273399bf829133a8385332ad43add3c34c889102Chiao Cheng // Note this resource is defined in the sync adapter package, not resourcePackageName. 261273399bf829133a8385332ad43add3c34c889102Chiao Cheng final CharSequence customTitle = 262273399bf829133a8385332ad43add3c34c889102Chiao Cheng getResourceText(context, syncAdapterPackageName, getViewGroupLabelResId(), null); 263273399bf829133a8385332ad43add3c34c889102Chiao Cheng 264273399bf829133a8385332ad43add3c34c889102Chiao Cheng return customTitle == null 265273399bf829133a8385332ad43add3c34c889102Chiao Cheng ? context.getText(R.string.view_updates_from_group) 266273399bf829133a8385332ad43add3c34c889102Chiao Cheng : customTitle; 267273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 268273399bf829133a8385332ad43add3c34c889102Chiao Cheng 269273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 270273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Return a string resource loaded from the given package (or the current package 271273399bf829133a8385332ad43add3c34c889102Chiao Cheng * if {@code packageName} is null), unless {@code resId} is -1, in which case it returns 272273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@code defaultValue}. 273273399bf829133a8385332ad43add3c34c889102Chiao Cheng * 274273399bf829133a8385332ad43add3c34c889102Chiao Cheng * (The behavior is undefined if the resource or package doesn't exist.) 275273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 276273399bf829133a8385332ad43add3c34c889102Chiao Cheng @VisibleForTesting 277273399bf829133a8385332ad43add3c34c889102Chiao Cheng static CharSequence getResourceText(Context context, String packageName, int resId, 278273399bf829133a8385332ad43add3c34c889102Chiao Cheng String defaultValue) { 279273399bf829133a8385332ad43add3c34c889102Chiao Cheng if (resId != -1 && packageName != null) { 280273399bf829133a8385332ad43add3c34c889102Chiao Cheng final PackageManager pm = context.getPackageManager(); 281273399bf829133a8385332ad43add3c34c889102Chiao Cheng return pm.getText(packageName, resId, null); 282273399bf829133a8385332ad43add3c34c889102Chiao Cheng } else if (resId != -1) { 283273399bf829133a8385332ad43add3c34c889102Chiao Cheng return context.getText(resId); 284273399bf829133a8385332ad43add3c34c889102Chiao Cheng } else { 285273399bf829133a8385332ad43add3c34c889102Chiao Cheng return defaultValue; 286273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 287273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 288273399bf829133a8385332ad43add3c34c889102Chiao Cheng 289273399bf829133a8385332ad43add3c34c889102Chiao Cheng public Drawable getDisplayIcon(Context context) { 290273399bf829133a8385332ad43add3c34c889102Chiao Cheng if (this.titleRes != -1 && this.syncAdapterPackageName != null) { 291273399bf829133a8385332ad43add3c34c889102Chiao Cheng final PackageManager pm = context.getPackageManager(); 292273399bf829133a8385332ad43add3c34c889102Chiao Cheng return pm.getDrawable(this.syncAdapterPackageName, this.iconRes, null); 293273399bf829133a8385332ad43add3c34c889102Chiao Cheng } else if (this.titleRes != -1) { 294273399bf829133a8385332ad43add3c34c889102Chiao Cheng return context.getResources().getDrawable(this.iconRes); 295273399bf829133a8385332ad43add3c34c889102Chiao Cheng } else { 296273399bf829133a8385332ad43add3c34c889102Chiao Cheng return null; 297273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 298273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 299273399bf829133a8385332ad43add3c34c889102Chiao Cheng 300273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 301273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Whether or not groups created under this account type have editable membership lists. 302273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 303273399bf829133a8385332ad43add3c34c889102Chiao Cheng abstract public boolean isGroupMembershipEditable(); 304273399bf829133a8385332ad43add3c34c889102Chiao Cheng 305273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 306273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link Comparator} to sort by {@link DataKind#weight}. 307273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 308273399bf829133a8385332ad43add3c34c889102Chiao Cheng private static Comparator<DataKind> sWeightComparator = new Comparator<DataKind>() { 309273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 310273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int compare(DataKind object1, DataKind object2) { 311273399bf829133a8385332ad43add3c34c889102Chiao Cheng return object1.weight - object2.weight; 312273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 313273399bf829133a8385332ad43add3c34c889102Chiao Cheng }; 314273399bf829133a8385332ad43add3c34c889102Chiao Cheng 315273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 316273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Return list of {@link DataKind} supported, sorted by 317273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link DataKind#weight}. 318273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 319273399bf829133a8385332ad43add3c34c889102Chiao Cheng public ArrayList<DataKind> getSortedDataKinds() { 320273399bf829133a8385332ad43add3c34c889102Chiao Cheng // TODO: optimize by marking if already sorted 321273399bf829133a8385332ad43add3c34c889102Chiao Cheng Collections.sort(mKinds, sWeightComparator); 322273399bf829133a8385332ad43add3c34c889102Chiao Cheng return mKinds; 323273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 324273399bf829133a8385332ad43add3c34c889102Chiao Cheng 325273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 326273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Find the {@link DataKind} for a specific MIME-type, if it's handled by 327273399bf829133a8385332ad43add3c34c889102Chiao Cheng * this data source. 328273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 329273399bf829133a8385332ad43add3c34c889102Chiao Cheng public DataKind getKindForMimetype(String mimeType) { 330273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this.mMimeKinds.get(mimeType); 331273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 332273399bf829133a8385332ad43add3c34c889102Chiao Cheng 333273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 334273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Add given {@link DataKind} to list of those provided by this source. 335273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 336273399bf829133a8385332ad43add3c34c889102Chiao Cheng public DataKind addKind(DataKind kind) throws DefinitionException { 337273399bf829133a8385332ad43add3c34c889102Chiao Cheng if (kind.mimeType == null) { 338273399bf829133a8385332ad43add3c34c889102Chiao Cheng throw new DefinitionException("null is not a valid mime type"); 339273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 340273399bf829133a8385332ad43add3c34c889102Chiao Cheng if (mMimeKinds.get(kind.mimeType) != null) { 341273399bf829133a8385332ad43add3c34c889102Chiao Cheng throw new DefinitionException( 342273399bf829133a8385332ad43add3c34c889102Chiao Cheng "mime type '" + kind.mimeType + "' is already registered"); 343273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 344273399bf829133a8385332ad43add3c34c889102Chiao Cheng 345273399bf829133a8385332ad43add3c34c889102Chiao Cheng kind.resourcePackageName = this.resourcePackageName; 346273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.mKinds.add(kind); 347273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.mMimeKinds.put(kind.mimeType, kind); 348273399bf829133a8385332ad43add3c34c889102Chiao Cheng return kind; 349273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 350273399bf829133a8385332ad43add3c34c889102Chiao Cheng 351273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 352273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Description of a specific "type" or "label" of a {@link DataKind} row, 353273399bf829133a8385332ad43add3c34c889102Chiao Cheng * such as {@link Phone#TYPE_WORK}. Includes constraints on total number of 354273399bf829133a8385332ad43add3c34c889102Chiao Cheng * rows a {@link Contacts} may have of this type, and details on how 355273399bf829133a8385332ad43add3c34c889102Chiao Cheng * user-defined labels are stored. 356273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 357273399bf829133a8385332ad43add3c34c889102Chiao Cheng public static class EditType { 358273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int rawValue; 359273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int labelRes; 360273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean secondary; 361273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 362273399bf829133a8385332ad43add3c34c889102Chiao Cheng * The number of entries allowed for the type. -1 if not specified. 363273399bf829133a8385332ad43add3c34c889102Chiao Cheng * @see DataKind#typeOverallMax 364273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 365273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int specificMax; 366273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String customColumn; 367273399bf829133a8385332ad43add3c34c889102Chiao Cheng 368273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditType(int rawValue, int labelRes) { 369273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.rawValue = rawValue; 370273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.labelRes = labelRes; 371273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.specificMax = -1; 372273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 373273399bf829133a8385332ad43add3c34c889102Chiao Cheng 374273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditType setSecondary(boolean secondary) { 375273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.secondary = secondary; 376273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 377273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 378273399bf829133a8385332ad43add3c34c889102Chiao Cheng 379273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditType setSpecificMax(int specificMax) { 380273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.specificMax = specificMax; 381273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 382273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 383273399bf829133a8385332ad43add3c34c889102Chiao Cheng 384273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditType setCustomColumn(String customColumn) { 385273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.customColumn = customColumn; 386273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 387273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 388273399bf829133a8385332ad43add3c34c889102Chiao Cheng 389273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 390273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean equals(Object object) { 391273399bf829133a8385332ad43add3c34c889102Chiao Cheng if (object instanceof EditType) { 392273399bf829133a8385332ad43add3c34c889102Chiao Cheng final EditType other = (EditType)object; 393273399bf829133a8385332ad43add3c34c889102Chiao Cheng return other.rawValue == rawValue; 394273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 395273399bf829133a8385332ad43add3c34c889102Chiao Cheng return false; 396273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 397273399bf829133a8385332ad43add3c34c889102Chiao Cheng 398273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 399273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int hashCode() { 400273399bf829133a8385332ad43add3c34c889102Chiao Cheng return rawValue; 401273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 402273399bf829133a8385332ad43add3c34c889102Chiao Cheng 403273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 404273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String toString() { 405273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this.getClass().getSimpleName() 406273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " rawValue=" + rawValue 407273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " labelRes=" + labelRes 408273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " secondary=" + secondary 409273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " specificMax=" + specificMax 410273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " customColumn=" + customColumn; 411273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 412273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 413273399bf829133a8385332ad43add3c34c889102Chiao Cheng 414273399bf829133a8385332ad43add3c34c889102Chiao Cheng public static class EventEditType extends EditType { 415273399bf829133a8385332ad43add3c34c889102Chiao Cheng private boolean mYearOptional; 416273399bf829133a8385332ad43add3c34c889102Chiao Cheng 417273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EventEditType(int rawValue, int labelRes) { 418273399bf829133a8385332ad43add3c34c889102Chiao Cheng super(rawValue, labelRes); 419273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 420273399bf829133a8385332ad43add3c34c889102Chiao Cheng 421273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean isYearOptional() { 422273399bf829133a8385332ad43add3c34c889102Chiao Cheng return mYearOptional; 423273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 424273399bf829133a8385332ad43add3c34c889102Chiao Cheng 425273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EventEditType setYearOptional(boolean yearOptional) { 426273399bf829133a8385332ad43add3c34c889102Chiao Cheng mYearOptional = yearOptional; 427273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 428273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 429273399bf829133a8385332ad43add3c34c889102Chiao Cheng 430273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 431273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String toString() { 432273399bf829133a8385332ad43add3c34c889102Chiao Cheng return super.toString() + " mYearOptional=" + mYearOptional; 433273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 434273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 435273399bf829133a8385332ad43add3c34c889102Chiao Cheng 436273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 437273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Description of a user-editable field on a {@link DataKind} row, such as 438273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link Phone#NUMBER}. Includes flags to apply to an {@link EditText}, and 439273399bf829133a8385332ad43add3c34c889102Chiao Cheng * the column where this field is stored. 440273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 441273399bf829133a8385332ad43add3c34c889102Chiao Cheng public static final class EditField { 442273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String column; 443273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int titleRes; 444273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int inputType; 445273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int minLines; 446273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean optional; 447273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean shortForm; 448273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean longForm; 449273399bf829133a8385332ad43add3c34c889102Chiao Cheng 450273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditField(String column, int titleRes) { 451273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.column = column; 452273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.titleRes = titleRes; 453273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 454273399bf829133a8385332ad43add3c34c889102Chiao Cheng 455273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditField(String column, int titleRes, int inputType) { 456273399bf829133a8385332ad43add3c34c889102Chiao Cheng this(column, titleRes); 457273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.inputType = inputType; 458273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 459273399bf829133a8385332ad43add3c34c889102Chiao Cheng 460273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditField setOptional(boolean optional) { 461273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.optional = optional; 462273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 463273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 464273399bf829133a8385332ad43add3c34c889102Chiao Cheng 465273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditField setShortForm(boolean shortForm) { 466273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.shortForm = shortForm; 467273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 468273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 469273399bf829133a8385332ad43add3c34c889102Chiao Cheng 470273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditField setLongForm(boolean longForm) { 471273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.longForm = longForm; 472273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 473273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 474273399bf829133a8385332ad43add3c34c889102Chiao Cheng 475273399bf829133a8385332ad43add3c34c889102Chiao Cheng public EditField setMinLines(int minLines) { 476273399bf829133a8385332ad43add3c34c889102Chiao Cheng this.minLines = minLines; 477273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this; 478273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 479273399bf829133a8385332ad43add3c34c889102Chiao Cheng 480273399bf829133a8385332ad43add3c34c889102Chiao Cheng public boolean isMultiLine() { 481273399bf829133a8385332ad43add3c34c889102Chiao Cheng return (inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) != 0; 482273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 483273399bf829133a8385332ad43add3c34c889102Chiao Cheng 484273399bf829133a8385332ad43add3c34c889102Chiao Cheng 485273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 486273399bf829133a8385332ad43add3c34c889102Chiao Cheng public String toString() { 487273399bf829133a8385332ad43add3c34c889102Chiao Cheng return this.getClass().getSimpleName() + ":" 488273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " column=" + column 489273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " titleRes=" + titleRes 490273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " inputType=" + inputType 491273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " minLines=" + minLines 492273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " optional=" + optional 493273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " shortForm=" + shortForm 494273399bf829133a8385332ad43add3c34c889102Chiao Cheng + " longForm=" + longForm; 495273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 496273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 497273399bf829133a8385332ad43add3c34c889102Chiao Cheng 498273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 499273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Generic method of inflating a given {@link ContentValues} into a user-readable 500273399bf829133a8385332ad43add3c34c889102Chiao Cheng * {@link CharSequence}. For example, an inflater could combine the multiple 501273399bf829133a8385332ad43add3c34c889102Chiao Cheng * columns of {@link StructuredPostal} together using a string resource 502273399bf829133a8385332ad43add3c34c889102Chiao Cheng * before presenting to the user. 503273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 504273399bf829133a8385332ad43add3c34c889102Chiao Cheng public interface StringInflater { 505273399bf829133a8385332ad43add3c34c889102Chiao Cheng public CharSequence inflateUsing(Context context, ContentValues values); 506273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 507273399bf829133a8385332ad43add3c34c889102Chiao Cheng 508273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** 509273399bf829133a8385332ad43add3c34c889102Chiao Cheng * Compare two {@link AccountType} by their {@link AccountType#getDisplayLabel} with the 510273399bf829133a8385332ad43add3c34c889102Chiao Cheng * current locale. 511273399bf829133a8385332ad43add3c34c889102Chiao Cheng */ 512273399bf829133a8385332ad43add3c34c889102Chiao Cheng public static class DisplayLabelComparator implements Comparator<AccountType> { 513273399bf829133a8385332ad43add3c34c889102Chiao Cheng private final Context mContext; 514273399bf829133a8385332ad43add3c34c889102Chiao Cheng /** {@link Comparator} for the current locale. */ 515273399bf829133a8385332ad43add3c34c889102Chiao Cheng private final Collator mCollator = Collator.getInstance(); 516273399bf829133a8385332ad43add3c34c889102Chiao Cheng 517273399bf829133a8385332ad43add3c34c889102Chiao Cheng public DisplayLabelComparator(Context context) { 518273399bf829133a8385332ad43add3c34c889102Chiao Cheng mContext = context; 519273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 520273399bf829133a8385332ad43add3c34c889102Chiao Cheng 521273399bf829133a8385332ad43add3c34c889102Chiao Cheng private String getDisplayLabel(AccountType type) { 522273399bf829133a8385332ad43add3c34c889102Chiao Cheng CharSequence label = type.getDisplayLabel(mContext); 523273399bf829133a8385332ad43add3c34c889102Chiao Cheng return (label == null) ? "" : label.toString(); 524273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 525273399bf829133a8385332ad43add3c34c889102Chiao Cheng 526273399bf829133a8385332ad43add3c34c889102Chiao Cheng @Override 527273399bf829133a8385332ad43add3c34c889102Chiao Cheng public int compare(AccountType lhs, AccountType rhs) { 528273399bf829133a8385332ad43add3c34c889102Chiao Cheng return mCollator.compare(getDisplayLabel(lhs), getDisplayLabel(rhs)); 529273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 530273399bf829133a8385332ad43add3c34c889102Chiao Cheng } 531273399bf829133a8385332ad43add3c34c889102Chiao Cheng} 532