Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f8d46b5 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Insert, update, delete photos. Trim empty fields.

Allow photo changes when the ContactsSource allows Photo
entries.  This change also trims out any inserted or updated
fields that are now "empty" according to their respective
DataKind fields.  Wrote unit tests for field trimming to
ensure wiping works.  Fixes http://b/2050549
parent 6fbf4e0b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
    android:clickable="true"
    android:focusable="true"
    android:src="@drawable/ic_menu_add_picture"
    android:cropToPadding="true"
    android:scaleType="center"
    android:background="@drawable/btn_contact_picture"
    android:gravity="center" />
+8 −0
Original line number Diff line number Diff line
@@ -34,6 +34,14 @@ public interface Editor {
         * Called when the given {@link Editor} has been deleted.
         */
        public void onDeleted(Editor editor);

        /**
         * Called when the given {@link Editor} has a request, for example it
         * wants to select a photo.
         */
        public void onRequest(int request);

        public static final int REQUEST_PICK_PHOTO = 1;
    }

    /**
+5 −0
Original line number Diff line number Diff line
@@ -551,6 +551,11 @@ public class EntityDelta implements Parcelable {
            mAfter.put(key, value);
        }

        public void put(String key, byte[] value) {
            ensureUpdate();
            mAfter.put(key, value);
        }

        public void put(String key, int value) {
            ensureUpdate();
            mAfter.put(key, value);
+46 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.contacts.model;

import com.android.contacts.model.ContactsSource.DataKind;
import com.android.contacts.model.ContactsSource.EditField;
import com.android.contacts.model.ContactsSource.EditType;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.google.android.collect.Lists;
@@ -34,6 +35,7 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Intents.Insert;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;

import java.util.ArrayList;
@@ -45,6 +47,8 @@ import java.util.List;
 * new rows, or enforcing {@link ContactsSource}.
 */
public class EntityModifier {
    private static final String TAG = "EntityModifier";

    /**
     * For the given {@link EntityDelta}, determine if the given
     * {@link DataKind} could be inserted under specific
@@ -334,6 +338,48 @@ public class EntityModifier {
        return child;
    }

    /**
     * Processing to trim any empty {@link ValuesDelta} rows from the given
     * {@link EntityDelta}, assuming the given {@link ContactsSource} dictates
     * the structure for various fields. This method ignores rows not described
     * by the {@link ContactsSource}.
     */
    public static void trimEmpty(ContactsSource source, EntityDelta state) {
        // Walk through entries for each well-known kind
        for (DataKind kind : source.getSortedDataKinds()) {
            final String mimeType = kind.mimeType;
            final ArrayList<ValuesDelta> entries = state.getMimeEntries(mimeType);
            if (entries == null) continue;

            for (ValuesDelta entry : entries) {
                // Test and remove this row if empty
                final boolean touched = entry.isInsert() || entry.isUpdate();
                if (touched && EntityModifier.isEmpty(entry, kind)) {
                    // TODO: remove this verbose logging
                    Log.w(TAG, "Trimming: " + entry.toString());
                    entry.markDeleted();
                }
            }
        }
    }

    /**
     * Test if the given {@link ValuesDelta} would be considered "empty" in
     * terms of {@link DataKind#fieldList}.
     */
    public static boolean isEmpty(ValuesDelta values, DataKind kind) {
        boolean hasValues = false;
        for (EditField field : kind.fieldList) {
            // If any field has values, we're not empty
            final String value = values.getAsString(field.column);
            if (!TextUtils.isEmpty(value)) {
                hasValues = true;
            }
        }

        return !hasValues;
    }

    /**
     * Parse the given {@link Bundle} into the given {@link EntityDelta} state,
     * assuming the extras defined through {@link Intents}.
+16 −2
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
     * existing {@link RawContacts#_ID} value. Usually used when creating
     * {@link AggregationExceptions} during an update.
     */
    public long findRawContactId() {
    protected long findRawContactId() {
        for (EntityDelta delta : this) {
            final Long rawContactId = delta.getValues().getAsLong(RawContacts._ID);
            if (rawContactId != null && rawContactId >= 0) {
@@ -177,8 +177,22 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
            final EntityDelta delta = this.get(index);
            return delta.getValues().getAsLong(RawContacts._ID);
        } else {
            return -1;
            return 0;
        }
    }

    /**
     * Find index of given {@link RawContacts#_ID} when present.
     */
    public int indexOfRawContactId(long rawContactId) {
        final int size = this.size();
        for (int i = 0; i < size; i++) {
            final long currentId = getRawContactId(i);
            if (currentId == rawContactId) {
                return i;
            }
        }
        return -1;
    }

    /** {@inheritDoc} */
Loading