1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.contacts.common.model.account;
18
19import android.content.ContentValues;
20import android.content.Context;
21import android.provider.ContactsContract.CommonDataKinds.Email;
22import android.provider.ContactsContract.CommonDataKinds.Event;
23import android.provider.ContactsContract.CommonDataKinds.Im;
24import android.provider.ContactsContract.CommonDataKinds.Nickname;
25import android.provider.ContactsContract.CommonDataKinds.Note;
26import android.provider.ContactsContract.CommonDataKinds.Organization;
27import android.provider.ContactsContract.CommonDataKinds.Phone;
28import android.provider.ContactsContract.CommonDataKinds.Photo;
29import android.provider.ContactsContract.CommonDataKinds.StructuredName;
30import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
31import android.provider.ContactsContract.CommonDataKinds.Website;
32import android.util.Log;
33
34import com.android.contacts.common.R;
35import com.android.contacts.common.model.dataitem.DataKind;
36import com.android.contacts.common.util.CommonDateUtils;
37import com.google.common.collect.Lists;
38
39import java.util.Locale;
40
41public class ExchangeAccountType extends BaseAccountType {
42    private static final String TAG = "ExchangeAccountType";
43
44    private static final String ACCOUNT_TYPE_AOSP = "com.android.exchange";
45    private static final String ACCOUNT_TYPE_GOOGLE_1 = "com.google.android.exchange";
46    private static final String ACCOUNT_TYPE_GOOGLE_2 = "com.google.android.gm.exchange";
47
48    public ExchangeAccountType(Context context, String authenticatorPackageName, String type) {
49        this.accountType = type;
50        this.resourcePackageName = null;
51        this.syncAdapterPackageName = authenticatorPackageName;
52
53        try {
54            addDataKindStructuredName(context);
55            addDataKindDisplayName(context);
56            addDataKindPhoneticName(context);
57            addDataKindNickname(context);
58            addDataKindPhone(context);
59            addDataKindEmail(context);
60            addDataKindStructuredPostal(context);
61            addDataKindIm(context);
62            addDataKindOrganization(context);
63            addDataKindPhoto(context);
64            addDataKindNote(context);
65            addDataKindEvent(context);
66            addDataKindWebsite(context);
67            addDataKindGroupMembership(context);
68
69            mIsInitialized = true;
70        } catch (DefinitionException e) {
71            Log.e(TAG, "Problem building account type", e);
72        }
73    }
74
75    public static boolean isExchangeType(String type) {
76        return ACCOUNT_TYPE_AOSP.equals(type) || ACCOUNT_TYPE_GOOGLE_1.equals(type)
77                || ACCOUNT_TYPE_GOOGLE_2.equals(type);
78    }
79
80    @Override
81    protected DataKind addDataKindStructuredName(Context context) throws DefinitionException {
82        DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
83                R.string.nameLabelsGroup, Weight.NONE, true));
84        kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
85        kind.actionBody = new SimpleInflater(Nickname.NAME);
86
87        kind.typeOverallMax = 1;
88
89        kind.fieldList = Lists.newArrayList();
90        kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
91                FLAGS_PERSON_NAME).setOptional(true));
92        kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
93                R.string.name_family, FLAGS_PERSON_NAME));
94        kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
95                R.string.name_middle, FLAGS_PERSON_NAME));
96        kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
97                R.string.name_given, FLAGS_PERSON_NAME));
98        kind.fieldList.add(new EditField(StructuredName.SUFFIX,
99                R.string.name_suffix, FLAGS_PERSON_NAME));
100
101        kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
102                R.string.name_phonetic_family, FLAGS_PHONETIC));
103        kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
104                R.string.name_phonetic_given, FLAGS_PHONETIC));
105
106        return kind;
107    }
108
109    @Override
110    protected DataKind addDataKindDisplayName(Context context) throws DefinitionException {
111        DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME,
112                R.string.nameLabelsGroup, Weight.NONE, true));
113
114        boolean displayOrderPrimary =
115                context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
116        kind.typeOverallMax = 1;
117
118        kind.fieldList = Lists.newArrayList();
119        kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
120                FLAGS_PERSON_NAME).setOptional(true));
121        if (!displayOrderPrimary) {
122            kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
123                    R.string.name_family, FLAGS_PERSON_NAME));
124            kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
125                    R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true));
126            kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
127                    R.string.name_given, FLAGS_PERSON_NAME));
128        } else {
129            kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
130                    R.string.name_given, FLAGS_PERSON_NAME));
131            kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
132                    R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true));
133            kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
134                    R.string.name_family, FLAGS_PERSON_NAME));
135        }
136        kind.fieldList.add(new EditField(StructuredName.SUFFIX,
137                R.string.name_suffix, FLAGS_PERSON_NAME).setOptional(true));
138
139        return kind;
140    }
141
142    @Override
143    protected DataKind addDataKindPhoneticName(Context context) throws DefinitionException {
144        DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME,
145                R.string.name_phonetic, Weight.NONE, true));
146        kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
147        kind.actionBody = new SimpleInflater(Nickname.NAME);
148
149        kind.typeOverallMax = 1;
150
151        kind.fieldList = Lists.newArrayList();
152        kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
153                R.string.name_phonetic_family, FLAGS_PHONETIC));
154        kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
155                R.string.name_phonetic_given, FLAGS_PHONETIC));
156
157        return kind;
158    }
159
160    @Override
161    protected DataKind addDataKindNickname(Context context) throws DefinitionException {
162        final DataKind kind = super.addDataKindNickname(context);
163
164        kind.typeOverallMax = 1;
165
166        kind.fieldList = Lists.newArrayList();
167        kind.fieldList.add(new EditField(Nickname.NAME, R.string.nicknameLabelsGroup,
168                FLAGS_PERSON_NAME));
169
170        return kind;
171    }
172
173    @Override
174    protected DataKind addDataKindPhone(Context context) throws DefinitionException {
175        final DataKind kind = super.addDataKindPhone(context);
176
177        kind.typeColumn = Phone.TYPE;
178        kind.typeList = Lists.newArrayList();
179        kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE).setSpecificMax(1));
180        kind.typeList.add(buildPhoneType(Phone.TYPE_HOME).setSpecificMax(2));
181        kind.typeList.add(buildPhoneType(Phone.TYPE_WORK).setSpecificMax(2));
182        kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true)
183                .setSpecificMax(1));
184        kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true)
185                .setSpecificMax(1));
186        kind.typeList
187                .add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true).setSpecificMax(1));
188        kind.typeList.add(buildPhoneType(Phone.TYPE_CAR).setSecondary(true).setSpecificMax(1));
189        kind.typeList.add(buildPhoneType(Phone.TYPE_COMPANY_MAIN).setSecondary(true)
190                .setSpecificMax(1));
191        kind.typeList.add(buildPhoneType(Phone.TYPE_MMS).setSecondary(true).setSpecificMax(1));
192        kind.typeList
193                .add(buildPhoneType(Phone.TYPE_RADIO).setSecondary(true).setSpecificMax(1));
194        kind.typeList.add(buildPhoneType(Phone.TYPE_ASSISTANT).setSecondary(true)
195                .setSpecificMax(1));
196
197        kind.fieldList = Lists.newArrayList();
198        kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE));
199
200        return kind;
201    }
202
203    @Override
204    protected DataKind addDataKindEmail(Context context) throws DefinitionException {
205        final DataKind kind = super.addDataKindEmail(context);
206
207        kind.typeOverallMax = 3;
208
209        kind.fieldList = Lists.newArrayList();
210        kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL));
211
212        return kind;
213    }
214
215    @Override
216    protected DataKind addDataKindStructuredPostal(Context context) throws DefinitionException {
217        final DataKind kind = super.addDataKindStructuredPostal(context);
218
219        final boolean useJapaneseOrder =
220            Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage());
221        kind.typeColumn = StructuredPostal.TYPE;
222        kind.typeList = Lists.newArrayList();
223        kind.typeList.add(buildPostalType(StructuredPostal.TYPE_WORK).setSpecificMax(1));
224        kind.typeList.add(buildPostalType(StructuredPostal.TYPE_HOME).setSpecificMax(1));
225        kind.typeList.add(buildPostalType(StructuredPostal.TYPE_OTHER).setSpecificMax(1));
226
227        kind.fieldList = Lists.newArrayList();
228        if (useJapaneseOrder) {
229            kind.fieldList.add(new EditField(StructuredPostal.COUNTRY,
230                    R.string.postal_country, FLAGS_POSTAL).setOptional(true));
231            kind.fieldList.add(new EditField(StructuredPostal.POSTCODE,
232                    R.string.postal_postcode, FLAGS_POSTAL));
233            kind.fieldList.add(new EditField(StructuredPostal.REGION,
234                    R.string.postal_region, FLAGS_POSTAL));
235            kind.fieldList.add(new EditField(StructuredPostal.CITY,
236                    R.string.postal_city,FLAGS_POSTAL));
237            kind.fieldList.add(new EditField(StructuredPostal.STREET,
238                    R.string.postal_street, FLAGS_POSTAL));
239        } else {
240            kind.fieldList.add(new EditField(StructuredPostal.STREET,
241                    R.string.postal_street, FLAGS_POSTAL));
242            kind.fieldList.add(new EditField(StructuredPostal.CITY,
243                    R.string.postal_city,FLAGS_POSTAL));
244            kind.fieldList.add(new EditField(StructuredPostal.REGION,
245                    R.string.postal_region, FLAGS_POSTAL));
246            kind.fieldList.add(new EditField(StructuredPostal.POSTCODE,
247                    R.string.postal_postcode, FLAGS_POSTAL));
248            kind.fieldList.add(new EditField(StructuredPostal.COUNTRY,
249                    R.string.postal_country, FLAGS_POSTAL).setOptional(true));
250        }
251
252        return kind;
253    }
254
255    @Override
256    protected DataKind addDataKindIm(Context context) throws DefinitionException {
257        final DataKind kind = super.addDataKindIm(context);
258
259        // Types are not supported for IM. There can be 3 IMs, but OWA only shows only the first
260        kind.typeOverallMax = 3;
261
262        kind.defaultValues = new ContentValues();
263        kind.defaultValues.put(Im.TYPE, Im.TYPE_OTHER);
264
265        kind.fieldList = Lists.newArrayList();
266        kind.fieldList.add(new EditField(Im.DATA, R.string.imLabelsGroup, FLAGS_EMAIL));
267
268        return kind;
269    }
270
271    @Override
272    protected DataKind addDataKindOrganization(Context context) throws DefinitionException {
273        final DataKind kind = super.addDataKindOrganization(context);
274
275        kind.typeOverallMax = 1;
276
277        kind.fieldList = Lists.newArrayList();
278        kind.fieldList.add(new EditField(Organization.COMPANY, R.string.ghostData_company,
279                FLAGS_GENERIC_NAME));
280        kind.fieldList.add(new EditField(Organization.TITLE, R.string.ghostData_title,
281                FLAGS_GENERIC_NAME));
282
283        return kind;
284    }
285
286    @Override
287    protected DataKind addDataKindPhoto(Context context) throws DefinitionException {
288        final DataKind kind = super.addDataKindPhoto(context);
289
290        kind.typeOverallMax = 1;
291
292        kind.fieldList = Lists.newArrayList();
293        kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1));
294
295        return kind;
296    }
297
298    @Override
299    protected DataKind addDataKindNote(Context context) throws DefinitionException {
300        final DataKind kind = super.addDataKindNote(context);
301
302        kind.fieldList = Lists.newArrayList();
303        kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE));
304
305        return kind;
306    }
307
308    protected DataKind addDataKindEvent(Context context) throws DefinitionException {
309        DataKind kind = addKind(new DataKind(Event.CONTENT_ITEM_TYPE, R.string.eventLabelsGroup,
310                Weight.EVENT, true));
311        kind.actionHeader = new EventActionInflater();
312        kind.actionBody = new SimpleInflater(Event.START_DATE);
313
314        kind.typeOverallMax = 1;
315
316        kind.typeColumn = Event.TYPE;
317        kind.typeList = Lists.newArrayList();
318        kind.typeList.add(buildEventType(Event.TYPE_BIRTHDAY, false).setSpecificMax(1));
319
320        kind.dateFormatWithYear = CommonDateUtils.DATE_AND_TIME_FORMAT;
321
322        kind.fieldList = Lists.newArrayList();
323        kind.fieldList.add(new EditField(Event.DATA, R.string.eventLabelsGroup, FLAGS_EVENT));
324
325        return kind;
326    }
327
328    @Override
329    protected DataKind addDataKindWebsite(Context context) throws DefinitionException {
330        final DataKind kind = super.addDataKindWebsite(context);
331
332        kind.typeOverallMax = 1;
333
334        kind.fieldList = Lists.newArrayList();
335        kind.fieldList.add(new EditField(Website.URL, R.string.websiteLabelsGroup, FLAGS_WEBSITE));
336
337        return kind;
338    }
339
340    @Override
341    public boolean isGroupMembershipEditable() {
342        return true;
343    }
344
345    @Override
346    public boolean areContactsWritable() {
347        return true;
348    }
349}
350