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

Commit 06f73a15 authored by Walter Jang's avatar Walter Jang
Browse files

Ignore new raw contact display names when saving contacts

Now that we have logic to ignore the display name
we add to newly created raw contacts (when the
user wants to edit a read-only contact) when
determining whether the user made any edits,
we can enable changing the display on the compact
editor again.

Note, there is one glitch -- the name disappears
on the compact editor after you click more fields
(but only when editing read-only contacts).

Tested scenarios:

1) Edit read-only contact, more fields, back, back

   No bogus contact is created and the read-only
   name is displayed on both editors.

2) Edit read-only contact, change name on compact
   editor, back, re-edit read-only contact, and split

   The read-only contact is unchanged and a new
   contact with the edited name is created.

3) Edit read-only contact, more fields, change name on
   full editor, back, back, re-edit read-only contact,
   and split

   Same result as (2)

4) Edit read-only contact, add phone on compact
   editor, back, re-edit read-only contact, and split

   The read-only contact is unchanged and a new
   contact with the read-only name and phone number is
   created.

5) Edit read-only contact, more fields, add phone on full
   editor, back, back, re-edit read-only contact, and split

   Same result as (4)

Bug 21858251
Bug 21464081

Change-Id: I9028fee38b8ea7569968654a756eb98025318e69
parent 25f9694f
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
@@ -36,8 +36,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Bundle;
import android.util.Log;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.LinearLayout;
@@ -201,7 +199,11 @@ public class CompactContactEditorFragment extends ContactEditorBaseFragment impl
        // Add input fields for the loaded Contact
        // Add input fields for the loaded Contact
        final CompactRawContactsEditorView editorView = getContent();
        final CompactRawContactsEditorView editorView = getContent();
        editorView.setListener(this);
        editorView.setListener(this);
        editorView.setState(mState, getMaterialPalette(), mViewIdGenerator, mPhotoId, mNameId);
        editorView.setState(mState, getMaterialPalette(), mViewIdGenerator, mPhotoId, mNameId,
                mReadOnlyDisplayName);
        if (mReadOnlyDisplayName != null) {
            mReadOnlyNameEditorView = editorView.getDefaultNameEditorView();
        }


        // Set up the photo widget
        // Set up the photo widget
        mPhotoHandler = createPhotoHandler();
        mPhotoHandler = createPhotoHandler();
+49 −4
Original line number Original line Diff line number Diff line
@@ -137,6 +137,8 @@ public class CompactRawContactsEditorView extends LinearLayout implements View.O


    private long mPhotoRawContactId;
    private long mPhotoRawContactId;


    private StructuredNameEditorView mDefaultNameEditorView;

    public CompactRawContactsEditorView(Context context) {
    public CompactRawContactsEditorView(Context context) {
        super(context);
        super(context);
    }
    }
