batch invitation

// FREEBIE
This commit is contained in:
Jake McGinty
2015-10-19 11:23:12 -07:00
committed by Moxie Marlinspike
parent 4371708fc4
commit 3e798a9863
47 changed files with 942 additions and 341 deletions

View File

@@ -21,6 +21,7 @@ import android.content.res.TypedArray;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -59,10 +60,6 @@ public class ContactSelectionListAdapter extends CursorAdapter
this.multiSelect = multiSelect;
}
public static class HeaderViewHolder {
TextView text;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return li.inflate(R.layout.contact_selection_list_item, parent, false);
@@ -90,27 +87,23 @@ public class ContactSelectionListAdapter extends CursorAdapter
@Override
public View getHeaderView(int i, View convertView, ViewGroup viewGroup) {
Cursor cursor = getCursor();
HeaderViewHolder holder;
Cursor cursor = getCursor();
final TextView text;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = li.inflate(R.layout.contact_selection_list_header, viewGroup, false);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
text = (TextView)li.inflate(R.layout.contact_selection_list_header, viewGroup, false);
} else {
holder = (HeaderViewHolder) convertView.getTag();
text = (TextView)convertView;
}
cursor.moveToPosition(i);
int contactType = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.CONTACT_TYPE_COLUMN));
if (contactType == ContactsDatabase.PUSH_TYPE) holder.text.setText(R.string.contact_selection_list__header_signal_users);
else holder.text.setText(R.string.contact_selection_list__header_other);
if (contactType == ContactsDatabase.PUSH_TYPE) text.setText(R.string.contact_selection_list__header_signal_users);
else text.setText(R.string.contact_selection_list__header_other);
return convertView;
return text;
}
@Override

View File

@@ -18,12 +18,18 @@ package org.thoughtcrime.securesms.contacts;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.support.annotation.NonNull;
import android.support.v4.content.CursorLoader;
import android.text.TextUtils;
import android.util.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.DirectoryHelper.UserCapabilities.Capability;
import org.thoughtcrime.securesms.util.NumberUtil;
import java.util.ArrayList;
@@ -37,14 +43,18 @@ public class ContactsCursorLoader extends CursorLoader {
private static final String TAG = ContactsCursorLoader.class.getSimpleName();
private final String filter;
private boolean includeSmsContacts;
public final static int MODE_ALL = 0;
public final static int MODE_PUSH_ONLY = 1;
public final static int MODE_OTHER_ONLY = 2;
public ContactsCursorLoader(Context context, boolean includeSmsContacts, String filter) {
private final String filter;
private final int mode;
public ContactsCursorLoader(Context context, int mode, String filter) {
super(context);
this.filter = filter;
this.includeSmsContacts = includeSmsContacts;
this.filter = filter;
this.mode = mode;
}
@Override
@@ -52,10 +62,14 @@ public class ContactsCursorLoader extends CursorLoader {
ContactsDatabase contactsDatabase = DatabaseFactory.getContactsDatabase(getContext());
ArrayList<Cursor> cursorList = new ArrayList<>(3);
cursorList.add(contactsDatabase.queryTextSecureContacts(filter));
if (mode != MODE_OTHER_ONLY) {
cursorList.add(contactsDatabase.queryTextSecureContacts(filter));
}
if (includeSmsContacts) {
if (mode == MODE_ALL) {
cursorList.add(contactsDatabase.querySystemContacts(filter));
} else if (mode == MODE_OTHER_ONLY) {
cursorList.add(filterNonPushContacts(contactsDatabase.querySystemContacts(filter)));
}
if (!TextUtils.isEmpty(filter) && NumberUtil.isValidSmsOrEmail(filter)) {
@@ -64,4 +78,35 @@ public class ContactsCursorLoader extends CursorLoader {
return new MergeCursor(cursorList.toArray(new Cursor[0]));
}
private @NonNull Cursor filterNonPushContacts(@NonNull Cursor cursor) {
try {
final long startMillis = System.currentTimeMillis();
final MatrixCursor matrix = new MatrixCursor(new String[]{ContactsDatabase.ID_COLUMN,
ContactsDatabase.NAME_COLUMN,
ContactsDatabase.NUMBER_COLUMN,
ContactsDatabase.NUMBER_TYPE_COLUMN,
ContactsDatabase.LABEL_COLUMN,
ContactsDatabase.CONTACT_TYPE_COLUMN});
while (cursor.moveToNext()) {
final String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN));
final Recipients recipients = RecipientFactory.getRecipientsFromString(getContext(), number, true);
if (DirectoryHelper.getUserCapabilities(getContext(), recipients)
.getTextCapability() != Capability.SUPPORTED)
{
matrix.addRow(new Object[]{cursor.getLong(cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN)),
cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN)),
number,
cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_TYPE_COLUMN)),
cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.LABEL_COLUMN)),
ContactsDatabase.NORMAL_TYPE});
}
}
Log.w(TAG, "filterNonPushContacts() -> " + (System.currentTimeMillis() - startMillis) + "ms");
return matrix;
} finally {
cursor.close();
}
}
}

View File

@@ -23,11 +23,13 @@ import android.content.OperationApplicationException;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.RawContacts;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -36,6 +38,10 @@ import android.util.Log;
import android.util.Pair;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.TextSecureDirectory;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.DirectoryHelper.UserCapabilities.Capability;
import org.whispersystems.libaxolotl.util.guava.Optional;
import org.whispersystems.textsecure.api.util.InvalidNumberException;
import org.whispersystems.textsecure.api.util.PhoneNumberFormatter;
@@ -55,7 +61,9 @@ import java.util.Set;
*/
public class ContactsDatabase {
private static final String TAG = ContactsDatabase.class.getSimpleName();
private static final String TAG = ContactsDatabase.class.getSimpleName();
private static final String MIME = "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact";
private static final String SYNC = "__TS";
public static final String ID_COLUMN = "_id";
public static final String NAME_COLUMN = "name";
@@ -154,12 +162,12 @@ public class ContactsDatabase {
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, e164number)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_OTHER)
.withValue(ContactsContract.Data.SYNC2, "__TS")
.withValue(ContactsContract.Data.SYNC2, SYNC)
.build());
operations.add(ContentProviderOperation.newInsert(dataUri)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, index)
.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact")
.withValue(ContactsContract.Data.MIMETYPE, MIME)
.withValue(ContactsContract.Data.DATA1, e164number)
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
.withValue(ContactsContract.Data.DATA3, context.getString(R.string.ContactsDatabase_message_s, e164number))
@@ -219,7 +227,7 @@ public class ContactsDatabase {
Cursor cursor = context.getContentResolver().query(uri, projection,
ContactsContract.Data.SYNC2 + " IS NULL OR " +
ContactsContract.Data.SYNC2 + " != ?",
new String[] {"__TS"},
new String[] {SYNC},
sort);
return new ProjectionMappingCursor(cursor, projectionMap,
@@ -245,13 +253,13 @@ public class ContactsDatabase {
cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
projection,
ContactsContract.Data.MIMETYPE + " = ?",
new String[] {"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact"},
new String[] {MIME},
sort);
} else {
cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
projection,
ContactsContract.Data.MIMETYPE + " = ? AND (" + ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? OR " + ContactsContract.Data.DATA1 + " LIKE ?)",
new String[] {"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact",
new String[] {MIME,
"%" + filter + "%", "%" + filter + "%"},
sort);
}