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