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    public static final String ACCOUNT_TYPE_AOSP = "com.android.exchange";
45    public static final String ACCOUNT_TYPE_GOOGLE = "com.google.android.exchange";
46
47    public ExchangeAccountType(Context context, String authenticatorPackageName, String type) {
48        this.accountType = type;
49        this.resourcePackageName = null;
50        this.syncAdapterPackageName = authenticatorPackageName;
51
52        try {
53            addDataKindStructuredName(context);
54            addDataKindDisplayName(context);
55            addDataKindPhoneticName(context);
56            addDataKindNickname(context);
57            addDataKindPhone(context);
58            addDataKindEmail(context);
59            addDataKindStructuredPostal(context);
60            addDataKindIm(context);
61            addDataKindOrganization(context);
62            addDataKindPhoto(context);
63            addDataKindNote(context);
64            addDataKindEvent(context);
65            addDataKindWebsite(context);
66            addDataKindGroupMembership(context);
67
68            mIsInitialized = true;
69        } catch (DefinitionException e) {
70            Log.e(TAG, "Problem building account type", e);
71        }
72    }
73
74    public static boolean isExchangeType(String type) {
75        return ACCOUNT_TYPE_AOSP.equals(type) || ACCOUNT_TYPE_GOOGLE.equals(type);
76    }
77
78    @Override
79    protected DataKind addDataKindStructuredName(Context context) throws DefinitionException {
80        DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
81                R.string.nameLabelsGroup, -1, true));
82        kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
83        kind.actionBody = new SimpleInflater(Nickname.NAME);
84
85        kind.typeOverallMax = 1;
86
87        kind.fieldList = Lists.newArrayList();
88        kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
89                FLAGS_PERSON_NAME).setOptional(true));
90        kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
91                R.string.name_family, FLAGS_PERSON_NAME));
92        kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
93                R.string.name_middle, FLAGS_PERSON_NAME));
94        kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
95                R.string.name_given, FLAGS_PERSON_NAME));
96        kind.fieldList.add(new EditField(StructuredName.SUFFIX,
97                R.string.name_suffix, FLAGS_PERSON_NAME));
98
99        kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
100                R.string.name_phonetic_family, FLAGS_PHONETIC));
101        kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
102                R.string.name_phonetic_given, FLAGS_PHONETIC));
103
104        return kind;
105    }
106
107    @Override
108    protected DataKind addDataKindDisplayName(Context context) throws DefinitionException {
109        DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME,
110                R.string.nameLabelsGroup, -1, true));
111
112        boolean displayOrderPrimary =
113                context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
114        kind.typeOverallMax = 1;
115
116        kind.fieldList = Lists.newArrayList();
117        kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
118                FLAGS_PERSON_NAME).setOptional(true));
119        if (!displayOrderPrimary) {
120            kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
121                    R.string.name_family, FLAGS_PERSON_NAME));
122            kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
123                    R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true));
124            kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
125                    R.string.name_given, FLAGS_PERSON_NAME));
126        } else {
127            kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
128                    R.string.name_given, FLAGS_PERSON_NAME));
129            kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
130                    R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true));
131            kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
132                    R.string.name_family, FLAGS_PERSON_NAME));
133        }
134        kind.fieldList.add(new EditField(StructuredName.SUFFIX,
135                R.string.name_suffix, FLAGS_PERSON_NAME).setOptional(true));
136
137        return kind;
138    }
139
140    @Override
141    protected DataKind addDataKindPhoneticName(Context context) throws DefinitionException {
142        DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME,
143                R.string.name_phonetic, -1, true));
144        kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
145        kind.actionBody = new SimpleInflater(Nickname.NAME);
146
147        kind.typeOverallMax = 1;
148
149        kind.fieldList = Lists.newArrayList();
150        kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
151                R.string.name_phonetic_family, FLAGS_PHONETIC));
152        kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
153                R.string.name_phonetic_given, FLAGS_PHONETIC));
154
155        return kind;
156    }
157
158    @Override
159    protected DataKind addDataKindNickname(Context context) throws DefinitionException {
160        final DataKind kind = super.addDataKindNickname(context);
161
162        kind.typeOverallMax = 1;
163
164        kind.fieldList = Lists.newArrayList();
165        kind.fieldList.add(new EditField(Nickname.NAME, R.string.nicknameLabelsGroup,
166                FLAGS_PERSON_NAME));
167
168        return kind;
169    }
170
171    @Override
172    protected DataKind addDataKindPhone(Context context) throws DefinitionException {
173        final DataKind kind = super.addDataKindPhone(context);
174
175        kind.typeColumn = Phone.TYPE;
176        kind.typeList = Lists.newArrayList();
177        kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE).setSpecificMax(1));
178        kind.typeList.add(buildPhoneType(Phone.TYPE_HOME).setSpecificMax(2));
179        kind.typeList.add(buildPhoneType(Phone.TYPE_WORK).setSpecificMax(2));
180        kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true)
181                .setSpecificMax(1));
182        kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true)
183                .setSpecificMax(1));
184        kind.typeList
185                .add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true).setSpecificMax(1));
186        kind.typeList.add(buildPhoneType(Phone.TYPE_CAR).setSecondary(true).setSpecificMax(1));
187        kind.typeList.add(buildPhoneType(Phone.TYPE_COMPANY_MAIN).setSecondary(true)
188                .setSpecificMax(1));
189        kind.typeList.add(buildPhoneType(Phone.TYPE_MMS).setSecondary(true).setSpecificMax(1));
190        kind.typeList
191                .add(buildPhoneType(Phone.TYPE_RADIO).setSecondary(true).setSpecificMax(1));
192        kind.typeList.add(buildPhoneType(Phone.TYPE_ASSISTANT).setSecondary(true)
193                .setSpecificMax(1));
194
195        kind.fieldList = Lists.newArrayList();
196        kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE));
197
198        return kind;
199    }
200
201    @Override
202    protected DataKind addDataKindEmail(Context context) throws DefinitionException {
203        final DataKind kind = super.addDataKindEmail(context);
204
205        kind.typeOverallMax = 3;
206
207        kind.fieldList = Lists.newArrayList();
208        kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL));
209
210        return kind;
211    }
212
213    @Override
214    protected DataKind addDataKindStructuredPostal(Context context) throws DefinitionException {
215        final DataKind kind = super.addDataKindStructuredPostal(context);
216
217        final boolean useJapaneseOrder =
218            Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage());
219        kind.typeColumn = StructuredPostal.TYPE;
220        kind.typeList = Lists.newArrayList();
221        kind.typeList.add(buildPostalType(StructuredPostal.TYPE_WORK).setSpecificMax(1));
222        kind.typeList.add(buildPostalType(StructuredPostal.TYPE_HOME).setSpecificMax(1));
223        kind.typeList.add(buildPostalType(StructuredPostal.TYPE_OTHER).setSpecificMax(1));
224
225        kind.fieldList = Lists.newArrayList();
226        if (useJapaneseOrder) {
227            kind.fieldList.add(new EditField(StructuredPostal.COUNTRY,
228                    R.string.postal_country, FLAGS_POSTAL).setOptional(true));
229            kind.fieldList.add(new EditField(StructuredPostal.POSTCODE,
230                    R.string.postal_postcode, FLAGS_POSTAL));
231            kind.fieldList.add(new EditField(StructuredPostal.REGION,
232                    R.string.postal_region, FLAGS_POSTAL));
233            kind.fieldList.add(new EditField(StructuredPostal.CITY,
234                    R.string.postal_city,FLAGS_POSTAL));
235            kind.fieldList.add(new EditField(StructuredPostal.STREET,
236                    R.string.postal_street, FLAGS_POSTAL));
237        } else {
238            kind.fieldList.add(new EditField(StructuredPostal.STREET,
239                    R.string.postal_street, FLAGS_POSTAL));
240            kind.fieldList.add(new EditField(StructuredPostal.CITY,
241                    R.string.postal_city,FLAGS_POSTAL));
242            kind.fieldList.add(new EditField(StructuredPostal.REGION,
243                    R.string.postal_region, FLAGS_POSTAL));
244            kind.fieldList.add(new EditField(StructuredPostal.POSTCODE,
245                    R.string.postal_postcode, FLAGS_POSTAL));
246            kind.fieldList.add(new EditField(StructuredPostal.COUNTRY,
247                    R.string.postal_country, FLAGS_POSTAL).setOptional(true));
248        }
249
250        return kind;
251    }
252
253    @Override
254    protected DataKind addDataKindIm(Context context) throws DefinitionException {
255        final DataKind kind = super.addDataKindIm(context);
256
257        // Types are not supported for IM. There can be 3 IMs, but OWA only shows only the first
258        kind.typeOverallMax = 3;
259
260        kind.defaultValues = new ContentValues();
261        kind.defaultValues.put(Im.TYPE, Im.TYPE_OTHER);
262
263        kind.fieldList = Lists.newArrayList();
264        kind.fieldList.add(new EditField(Im.DATA, R.string.imLabelsGroup, FLAGS_EMAIL));
265
266        return kind;
267    }
268
269    @Override
270    protected DataKind addDataKindOrganization(Context context) throws DefinitionException {
271        final DataKind kind = super.addDataKindOrganization(context);
272
273        kind.typeOverallMax = 1;
274
275        kind.fieldList = Lists.newArrayList();
276        kind.fieldList.add(new EditField(Organization.COMPANY, R.string.ghostData_company,
277                FLAGS_GENERIC_NAME));
278        kind.fieldList.add(new EditField(Organization.TITLE, R.string.ghostData_title,
279                FLAGS_GENERIC_NAME));
280
281        return kind;
282    }
283
284    @Override
285    protected DataKind addDataKindPhoto(Context context) throws DefinitionException {
286        final DataKind kind = super.addDataKindPhoto(context);
287
288        kind.typeOverallMax = 1;
289
290        kind.fieldList = Lists.newArrayList();
291        kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1));
292
293        return kind;
294    }
295
296    @Override
297    protected DataKind addDataKindNote(Context context) throws DefinitionException {
298        final DataKind kind = super.addDataKindNote(context);
299
300        kind.fieldList = Lists.newArrayList();
301        kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE));
302
303        return kind;
304    }
305
306    protected DataKind addDataKindEvent(Context context) throws DefinitionException {
307        DataKind kind = addKind(new DataKind(Event.CONTENT_ITEM_TYPE, R.string.eventLabelsGroup,
308                150, true));
309        kind.actionHeader = new EventActionInflater();
310        kind.actionBody = new SimpleInflater(Event.START_DATE);
311
312        kind.typeOverallMax = 1;
313
314        kind.typeColumn = Event.TYPE;
315        kind.typeList = Lists.newArrayList();
316        kind.typeList.add(buildEventType(Event.TYPE_BIRTHDAY, false).setSpecificMax(1));
317
318        kind.dateFormatWithYear = CommonDateUtils.DATE_AND_TIME_FORMAT;
319
320        kind.fieldList = Lists.newArrayList();
321        kind.fieldList.add(new EditField(Event.DATA, R.string.eventLabelsGroup, FLAGS_EVENT));
322
323        return kind;
324    }
325
326    @Override
327    protected DataKind addDataKindWebsite(Context context) throws DefinitionException {
328        final DataKind kind = super.addDataKindWebsite(context);
329
330        kind.typeOverallMax = 1;
331
332        kind.fieldList = Lists.newArrayList();
333        kind.fieldList.add(new EditField(Website.URL, R.string.websiteLabelsGroup, FLAGS_WEBSITE));
334
335        return kind;
336    }
337
338    @Override
339    public boolean isGroupMembershipEditable() {
340        return true;
341    }
342
343    @Override
344    public boolean areContactsWritable() {
345        return true;
346    }
347}
348