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

Commit ba5f6a10 authored by Marcus Hagerott's avatar Marcus Hagerott Committed by android-build-merger
Browse files

Allow creation of duplicates of empty system groups

am: 2d97b5f8

Change-Id: I3dc4d29b9b985c96075c8f26c90a8e6521c869c5
parents fddbb83d 2d97b5f8
Loading
Loading
Loading
Loading
+39 −38
Original line number Diff line number Diff line
@@ -25,9 +25,8 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Groups;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
@@ -273,16 +272,27 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // Only a single loader so id is ignored.
        return new CursorLoader(getActivity(), GroupNameQuery.URI,
                GroupNameQuery.PROJECTION, GroupNameQuery.getSelection(mAccount),
                GroupNameQuery.getSelectionArgs(mAccount), null);
        return new CursorLoader(getActivity(), Groups.CONTENT_SUMMARY_URI,
                new String[] { Groups.TITLE, Groups.SYSTEM_ID, Groups.ACCOUNT_TYPE,
                        Groups.SUMMARY_COUNT, Groups.GROUP_IS_READ_ONLY},
                getSelection(), getSelectionArgs(), null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        mExistingGroups = new HashSet<>();
        final GroupUtil.GroupsProjection projection = new GroupUtil.GroupsProjection(data);
        while (data.moveToNext()) {
            mExistingGroups.add(data.getString(GroupNameQuery.TITLE));
            final String title = projection.getTitle(data);
            // Empty system groups aren't shown in the nav drawer so it would be confusing to tell
            // the user that they already exist. Instead we allow them to create a duplicate
            // group in this case. This is how the web handles this case as well (it creates a
            // new non-system group if a new group with a title that matches a system group is
            // create).
            if (projection.isEmptyFFCGroup(data)) {
                continue;
            }
            mExistingGroups.add(title);
        }
    }

@@ -290,38 +300,6 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements
    public void onLoaderReset(Loader<Cursor> loader) {
    }

    /**
     * Defines the structure of the query performed by the CursorLoader created by
     * GroupNameEditDialogFragment
     */
    private static class GroupNameQuery {

        public static final int TITLE = 0;
        public static final Uri URI = ContactsContract.Groups.CONTENT_URI;
        public static final String[] PROJECTION = new String[] { ContactsContract.Groups.TITLE };

        public static String getSelection(AccountWithDataSet account) {
            final StringBuilder builder = new StringBuilder();
            builder.append(ContactsContract.Groups.ACCOUNT_NAME).append("=? AND ")
                    .append(ContactsContract.Groups.ACCOUNT_TYPE).append("=?");
            if (account.dataSet != null) {
                builder.append(" AND ").append(ContactsContract.Groups.DATA_SET).append("=?");
            }
            return builder.toString();
        }

        public static String[] getSelectionArgs(AccountWithDataSet account) {
            final int len = account.dataSet == null ? 2 : 3;
            final String[] args = new String[len];
            args[0] = account.name;
            args[1] = account.type;
            if (account.dataSet != null) {
                args[2] = account.dataSet;
            }
            return args;
        }
    }

    private void showInputMethod(View view) {
        final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
                Context.INPUT_METHOD_SERVICE);
@@ -352,4 +330,27 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements
        return mGroupNameEditText == null || mGroupNameEditText.getText() == null
                ? null : mGroupNameEditText.getText().toString();
    }

    private String getSelection() {
        final StringBuilder builder = new StringBuilder();
        builder.append(Groups.ACCOUNT_NAME).append("=? AND ")
               .append(Groups.ACCOUNT_TYPE).append("=? AND ")
               .append(Groups.DELETED).append("=?");
        if (mAccount.dataSet != null) {
            builder.append(" AND ").append(Groups.DATA_SET).append("=?");
        }
        return builder.toString();
    }

    private String[] getSelectionArgs() {
        final int len = mAccount.dataSet == null ? 3 : 4;
        final String[] args = new String[len];
        args[0] = mAccount.name;
        args[1] = mAccount.type;
        args[2] = "0"; // Not deleted
        if (mAccount.dataSet != null) {
            args[3] = mAccount.dataSet;
        }
        return args;
    }
}
+73 −0
Original line number Diff line number Diff line
@@ -219,4 +219,77 @@ public final class GroupUtil {
        }
        return array;
    }

    /**
     * Stores column ordering for the projection of a query of ContactsContract.Groups
     */
    public static final class GroupsProjection {
        public final int groupId;
        public final int title;
        public final int summaryCount;
        public final int systemId;
        public final int accountName;
        public final int accountType;
        public final int dataSet;
        public final int autoAdd;
        public final int favorites;
        public final int isReadOnly;
        public final int deleted;

        public GroupsProjection(Cursor cursor) {
            groupId = cursor.getColumnIndex(Groups._ID);
            title = cursor.getColumnIndex(Groups.TITLE);
            summaryCount = cursor.getColumnIndex(Groups.SUMMARY_COUNT);
            systemId = cursor.getColumnIndex(Groups.SYSTEM_ID);
            accountName = cursor.getColumnIndex(Groups.ACCOUNT_NAME);
            accountType = cursor.getColumnIndex(Groups.ACCOUNT_TYPE);
            dataSet = cursor.getColumnIndex(Groups.DATA_SET);
            autoAdd = cursor.getColumnIndex(Groups.AUTO_ADD);
            favorites = cursor.getColumnIndex(Groups.FAVORITES);
            isReadOnly = cursor.getColumnIndex(Groups.GROUP_IS_READ_ONLY);
            deleted = cursor.getColumnIndex(Groups.DELETED);
        }

        public GroupsProjection(String[] projection) {
            List<String> list = Arrays.asList(projection);
            groupId = list.indexOf(Groups._ID);
            title = list.indexOf(Groups.TITLE);
            summaryCount = list.indexOf(Groups.SUMMARY_COUNT);
            systemId = list.indexOf(Groups.SYSTEM_ID);
            accountName = list.indexOf(Groups.ACCOUNT_NAME);
            accountType = list.indexOf(Groups.ACCOUNT_TYPE);
            dataSet = list.indexOf(Groups.DATA_SET);
            autoAdd = list.indexOf(Groups.AUTO_ADD);
            favorites = list.indexOf(Groups.FAVORITES);
            isReadOnly = list.indexOf(Groups.GROUP_IS_READ_ONLY);
            deleted = list.indexOf(Groups.DELETED);
        }

        public String getTitle(Cursor cursor) {
            return cursor.getString(title);
        }

        public long getId(Cursor cursor) {
            return cursor.getLong(groupId);
        }

        public String getSystemId(Cursor cursor) {
            return cursor.getString(systemId);
        }

        public int getSummaryCount(Cursor cursor) {
            return cursor.getInt(summaryCount);
        }

        public boolean isEmptyFFCGroup(Cursor cursor) {
            if (accountType == -1 || isReadOnly == -1 ||
                    systemId == -1 || summaryCount == -1) {
                throw new IllegalArgumentException("Projection is missing required columns");
            }
            return GoogleAccountType.ACCOUNT_TYPE.equals(cursor.getString(accountType))
                    && cursor.getInt(isReadOnly) != 0
                    && isSystemIdFFC(cursor.getString(systemId))
                    && cursor.getInt(summaryCount) <= 0;
        }
    }
}
 No newline at end of file