@@ -233,6 +235,10 @@ public class CompactRawContactsEditorView extends LinearLayout implements View.O
        return mPhotoRawContactId;
        return mPhotoRawContactId;
    }
    }


    public StructuredNameEditorView getDefaultNameEditorView() {
        return mDefaultNameEditorView;
    }

    public StructuredNameEditorView getStructuredNameEditorView() {
    public StructuredNameEditorView getStructuredNameEditorView() {
        // We only ever show one StructuredName
        // We only ever show one StructuredName
        return mNames.getChildCount() == 0
        return mNames.getChildCount() == 0
@@ -254,9 +260,13 @@ public class CompactRawContactsEditorView extends LinearLayout implements View.O
        return mNames.getChildAt(0).findViewById(R.id.anchor_view);
        return mNames.getChildAt(0).findViewById(R.id.anchor_view);
    }
    }


    /**
     * @param readOnlyDisplayName The display name to set on the new raw contact created in order
     *         to edit a read-only contact.
     */
    public void setState(RawContactDeltaList rawContactDeltas,
    public void setState(RawContactDeltaList rawContactDeltas,
            MaterialColorMapUtils.MaterialPalette materialPalette,
            MaterialColorMapUtils.MaterialPalette materialPalette, ViewIdGenerator viewIdGenerator,
            ViewIdGenerator viewIdGenerator, long photoId, long nameId) {
            long photoId, long nameId, String readOnlyDisplayName) {
        mNames.removeAllViews();
        mNames.removeAllViews();
        mPhoneticNames.removeAllViews();
        mPhoneticNames.removeAllViews();
        mNicknames.removeAllViews();
        mNicknames.removeAllViews();
@@ -275,7 +285,7 @@ public class CompactRawContactsEditorView extends LinearLayout implements View.O


        vlog("Setting compact editor state from " + rawContactDeltas);
        vlog("Setting compact editor state from " + rawContactDeltas);
        addPhotoView(rawContactDeltas, viewIdGenerator, photoId);
        addPhotoView(rawContactDeltas, viewIdGenerator, photoId);
        addStructuredNameView(rawContactDeltas, nameId);
        addStructuredNameView(rawContactDeltas, nameId, readOnlyDisplayName);
        addEditorViews(rawContactDeltas);
        addEditorViews(rawContactDeltas);
        removeExtraEmptyTextFields(mPhoneNumbers);
        removeExtraEmptyTextFields(mPhoneNumbers);
        removeExtraEmptyTextFields(mEmails);
        removeExtraEmptyTextFields(mEmails);
@@ -364,7 +374,42 @@ public class CompactRawContactsEditorView extends LinearLayout implements View.O
        mPhoto.setVisibility(View.GONE);
        mPhoto.setVisibility(View.GONE);
    }
    }


    private void addStructuredNameView(RawContactDeltaList rawContactDeltas, long nameId) {
    private void addStructuredNameView(RawContactDeltaList rawContactDeltas, long nameId,
            String readOnlyDisplayName) {
        // If we're editing a read-only contact we want to display the name from the read-only
        // contact in a structured name editor backed by the new raw contact that was created.
        // The new raw contact is writable and merging it with the read-only contact allows us
        // to edit the read-only contact. See go/editing-read-only-contacts
        if (!TextUtils.isEmpty(readOnlyDisplayName)) {
            for (RawContactDelta rawContactDelta : rawContactDeltas) {
                if (!rawContactDelta.isVisible()) continue;
                final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);

                // Make sure we have a structured name
                RawContactModifier.ensureKindExists(
                        rawContactDelta, accountType, StructuredName.CONTENT_ITEM_TYPE);

                if (accountType.areContactsWritable()) {
                    for (ValuesDelta valuesDelta : rawContactDelta.getMimeEntries(
                            StructuredName.CONTENT_ITEM_TYPE)) {
                        if (valuesDelta != null) {
                            mNameValuesDelta = valuesDelta;
                            final NameEditorListener nameEditorListener = new NameEditorListener(
                                    mNameValuesDelta, rawContactDelta.getRawContactId(), mListener);
                            final StructuredNameEditorView nameEditorView =
                                    inflateStructuredNameEditorView(mNames, accountType,
                                            mNameValuesDelta, rawContactDelta, nameEditorListener,
                                            !accountType.areContactsWritable());
                            nameEditorView.setDisplayName(readOnlyDisplayName);
                            mNames.addView(nameEditorView);
                            mDefaultNameEditorView = nameEditorView;
                            return;
                        }
                    }
                }
            }
        }

        // Look for a match for the name ID that was passed in
        // Look for a match for the name ID that was passed in
        for (RawContactDelta rawContactDelta : rawContactDeltas) {
        for (RawContactDelta rawContactDelta : rawContactDeltas) {
            if (!rawContactDelta.isVisible()) continue;
            if (!rawContactDelta.isVisible()) continue;
+42 −9
Original line number Original line Diff line number Diff line
@@ -378,7 +378,11 @@ abstract public class ContactEditorBaseFragment extends Fragment implements
    //
    //


    // Used to pre-populate the editor with a display name when a user edits a read-only contact.
    // Used to pre-populate the editor with a display name when a user edits a read-only contact.
    protected String mDefaultDisplayName;
    protected String mReadOnlyDisplayName;

    // The name editor view for the new raw contact that was created so that the user can
    // edit a read-only contact (to which the new raw contact was joined)
    protected StructuredNameEditorView mReadOnlyNameEditorView;


    /**
    /**
     * The contact data loader listener.
     * The contact data loader listener.
@@ -917,7 +921,35 @@ abstract public class ContactEditorBaseFragment extends Fragment implements


        mStatus = Status.SAVING;
        mStatus = Status.SAVING;


        if (!hasPendingChanges()) {
        // Determine if changes were made in the editor that need to be saved
        // See go/editing-read-only-contacts
        boolean hasPendingChanges;
        if (mReadOnlyNameEditorView == null || mReadOnlyDisplayName == null) {
            hasPendingChanges = hasPendingChanges();
        } else {
            // We created a new raw contact delta with a default display name. We must test for
            // pending changes while ignoring the default display name.
            final String displayName = mReadOnlyNameEditorView.getDisplayName();
            if (mReadOnlyDisplayName.equals(displayName)) {
                // The user did not modify the default display name, erase it and
                // check if the user made any other changes
                mReadOnlyNameEditorView.setDisplayName(null);
                if (hasPendingChanges()) {
                    // Other changes were made to the aggregate contact, restore
                    // the display name and proceed.
                    mReadOnlyNameEditorView.setDisplayName(displayName);
                    hasPendingChanges = true;
                } else {
                    // No other changes were made to the aggregate contact. Don't add back
                    // the displayName so that a "bogus" contact is not created.
                    hasPendingChanges = false;
                }
            } else {
                hasPendingChanges = true;
            }
        }

        if (!hasPendingChanges) {
            if (mLookupUri == null && saveMode == SaveMode.RELOAD) {
            if (mLookupUri == null && saveMode == SaveMode.RELOAD) {
                // We don't have anything to save and there isn't even an existing contact yet.
                // We don't have anything to save and there isn't even an existing contact yet.
                // Nothing to do, simply go back to editing mode
                // Nothing to do, simply go back to editing mode
@@ -1120,7 +1152,7 @@ abstract public class ContactEditorBaseFragment extends Fragment implements
            }
            }
        }
        }


        String displayName = null;
        String readOnlyDisplayName = null;
        // Check for writable raw contacts.  If there are none, then we need to create one so user
        // Check for writable raw contacts.  If there are none, then we need to create one so user
        // can edit.  For the user profile case, there is already an editable contact.
        // can edit.  For the user profile case, there is already an editable contact.
        if (!contact.isUserProfile() && !contact.isWritableContact(mContext)) {
        if (!contact.isUserProfile() && !contact.isWritableContact(mContext)) {
@@ -1128,12 +1160,13 @@ abstract public class ContactEditorBaseFragment extends Fragment implements


            // This is potentially an asynchronous call and will add deltas to list.
            // This is potentially an asynchronous call and will add deltas to list.
            selectAccountAndCreateContact();
            selectAccountAndCreateContact();
            displayName = contact.getDisplayName();

            readOnlyDisplayName = contact.getDisplayName();
        }
        }


        // This also adds deltas to list
        // This also adds deltas to list.  If readOnlyDisplayName is null at this point it is
        // If displayName is null at this point it is simply ignored later on by the editor.
        // simply ignored later on by the editor.
        setStateForExistingContact(displayName, contact.isUserProfile(), mRawContacts);
        setStateForExistingContact(readOnlyDisplayName, contact.isUserProfile(), mRawContacts);
    }
    }


    /**
    /**
@@ -1202,10 +1235,10 @@ abstract public class ContactEditorBaseFragment extends Fragment implements
    /**
    /**
     * Prepare {@link #mState} for an existing contact.
     * Prepare {@link #mState} for an existing contact.
     */
     */
    protected void setStateForExistingContact(String displayName, boolean isUserProfile,
    protected void setStateForExistingContact(String readOnlyDisplayName, boolean isUserProfile,
            ImmutableList<RawContact> rawContacts) {
            ImmutableList<RawContact> rawContacts) {
        setEnabled(true);
        setEnabled(true);
        mDefaultDisplayName = displayName;
        mReadOnlyDisplayName = readOnlyDisplayName;


        mState.addAll(rawContacts.iterator());
        mState.addAll(rawContacts.iterator());
        setIntentExtras(mIntentExtras);
        setIntentExtras(mIntentExtras);
+5 −3
Original line number Original line Diff line number Diff line
@@ -169,7 +169,7 @@ public class ContactEditorFragment extends ContactEditorBaseFragment implements
            mState = new RawContactDeltaList();
            mState = new RawContactDeltaList();
            setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType);
            setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType);
            if (mIsEdit) {
            if (mIsEdit) {
                setStateForExistingContact(mDefaultDisplayName, mIsUserProfile, mRawContacts);
                setStateForExistingContact(mReadOnlyDisplayName, mIsUserProfile, mRawContacts);
            }
            }
        }
        }
    }
    }
@@ -293,8 +293,10 @@ public class ContactEditorFragment extends ContactEditorBaseFragment implements


                final StructuredNameEditorView nameEditor = rawContactEditor.getNameEditor();
                final StructuredNameEditorView nameEditor = rawContactEditor.getNameEditor();
                nameEditor.setEditorListener(structuredNameListener);
                nameEditor.setEditorListener(structuredNameListener);
                if (!TextUtils.isEmpty(mDefaultDisplayName)) {
                if (TextUtils.isEmpty(nameEditor.getDisplayName()) &&
                    nameEditor.setDisplayName(mDefaultDisplayName);
                        !TextUtils.isEmpty(mReadOnlyDisplayName)) {
                    nameEditor.setDisplayName(mReadOnlyDisplayName);
                    mReadOnlyNameEditorView = nameEditor;
                }
                }


                rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);
                rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);