Loading src/com/android/contacts/activities/ConfirmAddDetailActivity.java +57 −62 Original line number Diff line number Diff line Loading @@ -78,17 +78,16 @@ import java.util.HashMap; * This is a dialog-themed activity for confirming the addition of a detail to an existing contact * (once the user has selected this contact from a list of all contacts). The incoming intent * must have an extra with max 1 phone or email specified, using * {@link ContactsContract.Intents.Insert.PHONE} with type * {@link ContactsContract.Intents.Insert.PHONE_TYPE} or * {@link ContactsContract.Intents.Insert.EMAIL} with type * {@link ContactsContract.Intents.Insert.EMAIL_TYPE} intent keys. * {@link android.provider.ContactsContract.Intents.Insert#PHONE} with type * {@link android.provider.ContactsContract.Intents.Insert#PHONE_TYPE} or * {@link android.provider.ContactsContract.Intents.Insert#EMAIL} with type * {@link android.provider.ContactsContract.Intents.Insert#EMAIL_TYPE} intent keys. */ public class ConfirmAddDetailActivity extends Activity implements DialogManager.DialogShowingViewActivity { private static final String TAG = ConfirmAddDetailActivity.class.getSimpleName(); private static final String LEGACY_CONTACTS_AUTHORITY = "contacts"; private static final String TAG = "ConfirmAdd"; // The class name is too long to be a tag. private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE); private LayoutInflater mInflater; private View mRootView; Loading @@ -102,15 +101,19 @@ public class ConfirmAddDetailActivity extends Activity implements private ContentResolver mContentResolver; private AccountType mEditableAccountType; private EntityDelta mState; private Uri mContactUri; private long mContactId; private String mDisplayName; private boolean mIsReadyOnly; private boolean mIsReadOnly; private QueryHandler mQueryHandler; /** {@link EntityDeltaList} for the entire selected contact. */ private EntityDeltaList mEntityDeltaList; /** {@link EntityDeltaList} for the editable account */ private EntityDelta mEntityDelta; private String mMimetype = Phone.CONTENT_ITEM_TYPE; /** Loading Loading @@ -168,9 +171,9 @@ public class ConfirmAddDetailActivity extends Activity implements * a disambiguation case. For example, if the contact does not have a * nickname, use the email field, and etc. */ private static final String[] sMimeTypePriorityList = new String[] { Nickname.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE, Im.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE }; private static final String[] MIME_TYPE_PRIORITY_LIST = new String[] { Nickname.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE, Im.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE }; private static final int TOKEN_CONTACT_INFO = 0; private static final int TOKEN_PHOTO_QUERY = 1; Loading @@ -180,7 +183,7 @@ public class ConfirmAddDetailActivity extends Activity implements private final OnClickListener mDetailsButtonClickListener = new OnClickListener() { @Override public void onClick(View v) { if (mIsReadyOnly) { if (mIsReadOnly) { onSaveCompleted(true); } else { doSaveAction(); Loading Loading @@ -250,7 +253,8 @@ public class ConfirmAddDetailActivity extends Activity implements mPhotoView = (ImageView) findViewById(R.id.photo); mEditorContainerView = (ViewGroup) findViewById(R.id.editor_container); startContactQuery(mContactUri, true); resetAsyncQueryHandler(); startContactQuery(mContactUri); new QueryEntitiesTask(this).execute(intent); } Loading Loading @@ -282,13 +286,8 @@ public class ConfirmAddDetailActivity extends Activity implements * Internal method to query contact by Uri. * * @param contactUri the contact uri * @param resetQueryHandler whether to use a new AsyncQueryHandler or not */ private void startContactQuery(Uri contactUri, boolean resetQueryHandler) { if (resetQueryHandler) { resetAsyncQueryHandler(); } private void startContactQuery(Uri contactUri) { mQueryHandler.startQuery(TOKEN_CONTACT_INFO, contactUri, contactUri, ContactQuery.COLUMNS, null, null, null); } Loading @@ -298,13 +297,8 @@ public class ConfirmAddDetailActivity extends Activity implements * * @param photoId the photo id. * @param lookupKey the lookup uri. * @param resetQueryHandler whether to use a new AsyncQueryHandler or not. */ private void startPhotoQuery(long photoId, Uri lookupKey, boolean resetQueryHandler) { if (resetQueryHandler) { resetAsyncQueryHandler(); } private void startPhotoQuery(long photoId, Uri lookupKey) { mQueryHandler.startQuery(TOKEN_PHOTO_QUERY, lookupKey, ContentUris.withAppendedId(Data.CONTENT_URI, photoId), PhotoQuery.COLUMNS, null, null, null); Loading Loading @@ -420,9 +414,6 @@ public class ConfirmAddDetailActivity extends Activity implements return; } activityTarget.setEntityDeltaList(entityList); activityTarget.findEditableRawContact(); activityTarget.parseExtras(); activityTarget.bindEditor(); } } Loading Loading @@ -477,12 +468,11 @@ public class ConfirmAddDetailActivity extends Activity implements // Otherwise do the photo query. Uri lookupUri = Contacts.getLookupUri(mContactId, cursor.getString(ContactQuery.LOOKUP_KEY)); startPhotoQuery(photoId, lookupUri, false /* don't reset query handler */); startPhotoQuery(photoId, lookupUri); // Display the name because there is no // disambiguation query. setDisplayName(); onLoadDataFinished(); showDialogContent(); } } break; Loading @@ -500,7 +490,7 @@ public class ConfirmAddDetailActivity extends Activity implements // If there are no other contacts with this name, // then display the name. setDisplayName(); onLoadDataFinished(); showDialogContent(); } break; } Loading Loading @@ -535,14 +525,14 @@ public class ConfirmAddDetailActivity extends Activity implements // Find the first non-empty field according to the // mimetype priority list and display this under the // contact's display name to disambiguate the contact. for (String mimeType : sMimeTypePriorityList) { for (String mimeType : MIME_TYPE_PRIORITY_LIST) { if (hashMapCursorData.containsKey(mimeType)) { setDisplayName(); setExtraInfoField(hashMapCursorData.get(mimeType)); break; } } onLoadDataFinished(); showDialogContent(); } break; } Loading @@ -555,28 +545,35 @@ public class ConfirmAddDetailActivity extends Activity implements } } public void setEntityDeltaList(EntityDeltaList entityList) { mEntityDeltaList = entityList; } public void findEditableRawContact() { if (mEntityDeltaList == null) return; mState = mEntityDeltaList.getFirstWritableRawContact(this); if (mState != null) { mEditableAccountType = mState.getRawContactAccountType(this); private void setEntityDeltaList(EntityDeltaList entityList) { if (entityList == null) { throw new IllegalStateException(); } if (VERBOSE_LOGGING) { Log.v(TAG, "setEntityDeltaList: " + entityList); } public void parseExtras() { if (mEditableAccountType == null || mState == null) { return; } mEntityDeltaList = entityList; // Find the editable type. mEntityDelta = mEntityDeltaList.getFirstWritableRawContact(this); if (mEntityDelta == null) { mIsReadOnly = true; mEditableAccountType = null; } else { mIsReadOnly = false; mEditableAccountType = mEntityDelta.getRawContactAccountType(this); // Handle any incoming values that should be inserted final Bundle extras = getIntent().getExtras(); if (extras != null && extras.size() > 0) { // If there are any intent extras, add them as additional fields in the EntityDelta. EntityModifier.parseExtras(this, mEditableAccountType, mState, extras); EntityModifier.parseExtras(this, mEditableAccountType, mEntityDelta, extras); } } bindEditor(); } /** Loading @@ -584,19 +581,18 @@ public class ConfirmAddDetailActivity extends Activity implements */ private void bindEditor() { if (mEntityDeltaList == null) { return; throw new IllegalStateException(); } // If no valid raw contact (to insert the data) was found, we won't have an editable // account type to use. In this case, display an error message and hide the "OK" button. if (mEditableAccountType == null) { mIsReadyOnly = true; if (mIsReadOnly) { mReadOnlyWarningView.setText(getString(R.string.contact_read_only)); mReadOnlyWarningView.setVisibility(View.VISIBLE); mEditorContainerView.setVisibility(View.GONE); findViewById(R.id.btn_done).setVisibility(View.GONE); // Nothing more to be done, just show the UI onLoadDataFinished(); showDialogContent(); return; } Loading @@ -605,11 +601,11 @@ public class ConfirmAddDetailActivity extends Activity implements // Skip kind that are not editable if (!kind.editable) continue; if (mMimetype.equals(kind.mimeType)) { for (ValuesDelta valuesDelta : mState.getMimeEntries(mMimetype)) { for (ValuesDelta valuesDelta : mEntityDelta.getMimeEntries(mMimetype)) { // Skip entries that aren't visible if (!valuesDelta.isVisible()) continue; if (valuesDelta.isInsert()) { inflateEditorView(kind, valuesDelta, mState); inflateEditorView(kind, valuesDelta, mEntityDelta); return; } } Loading Loading @@ -660,7 +656,7 @@ public class ConfirmAddDetailActivity extends Activity implements * once all the queries have completed, otherwise the screen will flash as additional data * comes in. */ private void onLoadDataFinished() { private void showDialogContent() { mRootView.setVisibility(View.VISIBLE); } Loading @@ -673,14 +669,13 @@ public class ConfirmAddDetailActivity extends Activity implements task.execute(mEntityDeltaList); } /** * Background task for persisting edited contact data, using the changes * defined by a set of {@link EntityDelta}. This task starts * {@link EmptyService} to make sure the background thread can finish * persisting in cases where the system wants to reclaim our process. */ public static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> { private static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> { // In the future, use ContactSaver instead of WeakAsyncTask because of // the danger of the activity being null during a save action private static final int PERSIST_TRIES = 3; Loading src/com/android/contacts/model/EntityDelta.java +11 −3 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ public class EntityDelta implements Parcelable { * Internal map of children values from {@link Entity#getSubValues()}, which * we store here sorted into {@link Data#MIMETYPE} bins. */ private HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap(); private final HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap(); public EntityDelta() { } Loading Loading @@ -354,15 +354,18 @@ public class EntityDelta implements Parcelable { public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("\n("); builder.append("Uri="); builder.append(mContactsQueryUri); builder.append(", Values="); builder.append(mValues != null ? mValues.toString() : "null"); builder.append(") = {"); builder.append(", Entries={"); for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) { for (ValuesDelta child : mimeEntries) { builder.append("\n\t"); child.toString(builder); } } builder.append("\n}\n"); builder.append("\n})\n"); return builder.toString(); } Loading Loading @@ -865,6 +868,11 @@ public class EntityDelta implements Parcelable { */ public void toString(StringBuilder builder) { builder.append("{ "); builder.append("IdColumn="); builder.append(mIdColumn); builder.append(", FromTemplate="); builder.append(mFromTemplate); builder.append(", "); for (String key : this.keySet()) { builder.append(key); builder.append("="); Loading src/com/android/contacts/model/EntityDeltaList.java +40 −6 Original line number Diff line number Diff line Loading @@ -16,24 +16,25 @@ package com.android.contacts.model; import com.android.contacts.model.EntityDelta.ValuesDelta; import com.google.android.collect.Lists; import android.content.ContentProviderOperation; import android.content.ContentProviderOperation.Builder; import android.content.ContentResolver; import android.content.Context; import android.content.Entity; import android.content.EntityIterator; import android.content.ContentProviderOperation.Builder; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.provider.ContactsContract.AggregationExceptions; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.RawContacts; import com.google.android.collect.Lists; import com.android.contacts.model.EntityDelta.ValuesDelta; import android.util.Log; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; /** Loading @@ -42,6 +43,9 @@ import java.util.Iterator; * and applying another {@link EntityDeltaList} over it. */ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelable { private static final String TAG = "EntityDeltaList"; private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE); private boolean mSplitRawContacts; private long[] mJoinWithRawContactIds; Loading Loading @@ -123,6 +127,9 @@ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelabl * any {@link AggregationExceptions} rules needed to groups edits together. */ public ArrayList<ContentProviderOperation> buildDiff() { if (VERBOSE_LOGGING) { Log.v(TAG, "buildDiff: list=" + toString()); } final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); final long rawContactId = this.findRawContactId(); Loading Loading @@ -197,10 +204,23 @@ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelabl if (diff.size() == assertMark) { diff.clear(); } if (VERBOSE_LOGGING) { Log.v(TAG, "buildDiff: ops=" + diffToString(diff)); } return diff; } private static String diffToString(ArrayList<ContentProviderOperation> ops) { StringBuilder sb = new StringBuilder(); sb.append("[\n"); for (ContentProviderOperation op : ops) { sb.append(op.toString()); sb.append(",\n"); } sb.append("]\n"); return sb.toString(); } /** * Start building a {@link ContentProviderOperation} that will keep two * {@link RawContacts} together. Loading Loading @@ -416,4 +436,18 @@ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelabl return new EntityDeltaList[size]; } }; @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("("); sb.append("Split="); sb.append(mSplitRawContacts); sb.append(", Join=["); sb.append(Arrays.toString(mJoinWithRawContactIds)); sb.append("], Values="); sb.append(super.toString()); sb.append(")"); return sb.toString(); } } Loading
src/com/android/contacts/activities/ConfirmAddDetailActivity.java +57 −62 Original line number Diff line number Diff line Loading @@ -78,17 +78,16 @@ import java.util.HashMap; * This is a dialog-themed activity for confirming the addition of a detail to an existing contact * (once the user has selected this contact from a list of all contacts). The incoming intent * must have an extra with max 1 phone or email specified, using * {@link ContactsContract.Intents.Insert.PHONE} with type * {@link ContactsContract.Intents.Insert.PHONE_TYPE} or * {@link ContactsContract.Intents.Insert.EMAIL} with type * {@link ContactsContract.Intents.Insert.EMAIL_TYPE} intent keys. * {@link android.provider.ContactsContract.Intents.Insert#PHONE} with type * {@link android.provider.ContactsContract.Intents.Insert#PHONE_TYPE} or * {@link android.provider.ContactsContract.Intents.Insert#EMAIL} with type * {@link android.provider.ContactsContract.Intents.Insert#EMAIL_TYPE} intent keys. */ public class ConfirmAddDetailActivity extends Activity implements DialogManager.DialogShowingViewActivity { private static final String TAG = ConfirmAddDetailActivity.class.getSimpleName(); private static final String LEGACY_CONTACTS_AUTHORITY = "contacts"; private static final String TAG = "ConfirmAdd"; // The class name is too long to be a tag. private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE); private LayoutInflater mInflater; private View mRootView; Loading @@ -102,15 +101,19 @@ public class ConfirmAddDetailActivity extends Activity implements private ContentResolver mContentResolver; private AccountType mEditableAccountType; private EntityDelta mState; private Uri mContactUri; private long mContactId; private String mDisplayName; private boolean mIsReadyOnly; private boolean mIsReadOnly; private QueryHandler mQueryHandler; /** {@link EntityDeltaList} for the entire selected contact. */ private EntityDeltaList mEntityDeltaList; /** {@link EntityDeltaList} for the editable account */ private EntityDelta mEntityDelta; private String mMimetype = Phone.CONTENT_ITEM_TYPE; /** Loading Loading @@ -168,9 +171,9 @@ public class ConfirmAddDetailActivity extends Activity implements * a disambiguation case. For example, if the contact does not have a * nickname, use the email field, and etc. */ private static final String[] sMimeTypePriorityList = new String[] { Nickname.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE, Im.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE }; private static final String[] MIME_TYPE_PRIORITY_LIST = new String[] { Nickname.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE, Im.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE }; private static final int TOKEN_CONTACT_INFO = 0; private static final int TOKEN_PHOTO_QUERY = 1; Loading @@ -180,7 +183,7 @@ public class ConfirmAddDetailActivity extends Activity implements private final OnClickListener mDetailsButtonClickListener = new OnClickListener() { @Override public void onClick(View v) { if (mIsReadyOnly) { if (mIsReadOnly) { onSaveCompleted(true); } else { doSaveAction(); Loading Loading @@ -250,7 +253,8 @@ public class ConfirmAddDetailActivity extends Activity implements mPhotoView = (ImageView) findViewById(R.id.photo); mEditorContainerView = (ViewGroup) findViewById(R.id.editor_container); startContactQuery(mContactUri, true); resetAsyncQueryHandler(); startContactQuery(mContactUri); new QueryEntitiesTask(this).execute(intent); } Loading Loading @@ -282,13 +286,8 @@ public class ConfirmAddDetailActivity extends Activity implements * Internal method to query contact by Uri. * * @param contactUri the contact uri * @param resetQueryHandler whether to use a new AsyncQueryHandler or not */ private void startContactQuery(Uri contactUri, boolean resetQueryHandler) { if (resetQueryHandler) { resetAsyncQueryHandler(); } private void startContactQuery(Uri contactUri) { mQueryHandler.startQuery(TOKEN_CONTACT_INFO, contactUri, contactUri, ContactQuery.COLUMNS, null, null, null); } Loading @@ -298,13 +297,8 @@ public class ConfirmAddDetailActivity extends Activity implements * * @param photoId the photo id. * @param lookupKey the lookup uri. * @param resetQueryHandler whether to use a new AsyncQueryHandler or not. */ private void startPhotoQuery(long photoId, Uri lookupKey, boolean resetQueryHandler) { if (resetQueryHandler) { resetAsyncQueryHandler(); } private void startPhotoQuery(long photoId, Uri lookupKey) { mQueryHandler.startQuery(TOKEN_PHOTO_QUERY, lookupKey, ContentUris.withAppendedId(Data.CONTENT_URI, photoId), PhotoQuery.COLUMNS, null, null, null); Loading Loading @@ -420,9 +414,6 @@ public class ConfirmAddDetailActivity extends Activity implements return; } activityTarget.setEntityDeltaList(entityList); activityTarget.findEditableRawContact(); activityTarget.parseExtras(); activityTarget.bindEditor(); } } Loading Loading @@ -477,12 +468,11 @@ public class ConfirmAddDetailActivity extends Activity implements // Otherwise do the photo query. Uri lookupUri = Contacts.getLookupUri(mContactId, cursor.getString(ContactQuery.LOOKUP_KEY)); startPhotoQuery(photoId, lookupUri, false /* don't reset query handler */); startPhotoQuery(photoId, lookupUri); // Display the name because there is no // disambiguation query. setDisplayName(); onLoadDataFinished(); showDialogContent(); } } break; Loading @@ -500,7 +490,7 @@ public class ConfirmAddDetailActivity extends Activity implements // If there are no other contacts with this name, // then display the name. setDisplayName(); onLoadDataFinished(); showDialogContent(); } break; } Loading Loading @@ -535,14 +525,14 @@ public class ConfirmAddDetailActivity extends Activity implements // Find the first non-empty field according to the // mimetype priority list and display this under the // contact's display name to disambiguate the contact. for (String mimeType : sMimeTypePriorityList) { for (String mimeType : MIME_TYPE_PRIORITY_LIST) { if (hashMapCursorData.containsKey(mimeType)) { setDisplayName(); setExtraInfoField(hashMapCursorData.get(mimeType)); break; } } onLoadDataFinished(); showDialogContent(); } break; } Loading @@ -555,28 +545,35 @@ public class ConfirmAddDetailActivity extends Activity implements } } public void setEntityDeltaList(EntityDeltaList entityList) { mEntityDeltaList = entityList; } public void findEditableRawContact() { if (mEntityDeltaList == null) return; mState = mEntityDeltaList.getFirstWritableRawContact(this); if (mState != null) { mEditableAccountType = mState.getRawContactAccountType(this); private void setEntityDeltaList(EntityDeltaList entityList) { if (entityList == null) { throw new IllegalStateException(); } if (VERBOSE_LOGGING) { Log.v(TAG, "setEntityDeltaList: " + entityList); } public void parseExtras() { if (mEditableAccountType == null || mState == null) { return; } mEntityDeltaList = entityList; // Find the editable type. mEntityDelta = mEntityDeltaList.getFirstWritableRawContact(this); if (mEntityDelta == null) { mIsReadOnly = true; mEditableAccountType = null; } else { mIsReadOnly = false; mEditableAccountType = mEntityDelta.getRawContactAccountType(this); // Handle any incoming values that should be inserted final Bundle extras = getIntent().getExtras(); if (extras != null && extras.size() > 0) { // If there are any intent extras, add them as additional fields in the EntityDelta. EntityModifier.parseExtras(this, mEditableAccountType, mState, extras); EntityModifier.parseExtras(this, mEditableAccountType, mEntityDelta, extras); } } bindEditor(); } /** Loading @@ -584,19 +581,18 @@ public class ConfirmAddDetailActivity extends Activity implements */ private void bindEditor() { if (mEntityDeltaList == null) { return; throw new IllegalStateException(); } // If no valid raw contact (to insert the data) was found, we won't have an editable // account type to use. In this case, display an error message and hide the "OK" button. if (mEditableAccountType == null) { mIsReadyOnly = true; if (mIsReadOnly) { mReadOnlyWarningView.setText(getString(R.string.contact_read_only)); mReadOnlyWarningView.setVisibility(View.VISIBLE); mEditorContainerView.setVisibility(View.GONE); findViewById(R.id.btn_done).setVisibility(View.GONE); // Nothing more to be done, just show the UI onLoadDataFinished(); showDialogContent(); return; } Loading @@ -605,11 +601,11 @@ public class ConfirmAddDetailActivity extends Activity implements // Skip kind that are not editable if (!kind.editable) continue; if (mMimetype.equals(kind.mimeType)) { for (ValuesDelta valuesDelta : mState.getMimeEntries(mMimetype)) { for (ValuesDelta valuesDelta : mEntityDelta.getMimeEntries(mMimetype)) { // Skip entries that aren't visible if (!valuesDelta.isVisible()) continue; if (valuesDelta.isInsert()) { inflateEditorView(kind, valuesDelta, mState); inflateEditorView(kind, valuesDelta, mEntityDelta); return; } } Loading Loading @@ -660,7 +656,7 @@ public class ConfirmAddDetailActivity extends Activity implements * once all the queries have completed, otherwise the screen will flash as additional data * comes in. */ private void onLoadDataFinished() { private void showDialogContent() { mRootView.setVisibility(View.VISIBLE); } Loading @@ -673,14 +669,13 @@ public class ConfirmAddDetailActivity extends Activity implements task.execute(mEntityDeltaList); } /** * Background task for persisting edited contact data, using the changes * defined by a set of {@link EntityDelta}. This task starts * {@link EmptyService} to make sure the background thread can finish * persisting in cases where the system wants to reclaim our process. */ public static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> { private static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> { // In the future, use ContactSaver instead of WeakAsyncTask because of // the danger of the activity being null during a save action private static final int PERSIST_TRIES = 3; Loading
src/com/android/contacts/model/EntityDelta.java +11 −3 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ public class EntityDelta implements Parcelable { * Internal map of children values from {@link Entity#getSubValues()}, which * we store here sorted into {@link Data#MIMETYPE} bins. */ private HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap(); private final HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap(); public EntityDelta() { } Loading Loading @@ -354,15 +354,18 @@ public class EntityDelta implements Parcelable { public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("\n("); builder.append("Uri="); builder.append(mContactsQueryUri); builder.append(", Values="); builder.append(mValues != null ? mValues.toString() : "null"); builder.append(") = {"); builder.append(", Entries={"); for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) { for (ValuesDelta child : mimeEntries) { builder.append("\n\t"); child.toString(builder); } } builder.append("\n}\n"); builder.append("\n})\n"); return builder.toString(); } Loading Loading @@ -865,6 +868,11 @@ public class EntityDelta implements Parcelable { */ public void toString(StringBuilder builder) { builder.append("{ "); builder.append("IdColumn="); builder.append(mIdColumn); builder.append(", FromTemplate="); builder.append(mFromTemplate); builder.append(", "); for (String key : this.keySet()) { builder.append(key); builder.append("="); Loading
src/com/android/contacts/model/EntityDeltaList.java +40 −6 Original line number Diff line number Diff line Loading @@ -16,24 +16,25 @@ package com.android.contacts.model; import com.android.contacts.model.EntityDelta.ValuesDelta; import com.google.android.collect.Lists; import android.content.ContentProviderOperation; import android.content.ContentProviderOperation.Builder; import android.content.ContentResolver; import android.content.Context; import android.content.Entity; import android.content.EntityIterator; import android.content.ContentProviderOperation.Builder; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.provider.ContactsContract.AggregationExceptions; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.RawContacts; import com.google.android.collect.Lists; import com.android.contacts.model.EntityDelta.ValuesDelta; import android.util.Log; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; /** Loading @@ -42,6 +43,9 @@ import java.util.Iterator; * and applying another {@link EntityDeltaList} over it. */ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelable { private static final String TAG = "EntityDeltaList"; private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE); private boolean mSplitRawContacts; private long[] mJoinWithRawContactIds; Loading Loading @@ -123,6 +127,9 @@ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelabl * any {@link AggregationExceptions} rules needed to groups edits together. */ public ArrayList<ContentProviderOperation> buildDiff() { if (VERBOSE_LOGGING) { Log.v(TAG, "buildDiff: list=" + toString()); } final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); final long rawContactId = this.findRawContactId(); Loading Loading @@ -197,10 +204,23 @@ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelabl if (diff.size() == assertMark) { diff.clear(); } if (VERBOSE_LOGGING) { Log.v(TAG, "buildDiff: ops=" + diffToString(diff)); } return diff; } private static String diffToString(ArrayList<ContentProviderOperation> ops) { StringBuilder sb = new StringBuilder(); sb.append("[\n"); for (ContentProviderOperation op : ops) { sb.append(op.toString()); sb.append(",\n"); } sb.append("]\n"); return sb.toString(); } /** * Start building a {@link ContentProviderOperation} that will keep two * {@link RawContacts} together. Loading Loading @@ -416,4 +436,18 @@ public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelabl return new EntityDeltaList[size]; } }; @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("("); sb.append("Split="); sb.append(mSplitRawContacts); sb.append(", Join=["); sb.append(Arrays.toString(mJoinWithRawContactIds)); sb.append("], Values="); sb.append(super.toString()); sb.append(")"); return sb.toString(); } }