1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.contacts.common.model.account; 18 19 import android.content.ContentValues; 20 import android.content.Context; 21 import android.provider.ContactsContract.CommonDataKinds.Email; 22 import android.provider.ContactsContract.CommonDataKinds.Event; 23 import android.provider.ContactsContract.CommonDataKinds.Im; 24 import android.provider.ContactsContract.CommonDataKinds.Nickname; 25 import android.provider.ContactsContract.CommonDataKinds.Note; 26 import android.provider.ContactsContract.CommonDataKinds.Organization; 27 import android.provider.ContactsContract.CommonDataKinds.Phone; 28 import android.provider.ContactsContract.CommonDataKinds.Photo; 29 import android.provider.ContactsContract.CommonDataKinds.StructuredName; 30 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 31 import android.provider.ContactsContract.CommonDataKinds.Website; 32 import android.util.Log; 33 34 import com.android.contacts.common.R; 35 import com.android.contacts.common.model.dataitem.DataKind; 36 import com.android.contacts.common.util.CommonDateUtils; 37 import com.google.common.collect.Lists; 38 39 import java.util.Locale; 40 41 public 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