/**
* galaxy inc.
* meetup client for android
*/
package com.galaxy.meetup.client.android.service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import com.galaxy.meetup.client.android.R;
import com.galaxy.meetup.client.android.api.DownloadImageOperation;
import com.galaxy.meetup.client.android.content.AvatarImageRequest;
import com.galaxy.meetup.client.android.content.EsAccount;
import com.galaxy.meetup.client.android.content.EsAccountsData;
import com.galaxy.meetup.client.android.content.EsAvatarData;
import com.galaxy.meetup.client.android.content.EsPeopleData;
import com.galaxy.meetup.client.android.content.EsProvider;
import com.galaxy.meetup.client.android.content.cache.EsMediaCache;
import com.galaxy.meetup.client.util.AccountsUtil;
import com.galaxy.meetup.client.util.EsLog;
import com.galaxy.meetup.client.util.ImageUtils;
import com.galaxy.meetup.server.client.domain.ContactTag;
import com.galaxy.meetup.server.client.domain.Contacts;
import com.galaxy.meetup.server.client.domain.DataCircleMemberPropertiesAddress;
import com.galaxy.meetup.server.client.domain.DataEmail;
import com.galaxy.meetup.server.client.domain.DataPhone;
import com.galaxy.meetup.server.client.domain.TaggedAddress;
import com.galaxy.meetup.server.client.domain.TaggedEmail;
import com.galaxy.meetup.server.client.domain.TaggedPhone;
/**
*
* @author sihai
*
*/
public class AndroidContactsSync {
private static final String ACTIVITY_PROJECTION[] = {
"activity_id", "embed_media", "total_comment_count", "plus_one_data", "loc", "original_author_name", "annotation", "title"
};
private static final Comparator ACTIVITY_STATE_COMPARATOR = new Comparator() {
public final int compare(Object obj, Object obj1)
{
int i;
ActivityState activitystate;
ActivityState activitystate1;
i = -1;
activitystate = (ActivityState)obj;
activitystate1 = (ActivityState)obj1;
if(!activitystate.exists || activitystate1.exists) {
if(activitystate.exists || !activitystate1.exists)
{
if(activitystate.created == activitystate1.created)
{
return activitystate.activityId.compareTo(activitystate1.activityId);
}
if(activitystate.created > activitystate1.created)
return -1;
}
i = 1;
}
return i;
}
};
private static final String ACTIVITY_SUMMARY_PROJECTION[] = {
"activity_id", "author_id", "created", "modified"
};
private static final String AVATAR_URL_PROJECTION[] = {
"gaia_id", "avatar"
};
private static final String CONTACTS_PROJECTION[] = {
"person_id", "last_updated_time", "for_sharing"
};
private static final Uri DISPLAY_PHOTO_CONTENT_MAX_DIMENSIONS_URI;
private static final String EMAIL_TYPE_CUSTOM = String.valueOf(0);
private static final String EMAIL_TYPE_HOME = String.valueOf(1);
private static final String EMAIL_TYPE_OTHER = String.valueOf(3);
private static final String EMAIL_TYPE_WORK = String.valueOf(2);
private static final String ENTITIES_PROJECTION[] = {
"sourceid", "mimetype", "data_id", "data1", "data2", "data3"
};
private static final String GROUPS_PROJECTION[] = {
"_id", "sourceid", "title"
};
private static final String LARGE_AVATAR_RAW_CONTACTS_PROJECTION[] = {
"_id", "sourceid", "sync2"
};
private static final String MY_PROFILE_PROJECTION[] = {
"name", "last_updated_time", "profile_proto"
};
private static final String PHONE_TYPE_ASSISTANT = String.valueOf(19);
private static final String PHONE_TYPE_CALLBACK = String.valueOf(8);
private static final String PHONE_TYPE_CAR = String.valueOf(9);
private static final String PHONE_TYPE_COMPANY_MAIN = String.valueOf(10);
private static final String PHONE_TYPE_CUSTOM = String.valueOf(0);
private static final String PHONE_TYPE_HOME = String.valueOf(1);
private static final String PHONE_TYPE_HOME_FAX = String.valueOf(5);
private static final String PHONE_TYPE_ISDN = String.valueOf(11);
private static final String PHONE_TYPE_MAIN = String.valueOf(12);
private static final String PHONE_TYPE_MOBILE = String.valueOf(2);
private static final String PHONE_TYPE_OTHER = String.valueOf(7);
private static final String PHONE_TYPE_OTHER_FAX = String.valueOf(13);
private static final String PHONE_TYPE_PAGER = String.valueOf(6);
private static final String PHONE_TYPE_RADIO = String.valueOf(14);
private static final String PHONE_TYPE_TELEX = String.valueOf(15);
private static final String PHONE_TYPE_TTY_TDD = String.valueOf(16);
private static final String PHONE_TYPE_WORK = String.valueOf(3);
private static final String PHONE_TYPE_WORK_FAX = String.valueOf(4);
private static final String PHONE_TYPE_WORK_MOBILE = String.valueOf(17);
private static final String PHONE_TYPE_WORK_PAGER = String.valueOf(18);
private static final String POSTAL_TYPE_CUSTOM = String.valueOf(0);
private static final String POSTAL_TYPE_HOME = String.valueOf(1);
private static final String POSTAL_TYPE_OTHER = String.valueOf(3);
private static final String POSTAL_TYPE_WORK = String.valueOf(2);
private static final Uri PROFILE_CONTENT_RAW_CONTACTS_URI;
private static final String PROFILE_ENTITIES_PROJECTION[] = {
"mimetype", "_id", "data1", "data2", "data3"
};
private static final String PROFILE_PROJECTION[] = {
"person_id", "name", "contact_proto"
};
public static final String PROFILE_RAW_CONTACT_PROJECTION[] = {
"_id", "sync1"
};
private static final String RAW_CONTACT_PROJECTION[] = {
"_id", "sourceid", "sync1"
};
private static final String RAW_CONTACT_REFRESH_PROJECTION[] = {
"_id", "account_type", "account_name", "data_set", "sourceid", "sync2", "sync4"
};
private static final String RAW_CONTACT_SOURCE_ID_PROJECTION[] = {
"_id", "sourceid"
};
public static final Uri STREAM_ITEMS_CONTENT_LIMIT_URI;
public static final Uri STREAM_ITEMS_PHOTO_URI;
private static final String STREAM_ITEMS_PROJECTION[] = {
"_id", "raw_contact_source_id", "stream_item_sync1", "timestamp", "stream_item_sync2"
};
public static final Uri STREAM_ITEMS_URI;
private static final String THUMBNAILS_RAW_CONTACT_PROJECTION[] = {
"_id", "sourceid", "data_id", "mimetype", "sync3"
};
private static AndroidContactsSyncThread sAndroidSyncThread;
private static boolean sContactsProviderExists;
private static boolean sContactsProviderStatusKnown;
private static int sMaxStreamItemsPerRawContact;
private static SparseArray sPhoneTypeMap;
private static int sThumbnailSize;
static
{
PROFILE_CONTENT_RAW_CONTACTS_URI = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "profile/raw_contacts");
STREAM_ITEMS_URI = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "stream_items");
STREAM_ITEMS_CONTENT_LIMIT_URI = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "stream_items_limit");
STREAM_ITEMS_PHOTO_URI = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "stream_items/photo");
DISPLAY_PHOTO_CONTENT_MAX_DIMENSIONS_URI = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "photo_dimensions");
SparseArray sparsearray = new SparseArray();
sPhoneTypeMap = sparsearray;
sparsearray.put(1, PHONE_TYPE_HOME);
sPhoneTypeMap.put(2, PHONE_TYPE_WORK);
sPhoneTypeMap.put(3, PHONE_TYPE_OTHER);
sPhoneTypeMap.put(4, PHONE_TYPE_HOME_FAX);
sPhoneTypeMap.put(5, PHONE_TYPE_WORK_FAX);
sPhoneTypeMap.put(6, PHONE_TYPE_MOBILE);
sPhoneTypeMap.put(7, PHONE_TYPE_PAGER);
sPhoneTypeMap.put(8, PHONE_TYPE_OTHER_FAX);
sPhoneTypeMap.put(9, PHONE_TYPE_COMPANY_MAIN);
sPhoneTypeMap.put(10, PHONE_TYPE_ASSISTANT);
sPhoneTypeMap.put(11, PHONE_TYPE_CAR);
sPhoneTypeMap.put(12, PHONE_TYPE_RADIO);
sPhoneTypeMap.put(13, PHONE_TYPE_ISDN);
sPhoneTypeMap.put(14, PHONE_TYPE_CALLBACK);
sPhoneTypeMap.put(15, PHONE_TYPE_TELEX);
sPhoneTypeMap.put(16, PHONE_TYPE_TTY_TDD);
sPhoneTypeMap.put(17, PHONE_TYPE_WORK_MOBILE);
sPhoneTypeMap.put(18, PHONE_TYPE_WORK_PAGER);
sPhoneTypeMap.put(19, PHONE_TYPE_MAIN);
}
private static DataState addData(RawContactState rawcontactstate, String s, String s1)
{
DataState datastate = new DataState();
datastate.mimetype = s;
datastate.data1 = s1;
rawcontactstate.data.add(datastate);
return datastate;
}
private static void appendImgTag(Context context, StringBuilder stringbuilder, int i)
{
stringbuilder.append("<img src='res://").append(context.getPackageName()).append('/').append(context.getResources().getResourceEntryName(i)).append("'/>");
}
private static void applyActivityChanges(Context context, EsAccount esaccount, HashMap hashmap)
{
ContentResolver contentresolver = context.getContentResolver();
ArrayList arraylist = new ArrayList();
ArrayList arraylist1 = new ArrayList(hashmap.values());
int ai[] = {
0
};
int i = arraylist1.size();
int k;
for(int j = 0; j < i; j = k)
{
k = j + 32;
if(k > i)
k = i;
if(EsLog.isLoggable("GooglePlusContactsSync", 3))
{
for(int l = j; l < k; l++)
dumpPersonActivityState((PersonActivityState)arraylist1.get(l));
}
deleteObsoleteStreamItems(esaccount, arraylist1, j, k, arraylist);
updateStreamItems(context, esaccount, arraylist1, j, k, arraylist, ai);
}
flushBatch(contentresolver, arraylist, true);
}
private static void buildContentProviderOperations(Context context, Uri uri, ArrayList arraylist, RawContactState rawcontactstate, boolean flag)
{
int i;
DataState datastate;
ContentProviderOperation contentprovideroperation;
if(EsLog.isLoggable("GooglePlusContactsSync", 3))
dumpRawContactState(rawcontactstate);
android.content.ContentProviderOperation.Builder builder2;
String as2[];
if(rawcontactstate.rawContactId == 0L)
{
i = arraylist.size();
arraylist.add(ContentProviderOperation.newInsert(uri).withYieldAllowed(true).withValue("sourceid", rawcontactstate.personId).withValue("sync1", Long.valueOf(rawcontactstate.lastUpdateTime)).withValue("raw_contact_is_read_only", Integer.valueOf(1)).build());
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValueBackReference("raw_contact_id", i).withValue("mimetype", "vnd.android.cursor.item/name").withValue("data1", rawcontactstate.fullName).build());
if(!flag)
{
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValueBackReference("raw_contact_id", i).withValue("mimetype", "vnd.android.cursor.item/vnd.googleplus.profile").withValue("data4", Integer.valueOf(10)).withValue("data5", "conversation").withValue("data3", context.getString(R.string.start_conversation_action_label)).build());
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValueBackReference("raw_contact_id", i).withValue("mimetype", "vnd.android.cursor.item/vnd.googleplus.profile").withValue("data4", Integer.valueOf(14)).withValue("data5", "hangout").withValue("data3", context.getString(R.string.start_hangout_action_label)).build());
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValueBackReference("raw_contact_id", i).withValue("mimetype", "vnd.android.cursor.item/vnd.googleplus.profile").withValue("data4", Integer.valueOf(20)).withValue("data5", "addtocircle").withValue("data3", context.getString(R.string.add_to_circle_action_label)).build());
}
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValueBackReference("raw_contact_id", i).withValue("mimetype", "vnd.android.cursor.item/vnd.googleplus.profile").withValue("data4", Integer.valueOf(30)).withValue("data5", "view").withValue("data3", context.getString(R.string.view_profile_action_label)).build());
String s = EsPeopleData.extractGaiaId(rawcontactstate.personId);
if(s != null)
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValueBackReference("raw_contact_id", i).withValue("mimetype", "vnd.android.cursor.item/identity").withValue("data2", AccountsUtil.ACCOUNT_TYPE).withValue("data1", (new StringBuilder("gprofile:")).append(s).toString()).build());
} else
{
android.content.ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(uri).withYieldAllowed(true);
String as[] = new String[1];
as[0] = String.valueOf(rawcontactstate.rawContactId);
arraylist.add(builder.withSelection("_id=?", as).withValue("sync1", Long.valueOf(rawcontactstate.lastUpdateTime)).build());
i = 0;
}
for(Iterator iterator = rawcontactstate.data.iterator(); iterator.hasNext();) {
datastate = (DataState)iterator.next();
if(!datastate.exists) {
builder2 = ContentProviderOperation.newDelete(android.provider.ContactsContract.Data.CONTENT_URI);
as2 = new String[1];
as2[0] = String.valueOf(datastate.dataId);
contentprovideroperation = builder2.withSelection("_id=?", as2).build();
} else {
android.content.ContentProviderOperation.Builder builder1;
if(0L == datastate.dataId) {
builder1 = ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI);
builder1.withValue("mimetype", datastate.mimetype);
if(rawcontactstate.rawContactId == 0L)
builder1.withValueBackReference("raw_contact_id", i);
else
builder1.withValue("raw_contact_id", Long.valueOf(rawcontactstate.rawContactId));
} else if(datastate.changed) {
builder1 = ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI);
String as1[] = new String[1];
as1[0] = String.valueOf(datastate.dataId);
builder1.withSelection("_id=?", as1);
} else {
continue;
}
builder1.withValue("data1", datastate.data1);
builder1.withValue("data2", datastate.data2);
builder1.withValue("data3", datastate.data3);
contentprovideroperation = builder1.build();
}
arraylist.add(contentprovideroperation);
}
}
private static void buildContentProviderOperations(Context context, Uri uri, ArrayList arraylist, String as[], HashMap hashmap)
{
for(int i = 0; i < as.length; i++)
buildContentProviderOperations(context, uri, arraylist, (RawContactState)hashmap.get(as[i]), false);
}
private static synchronized void cancelSync() {
if(sAndroidSyncThread != null)
sAndroidSyncThread.cancel();
}
private static void cleanUpActivityStateMap(HashMap hashmap)
{
Iterator iterator = (new ArrayList(hashmap.values())).iterator();
do
{
if(!iterator.hasNext())
break;
PersonActivityState personactivitystate = (PersonActivityState)iterator.next();
Iterator iterator1 = personactivitystate.activities.iterator();
boolean flag1;
do
{
boolean flag = iterator1.hasNext();
flag1 = false;
if(!flag)
break;
ActivityState activitystate = (ActivityState)iterator1.next();
if((!activitystate.exists || activitystate.streamItemId != 0L) && (activitystate.exists || activitystate.streamItemId == 0L) && !activitystate.changed)
continue;
flag1 = true;
break;
} while(true);
if(!flag1)
hashmap.remove(personactivitystate.gaiaId);
} while(true);
}
private static void clearAndroidCircles(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate)
{
syncstate.onStart("Android:DeleteCircles");
syncstate.incrementCount(context.getContentResolver().delete(getGroupsUri(esaccount), null, null));
syncstate.onFinish();
}
private static void clearAndroidContacts(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate)
{
syncstate.onStart("Android:DeleteContacts");
deleteAndroidContacts(context, getRawContactsUri(esaccount), null, null, syncstate);
syncstate.onFinish();
}
private static void clearAndroidContactsForOtherAccounts(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate)
{
Cursor cursor = null;
String as[] = new String[1];
String s;
long l;
if(esaccount != null)
s = esaccount.getName();
else
s = "";
as[0] = s;
syncstate.onStart("Android:DeleteProfilesOtherAccounts");
deleteAndroidContacts(context, PROFILE_CONTENT_RAW_CONTACTS_URI.buildUpon().appendQueryParameter("caller_is_syncadapter", "true").build(), "data_set='plus' AND account_name!=? AND account_type='com.google'", as, syncstate);
syncstate.onFinish();
syncstate.onStart("Android:DeleteContactsOtherAccounts");
deleteAndroidContacts(context, android.provider.ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter("caller_is_syncadapter", "true").build(), "data_set='plus' AND account_name!=? AND account_type='com.google'", as, syncstate);
syncstate.onFinish();
syncstate.onStart("Android:DeleteCirclesOtherAccounts");
Uri uri = android.provider.ContactsContract.Groups.CONTENT_URI.buildUpon().appendQueryParameter("caller_is_syncadapter", "true").build();
try {
cursor = context.getContentResolver().query(uri, new String[] {
"_id"
}, "data_set='plus' AND account_name!=? AND account_type='com.google'", as, null);
if(null != cursor) {
for(; cursor.moveToNext(); syncstate.incrementCount(context.getContentResolver().delete(ContentUris.withAppendedId(uri, l), null, null)))
l = cursor.getLong(0);
}
} finally {
if(null != cursor) {
cursor.close();
}
syncstate.onFinish();
}
}
private static void clearAndroidProfile(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate)
{
long l = 0L;
Cursor cursor = null;
syncstate.onStart("Android:DeleteProfile");
ContentResolver contentresolver = context.getContentResolver();
try {
cursor = contentresolver.query(getProfileRawContactUri(esaccount), PROFILE_RAW_CONTACT_PROJECTION, null, null, null);
if(null != cursor && cursor.moveToFirst()) {
l = cursor.getLong(0);
}
if(l != 0L)
syncstate.incrementCount(contentresolver.delete(ContentUris.withAppendedId(getRawContactsUri(esaccount), l), null, null));
syncstate.onFinish();
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static void collectRawContactIds(Context context, HashSet hashset, Uri uri, String as[], String s, String s1)
{
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, as, s, null, s1);
if(null != cursor) {
for(; cursor.moveToNext(); hashset.add(cursor.getString(0)));
}
} finally {
if(null != cursor) {
cursor.close();
}
}
}
public static void deactivateAccount(Context context, EsAccount esaccount)
{
if(isAndroidSyncSupported(context))
{
cancelSync();
EsAccountsData.saveContactsSyncCleanupStatus(context, false);
EsAccountsData.saveContactsStatsSyncCleanupStatus(context, false);
clearAndroidProfile(context, esaccount, new EsSyncAdapterService.SyncState());
requestSync(context);
}
}
private static void deleteAndroidContacts(Context context, Uri uri, String s, String as[], EsSyncAdapterService.SyncState syncstate)
{
Cursor cursor = null;
ContentResolver contentresolver = context.getContentResolver();
ArrayList arraylist = new ArrayList();
try {
cursor = contentresolver.query(uri, new String[] {
"_id"
}, s, as, null);
if(null != cursor) {
for(; cursor.moveToNext(); arraylist.add(cursor.getString(0)));
}
if(!arraylist.isEmpty())
{
ArrayList arraylist1 = new ArrayList();
for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); syncstate.incrementCount())
{
String s1 = (String)iterator.next();
arraylist1.add(ContentProviderOperation.newDelete(uri).withSelection("_id=?", new String[] {
s1
}).withYieldAllowed(true).build());
flushBatch(contentresolver, arraylist1, false);
}
flushBatch(contentresolver, arraylist1, true);
}
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static void deleteContacts(ContentResolver contentresolver, EsAccount esaccount, ArrayList arraylist, ArrayList arraylist1)
{
Uri uri = getRawContactsUri(esaccount);
android.content.ContentProviderOperation.Builder builder;
String as[];
for(Iterator iterator = arraylist1.iterator(); iterator.hasNext(); arraylist.add(builder.withSelection("_id=?", as).build()))
{
RawContactState rawcontactstate = (RawContactState)iterator.next();
if(EsLog.isLoggable("GooglePlusContactsSync", 3))
dumpRawContactState(rawcontactstate);
builder = ContentProviderOperation.newDelete(uri).withYieldAllowed(true);
as = new String[1];
as[0] = String.valueOf(rawcontactstate.rawContactId);
}
flushBatch(contentresolver, arraylist, false);
}
private static void deleteObsoleteStreamItems(EsAccount esaccount, ArrayList arraylist, int i, int j, ArrayList arraylist1)
{
ActivityState activitystate;
Uri uri = getStreamItemsUri(esaccount);
for(int k = i; k < j; k++)
{
PersonActivityState personactivitystate1 = (PersonActivityState)arraylist.get(k);
if(!TextUtils.equals(personactivitystate1.gaiaId, esaccount.getGaiaId()))
continue;
for(Iterator iterator1 = personactivitystate1.activities.iterator(); iterator1.hasNext();) {
activitystate = (ActivityState)iterator1.next();
if(activitystate.exists || activitystate.streamItemId == 0L) {
continue;
} else {
arraylist1.add(ContentProviderOperation.newDelete(ContentUris.withAppendedId(uri, activitystate.streamItemId)).build());
break;
}
}
}
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("_id IN (");
ArrayList arraylist2 = new ArrayList();
for(int l = i; l < j; l++)
{
PersonActivityState personactivitystate = (PersonActivityState)arraylist.get(l);
if(TextUtils.equals(personactivitystate.gaiaId, esaccount.getGaiaId()))
continue;
for(Iterator iterator = personactivitystate.activities.iterator(); iterator.hasNext();) {
activitystate = (ActivityState)iterator.next();
if(activitystate.exists || activitystate.streamItemId == 0L) {
continue;
} else {
if(!arraylist2.isEmpty())
stringbuilder.append(',');
stringbuilder.append('?');
arraylist2.add(String.valueOf(activitystate.streamItemId));
break;
}
}
}
if(!arraylist2.isEmpty())
{
stringbuilder.append(')');
arraylist1.add(ContentProviderOperation.newDelete(uri).withSelection(stringbuilder.toString(), (String[])arraylist2.toArray(new String[0])).build());
}
}
private static void deleteRemovedContacts(ContentResolver contentresolver, EsAccount esaccount, HashMap hashmap, ArrayList arraylist)
{
ArrayList arraylist1 = new ArrayList();
Iterator iterator = hashmap.values().iterator();
do
{
if(!iterator.hasNext())
break;
RawContactState rawcontactstate = (RawContactState)iterator.next();
if(!rawcontactstate.exists)
arraylist1.add(rawcontactstate);
} while(true);
if(!arraylist1.isEmpty())
deleteContacts(contentresolver, esaccount, arraylist, arraylist1);
}
private static void downloadLargeAvatars(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate, HashMap hashmap, int i)
{
ContentResolver contentresolver = context.getContentResolver();
ArrayList arraylist = new ArrayList(hashmap.values());
int j = arraylist.size();
int k = 0;
do
{
if(k >= j || syncstate.isCanceled())
break;
int l = k + 8;
if(l > j)
l = j;
int i1 = k;
while(i1 < l)
{
AvatarState avatarstate = (AvatarState)arraylist.get(i1);
if(avatarstate.signature == 1)
saveAvatarSignature(contentresolver, esaccount, avatarstate);
else
if(avatarstate.avatarUrl != null)
{
DownloadImageOperation downloadimageoperation = new DownloadImageOperation(context, esaccount, new AvatarImageRequest(avatarstate.gaiaId, EsAvatarData.uncompressAvatarUrl(avatarstate.avatarUrl), 2, i), false, null, null);
downloadimageoperation.start();
if(downloadimageoperation.hasError())
downloadimageoperation.logError("GooglePlusContactsSync");
byte abyte0[] = downloadimageoperation.getImageBytes();
if(abyte0 != null)
{
Uri uri = Uri.withAppendedPath(ContentUris.withAppendedId(getRawContactsUri(esaccount), avatarstate.rawContactId), "display_photo");
try
{
OutputStream outputstream = contentresolver.openOutputStream(uri);
outputstream.write(abyte0);
outputstream.close();
saveAvatarSignature(contentresolver, esaccount, avatarstate);
}
catch(IOException ioexception)
{
if(EsLog.isLoggable("GooglePlusContactsSync", 6))
Log.e("GooglePlusContactsSync", (new StringBuilder("Could not store large avatar: ")).append(avatarstate.gaiaId).toString(), ioexception);
}
}
}
i1++;
}
k = l;
} while(true);
}
private static void dumpPersonActivityState(PersonActivityState personactivitystate)
{
String s;
ActivityState activitystate;
Log.d("GooglePlusContactsSync", (new StringBuilder("[STREAM] Gaia ID: ")).append(personactivitystate.gaiaId).append(" (raw_contact_id=").append(personactivitystate.rawContactId).append(")").toString());
for(Iterator iterator = personactivitystate.activities.iterator(); iterator.hasNext();) {
s = null;
activitystate = (ActivityState)iterator.next();
if(!activitystate.exists && activitystate.streamItemId != 0L)
{
s = "[DELETE]";
} else if(activitystate.exists && activitystate.streamItemId == 0L)
{
s = "[INSERT]";
} else if(activitystate.changed) {
s = "[UPDATE]";
}
if(null != s) {
Log.d("GooglePlusContactsSync", (new StringBuilder(" ")).append(s).append(" ").append(activitystate.activityId).append(" (stream_item_id=").append(activitystate.streamItemId).append(") created=").append(activitystate.created).append("', modified=").append(activitystate.lastModified).toString());
}
}
}
private static void dumpRawContactState(RawContactState rawcontactstate)
{
DataState datastate;
String s1;
String s;
if(!rawcontactstate.exists)
s = "[DELETE]";
else
if(rawcontactstate.rawContactId == 0L)
s = "[INSERT]";
else
s = "[UPDATE]";
Log.d("GooglePlusContactsSync", (new StringBuilder()).append(s).append(" ").append(rawcontactstate.personId).append(" ").append(rawcontactstate.fullName).append(" (raw_contact_id=").append(rawcontactstate.rawContactId).append(") last_updated=").append(rawcontactstate.lastUpdateTime).toString());
for(Iterator iterator = rawcontactstate.data.iterator(); iterator.hasNext();) {
s1 = null;
datastate = (DataState)iterator.next();
if(!datastate.exists)
{
s1 = "[DELETE]";
} else if(datastate.dataId == 0)
{
s1 = "[INSERT]";
} else if(datastate.changed) {
s1 = "[UPDATE]";
}
if(null != s1) {
Log.d("GooglePlusContactsSync", (new StringBuilder(" ")).append(s1).append(" ").append(datastate.mimetype).append(" (data_id=").append(datastate.dataId).append(") '").append(datastate.data1).append("', type=").append(datastate.data2).append(" ").append(datastate.data3).toString());
}
}
}
private static HashMap findChangesInCircles(Context context, EsAccount esaccount)
{
HashMap hashmap = new HashMap();
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(getGroupsUri(esaccount), GROUPS_PROJECTION, null, null, null);
if(null != cursor) {
CircleState circlestate;
for(; cursor.moveToNext(); hashmap.put(circlestate.circleId, circlestate))
{
circlestate = new CircleState();
circlestate.groupId = cursor.getLong(0);
circlestate.circleId = cursor.getString(1);
circlestate.circleName = cursor.getString(2);
}
}
if((CircleState)hashmap.get("plus") == null)
{
CircleState circlestate1 = new CircleState();
circlestate1.circleId = "plus";
circlestate1.circleName = context.getString(R.string.android_contact_group);
circlestate1.exists = true;
hashmap.put("plus", circlestate1);
} else
{
hashmap.remove("plus");
}
return hashmap;
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static HashMap findChangesInContacts(Context context, EsAccount esaccount)
{
HashMap hashmap = new HashMap();
Cursor cursor = null;
Cursor cursor1 = null;
ContentResolver contentresolver = context.getContentResolver();
try {
cursor = contentresolver.query(getRawContactsUri(esaccount), RAW_CONTACT_PROJECTION, null, null, null);
if(null != cursor) {
RawContactState rawcontactstate;
for(; cursor.moveToNext(); hashmap.put(rawcontactstate.personId, rawcontactstate))
{
rawcontactstate = new RawContactState();
rawcontactstate.rawContactId = cursor.getLong(0);
rawcontactstate.personId = cursor.getString(1);
rawcontactstate.lastUpdateTime = cursor.getLong(2);
}
}
cursor1 = contentresolver.query(EsProvider.appendAccountParameter(EsProvider.CONTACTS_URI, esaccount), CONTACTS_PROJECTION, "in_my_circles=1 AND profile_type!=2 AND for_sharing!=0", null, null);
if(null != cursor1) {
String s;
long l;
RawContactState rawcontactstate1;
while(cursor1.moveToNext()) {
s = cursor1.getString(0);
l = cursor1.getLong(1);
rawcontactstate1 = (RawContactState)hashmap.get(s);
if(null == rawcontactstate1) {
rawcontactstate1 = new RawContactState();
rawcontactstate1.personId = s;
rawcontactstate1.lastUpdateTime = l;
hashmap.put(rawcontactstate1.personId, rawcontactstate1);
} else {
if(rawcontactstate1.lastUpdateTime == l)
hashmap.remove(s);
else
rawcontactstate1.lastUpdateTime = l;
}
rawcontactstate1.exists = true;
}
} else {
hashmap.remove(esaccount.getPersonId());
}
return hashmap;
} finally {
if(null != cursor) {
cursor.close();
}
if(null != cursor1) {
cursor1.close();
}
}
}
private static ContentProviderResult[] flushBatch(ContentResolver contentresolver, ArrayList arraylist, int i, boolean flag)
{
int size = arraylist.size();
if(0 == size) {
return null;
}
if(!flag)
{
if(size < i)
return null;
}
try {
return contentresolver.applyBatch("com.android.contacts", arraylist);
} catch (Exception exception) {
if(EsLog.isLoggable("GooglePlusContactsSync", 6)) {
Log.e("GooglePlusContactsSync", "Cannot apply a batch of content provider operations", exception);
}
return null;
} finally {
arraylist.clear();
}
}
private static ContentProviderResult[] flushBatch(ContentResolver contentresolver, ArrayList arraylist, boolean flag)
{
return flushBatch(contentresolver, arraylist, 128, flag);
}
private static HashMap getCircleIdMap(ContentResolver contentresolver, EsAccount esaccount)
{
HashMap hashmap = new HashMap();
Cursor cursor = null;
try {
cursor = contentresolver.query(getGroupsUri(esaccount), GROUPS_PROJECTION, null, null, null);
for(; cursor.moveToNext(); hashmap.put(cursor.getString(1), Long.valueOf(cursor.getLong(0))));
} finally {
if(null != cursor) {
cursor.close();
}
}
return hashmap;
}
private static Uri getEntitiesUri(EsAccount esaccount)
{
return android.provider.ContactsContract.RawContactsEntity.CONTENT_URI.buildUpon().appendQueryParameter("account_type", AccountsUtil.ACCOUNT_TYPE).appendQueryParameter("data_set", "plus").appendQueryParameter("account_name", esaccount.getName()).appendQueryParameter("caller_is_syncadapter", "true").build();
}
private static Uri getGroupsUri(EsAccount esaccount)
{
return android.provider.ContactsContract.Groups.CONTENT_URI.buildUpon().appendQueryParameter("account_type", AccountsUtil.ACCOUNT_TYPE).appendQueryParameter("data_set", "plus").appendQueryParameter("account_name", esaccount.getName()).appendQueryParameter("caller_is_syncadapter", "true").build();
}
private static String[] getLimitedRawContactSet(Context context, EsAccount esaccount)
{
HashSet hashset = new HashSet();
Uri uri = android.provider.ContactsContract.Data.CONTENT_URI.buildUpon().appendQueryParameter("account_type", AccountsUtil.ACCOUNT_TYPE).appendQueryParameter("data_set", "plus").appendQueryParameter("account_name", esaccount.getName()).appendQueryParameter("caller_is_syncadapter", "true").build();
String as[] = {
"raw_contact_id"
};
collectRawContactIds(context, hashset, uri, as, "starred!=0 AND mimetype='vnd.android.cursor.item/vnd.googleplus.profile'", null);
collectRawContactIds(context, hashset, uri, as, "starred=0 AND times_contacted>0 AND mimetype='vnd.android.cursor.item/vnd.googleplus.profile'", "times_contacted DESC LIMIT 8");
collectRawContactIds(context, hashset, uri, as, "starred=0 AND last_time_contacted>0 AND mimetype='vnd.android.cursor.item/vnd.googleplus.profile'", "last_time_contacted DESC LIMIT 8");
return (String[])hashset.toArray(new String[0]);
}
private static int getMaxStreamItemsPerRawContact(Context context)
{
if(sMaxStreamItemsPerRawContact != 0) {
return sMaxStreamItemsPerRawContact;
}
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(STREAM_ITEMS_CONTENT_LIMIT_URI, new String[] {
"max_items"
}, null, null, null);
if(cursor.moveToFirst())
{
sMaxStreamItemsPerRawContact = cursor.getInt(0);
return sMaxStreamItemsPerRawContact;
} else {
return 2;
}
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static int getPreferredAvatarSize(ContentResolver contentresolver, String s)
{
Cursor cursor = null;
try {
cursor = contentresolver.query(DISPLAY_PHOTO_CONTENT_MAX_DIMENSIONS_URI, null, null, null, null);
if(null != cursor && cursor.moveToFirst()) {
return cursor.getInt(cursor.getColumnIndex(s));
} else {
return 96;
}
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static Uri getProfileRawContactUri(EsAccount esaccount)
{
return PROFILE_CONTENT_RAW_CONTACTS_URI.buildUpon().appendQueryParameter("account_type", AccountsUtil.ACCOUNT_TYPE).appendQueryParameter("data_set", "plus").appendQueryParameter("account_name", esaccount.getName()).appendQueryParameter("caller_is_syncadapter", "true").build();
}
private static Uri getRawContactsUri(EsAccount esaccount)
{
return android.provider.ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter("account_type", AccountsUtil.ACCOUNT_TYPE).appendQueryParameter("data_set", "plus").appendQueryParameter("account_name", esaccount.getName()).appendQueryParameter("caller_is_syncadapter", "true").build();
}
private static Uri getStreamItemsUri(EsAccount esaccount)
{
return STREAM_ITEMS_URI.buildUpon().appendQueryParameter("account_type", AccountsUtil.ACCOUNT_TYPE).appendQueryParameter("data_set", "plus").appendQueryParameter("account_name", esaccount.getName()).appendQueryParameter("caller_is_syncadapter", "true").build();
}
private static void insertNewContacts(Context context, EsAccount esaccount, HashMap hashmap, ArrayList arraylist, HashMap hashmap1)
{
ArrayList arraylist1 = new ArrayList();
Iterator iterator = hashmap.values().iterator();
do
{
if(!iterator.hasNext())
break;
RawContactState rawcontactstate = (RawContactState)iterator.next();
if(rawcontactstate.exists && rawcontactstate.rawContactId == 0L)
arraylist1.add(rawcontactstate);
} while(true);
if(!arraylist1.isEmpty())
updateContacts(context, esaccount, arraylist, arraylist1, hashmap, true, hashmap1);
}
public static boolean isAndroidSyncSupported(Context context)
{
boolean flag;
if(android.os.Build.VERSION.SDK_INT < 14)
flag = false;
else
flag = isContactsProviderAvailable(context);
return flag;
}
public static boolean isContactsProviderAvailable(Context context)
{
boolean flag = true;
if(sContactsProviderStatusKnown) {
return sContactsProviderExists;
} else {
ContentProviderClient contentproviderclient = null;
try {
contentproviderclient = context.getContentResolver().acquireContentProviderClient("com.android.contacts");
if(contentproviderclient == null)
flag = false;
sContactsProviderExists = flag;
sContactsProviderStatusKnown = true;
} catch (Throwable throwable) {
Log.e("GooglePlusContactsSync", "Cannot determine availability of the contacts provider");
} finally {
if(contentproviderclient != null)
contentproviderclient.release();
}
return sContactsProviderExists;
}
}
private static void limitStreamItemsPerRawContact(Context context, HashMap hashmap)
{
int i = getMaxStreamItemsPerRawContact(context);
Iterator iterator = hashmap.values().iterator();
do
{
if(!iterator.hasNext())
break;
ArrayList arraylist = ((PersonActivityState)iterator.next()).activities;
if(arraylist.size() > i)
{
Collections.sort(arraylist, ACTIVITY_STATE_COMPARATOR);
int j = i;
while(j < arraylist.size())
{
((ActivityState)arraylist.get(j)).exists = false;
j++;
}
}
} while(true);
}
private static void loadContactCircleMembership(String as[], HashMap hashmap, HashMap hashmap1)
{
for(int i = 0; i < as.length; i++)
{
RawContactState rawcontactstate = (RawContactState)hashmap.get(as[i]);
Long long1 = (Long)hashmap1.get("plus");
if(long1 != null)
addData(rawcontactstate, "vnd.android.cursor.item/group_membership", long1.toString()).exists = true;
}
}
private static void populateRawContactState(Context context, RawContactState rawcontactstate, EsPeopleData.ContactInfo contactinfo)
{
if(null != contactinfo.emails) {
for(Iterator iterator2 = contactinfo.emails.iterator(); iterator2.hasNext();) {
DataEmail dataemail = (DataEmail)iterator2.next();
DataState datastate2 = addData(rawcontactstate, "vnd.android.cursor.item/email_v2", dataemail.value);
datastate2.exists = true;
Integer integer2 = dataemail.standardTag;
String s3 = dataemail.customTag;
int j;
if(integer2 == null)
j = 0;
else
j = integer2.intValue();
switch(j)
{
default:
datastate2.data2 = EMAIL_TYPE_CUSTOM;
datastate2.data3 = s3;
break;
case 1: // '\001'
datastate2.data2 = EMAIL_TYPE_HOME;
break;
case 2: // '\002'
datastate2.data2 = EMAIL_TYPE_WORK;
break;
case 3: // '\003'
datastate2.data2 = EMAIL_TYPE_OTHER;
break;
}
}
}
if(contactinfo.phones != null)
{
for(Iterator iterator1 = contactinfo.phones.iterator(); iterator1.hasNext();)
{
DataPhone dataphone = (DataPhone)iterator1.next();
DataState datastate1 = addData(rawcontactstate, "vnd.android.cursor.item/phone_v2", dataphone.value);
datastate1.exists = true;
Integer integer1 = dataphone.standardTag;
String s1 = dataphone.customTag;
String s2;
if(integer1 == null)
s2 = null;
else
s2 = (String)sPhoneTypeMap.get(integer1.intValue());
if(s2 != null)
datastate1.data2 = s2;
else
if(integer1 != null && integer1.intValue() == 20)
{
datastate1.data2 = PHONE_TYPE_CUSTOM;
datastate1.data3 = context.getString(R.string.profile_item_phone_google_voice);
} else
{
datastate1.data2 = PHONE_TYPE_CUSTOM;
datastate1.data3 = s1;
}
}
}
if(null != contactinfo.addresses) {
for(Iterator iterator = contactinfo.addresses.iterator(); iterator.hasNext();) {
DataCircleMemberPropertiesAddress datacirclememberpropertiesaddress = (DataCircleMemberPropertiesAddress)iterator.next();
DataState datastate = addData(rawcontactstate, "vnd.android.cursor.item/postal-address_v2", datacirclememberpropertiesaddress.value);
datastate.exists = true;
Integer integer = datacirclememberpropertiesaddress.standardTag;
String s = datacirclememberpropertiesaddress.customTag;
int i;
if(integer == null)
i = 0;
else
i = integer.intValue();
switch(i)
{
default:
datastate.data2 = POSTAL_TYPE_CUSTOM;
datastate.data3 = s;
break;
case 1: // '\001'
datastate.data2 = POSTAL_TYPE_HOME;
break;
case 2: // '\002'
datastate.data2 = POSTAL_TYPE_WORK;
break;
case 3: // '\003'
datastate.data2 = POSTAL_TYPE_OTHER;
break;
}
}
}
}
private static void populateRawContactState(RawContactState rawcontactstate, Contacts contacts)
{
if(contacts.email != null)
{
Iterator iterator2 = contacts.email.iterator();
do
{
if(!iterator2.hasNext())
break;
TaggedEmail taggedemail = (TaggedEmail)iterator2.next();
DataState datastate2 = addData(rawcontactstate, "vnd.android.cursor.item/email_v2", taggedemail.value);
datastate2.exists = true;
if(taggedemail.tag != null)
{
ContactTag contacttag2 = taggedemail.tag;
if("HOME".equals(contacttag2.tag))
datastate2.data2 = EMAIL_TYPE_HOME;
else
if("WORK".equals(contacttag2.tag))
datastate2.data2 = EMAIL_TYPE_WORK;
else
if("OTHER".equals(contacttag2.tag))
datastate2.data2 = EMAIL_TYPE_OTHER;
else
if("CUSTOM".equals(contacttag2.tag))
{
datastate2.data2 = EMAIL_TYPE_CUSTOM;
datastate2.data3 = contacttag2.customTag;
}
}
} while(true);
}
if(contacts.phone != null)
{
Iterator iterator1 = contacts.phone.iterator();
do
{
if(!iterator1.hasNext())
break;
TaggedPhone taggedphone = (TaggedPhone)iterator1.next();
DataState datastate1 = addData(rawcontactstate, "vnd.android.cursor.item/phone_v2", taggedphone.value);
datastate1.exists = true;
if(taggedphone.tag != null)
{
ContactTag contacttag1 = taggedphone.tag;
if("HOME".equals(contacttag1.tag))
datastate1.data2 = PHONE_TYPE_HOME;
else
if("WORK".equals(contacttag1.tag))
datastate1.data2 = PHONE_TYPE_WORK;
else
if("OTHER".equals(contacttag1.tag))
datastate1.data2 = PHONE_TYPE_OTHER;
else
if("CUSTOM".equals(contacttag1.tag))
{
datastate1.data2 = PHONE_TYPE_CUSTOM;
datastate1.data3 = contacttag1.customTag;
}
}
} while(true);
}
if(contacts.address != null)
{
Iterator iterator = contacts.address.iterator();
do
{
if(!iterator.hasNext())
break;
TaggedAddress taggedaddress = (TaggedAddress)iterator.next();
DataState datastate = addData(rawcontactstate, "vnd.android.cursor.item/postal-address_v2", taggedaddress.value);
datastate.exists = true;
if(taggedaddress.tag != null)
{
ContactTag contacttag = taggedaddress.tag;
if("HOME".equals(contacttag.tag))
datastate.data2 = POSTAL_TYPE_HOME;
else
if("WORK".equals(contacttag.tag))
datastate.data2 = POSTAL_TYPE_WORK;
else
if("OTHER".equals(contacttag.tag))
datastate.data2 = POSTAL_TYPE_OTHER;
else
if("CUSTOM".equals(contacttag.tag))
{
datastate.data2 = POSTAL_TYPE_CUSTOM;
datastate.data3 = contacttag.customTag;
}
}
} while(true);
}
}
private static HashMap queryRawContactsRequiringActivities(Context context, EsAccount esaccount)
{
String as[] = getLimitedRawContactSet(context, esaccount);
int i = as.length;
HashMap hashmap = new HashMap();
if(0 == i) {
return hashmap;
}
Cursor cursor = null;
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("_id IN (");
for(int j = 0; j < as.length; j++)
{
if(j != 0)
stringbuilder.append(',');
stringbuilder.append('?');
}
stringbuilder.append(')');
try {
cursor = context.getContentResolver().query(getRawContactsUri(esaccount), RAW_CONTACT_SOURCE_ID_PROJECTION, stringbuilder.toString(), as, null);
do
{
if(!cursor.moveToNext())
break;
String s = EsPeopleData.extractGaiaId(cursor.getString(1));
if(s != null)
{
PersonActivityState personactivitystate = new PersonActivityState();
personactivitystate.gaiaId = s;
personactivitystate.rawContactId = cursor.getLong(0);
hashmap.put(s, personactivitystate);
}
} while(true);
return hashmap;
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static HashMap queryRawContactsRequiringLargeAvatars(Context context, EsAccount esaccount)
{
HashMap hashmap = new HashMap();
String as[] = getLimitedRawContactSet(context, esaccount);
int i = as.length;
hashmap = null;
if(0 == i) {
return hashmap;
}
Cursor cursor = null;
ContentResolver contentresolver = context.getContentResolver();
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("_id IN (");
for(int j = 0; j < as.length; j++)
{
if(j != 0)
stringbuilder.append(',');
stringbuilder.append('?');
}
stringbuilder.append(')');
stringbuilder.append(" OR sync2").append(" != 0");
try {
cursor = contentresolver.query(getRawContactsUri(esaccount), LARGE_AVATAR_RAW_CONTACTS_PROJECTION, stringbuilder.toString(), as, null);
if(null != cursor) {
do
{
if(!cursor.moveToNext())
break;
String s = EsPeopleData.extractGaiaId(cursor.getString(1));
if(s != null)
{
AvatarState avatarstate = new AvatarState();
avatarstate.gaiaId = s;
avatarstate.rawContactId = cursor.getLong(0);
avatarstate.signature = cursor.getInt(2);
hashmap.put(s, avatarstate);
}
} while(true);
}
if(!hashmap.isEmpty())
retrieveAvatarSignatures(context, esaccount, hashmap, new ArrayList(hashmap.keySet()));
return hashmap;
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static HashMap queryRawContactsRequiringThumbnails(ContentResolver contentresolver, EsAccount esaccount)
{
Cursor cursor = null;
Cursor cursor1 = null;
HashMap hashmap = new HashMap();
try {
cursor = contentresolver.query(getEntitiesUri(esaccount), THUMBNAILS_RAW_CONTACT_PROJECTION, "(mimetype='vnd.android.cursor.item/photo' OR mimetype='vnd.android.cursor.item/vnd.googleplus.profile') AND (sync2=0 OR sync2 IS NULL)", null, null);
if(null != cursor) {
do
{
if(!cursor.moveToNext())
break;
String s2 = EsPeopleData.extractGaiaId(cursor.getString(1));
if(s2 != null)
{
AvatarState avatarstate1 = (AvatarState)hashmap.get(s2);
if(avatarstate1 == null)
{
avatarstate1 = new AvatarState();
avatarstate1.gaiaId = s2;
avatarstate1.rawContactId = cursor.getLong(0);
avatarstate1.signature = cursor.getInt(4);
hashmap.put(s2, avatarstate1);
}
if("vnd.android.cursor.item/photo".equals(cursor.getString(3)))
avatarstate1.dataId = cursor.getLong(2);
}
} while(true);
}
cursor1 = contentresolver.query(EsProvider.appendAccountParameter(EsProvider.CONTACTS_URI, esaccount), AVATAR_URL_PROJECTION, "in_my_circles=1", null, null);
if(null != cursor1) {
String s;
String s1;
int i;
AvatarState avatarstate;
while(cursor1.moveToNext()) {
s = cursor1.getString(0);
s1 = cursor1.getString(1);
i = EsAvatarData.getAvatarUrlSignature(s1);
avatarstate = (AvatarState)hashmap.get(s);
if(avatarstate == null) {
continue;
} else if(avatarstate.signature == i) {
hashmap.remove(s);
} else {
avatarstate.signature = i;
avatarstate.avatarUrl = s1;
}
}
}
return hashmap;
} finally {
if(null != cursor) {
cursor.close();
}
if(null != cursor1) {
cursor1.close();
}
}
}
private static boolean queryStreamItemState(Context context, HashMap hashmap, Uri uri, String s, String as[]) {
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, STREAM_ITEMS_PROJECTION, s, as, null);
if(null == cursor) {
return false;
}
do
{
if(!cursor.moveToNext())
break;
String s1 = EsPeopleData.extractGaiaId(cursor.getString(1));
if(s1 != null)
{
PersonActivityState personactivitystate = (PersonActivityState)hashmap.get(s1);
if(personactivitystate != null)
{
ActivityState activitystate = new ActivityState();
activitystate.rawContactId = personactivitystate.rawContactId;
activitystate.streamItemId = cursor.getLong(0);
activitystate.activityId = cursor.getString(2);
activitystate.created = cursor.getLong(3);
activitystate.lastModified = cursor.getLong(4);
personactivitystate.activities.add(activitystate);
}
}
} while(true);
return true;
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static void reconcileActivitiesAndStreamItems(Context context, EsAccount esaccount, HashMap hashmap, String s, String as[])
{
Cursor cursor = null;
String s3 = null;
long l = 0L;
long l1 = 0L;
PersonActivityState personactivitystate = null;
ActivityState activitystate;
ContentResolver contentresolver = context.getContentResolver();
String s1;
String s2;
Iterator iterator;
boolean flag;
ActivityState activitystate1;
if(s != null)
s1 = (new StringBuilder("(")).append(s).append(")").toString();
else
s1 = null;
try {
cursor = contentresolver.query(EsProvider.appendAccountParameter(EsProvider.ACTIVITY_SUMMARY_URI, esaccount), ACTIVITY_SUMMARY_PROJECTION, s1, as, null);
do
{
if(!cursor.moveToNext())
break;
s2 = cursor.getString(1);
s3 = cursor.getString(0);
l = cursor.getLong(2);
l1 = cursor.getLong(3);
personactivitystate = (PersonActivityState)hashmap.get(s2);
} while(personactivitystate == null);
if(null != personactivitystate) {
iterator = personactivitystate.activities.iterator();
do
{
flag = iterator.hasNext();
activitystate = null;
if(!flag)
break;
activitystate1 = (ActivityState)iterator.next();
if(!s3.equals(activitystate1.activityId))
continue;
activitystate = activitystate1;
break;
} while(true);
if(activitystate == null) {
activitystate = new ActivityState();
activitystate.rawContactId = personactivitystate.rawContactId;
activitystate.activityId = s3;
activitystate.created = l;
activitystate.lastModified = l1;
personactivitystate.activities.add(activitystate);
} else {
if(activitystate.lastModified != l1)
{
activitystate.changed = true;
activitystate.lastModified = l1;
}
}
activitystate.exists = true;
}
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static boolean reconcileContacts(ContentResolver contentresolver, Uri uri, String as[], HashMap hashmap)
{
Cursor cursor = null;
String as1[] = new String[as.length];
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("_id IN (");
for(int i = 0; i < as.length; i++)
{
as1[i] = String.valueOf(((RawContactState)hashmap.get(as[i])).rawContactId);
if(i != 0)
stringbuilder.append(',');
stringbuilder.append('?');
}
stringbuilder.append(") AND mimetype IN ('vnd.android.cursor.item/email_v2','vnd.android.cursor.item/phone_v2','vnd.android.cursor.item/postal-address_v2','vnd.android.cursor.item/group_membership')");
try {
cursor = contentresolver.query(uri, ENTITIES_PROJECTION, stringbuilder.toString(), as1, null);
if(null == cursor) {
return false;
}
for(; cursor.moveToNext(); reconcileData((RawContactState)hashmap.get(cursor.getString(0)), cursor.getLong(2), cursor.getString(1), cursor.getString(3), cursor.getString(4), cursor.getString(5)));
return true;
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static void reconcileData(RawContactState rawcontactstate, long l, String s, String s1, String s2, String s3)
{
if(TextUtils.isEmpty(s1))
s1 = null;
if(TextUtils.isEmpty(s2))
s2 = null;
if(TextUtils.isEmpty(s3))
s3 = null;
DataState datastate = null;
for(Iterator iterator = rawcontactstate.data.iterator(); iterator.hasNext();) {
datastate = (DataState)iterator.next();
if(!TextUtils.equals(datastate.mimetype, s) || !TextUtils.equals(datastate.data1, s1) || datastate.dataId != 0L)
continue;
else {
datastate.dataId = l;
if(!TextUtils.equals(datastate.data2, s2) || !TextUtils.equals(datastate.data3, s3))
{
datastate.data2 = s2;
datastate.data3 = s3;
datastate.changed = true;
}
return;
}
}
DataState datastate1 = new DataState();
datastate1.dataId = l;
rawcontactstate.data.add(datastate1);
}
public static synchronized void requestSync(Context context)
{
requestSync(context, false);
}
public static synchronized void requestSync(Context context, boolean flag)
{
boolean flag1 = isAndroidSyncSupported(context);
if(!flag1)
return;
if(sAndroidSyncThread == null) {
AndroidContactsSyncThread androidcontactssyncthread = new AndroidContactsSyncThread(context.getApplicationContext());
sAndroidSyncThread = androidcontactssyncthread;
androidcontactssyncthread.start();
} else {
sAndroidSyncThread.requestSync(flag);
}
}
private static byte[] resizeThumbnail(byte abyte0[], int i)
{
if(abyte0 == null)
{
abyte0 = null;
} else
{
Bitmap bitmap = ImageUtils.decodeByteArray(abyte0, 0, abyte0.length);
if(bitmap == null)
abyte0 = null;
else
if(bitmap.getWidth() <= i && bitmap.getHeight() <= i)
{
bitmap.recycle();
} else
{
Bitmap bitmap1 = ImageUtils.resizeToSquareBitmap(bitmap, i);
bitmap.recycle();
if(bitmap1 == null)
{
abyte0 = null;
} else
{
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(4000);
bitmap1.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, bytearrayoutputstream);
bitmap1.recycle();
abyte0 = bytearrayoutputstream.toByteArray();
}
}
}
return abyte0;
}
private static void retrieveAvatarSignatures(Context context, EsAccount esaccount, HashMap hashmap, ArrayList arraylist)
{
Cursor cursor = null;
String as[] = new String[arraylist.size()];
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("gaia_id IN (");
for(int i = 0; i < as.length; i++)
{
if(i != 0)
stringbuilder.append(',');
stringbuilder.append('?');
as[i] = ((String)arraylist.get(i)).toString();
}
stringbuilder.append(")");
try {
cursor = context.getContentResolver().query(EsProvider.appendAccountParameter(EsProvider.CONTACTS_URI, esaccount), AVATAR_URL_PROJECTION, stringbuilder.toString(), as, null);
if(null != cursor) {
String s;
String s1;
int j;
AvatarState avatarstate;
while(cursor.moveToNext()) {
s = cursor.getString(0);
s1 = cursor.getString(1);
j = EsAvatarData.getAvatarUrlSignature(s1);
avatarstate = (AvatarState)hashmap.get(s);
if(null != avatarstate) {
if(avatarstate.signature == j)
{
hashmap.remove(s);
continue;
} else {
avatarstate.signature = j;
avatarstate.avatarUrl = s1;
}
}
}
}
} finally {
if(null != cursor) {
cursor.close();
}
}
}
private static void saveAvatarSignature(ContentResolver contentresolver, EsAccount esaccount, AvatarState avatarstate)
{
Uri uri = ContentUris.withAppendedId(getRawContactsUri(esaccount), avatarstate.rawContactId);
ContentValues contentvalues = new ContentValues();
contentvalues.put("sync2", Integer.valueOf(avatarstate.signature));
contentvalues.put("sync3", Integer.valueOf(avatarstate.signature));
contentresolver.update(uri, contentvalues, null, null);
}
private static boolean shouldSync(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate)
{
boolean flag;
if(isAndroidSyncSupported(context) && EsAccountsData.isContactsSyncEnabled(context, esaccount) && (syncstate == null || !syncstate.isCanceled()))
flag = true;
else
flag = false;
return flag;
}
private static void syncActivitiesForRawContact(Context context, EsAccount esaccount, long l, String s)
{
HashMap hashmap = new HashMap();
PersonActivityState personactivitystate = new PersonActivityState();
personactivitystate.gaiaId = s;
personactivitystate.rawContactId = l;
hashmap.put(s, personactivitystate);
if(queryStreamItemState(context, hashmap, Uri.withAppendedPath(ContentUris.withAppendedId(getRawContactsUri(esaccount), l), "stream_items"), null, null))
{
reconcileActivitiesAndStreamItems(context, esaccount, hashmap, "author_id=?", new String[] {
s
});
limitStreamItemsPerRawContact(context, hashmap);
cleanUpActivityStateMap(hashmap);
if(!hashmap.isEmpty())
applyActivityChanges(context, esaccount, hashmap);
}
}
protected static void syncContactsForCurrentAccount(Context context, EsSyncAdapterService.SyncState syncstate)
{
// TODO
}
public static void syncRawContact(Context context, Uri uri)
{
EsAccount esaccount = EsAccountsData.getActiveAccount(context);
if(esaccount != null && isAndroidSyncSupported(context))
syncRawContact(context, esaccount, uri);
}
private static void syncRawContact(Context context, EsAccount esaccount, Uri uri)
{
// TODO
}
private static void syncSmallAvatars(Context context, EsAccount esaccount, EsSyncAdapterService.SyncState syncstate)
{
if(shouldSync(context, esaccount, syncstate))
{
syncstate.onStart("Android:Avatars");
ContentResolver contentresolver = context.getContentResolver();
HashMap hashmap = queryRawContactsRequiringThumbnails(contentresolver, esaccount);
if(hashmap == null || hashmap.isEmpty())
{
syncstate.onFinish();
} else
{
int i = EsAvatarData.getMediumAvatarSize(context);
ArrayList arraylist = new ArrayList();
ArrayList arraylist1 = new ArrayList(hashmap.values());
int j = arraylist1.size();
int l;
for(int k = 0; k < j && !syncstate.isCanceled(); k = l)
{
l = k + 8;
if(l > j)
l = j;
int i1 = k;
while(i1 < l)
{
AvatarState avatarstate = (AvatarState)arraylist1.get(i1);
if(avatarstate.avatarUrl == null)
continue;
AvatarImageRequest avatarimagerequest = new AvatarImageRequest(avatarstate.gaiaId, EsAvatarData.uncompressAvatarUrl(avatarstate.avatarUrl), 2, i);
byte abyte0[] = EsMediaCache.getMedia(context, avatarimagerequest);
if(abyte0 == null)
{
DownloadImageOperation downloadimageoperation = new DownloadImageOperation(context, esaccount, avatarimagerequest, null, null);
downloadimageoperation.start();
abyte0 = downloadimageoperation.getImageBytes();
}
if(abyte0 != null)
{
if(sThumbnailSize == 0)
sThumbnailSize = getPreferredAvatarSize(context.getContentResolver(), "thumbnail_max_dim");
android.content.ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(getRawContactsUri(esaccount)).withYieldAllowed(true);
String as[] = new String[1];
as[0] = String.valueOf(avatarstate.rawContactId);
arraylist.add(builder.withSelection("_id=?", as).withValue("sync3", Integer.valueOf(avatarstate.signature)).build());
if(avatarstate.dataId != 0L)
{
android.content.ContentProviderOperation.Builder builder1 = ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI);
String as1[] = new String[1];
as1[0] = String.valueOf(avatarstate.dataId);
arraylist.add(builder1.withSelection("_id=?", as1).withValue("data15", resizeThumbnail(abyte0, sThumbnailSize)).build());
} else
{
arraylist.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI).withValue("raw_contact_id", Long.valueOf(avatarstate.rawContactId)).withValue("mimetype", "vnd.android.cursor.item/photo").withValue("data15", resizeThumbnail(abyte0, sThumbnailSize)).build());
}
}
i1++;
}
flushBatch(contentresolver, arraylist, 8, false);
}
flushBatch(contentresolver, arraylist, true);
syncstate.onFinish(j);
}
}
}
private static void updateChangedContacts(Context context, EsAccount esaccount, HashMap hashmap, ArrayList arraylist, HashMap hashmap1)
{
ArrayList arraylist1 = new ArrayList();
arraylist1.clear();
Iterator iterator = hashmap.values().iterator();
do
{
if(!iterator.hasNext())
break;
RawContactState rawcontactstate = (RawContactState)iterator.next();
if(rawcontactstate.exists && rawcontactstate.rawContactId != 0L)
arraylist1.add(rawcontactstate);
} while(true);
if(!arraylist1.isEmpty())
updateContacts(context, esaccount, arraylist, arraylist1, hashmap, false, hashmap1);
}
private static void updateContacts(Context context, EsAccount esaccount, ArrayList arraylist, ArrayList arraylist1, HashMap hashmap, boolean flag, HashMap hashmap1)
{
// TODO
}
private static void updateMyProfile(Context context, EsAccount esaccount, String s, long l, byte abyte0[])
{
if(!isAndroidSyncSupported(context))
return;
// TODO
}
private static void updateStreamItems(Context context, EsAccount esaccount, ArrayList arraylist, int i, int j, ArrayList arraylist1, int ai[])
{
// TODO
}
//==================================================================================================================
// Inner class
//==================================================================================================================
private static final class ActivityState
{
String activityId;
boolean changed;
long created;
boolean exists;
long lastModified;
long rawContactId;
long streamItemId;
}
private static final class AndroidContactsSyncThread extends Thread {
private final Context mContext;
private volatile EsSyncAdapterService.SyncState mSyncState;
private volatile Handler mThreadHandler;
public AndroidContactsSyncThread(Context context)
{
mSyncState = new EsSyncAdapterService.SyncState();
mContext = context;
setName("AndroidContactsSync");
}
private void syncContactsForCurrentAccount()
{
try {
Context context = mContext;
mSyncState.cancel();
mSyncState = new EsSyncAdapterService.SyncState();
AndroidContactsSync.syncContactsForCurrentAccount(context, mSyncState);
} catch (Throwable throwable) {
Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), throwable);
}
}
public final void cancel()
{
mSyncState.cancel();
if(mThreadHandler != null)
mThreadHandler.removeMessages(0);
}
public final void requestSync(boolean flag)
{
mSyncState.cancel();
if(mThreadHandler != null)
{
mThreadHandler.removeMessages(0);
Handler handler = mThreadHandler;
long l;
if(flag)
l = 500L;
else
l = 5000L;
handler.sendEmptyMessageDelayed(0, l);
}
}
public final void run()
{
android.os.Process.setThreadPriority(19);
Looper.prepare();
mThreadHandler = new Handler() {
public final void handleMessage(Message message)
{
syncContactsForCurrentAccount();
}
};
syncContactsForCurrentAccount();
Looper.loop();
}
}
private static final class AvatarState {
String avatarUrl;
long dataId;
String gaiaId;
long rawContactId;
int signature;
AvatarState()
{
}
}
private static final class CircleState
{
String circleId;
String circleName;
boolean exists;
long groupId;
CircleState()
{
}
}
private static final class DataState
{
boolean changed;
String data1;
String data2;
String data3;
long dataId;
boolean exists;
String mimetype;
}
private static final class ImageContainer
{
byte imageBytes[];
int mediaIndex;
}
private static final class PersonActivityState
{
final ArrayList activities;
String gaiaId;
long rawContactId;
PersonActivityState()
{
activities = new ArrayList();
}
}
private static final class RawContactState
{
final ArrayList data;
boolean exists;
String fullName;
long lastUpdateTime;
String personId;
long rawContactId;
RawContactState()
{
data = new ArrayList();
}
}
}