1ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonpackage com.android.exchange.adapter; 2ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 3ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.ContentProviderOperation; 4add575db94f86397c9246d89ed85d29968b5aeaaAlon Albertimport android.content.ContentProviderOperation.Builder; 5ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.ContentProviderResult; 6ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.ContentResolver; 7ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.ContentUris; 8ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.ContentValues; 9ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.Context; 10ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.Entity; 11add575db94f86397c9246d89ed85d29968b5aeaaAlon Albertimport android.content.Entity.NamedContentValues; 12ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.EntityIterator; 13ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.content.OperationApplicationException; 14ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.database.Cursor; 15ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.net.Uri; 16ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.os.RemoteException; 17ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract; 18ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Email; 19ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Event; 20ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 21ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Im; 22ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Nickname; 23ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Note; 24ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Organization; 25ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Phone; 26ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Photo; 27ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Relation; 28ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 29ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 30ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.provider.ContactsContract.CommonDataKinds.Website; 31add575db94f86397c9246d89ed85d29968b5aeaaAlon Albertimport android.provider.ContactsContract.Data; 32add575db94f86397c9246d89ed85d29968b5aeaaAlon Albertimport android.provider.ContactsContract.RawContacts; 33add575db94f86397c9246d89ed85d29968b5aeaaAlon Albertimport android.provider.ContactsContract.SyncState; 34add575db94f86397c9246d89ed85d29968b5aeaaAlon Albertimport android.provider.SyncStateContract; 356cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shraunerimport android.text.TextUtils; 36ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.text.util.Rfc822Token; 37ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.text.util.Rfc822Tokenizer; 38ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport android.util.Base64; 39ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 40ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport com.android.emailcommon.provider.Account; 41ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport com.android.emailcommon.provider.Mailbox; 42ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport com.android.emailcommon.utility.Utility; 43ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport com.android.exchange.Eas; 446cb6c70ea47035a27bd1d808babe39a2d1829c8dYu Ping Huimport com.android.exchange.eas.EasSyncCollectionTypeBase; 45f4195d389ffd4d92e37cd1d01db1713180740291Yu Ping Huimport com.android.exchange.eas.EasSyncContacts; 46ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport com.android.exchange.utility.CalendarUtilities; 47ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport com.android.mail.utils.LogUtils; 48ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 49ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport java.io.IOException; 50ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport java.io.InputStream; 512f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shraunerimport java.text.ParseException; 52ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport java.util.ArrayList; 53ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport java.util.GregorianCalendar; 54ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonimport java.util.TimeZone; 55ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 56ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdonpublic class ContactsSyncParser extends AbstractSyncParser { 57110837ebff288a75f9bda067c38e2c46797d99b5Alon Albert private static final String TAG = Eas.LOG_TAG; 58ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 59ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final String SERVER_ID_SELECTION = RawContacts.SOURCE_ID + "=?"; 60ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final String CLIENT_ID_SELECTION = RawContacts.SYNC1 + "=?"; 61ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final String[] ID_PROJECTION = new String[] {RawContacts._ID}; 62ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 63ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final ArrayList<NamedContentValues> EMPTY_ARRAY_NAMEDCONTENTVALUES 64ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon = new ArrayList<NamedContentValues>(); 65ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 66ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final String FOUND_DATA_ROW = "com.android.exchange.FOUND_ROW"; 67ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 68ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final int MAX_IM_ROWS = 3; 69ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final int MAX_EMAIL_ROWS = 3; 70ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final int MAX_PHONE_ROWS = 2; 71ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final String COMMON_DATA_ROW = Im.DATA; // Could have been Email.DATA, etc. 72ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final String COMMON_TYPE_ROW = Phone.TYPE; // Could have been any typed row 73ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 74ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String[] mBindArgument = new String[1]; 75ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContactOperations ops = new ContactOperations(); 76ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private final android.accounts.Account mAccountManagerAccount; 77ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private final Uri mAccountUri; 78ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private boolean mGroupsUsed = false; 79ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 80ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public ContactsSyncParser(final Context context, final ContentResolver resolver, 81ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon final InputStream in, final Mailbox mailbox, final Account account, 82ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon final android.accounts.Account accountManagerAccount) throws IOException { 83ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon super(context, resolver, in, mailbox, account); 84ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mAccountManagerAccount = accountManagerAccount; 85ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mAccountUri = uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI, 86ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mAccount.mEmailAddress); 87ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 88ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 89ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public boolean isGroupsUsed() { 90ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return mGroupsUsed; 91ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 92ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 93ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addData(String serverId, ContactOperations ops, Entity entity) 94ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon throws IOException { 95ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String prefix = null; 96ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String firstName = null; 97ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String lastName = null; 98ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String middleName = null; 99ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String suffix = null; 100ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String companyName = null; 101ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String yomiFirstName = null; 102ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String yomiLastName = null; 103ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String yomiCompanyName = null; 104ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String title = null; 105ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String department = null; 106ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String officeLocation = null; 107ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Address home = new Address(); 108ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Address work = new Address(); 109ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Address other = new Address(); 110ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon EasBusiness business = new EasBusiness(); 111ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon EasPersonal personal = new EasPersonal(); 112ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<String> children = new ArrayList<String>(); 113ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<UntypedRow> emails = new ArrayList<UntypedRow>(); 114ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<UntypedRow> ims = new ArrayList<UntypedRow>(); 115ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<UntypedRow> homePhones = new ArrayList<UntypedRow>(); 116ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<UntypedRow> workPhones = new ArrayList<UntypedRow>(); 117ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (entity == null) { 118ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.newContact(serverId, mAccount.mEmailAddress); 119ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 120ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 121ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_APPLICATION_DATA) != END) { 122ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 123ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_FIRST_NAME: 124ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon firstName = getValue(); 125ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 126ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_LAST_NAME: 127ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon lastName = getValue(); 128ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 129ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_MIDDLE_NAME: 130ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon middleName = getValue(); 131ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 132ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_SUFFIX: 133ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon suffix = getValue(); 134ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 135ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_COMPANY_NAME: 136ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon companyName = getValue(); 137ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 138ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_JOB_TITLE: 139ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon title = getValue(); 140ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 141ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_EMAIL1_ADDRESS: 142ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_EMAIL2_ADDRESS: 143ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_EMAIL3_ADDRESS: 144ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon emails.add(new EmailRow(getValue())); 145ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 146ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS2_TELEPHONE_NUMBER: 147ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_TELEPHONE_NUMBER: 148ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon workPhones.add(new PhoneRow(getValue(), Phone.TYPE_WORK)); 149ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 150ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_MMS: 151ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_MMS, getValue()); 152ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 153ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_FAX_NUMBER: 154ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_FAX_WORK, getValue()); 155ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 156ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_COMPANY_MAIN_PHONE: 157ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_COMPANY_MAIN, getValue()); 158ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 159ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_FAX_NUMBER: 160ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_FAX_HOME, getValue()); 161ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 162ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_TELEPHONE_NUMBER: 163ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME2_TELEPHONE_NUMBER: 164ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon homePhones.add(new PhoneRow(getValue(), Phone.TYPE_HOME)); 165ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 166ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_MOBILE_TELEPHONE_NUMBER: 167ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_MOBILE, getValue()); 168ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 169ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_CAR_TELEPHONE_NUMBER: 170ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_CAR, getValue()); 171ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 172ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_RADIO_TELEPHONE_NUMBER: 173ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_RADIO, getValue()); 174ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 175ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_PAGER_NUMBER: 176ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_PAGER, getValue()); 177ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 178ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_ASSISTANT_TELEPHONE_NUMBER: 179ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhone(entity, Phone.TYPE_ASSISTANT, getValue()); 180ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 181ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_IM_ADDRESS: 182ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_IM_ADDRESS_2: 183ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_IM_ADDRESS_3: 184ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ims.add(new ImRow(getValue())); 185ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 186ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_ADDRESS_CITY: 187ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon work.city = getValue(); 188ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 189ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_ADDRESS_COUNTRY: 190ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon work.country = getValue(); 191ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 192ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_ADDRESS_POSTAL_CODE: 193ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon work.code = getValue(); 194ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 195ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_ADDRESS_STATE: 196ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon work.state = getValue(); 197ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 198ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BUSINESS_ADDRESS_STREET: 199ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon work.street = getValue(); 200ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 201ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_ADDRESS_CITY: 202ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon home.city = getValue(); 203ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 204ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_ADDRESS_COUNTRY: 205ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon home.country = getValue(); 206ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 207ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_ADDRESS_POSTAL_CODE: 208ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon home.code = getValue(); 209ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 210ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_ADDRESS_STATE: 211ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon home.state = getValue(); 212ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 213ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_HOME_ADDRESS_STREET: 214ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon home.street = getValue(); 215ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 216ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_OTHER_ADDRESS_CITY: 217ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon other.city = getValue(); 218ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 219ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_OTHER_ADDRESS_COUNTRY: 220ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon other.country = getValue(); 221ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 222ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_OTHER_ADDRESS_POSTAL_CODE: 223ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon other.code = getValue(); 224ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 225ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_OTHER_ADDRESS_STATE: 226ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon other.state = getValue(); 227ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 228ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_OTHER_ADDRESS_STREET: 229ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon other.street = getValue(); 230ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 231ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 232ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_CHILDREN: 233ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon childrenParser(children); 234ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 235ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 236ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_YOMI_COMPANY_NAME: 237ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon yomiCompanyName = getValue(); 238ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 239ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_YOMI_FIRST_NAME: 240ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon yomiFirstName = getValue(); 241ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 242ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_YOMI_LAST_NAME: 243ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon yomiLastName = getValue(); 244ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 245ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 246ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_NICKNAME: 247ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addNickname(entity, getValue()); 248ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 249ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 250ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_ASSISTANT_NAME: 251ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addRelation(entity, Relation.TYPE_ASSISTANT, getValue()); 252ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 253ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_MANAGER_NAME: 254ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addRelation(entity, Relation.TYPE_MANAGER, getValue()); 255ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 256ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_SPOUSE: 257ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addRelation(entity, Relation.TYPE_SPOUSE, getValue()); 258ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 259ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_DEPARTMENT: 260ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon department = getValue(); 261ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 262ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_TITLE: 263ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon prefix = getValue(); 264ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 265ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 266ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // EAS Business 267ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_OFFICE_LOCATION: 268ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon officeLocation = getValue(); 269ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 270ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_CUSTOMER_ID: 271ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon business.customerId = getValue(); 272ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 273ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_GOVERNMENT_ID: 274ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon business.governmentId = getValue(); 275ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 276ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS2_ACCOUNT_NAME: 277ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon business.accountName = getValue(); 278ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 279ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 280ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // EAS Personal 281ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_ANNIVERSARY: 282ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon personal.anniversary = getValue(); 283ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 284102e1cf9d34fceebbad64356e58e3427ee4e6da4Anthony Lee case Tags.CONTACTS_FILE_AS: 285102e1cf9d34fceebbad64356e58e3427ee4e6da4Anthony Lee personal.fileAs = getValue(); 286102e1cf9d34fceebbad64356e58e3427ee4e6da4Anthony Lee break; 287ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BIRTHDAY: 288ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addBirthday(entity, getValue()); 289ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 290ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_WEBPAGE: 291ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addWebpage(entity, getValue()); 292ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 293ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 294ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_PICTURE: 295ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPhoto(entity, getValue()); 296ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 297ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 298ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.BASE_BODY: 299ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addNote(entity, bodyParser()); 300ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 301ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_BODY: 302ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addNote(entity, getValue()); 303ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 304ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 305ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_CATEGORIES: 306ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mGroupsUsed = true; 307ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon categoriesParser(ops, entity); 308ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 309ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 310ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 311ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 312ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 313ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 314ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 315ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addName(entity, prefix, firstName, lastName, middleName, suffix, 316ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon yomiFirstName, yomiLastName); 317ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addBusiness(entity, business); 318ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPersonal(entity, personal); 319ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 320ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addUntyped(entity, emails, Email.CONTENT_ITEM_TYPE, -1, MAX_EMAIL_ROWS); 321ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addUntyped(entity, ims, Im.CONTENT_ITEM_TYPE, -1, MAX_IM_ROWS); 322ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addUntyped(entity, homePhones, Phone.CONTENT_ITEM_TYPE, Phone.TYPE_HOME, 323ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon MAX_PHONE_ROWS); 324ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addUntyped(entity, workPhones, Phone.CONTENT_ITEM_TYPE, Phone.TYPE_WORK, 325ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon MAX_PHONE_ROWS); 326ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 327ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!children.isEmpty()) { 328ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addChildren(entity, children); 329ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 330ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 331ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (work.hasData()) { 332ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPostal(entity, StructuredPostal.TYPE_WORK, work.street, work.city, 333ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon work.state, work.country, work.code); 334ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 335ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (home.hasData()) { 336ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPostal(entity, StructuredPostal.TYPE_HOME, home.street, home.city, 337ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon home.state, home.country, home.code); 338ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 339ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (other.hasData()) { 340ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addPostal(entity, StructuredPostal.TYPE_OTHER, other.street, other.city, 341ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon other.state, other.country, other.code); 342ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 343ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 344ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (companyName != null) { 345ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addOrganization(entity, Organization.TYPE_WORK, companyName, title, department, 346ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon yomiCompanyName, officeLocation); 347ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 348ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 349ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (entity != null) { 350ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // We've been removing rows from the list as they've been found in the xml 351ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Any that are left must have been deleted on the server 352ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<NamedContentValues> ncvList = entity.getSubValues(); 353ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (NamedContentValues ncv: ncvList) { 354ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // These rows need to be deleted... 355ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Uri u = dataUriFromNamedContentValues(ncv); 356ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.add(ContentProviderOperation.newDelete(addCallerIsSyncAdapterParameter(u)) 357ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .build()); 358ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 359ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 360ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 361ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 362ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private void categoriesParser(ContactOperations ops, Entity entity) throws IOException { 363ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.CONTACTS_CATEGORIES) != END) { 364ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 365ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_CATEGORY: 366ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.addGroup(entity, getValue()); 367ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 368ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 369ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 370ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 371ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 372ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 373ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 374ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private void childrenParser(ArrayList<String> children) throws IOException { 375ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.CONTACTS_CHILDREN) != END) { 376ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 377ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.CONTACTS_CHILD: 378ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (children.size() < EasChildren.MAX_CHILDREN) { 379ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon children.add(getValue()); 380ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 381ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 382ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 383ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 384ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 385ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 386ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 387ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 388ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private String bodyParser() throws IOException { 389ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String body = null; 390ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.BASE_BODY) != END) { 391ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 392ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.BASE_DATA: 393ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon body = getValue(); 394ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 395ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 396ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 397ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 398ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 399ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return body; 400ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 401ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 402ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addParser(ContactOperations ops) throws IOException { 403ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String serverId = null; 404ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_ADD) != END) { 405ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 406ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_SERVER_ID: // same as 407ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon serverId = getValue(); 408ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 409ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_APPLICATION_DATA: 410ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addData(serverId, ops, null); 411ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 412ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 413ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 414ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 415ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 416ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 417ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 418ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private Cursor getServerIdCursor(String serverId) { 419ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mBindArgument[0] = serverId; 420ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return mContentResolver.query(mAccountUri, ID_PROJECTION, SERVER_ID_SELECTION, 421ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mBindArgument, null); 422ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 423ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 424ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private Cursor getClientIdCursor(String clientId) { 425ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mBindArgument[0] = clientId; 426ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return mContentResolver.query(mAccountUri, ID_PROJECTION, CLIENT_ID_SELECTION, 427ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mBindArgument, null); 428ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 429ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 430ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void deleteParser(ContactOperations ops) throws IOException { 431ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_DELETE) != END) { 432ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 433ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_SERVER_ID: 434ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String serverId = getValue(); 435ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Find the message in this mailbox with the given serverId 436ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Cursor c = getServerIdCursor(serverId); 437ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon try { 438ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (c.moveToFirst()) { 439ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon userLog("Deleting ", serverId); 440ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.delete(c.getLong(0)); 441ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 442ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } finally { 443ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon c.close(); 444ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 445ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 446ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 447ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 448ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 449ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 450ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 451ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 452ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon class ServerChange { 453ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon long id; 454ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon boolean read; 455ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 456ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ServerChange(long _id, boolean _read) { 457ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon id = _id; 458ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon read = _read; 459ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 460ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 461ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 462ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 463ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * Changes are handled row by row, and only changed/new rows are acted upon 464ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param ops the array of pending ContactProviderOperations. 465ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @throws IOException 466ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 467ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void changeParser(ContactOperations ops) throws IOException { 468ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String serverId = null; 469ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Entity entity = null; 470ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_CHANGE) != END) { 471ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 472ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_SERVER_ID: 473ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon serverId = getValue(); 474ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Cursor c = getServerIdCursor(serverId); 475ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon try { 476ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (c.moveToFirst()) { 477ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // TODO Handle deleted individual rows... 478ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Uri uri = ContentUris.withAppendedId( 479ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RawContacts.CONTENT_URI, c.getLong(0)); 480ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon uri = Uri.withAppendedPath( 481ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon uri, RawContacts.Entity.CONTENT_DIRECTORY); 482185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner final Cursor cursor = mContentResolver.query(uri, 483185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner null, null, null, null); 484185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner if (cursor != null) { 485185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner final EntityIterator entityIterator = 486185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner RawContacts.newEntityIterator(cursor); 487185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner if (entityIterator.hasNext()) { 488185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner entity = entityIterator.next(); 489185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner } 490185060cbeb39dc4539fbc0c72a865d8ec8d12979Jay Shrauner userLog("Changing contact ", serverId); 491ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 492ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 493ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } finally { 494ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon c.close(); 495ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 496ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 497ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_APPLICATION_DATA: 498ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addData(serverId, ops, entity); 499ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 500ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 501ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 502ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 503ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 504ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 505ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 506ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 507ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void commandsParser() throws IOException { 508ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_COMMANDS) != END) { 509ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (tag == Tags.SYNC_ADD) { 510ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addParser(ops); 511ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else if (tag == Tags.SYNC_DELETE) { 512ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon deleteParser(ops); 513ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else if (tag == Tags.SYNC_CHANGE) { 514ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon changeParser(ops); 515ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else 516ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 517ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 518ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 519ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 520ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 521ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void commit() throws IOException { 522ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Save the syncKey here, using the Helper provider by Contacts provider 523ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon userLog("Contacts SyncKey saved as: ", mMailbox.mSyncKey); 524ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.add(SyncStateContract.Helpers.newSetOperation(SyncState.CONTENT_URI, 525ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mAccountManagerAccount, mMailbox.mSyncKey.getBytes())); 526ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 527ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Execute these all at once... 528ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.execute(mContext); 529ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 530d34e08dade60d10a9751920f928fe0d02f58ac4cJay Shrauner if (ops.mResults != null && ops.mResults.length > 0) { 531d34e08dade60d10a9751920f928fe0d02f58ac4cJay Shrauner final ContentValues cv = new ContentValues(); 532ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cv.put(RawContacts.DIRTY, 0); 533ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (int i = 0; i < ops.mContactIndexCount; i++) { 534d34e08dade60d10a9751920f928fe0d02f58ac4cJay Shrauner final int index = ops.mContactIndexArray[i]; 535d34e08dade60d10a9751920f928fe0d02f58ac4cJay Shrauner final Uri u = index < ops.mResults.length ? ops.mResults[index].uri : null; 536ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (u != null) { 537ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String idString = u.getLastPathSegment(); 538ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mContentResolver.update( 539ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI), cv, 540ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RawContacts._ID + "=" + idString, null); 541ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 542ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 543ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 544ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 545ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 546ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addResponsesParser() throws IOException { 547ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String serverId = null; 548ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String clientId = null; 549ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = new ContentValues(); 550ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_ADD) != END) { 551ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 552ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_SERVER_ID: 553ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon serverId = getValue(); 554ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 555ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_CLIENT_ID: 556ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon clientId = getValue(); 557ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 558ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_STATUS: 559ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon getValue(); 560ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 561ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 562ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 563ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 564ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 565ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 566ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // This is theoretically impossible, but... 567ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (clientId == null || serverId == null) return; 568ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 569ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Cursor c = getClientIdCursor(clientId); 570ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon try { 571ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (c.moveToFirst()) { 572ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cv.put(RawContacts.SOURCE_ID, serverId); 573ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cv.put(RawContacts.DIRTY, 0); 574ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ops.add(ContentProviderOperation.newUpdate( 575ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentUris.withAppendedId( 576ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI), 577ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon c.getLong(0))) 578ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .withValues(cv) 579ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .build()); 580ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon userLog("New contact " + clientId + " was given serverId: " + serverId); 581ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 582ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } finally { 583ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon c.close(); 584ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 585ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 586ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 587ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void changeResponsesParser() throws IOException { 588ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String serverId = null; 589ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String status = null; 590ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_CHANGE) != END) { 591ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon switch (tag) { 592ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_SERVER_ID: 593ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon serverId = getValue(); 594ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 595ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon case Tags.SYNC_STATUS: 596ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon status = getValue(); 597ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 598ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon default: 599ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 600ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 601ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 602ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (serverId != null && status != null) { 603ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon userLog("Changed contact " + serverId + " failed with status: " + status); 604ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 605ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 606ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 607ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 608ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 609ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void responsesParser() throws IOException { 610ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Handle server responses here (for Add and Change) 611ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon while (nextTag(Tags.SYNC_RESPONSES) != END) { 612ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (tag == Tags.SYNC_ADD) { 613ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addResponsesParser(); 614ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else if (tag == Tags.SYNC_CHANGE) { 615ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon changeResponsesParser(); 616ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else 617ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon skipTag(); 618ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 619ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 620ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 621ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static Uri uriWithAccountAndIsSyncAdapter(final Uri uri, final String emailAddress) { 622ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return uri.buildUpon() 623ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .appendQueryParameter(RawContacts.ACCOUNT_NAME, emailAddress) 624ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .appendQueryParameter(RawContacts.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE) 625ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") 626ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .build(); 627ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 628ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 629ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon static Uri addCallerIsSyncAdapterParameter(Uri uri) { 630ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return uri.buildUpon() 631ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") 632ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .build(); 633ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 634ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 635ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 636ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * Generate the uri for the data row associated with this NamedContentValues object 637ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param ncv the NamedContentValues object 638ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @return a uri that can be used to refer to this row 639ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 640ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static Uri dataUriFromNamedContentValues(NamedContentValues ncv) { 641ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon long id = ncv.values.getAsLong(RawContacts._ID); 642ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Uri dataUri = ContentUris.withAppendedId(ncv.uri, id); 643ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return dataUri; 644ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 645ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 646ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final class EasChildren { 647ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private EasChildren() {} 648ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 649ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** MIME type used when storing this in data table. */ 650ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_children"; 651ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final int MAX_CHILDREN = 8; 652ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String[] ROWS = 653ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon new String[] {"data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9"}; 654ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 655ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 656ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final class EasPersonal { 657ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String anniversary; 658ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String fileAs; 659ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 660ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** MIME type used when storing this in data table. */ 661ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_personal"; 662ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String ANNIVERSARY = "data2"; 663ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String FILE_AS = "data4"; 664ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 665ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon boolean hasData() { 666ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return anniversary != null || fileAs != null; 667ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 668ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 669ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 670ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final class EasBusiness { 671ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String customerId; 672ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String governmentId; 673ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String accountName; 674ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 675ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** MIME type used when storing this in data table. */ 676ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_business"; 677ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String CUSTOMER_ID = "data6"; 678ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String GOVERNMENT_ID = "data7"; 679ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final String ACCOUNT_NAME = "data8"; 680ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 681ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon boolean hasData() { 682ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return customerId != null || governmentId != null || accountName != null; 683ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 684ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 685ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 686ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static final class Address { 687ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String city; 688ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String country; 689ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String code; 690ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String street; 691ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String state; 692ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 693ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon boolean hasData() { 694ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return city != null || country != null || code != null || state != null 695ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon || street != null; 696ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 697ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 698ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 699ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon interface UntypedRow { 700ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addValues(RowBuilder builder); 701ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public boolean isSameAs(int type, String value); 702ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 703ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 704ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon static class EmailRow implements UntypedRow { 705ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String email; 706ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String displayName; 707ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 708ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public EmailRow(String _email) { 709ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(_email); 710ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Can't happen, but belt & suspenders 711ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (tokens.length == 0) { 712ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon email = ""; 713ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon displayName = ""; 714ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else { 715ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Rfc822Token token = tokens[0]; 716ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon email = token.getAddress(); 717ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon displayName = token.getName(); 718ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 719ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 720ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 721ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 722ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addValues(RowBuilder builder) { 723ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Email.DATA, email); 724ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Email.DISPLAY_NAME, displayName); 725ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 726ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 727ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 728ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public boolean isSameAs(int type, String value) { 729ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return email.equalsIgnoreCase(value); 730ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 731ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 732ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 733ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon static class ImRow implements UntypedRow { 734ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String im; 735ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 736ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public ImRow(String _im) { 737ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon im = _im; 738ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 739ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 740ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 741ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addValues(RowBuilder builder) { 742ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Im.DATA, im); 743ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 744ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 745ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 746ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public boolean isSameAs(int type, String value) { 747ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return im.equalsIgnoreCase(value); 748ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 749ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 750ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 751ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon static class PhoneRow implements UntypedRow { 752ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String phone; 753ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int type; 754ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 755ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public PhoneRow(String _phone, int _type) { 756ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon phone = _phone; 757ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon type = _type; 758ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 759ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 760ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 761ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addValues(RowBuilder builder) { 762ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Im.DATA, phone); 763ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Phone.TYPE, type); 764ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 765ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 766ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 767ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public boolean isSameAs(int _type, String value) { 768ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return type == _type && phone.equalsIgnoreCase(value); 769ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 770ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 771ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 772ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 773ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * RowBuilder is a wrapper for the Builder class that is used to create/update rows for a 774ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * ContentProvider. It has, in addition to the Builder, ContentValues which, if present, 775ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * represent the current values of that row, that can be compared against current values to 776ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * see whether an update is even necessary. The methods on SmartBuilder are delegated to 777ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * the Builder. 778ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 779ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static class RowBuilder { 780ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Builder builder; 781ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv; 782ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 783ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public RowBuilder(Builder _builder) { 784ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder = _builder; 785ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 786ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 787ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public RowBuilder(Builder _builder, NamedContentValues _ncv) { 788ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder = _builder; 789ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cv = _ncv.values; 790ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 791ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 792ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder withValueBackReference(String key, int previousResult) { 793ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValueBackReference(key, previousResult); 794ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return this; 795ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 796ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 797ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentProviderOperation build() { 798ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return builder.build(); 799ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 800ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 801ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder withValue(String key, Object value) { 802ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(key, value); 803ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return this; 804ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 805ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 806ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public static class ContactOperations extends ArrayList<ContentProviderOperation> { 807ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static final long serialVersionUID = 1L; 808ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private int mCount = 0; 809ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private int mContactBackValue = mCount; 8105b874897559eb3ad6ac777c7317cfd5d253704f9Yu Ping Hu // Make an array big enough for the max possible window size. 8116cb6c70ea47035a27bd1d808babe39a2d1829c8dYu Ping Hu private final int[] mContactIndexArray = new int[EasSyncCollectionTypeBase.MAX_WINDOW_SIZE]; 812ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private int mContactIndexCount = 0; 813ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private ContentProviderResult[] mResults = null; 814ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 815ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon @Override 816ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public boolean add(ContentProviderOperation op) { 817ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon super.add(op); 818ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mCount++; 819ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return true; 820ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 821ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 822ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void newContact(final String serverId, final String emailAddress) { 823ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon Builder builder = ContentProviderOperation.newInsert( 824ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI, emailAddress)); 825ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues values = new ContentValues(); 826ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon values.put(RawContacts.SOURCE_ID, serverId); 827ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValues(values); 828ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mContactBackValue = mCount; 829ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mContactIndexArray[mContactIndexCount++] = mCount; 830ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 831ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 832ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 833ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void delete(long id) { 834ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(ContentProviderOperation 835ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .newDelete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, id) 836ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .buildUpon() 837ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") 838ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .build()) 839ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .build()); 840ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 841ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 842ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void execute(final Context context) { 843ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon try { 844ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!isEmpty()) { 845ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon mResults = context.getContentResolver().applyBatch( 846ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContactsContract.AUTHORITY, this); 847ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 848ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } catch (RemoteException e) { 849ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // There is nothing sensible to be done here 850ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon LogUtils.e(TAG, "problem inserting contact during server update", e); 851ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } catch (OperationApplicationException e) { 852ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // There is nothing sensible to be done here 853ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon LogUtils.e(TAG, "problem inserting contact during server update", e); 8540c0fdc5dfe605eb4b2047d4a7a89bcce5b2aa813Jay Shrauner } catch (IllegalArgumentException e) { 8550c0fdc5dfe605eb4b2047d4a7a89bcce5b2aa813Jay Shrauner // CP2 has been disabled 8560c0fdc5dfe605eb4b2047d4a7a89bcce5b2aa813Jay Shrauner LogUtils.e(TAG, "CP2 is disabled; unable to insert contact."); 857ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 858ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 859ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 860ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 861ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * Given the list of NamedContentValues for an entity, a mime type, and a subtype, 862ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * tries to find a match, returning it 863ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param list the list of NCV's from the contact entity 864ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param contentItemType the mime type we're looking for 865ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param type the subtype (e.g. HOME, WORK, etc.) 866ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @return the matching NCV or null if not found 867ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 868ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static NamedContentValues findTypedData(ArrayList<NamedContentValues> list, 869ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String contentItemType, int type, String stringType) { 870ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon NamedContentValues result = null; 8716cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner if (contentItemType == null) { 8726cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner return result; 8736cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner } 874ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 875ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Loop through the ncv's, looking for an existing row 876ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (NamedContentValues namedContentValues: list) { 8776cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final Uri uri = namedContentValues.uri; 8786cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final ContentValues cv = namedContentValues.values; 879ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (Data.CONTENT_URI.equals(uri)) { 8806cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final String mimeType = cv.getAsString(Data.MIMETYPE); 8816cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner if (TextUtils.equals(mimeType, contentItemType)) { 882ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (stringType != null) { 883ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv.getAsString(GroupMembership.GROUP_ROW_ID).equals(stringType)) { 884ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon result = namedContentValues; 885ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 886ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Note Email.TYPE could be ANY type column; they are all defined in 887ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // the private CommonColumns class in ContactsContract 888ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // We'll accept either type < 0 (don't care), cv doesn't have a type, 889ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // or the types are equal 890ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else if (type < 0 || !cv.containsKey(Email.TYPE) || 891ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cv.getAsInteger(Email.TYPE) == type) { 892ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon result = namedContentValues; 893ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 894ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 895ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 896ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 897ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 898ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // If we've found an existing data row, we'll delete it. Any rows left at the 899ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // end should be deleted... 900ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (result != null) { 901ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon list.remove(result); 902ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 903ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 904ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Return the row found (or null) 905ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return result; 906ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 907ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 908ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 909ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * Given the list of NamedContentValues for an entity and a mime type 910ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * gather all of the matching NCV's, returning them 911ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param list the list of NCV's from the contact entity 912ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param contentItemType the mime type we're looking for 913ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param type the subtype (e.g. HOME, WORK, etc.) 914ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @return the matching NCVs 915ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 916ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static ArrayList<NamedContentValues> findUntypedData( 917ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<NamedContentValues> list, int type, String contentItemType) { 9186cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final ArrayList<NamedContentValues> result = new ArrayList<NamedContentValues>(); 9196cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner if (contentItemType == null) { 9206cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner return result; 9216cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner } 922ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 923ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Loop through the ncv's, looking for an existing row 924ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (NamedContentValues namedContentValues: list) { 9256cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final Uri uri = namedContentValues.uri; 9266cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final ContentValues cv = namedContentValues.values; 927ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (Data.CONTENT_URI.equals(uri)) { 9286cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final String mimeType = cv.getAsString(Data.MIMETYPE); 9296cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner if (TextUtils.equals(mimeType, contentItemType)) { 930ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (type != -1) { 9316cf9c927628e2d5d84f5983f4e1737e6e448485eJay Shrauner final int subtype = cv.getAsInteger(Phone.TYPE); 932ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (type != subtype) { 933ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon continue; 934ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 935ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 936ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon result.add(namedContentValues); 937ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 938ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 939ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 940ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 941ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // If we've found an existing data row, we'll delete it. Any rows left at the 942ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // end should be deleted... 943ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (NamedContentValues values : result) { 944ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon list.remove(values); 945ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 946ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 947ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Return the row found (or null) 948ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return result; 949ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 950ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 951ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 952ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * Create a wrapper for a builder (insert or update) that also includes the NCV for 953ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * an existing row of this type. If the SmartBuilder's cv field is not null, then 954ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * it represents the current (old) values of this field. The caller can then check 955ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * whether the field is now different and needs to be updated; if it's not different, 956ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * the caller will simply return and not generate a new CPO. Otherwise, the builder 957ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * should have its content values set, and the built CPO should be added to the 958ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * ContactOperations list. 959ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * 960ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param entity the contact entity (or null if this is a new contact) 961ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param mimeType the mime type of this row 962ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param type the subtype of this row 963ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param stringType for groups, the name of the group (type will be ignored), or null 964ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @return the created SmartBuilder 965ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 966ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public RowBuilder createBuilder(Entity entity, String mimeType, int type, 967ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String stringType) { 968ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = null; 969ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 970ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (entity != null) { 971ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon NamedContentValues ncv = 972ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon findTypedData(entity.getSubValues(), mimeType, type, stringType); 973ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (ncv != null) { 974ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder = new RowBuilder( 975ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentProviderOperation 976ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .newUpdate(addCallerIsSyncAdapterParameter( 977ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon dataUriFromNamedContentValues(ncv))), 978ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ncv); 979ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 980ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 981ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 982ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (builder == null) { 983ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder = newRowBuilder(entity, mimeType); 984ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 985ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 986ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Return the appropriate builder (insert or update) 987ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Caller will fill in the appropriate values; 4 MIMETYPE is already set 988ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return builder; 989ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 990ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 991ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private RowBuilder typedRowBuilder(Entity entity, String mimeType, int type) { 992ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return createBuilder(entity, mimeType, type, null); 993ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 994ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 995ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private RowBuilder untypedRowBuilder(Entity entity, String mimeType) { 996ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return createBuilder(entity, mimeType, -1, null); 997ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 998ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 999ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private RowBuilder newRowBuilder(Entity entity, String mimeType) { 1000ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // This is a new row; first get the contactId 1001ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // If the Contact is new, use the saved back value; otherwise the value in the entity 1002ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int contactId = mContactBackValue; 1003ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (entity != null) { 1004ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon contactId = entity.getEntityValues().getAsInteger(RawContacts._ID); 1005ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1006ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1007ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Create an insert operation with the proper contactId reference 1008ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = 1009ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon new RowBuilder(ContentProviderOperation.newInsert( 1010ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon addCallerIsSyncAdapterParameter(Data.CONTENT_URI))); 1011ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (entity == null) { 1012ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValueBackReference(Data.RAW_CONTACT_ID, contactId); 1013ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else { 1014ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Data.RAW_CONTACT_ID, contactId); 1015ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1016ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1017ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Set the mime type of the row 1018ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Data.MIMETYPE, mimeType); 1019ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return builder; 1020ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1021ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1022ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 1023ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * Compare a column in a ContentValues with an (old) value, and see if they are the 1024ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * same. For this purpose, null and an empty string are considered the same. 1025ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param cv a ContentValues object, from a NamedContentValues 1026ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param column a column that might be in the ContentValues 1027ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @param oldValue an old value (or null) to check against 1028ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * @return whether the column's value in the ContentValues matches oldValue 1029ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 1030ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon private static boolean cvCompareString(ContentValues cv, String column, String oldValue) { 1031ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv.containsKey(column)) { 1032ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (oldValue != null && cv.getAsString(column).equals(oldValue)) { 1033ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return true; 1034ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1035ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else if (oldValue == null || oldValue.length() == 0) { 1036ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return true; 1037ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1038ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return false; 1039ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1040ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1041ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addChildren(Entity entity, ArrayList<String> children) { 1042ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = untypedRowBuilder(entity, EasChildren.CONTENT_ITEM_TYPE); 1043ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int i = 0; 1044ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (String child: children) { 1045ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(EasChildren.ROWS[i++], child); 1046ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1047ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1048ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1049ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1050ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addGroup(Entity entity, String group) { 1051ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = 1052ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon createBuilder(entity, GroupMembership.CONTENT_ITEM_TYPE, -1, group); 1053ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(GroupMembership.GROUP_SOURCE_ID, group); 1054ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1055ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1056ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1057ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addBirthday(Entity entity, String birthday) { 1058ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = 1059ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon typedRowBuilder(entity, Event.CONTENT_ITEM_TYPE, Event.TYPE_BIRTHDAY); 1060ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1061ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Event.START_DATE, birthday)) { 1062ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1063ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1064ab9c23bcf59ec01a3dd79000b7b4136791a9db65Yu Ping Hu // TODO: Store the date in the format expected by EAS servers. 10652f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner final long millis; 10662f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner try { 10672f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner millis = Utility.parseEmailDateTimeToMillis(birthday); 10682f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner } catch (ParseException e) { 10692f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner LogUtils.w(TAG, "Parse error for birthday date field.", e); 10702f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner return; 10712f369a47e14916a34f49c79c0a246a2e3ac3072fJay Shrauner } 1072ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); 1073ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cal.setTimeInMillis(millis); 1074ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cal.get(GregorianCalendar.HOUR_OF_DAY) >= 12) { 1075ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cal.add(GregorianCalendar.DATE, 1); 1076ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1077ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String realBirthday = CalendarUtilities.calendarToBirthdayString(cal); 1078ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Event.START_DATE, realBirthday); 1079ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY); 1080ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1081ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1082ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1083ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addName(Entity entity, String prefix, String givenName, String familyName, 1084ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String middleName, String suffix, String yomiFirstName, String yomiLastName) { 1085ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = untypedRowBuilder(entity, StructuredName.CONTENT_ITEM_TYPE); 1086ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1087ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, StructuredName.GIVEN_NAME, givenName) && 1088ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredName.FAMILY_NAME, familyName) && 1089ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredName.MIDDLE_NAME, middleName) && 1090ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredName.PREFIX, prefix) && 1091ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredName.PHONETIC_GIVEN_NAME, yomiFirstName) && 1092ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredName.PHONETIC_FAMILY_NAME, yomiLastName) && 1093ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredName.SUFFIX, suffix)) { 1094ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1095ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1096ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.GIVEN_NAME, givenName); 1097ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.FAMILY_NAME, familyName); 1098ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.MIDDLE_NAME, middleName); 1099ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.SUFFIX, suffix); 1100ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, yomiFirstName); 1101ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, yomiLastName); 1102ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredName.PREFIX, prefix); 1103ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1104ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1105ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1106ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addPersonal(Entity entity, EasPersonal personal) { 1107ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = untypedRowBuilder(entity, EasPersonal.CONTENT_ITEM_TYPE); 1108ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1109ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, EasPersonal.ANNIVERSARY, personal.anniversary) && 1110ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, EasPersonal.FILE_AS , personal.fileAs)) { 1111ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1112ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1113ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!personal.hasData()) { 1114ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1115ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1116ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(EasPersonal.FILE_AS, personal.fileAs); 1117ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(EasPersonal.ANNIVERSARY, personal.anniversary); 1118ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1119ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1120ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1121ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addBusiness(Entity entity, EasBusiness business) { 1122ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = untypedRowBuilder(entity, EasBusiness.CONTENT_ITEM_TYPE); 1123ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1124ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, EasBusiness.ACCOUNT_NAME, business.accountName) && 1125ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, EasBusiness.CUSTOMER_ID, business.customerId) && 1126ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, EasBusiness.GOVERNMENT_ID, business.governmentId)) { 1127ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1128ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1129ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!business.hasData()) { 1130ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1131ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1132ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(EasBusiness.ACCOUNT_NAME, business.accountName); 1133ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(EasBusiness.CUSTOMER_ID, business.customerId); 1134ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(EasBusiness.GOVERNMENT_ID, business.governmentId); 1135ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1136ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1137ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1138ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addPhoto(Entity entity, String photo) { 1139ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // We're always going to add this; it's not worth trying to figure out whether the 1140ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // picture is the same as the one stored. 11417c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner final byte[] pic; 11427c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner try { 11437c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner pic = Base64.decode(photo, Base64.DEFAULT); 11447c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner } catch (IllegalArgumentException e) { 11457c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner LogUtils.w(TAG, "Bad base-64 encoding; unable to decode photo."); 11467c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner return; 11477c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner } 11487c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner 11497c3686eae16af8c7873e114976c67f4c8b62bc60Jay Shrauner final RowBuilder builder = untypedRowBuilder(entity, Photo.CONTENT_ITEM_TYPE); 1150ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Photo.PHOTO, pic); 1151ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1152ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1153ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1154ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addPhone(Entity entity, int type, String phone) { 1155ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = typedRowBuilder(entity, Phone.CONTENT_ITEM_TYPE, type); 1156ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1157ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Phone.NUMBER, phone)) { 1158ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1159ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1160ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Phone.TYPE, type); 1161ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Phone.NUMBER, phone); 1162ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1163ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1164ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1165ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addWebpage(Entity entity, String url) { 1166ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = untypedRowBuilder(entity, Website.CONTENT_ITEM_TYPE); 1167ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1168ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Website.URL, url)) { 1169ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1170ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1171ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Website.TYPE, Website.TYPE_WORK); 1172ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Website.URL, url); 1173ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1174ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1175ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1176ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addRelation(Entity entity, int type, String value) { 1177ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = typedRowBuilder(entity, Relation.CONTENT_ITEM_TYPE, type); 1178ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1179ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Relation.DATA, value)) { 1180ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1181ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1182ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Relation.TYPE, type); 1183ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Relation.DATA, value); 1184ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1185ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1186ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1187ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addNickname(Entity entity, String name) { 1188ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = 1189ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon typedRowBuilder(entity, Nickname.CONTENT_ITEM_TYPE, Nickname.TYPE_DEFAULT); 1190ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1191ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Nickname.NAME, name)) { 1192ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1193ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1194ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT); 1195ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Nickname.NAME, name); 1196ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1197ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1198ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1199ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addPostal(Entity entity, int type, String street, String city, String state, 1200ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String country, String code) { 1201ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = typedRowBuilder(entity, StructuredPostal.CONTENT_ITEM_TYPE, 1202ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon type); 1203ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1204ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, StructuredPostal.CITY, city) && 1205ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredPostal.STREET, street) && 1206ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredPostal.COUNTRY, country) && 1207ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredPostal.POSTCODE, code) && 1208ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, StructuredPostal.REGION, state)) { 1209ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1210ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1211ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredPostal.TYPE, type); 1212ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredPostal.CITY, city); 1213ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredPostal.STREET, street); 1214ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredPostal.COUNTRY, country); 1215ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredPostal.POSTCODE, code); 1216ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(StructuredPostal.REGION, state); 1217ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1218ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1219ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1220ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon /** 1221ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * We now are dealing with up to maxRows typeless rows of mimeType data. We need to try to 1222ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * match them with existing rows; if there's a match, everything's great. Otherwise, we 1223ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * either need to add a new row for the data, or we have to replace an existing one 1224ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon * that no longer matches. This is similar to the way Emails are handled. 1225ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon */ 1226ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addUntyped(Entity entity, ArrayList<UntypedRow> rows, String mimeType, 1227ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int type, int maxRows) { 1228ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Make a list of all same type rows in the existing entity 1229ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<NamedContentValues> oldValues = EMPTY_ARRAY_NAMEDCONTENTVALUES; 1230ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<NamedContentValues> entityValues = EMPTY_ARRAY_NAMEDCONTENTVALUES; 1231ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (entity != null) { 1232ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon oldValues = findUntypedData(entityValues, type, mimeType); 1233ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon entityValues = entity.getSubValues(); 1234ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1235ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1236ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // These will be rows needing replacement with new values 1237ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ArrayList<UntypedRow> rowsToReplace = new ArrayList<UntypedRow>(); 1238ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1239ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // The count of existing rows 1240ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int numRows = oldValues.size(); 1241ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (UntypedRow row: rows) { 1242ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon boolean found = false; 1243ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // If we already have this row, mark it 1244ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (NamedContentValues ncv: oldValues) { 1245ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = ncv.values; 1246ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String data = cv.getAsString(COMMON_DATA_ROW); 1247ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int rowType = -1; 1248ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv.containsKey(COMMON_TYPE_ROW)) { 1249ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon rowType = cv.getAsInteger(COMMON_TYPE_ROW); 1250ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1251ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (row.isSameAs(rowType, data)) { 1252ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cv.put(FOUND_DATA_ROW, true); 1253ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Remove this to indicate it's still being used 1254ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon entityValues.remove(ncv); 1255ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon found = true; 1256ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 1257ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1258ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1259ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!found) { 1260ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // If we don't, there are two possibilities 1261ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (numRows < maxRows) { 1262ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // If there are available rows, add a new one 1263ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = newRowBuilder(entity, mimeType); 1264ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon row.addValues(builder); 1265ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1266ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon numRows++; 1267ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } else { 1268ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Otherwise, say we need to replace a row with this 1269ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon rowsToReplace.add(row); 1270ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1271ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1272ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1273ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1274ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Go through rows needing replacement 1275ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (UntypedRow row: rowsToReplace) { 1276ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (NamedContentValues ncv: oldValues) { 1277ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = ncv.values; 1278ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Find a row that hasn't been used (i.e. doesn't match current rows) 1279ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!cv.containsKey(FOUND_DATA_ROW)) { 1280ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // And update it 1281ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = new RowBuilder( 1282ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentProviderOperation 1283ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon .newUpdate(addCallerIsSyncAdapterParameter( 1284ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon dataUriFromNamedContentValues(ncv))), 1285ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ncv); 1286ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon row.addValues(builder); 1287ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1288ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1289ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1290ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1291ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1292ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1293ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addOrganization(Entity entity, int type, String company, String title, 1294ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon String department, String yomiCompanyName, String officeLocation) { 1295ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = typedRowBuilder(entity, Organization.CONTENT_ITEM_TYPE, type); 1296ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1297ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Organization.COMPANY, company) && 1298ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, Organization.PHONETIC_NAME, yomiCompanyName) && 1299ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, Organization.DEPARTMENT, department) && 1300ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, Organization.TITLE, title) && 1301ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon cvCompareString(cv, Organization.OFFICE_LOCATION, officeLocation)) { 1302ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1303ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1304ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Organization.TYPE, type); 1305ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Organization.COMPANY, company); 1306ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Organization.TITLE, title); 1307ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Organization.DEPARTMENT, department); 1308ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Organization.PHONETIC_NAME, yomiCompanyName); 1309ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Organization.OFFICE_LOCATION, officeLocation); 1310ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1311ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1312ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1313ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon public void addNote(Entity entity, String note) { 1314ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon RowBuilder builder = typedRowBuilder(entity, Note.CONTENT_ITEM_TYPE, -1); 1315ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon ContentValues cv = builder.cv; 1316ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (note == null) return; 1317ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon note = note.replaceAll("\r\n", "\n"); 1318ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (cv != null && cvCompareString(cv, Note.NOTE, note)) { 1319ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon return; 1320ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1321ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1322ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // Reject notes with nothing in them. Often, we get something from Outlook when 1323ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon // nothing was ever entered. Sigh. 1324ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int len = note.length(); 1325ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon int i = 0; 1326ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon for (; i < len; i++) { 1327ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon char c = note.charAt(i); 1328ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (!Character.isWhitespace(c)) { 1329ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon break; 1330ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1331ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1332ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon if (i == len) return; 1333ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon 1334ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon builder.withValue(Note.NOTE, note); 1335ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon add(builder.build()); 1336ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 1337ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon } 133828f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon 133928f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon @Override 134028f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon protected void wipe() { 134128f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon LogUtils.w(TAG, "Wiping contacts for account %d", mAccount.mId); 1342f4195d389ffd4d92e37cd1d01db1713180740291Yu Ping Hu EasSyncContacts.wipeAccountFromContentProvider(mContext, 134328f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon mAccount.mEmailAddress); 134428f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon } 1345ff9fed5ccdd57d5408e759f0ca6c41e79e09e999Martin Hibdon} 1346