Loading src/com/android/contacts/group/GroupNameEditDialogFragment.java +39 −38 Original line number Original line Diff line number Diff line Loading @@ -25,9 +25,8 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.Intent; import android.content.Loader; import android.content.Loader; import android.database.Cursor; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.Groups; import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.Editable; Loading Loading @@ -273,16 +272,27 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements @Override @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) { // Only a single loader so id is ignored. // Only a single loader so id is ignored. return new CursorLoader(getActivity(), GroupNameQuery.URI, return new CursorLoader(getActivity(), Groups.CONTENT_SUMMARY_URI, GroupNameQuery.PROJECTION, GroupNameQuery.getSelection(mAccount), new String[] { Groups.TITLE, Groups.SYSTEM_ID, Groups.ACCOUNT_TYPE, GroupNameQuery.getSelectionArgs(mAccount), null); Groups.SUMMARY_COUNT, Groups.GROUP_IS_READ_ONLY}, getSelection(), getSelectionArgs(), null); } } @Override @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mExistingGroups = new HashSet<>(); mExistingGroups = new HashSet<>(); final GroupUtil.GroupsProjection projection = new GroupUtil.GroupsProjection(data); while (data.moveToNext()) { 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); } } } } Loading @@ -290,38 +300,6 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements public void onLoaderReset(Loader<Cursor> loader) { 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) { private void showInputMethod(View view) { final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( Context.INPUT_METHOD_SERVICE); Context.INPUT_METHOD_SERVICE); Loading Loading @@ -352,4 +330,27 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements return mGroupNameEditText == null || mGroupNameEditText.getText() == null return mGroupNameEditText == null || mGroupNameEditText.getText() == null ? null : mGroupNameEditText.getText().toString(); ? 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; } } } src/com/android/contacts/group/GroupUtil.java +73 −0 Original line number Original line Diff line number Diff line Loading @@ -219,4 +219,77 @@ public final class GroupUtil { } } return array; 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 Loading
src/com/android/contacts/group/GroupNameEditDialogFragment.java +39 −38 Original line number Original line Diff line number Diff line Loading @@ -25,9 +25,8 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.Intent; import android.content.Loader; import android.content.Loader; import android.database.Cursor; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.Groups; import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.Editable; Loading Loading @@ -273,16 +272,27 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements @Override @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) { // Only a single loader so id is ignored. // Only a single loader so id is ignored. return new CursorLoader(getActivity(), GroupNameQuery.URI, return new CursorLoader(getActivity(), Groups.CONTENT_SUMMARY_URI, GroupNameQuery.PROJECTION, GroupNameQuery.getSelection(mAccount), new String[] { Groups.TITLE, Groups.SYSTEM_ID, Groups.ACCOUNT_TYPE, GroupNameQuery.getSelectionArgs(mAccount), null); Groups.SUMMARY_COUNT, Groups.GROUP_IS_READ_ONLY}, getSelection(), getSelectionArgs(), null); } } @Override @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mExistingGroups = new HashSet<>(); mExistingGroups = new HashSet<>(); final GroupUtil.GroupsProjection projection = new GroupUtil.GroupsProjection(data); while (data.moveToNext()) { 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); } } } } Loading @@ -290,38 +300,6 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements public void onLoaderReset(Loader<Cursor> loader) { 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) { private void showInputMethod(View view) { final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( Context.INPUT_METHOD_SERVICE); Context.INPUT_METHOD_SERVICE); Loading Loading @@ -352,4 +330,27 @@ public final class GroupNameEditDialogFragment extends DialogFragment implements return mGroupNameEditText == null || mGroupNameEditText.getText() == null return mGroupNameEditText == null || mGroupNameEditText.getText() == null ? null : mGroupNameEditText.getText().toString(); ? 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; } } }
src/com/android/contacts/group/GroupUtil.java +73 −0 Original line number Original line Diff line number Diff line Loading @@ -219,4 +219,77 @@ public final class GroupUtil { } } return array; 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