Don't pass read-only portions of RawContactDeltaList to contact save service
Bug 23896510
Change-Id: Ie50aa5c0581779c12861072ec838f26d444fb549
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index c3a7f24..10f8f9c 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -56,6 +56,7 @@
import com.android.contacts.common.model.RawContactDelta;
import com.android.contacts.common.model.RawContactDeltaList;
import com.android.contacts.common.model.RawContactModifier;
+import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.compat.PinnedPositionsCompat;
@@ -66,6 +67,7 @@
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -372,8 +374,12 @@
String saveModeExtraKey, int saveMode, boolean isProfile,
Class<? extends Activity> callbackActivity, String callbackAction,
Bundle updatedPhotos, String joinContactIdExtraKey, Long joinContactId) {
- Intent serviceIntent = new Intent(
- context, ContactSaveService.class);
+ // Don't pass read-only RawContactDeltas in RawContactDeltaList to contact save service,
+ // because 1. read-only RawContactDeltas are not writable anyway; 2. read-only
+ // RawContactDeltas may be problematic, see b/23896510.
+ removeReadOnlyContacts(context, state);
+
+ Intent serviceIntent = new Intent(context, ContactSaveService.class);
serviceIntent.setAction(ContactSaveService.ACTION_SAVE_CONTACT);
serviceIntent.putExtra(EXTRA_CONTACT_STATE, (Parcelable) state);
serviceIntent.putExtra(EXTRA_SAVE_IS_PROFILE, isProfile);
@@ -398,6 +404,26 @@
return serviceIntent;
}
+ private static void removeReadOnlyContacts(Context context, RawContactDeltaList state) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Before trimming: " + state.size());
+ }
+ int countReadOnly = 0;
+ final Iterator<RawContactDelta> iterator = state.iterator();
+ while (iterator.hasNext()) {
+ final RawContactDelta rawContactDelta = iterator.next();
+ final AccountType accountType = rawContactDelta.getRawContactAccountType(context);
+ if (accountType != null && !accountType.areContactsWritable()) {
+ countReadOnly++;
+ iterator.remove();
+ }
+ }
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "# of read-only removed: " + countReadOnly);
+ Log.v(TAG, "After trimming: " + state.size());
+ }
+ }
+
private void saveContact(Intent intent) {
RawContactDeltaList state = intent.getParcelableExtra(EXTRA_CONTACT_STATE);
boolean isProfile = intent.getBooleanExtra(EXTRA_SAVE_IS_PROFILE, false);