From f1ca5fc8e2f4eda0500b58c7517aead43a182d68 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 22 Oct 2019 12:09:27 -0400 Subject: [PATCH] Exclude inactive groups from search results where appropriate. Fixes #9091 Fixes #9080 --- .../securesms/ContactSelectionActivity.java | 2 +- .../thoughtcrime/securesms/ShareActivity.java | 11 ++++-- .../securesms/contacts/ContactAccessor.java | 2 +- .../contacts/ContactsCursorLoader.java | 27 +++++++++----- .../securesms/database/GroupDatabase.java | 20 +++++++--- .../securesms/database/ThreadDatabase.java | 37 ++++++++----------- .../securesms/jobs/PushGroupSendJob.java | 10 +++++ .../mediasend/CameraContactsRepository.java | 4 +- .../securesms/service/DirectShareService.java | 4 +- 9 files changed, 71 insertions(+), 46 deletions(-) diff --git a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java index 01f9182b12..32de223fd0 100644 --- a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java +++ b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java @@ -64,7 +64,7 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB protected void onCreate(Bundle icicle, boolean ready) { if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) { int displayMode = TextSecurePreferences.isSmsEnabled(this) ? DisplayMode.FLAG_ALL - : DisplayMode.FLAG_PUSH | DisplayMode.FLAG_GROUPS; + : DisplayMode.FLAG_PUSH | DisplayMode.FLAG_ACTIVE_GROUPS | DisplayMode.FLAG_INACTIVE_GROUPS; getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode); } diff --git a/src/org/thoughtcrime/securesms/ShareActivity.java b/src/org/thoughtcrime/securesms/ShareActivity.java index 9121c07b80..87a1dce76b 100644 --- a/src/org/thoughtcrime/securesms/ShareActivity.java +++ b/src/org/thoughtcrime/securesms/ShareActivity.java @@ -96,10 +96,13 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity @Override protected void onCreate(Bundle icicle, boolean ready) { if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) { - getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, - TextSecurePreferences.isSmsEnabled(this) - ? DisplayMode.FLAG_ALL - : DisplayMode.FLAG_PUSH | DisplayMode.FLAG_GROUPS); + int mode = DisplayMode.FLAG_PUSH | DisplayMode.FLAG_ACTIVE_GROUPS; + + if (TextSecurePreferences.isSmsEnabled(this)) { + mode |= DisplayMode.FLAG_SMS; + + } + getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, mode); } getIntent().putExtra(ContactSelectionListFragment.REFRESHABLE, false); diff --git a/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java b/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java index bc19af3c1b..5de0ca5b00 100644 --- a/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java +++ b/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java @@ -200,7 +200,7 @@ public class ContactAccessor { GroupRecord record; try { - reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint); + reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint, true); while ((record = reader.getNext()) != null) { numberList.add(record.getEncodedId()); diff --git a/src/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java b/src/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java index 42cee367c4..5054ff4311 100644 --- a/src/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java +++ b/src/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java @@ -51,10 +51,11 @@ public class ContactsCursorLoader extends CursorLoader { private static final String TAG = ContactsCursorLoader.class.getSimpleName(); public static final class DisplayMode { - public static final int FLAG_PUSH = 1; - public static final int FLAG_SMS = 1 << 1; - public static final int FLAG_GROUPS = 1 << 2; - public static final int FLAG_ALL = FLAG_PUSH | FLAG_SMS | FLAG_GROUPS; + public static final int FLAG_PUSH = 1; + public static final int FLAG_SMS = 1 << 1; + public static final int FLAG_ACTIVE_GROUPS = 1 << 2; + public static final int FLAG_INACTIVE_GROUPS = 1 << 3; + public static final int FLAG_ALL = FLAG_PUSH | FLAG_SMS | FLAG_ACTIVE_GROUPS | FLAG_INACTIVE_GROUPS; } private static final String[] CONTACT_PROJECTION = new String[]{ContactRepository.ID_COLUMN, @@ -76,6 +77,10 @@ public class ContactsCursorLoader extends CursorLoader { { super(context); + if (flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS) && !flagSet(mode, DisplayMode.FLAG_ACTIVE_GROUPS)) { + throw new AssertionError("Inactive group flag set, but the active group flag isn't!"); + } + this.filter = filter == null ? "" : filter; this.mode = mode; this.recents = recents; @@ -172,7 +177,7 @@ public class ContactsCursorLoader extends CursorLoader { ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(getContext()); MatrixCursor recentConversations = new MatrixCursor(CONTACT_PROJECTION, RECENT_CONVERSATION_MAX); - try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX)) { + try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS))) { ThreadDatabase.Reader reader = threadDatabase.readerFor(rawConversations); ThreadRecord threadRecord; while ((threadRecord = reader.getNext()) != null) { @@ -208,7 +213,7 @@ public class ContactsCursorLoader extends CursorLoader { private Cursor getGroupsCursor() { MatrixCursor groupContacts = new MatrixCursor(CONTACT_PROJECTION); - try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(getContext()).getGroupsFilteredByTitle(filter)) { + try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(getContext()).getGroupsFilteredByTitle(filter, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS))) { GroupDatabase.GroupRecord groupRecord; while ((groupRecord = reader.getNext()) != null) { groupContacts.addRow(new Object[] { groupRecord.getRecipientId().serialize(), @@ -266,14 +271,18 @@ public class ContactsCursorLoader extends CursorLoader { } private static boolean pushEnabled(int mode) { - return (mode & DisplayMode.FLAG_PUSH) > 0; + return flagSet(mode, DisplayMode.FLAG_PUSH); } private static boolean smsEnabled(int mode) { - return (mode & DisplayMode.FLAG_SMS) > 0; + return flagSet(mode, DisplayMode.FLAG_SMS); } private static boolean groupsEnabled(int mode) { - return (mode & DisplayMode.FLAG_GROUPS) > 0; + return flagSet(mode, DisplayMode.FLAG_ACTIVE_GROUPS); + } + + private static boolean flagSet(int mode, int flag) { + return (mode & flag) > 0; } } diff --git a/src/org/thoughtcrime/securesms/database/GroupDatabase.java b/src/org/thoughtcrime/securesms/database/GroupDatabase.java index d737ff7c76..ccc468af3d 100644 --- a/src/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/src/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -49,7 +49,7 @@ public class GroupDatabase extends Database { private static final String AVATAR_RELAY = "avatar_relay"; private static final String AVATAR_DIGEST = "avatar_digest"; private static final String TIMESTAMP = "timestamp"; - private static final String ACTIVE = "active"; + static final String ACTIVE = "active"; static final String MMS = "mms"; public static final String CREATE_TABLE = @@ -117,11 +117,19 @@ public class GroupDatabase extends Database { return !getGroup(groupId).isPresent(); } - public Reader getGroupsFilteredByTitle(String constraint) { - @SuppressLint("Recycle") - Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, TITLE + " LIKE ?", - new String[]{"%" + constraint + "%"}, - null, null, null); + public Reader getGroupsFilteredByTitle(String constraint, boolean includeInactive) { + String query; + String[] queryArgs; + + if (includeInactive) { + query = TITLE + " LIKE ? AND (" + ACTIVE + " = ? OR " + RECIPIENT_ID + " IN (SELECT " + ThreadDatabase.RECIPIENT_ID + " FROM " + ThreadDatabase.TABLE_NAME + "))"; + queryArgs = new String[]{"%" + constraint + "%", "1"}; + } else { + query = TITLE + " LIKE ? AND " + ACTIVE + " = ?"; + queryArgs = new String[]{"%" + constraint + "%", "1"}; + } + + Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, query, queryArgs, null, null, TITLE + " COLLATE NOCASE ASC"); return new Reader(cursor); } diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index 0b948e316e..7429e1813d 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -374,23 +374,25 @@ public class ThreadDatabase extends Database { return cursor; } - public Cursor getRecentConversationList(int limit) { + public Cursor getRecentConversationList(int limit, boolean includeInactiveGroups) { SQLiteDatabase db = databaseHelper.getReadableDatabase(); - String query = createQuery(MESSAGE_COUNT + " != 0", limit); - - return db.rawQuery(query, null); + String query = !includeInactiveGroups ? MESSAGE_COUNT + " != 0 AND " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.ACTIVE + " = 1" + : MESSAGE_COUNT + " != 0"; + return db.rawQuery(createQuery(query, limit), null); } - public Cursor getRecentPushConversationList(int limit) { - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - String where = MESSAGE_COUNT + " != 0 AND " + - "(" + - RecipientDatabase.REGISTERED + " = " + RecipientDatabase.RegisteredState.REGISTERED.getId() + " OR " + - "(" + - GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID + " NOT NULL AND " + - GroupDatabase.TABLE_NAME + "." + GroupDatabase.MMS + " = 0" + - ")" + - ")"; + public Cursor getRecentPushConversationList(int limit, boolean includeInactiveGroups) { + SQLiteDatabase db = databaseHelper.getReadableDatabase(); + String activeGroupQuery = !includeInactiveGroups ? " AND " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.ACTIVE + " = 1" : ""; + String where = MESSAGE_COUNT + " != 0 AND " + + "(" + + RecipientDatabase.REGISTERED + " = " + RecipientDatabase.RegisteredState.REGISTERED.getId() + " OR " + + "(" + + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID + " NOT NULL AND " + + GroupDatabase.TABLE_NAME + "." + GroupDatabase.MMS + " = 0" + + activeGroupQuery + + ")" + + ")"; String query = createQuery(where, limit); return db.rawQuery(query, null); @@ -414,13 +416,6 @@ public class ThreadDatabase extends Database { return cursor; } - public Cursor getDirectShareList() { - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - String query = createQuery(MESSAGE_COUNT + " != 0", 0); - - return db.rawQuery(query, null); - } - public int getArchivedConversationListCount() { SQLiteDatabase db = databaseHelper.getReadableDatabase(); Cursor cursor = null; diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 8b71249fb5..e29fd35772 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; @@ -90,6 +91,15 @@ public class PushGroupSendJob extends PushSendJob { @Nullable RecipientId filterAddress) { try { + Recipient group = Recipient.resolved(destination); + if (!group.isPushGroup()) { + throw new AssertionError("Not a group!"); + } + + if (!DatabaseFactory.getGroupDatabase(context).isActive(group.requireAddress().toGroupString())) { + throw new MmsException("Inactive group!"); + } + MmsDatabase database = DatabaseFactory.getMmsDatabase(context); OutgoingMediaMessage message = database.getOutgoingMessage(messageId); JobManager.Chain compressAndUploadAttachment = createCompressingAndUploadAttachmentsChain(jobManager, message); diff --git a/src/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java b/src/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java index 64d376105f..74db0b495a 100644 --- a/src/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java +++ b/src/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java @@ -65,7 +65,7 @@ class CameraContactsRepository { List recipients = new ArrayList<>(RECENT_MAX); - try (ThreadDatabase.Reader threadReader = threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(RECENT_MAX))) { + try (ThreadDatabase.Reader threadReader = threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(RECENT_MAX, false))) { ThreadRecord threadRecord; while ((threadRecord = threadReader.getNext()) != null) { recipients.add(threadRecord.getRecipient().resolve()); @@ -98,7 +98,7 @@ class CameraContactsRepository { List recipients = new ArrayList<>(); - try (GroupDatabase.Reader reader = groupDatabase.getGroupsFilteredByTitle(query)) { + try (GroupDatabase.Reader reader = groupDatabase.getGroupsFilteredByTitle(query, false)) { GroupDatabase.GroupRecord groupRecord; while ((groupRecord = reader.getNext()) != null) { RecipientId recipientId = recipientDatabase.getOrInsertFromGroupId(groupRecord.getEncodedId()); diff --git a/src/org/thoughtcrime/securesms/service/DirectShareService.java b/src/org/thoughtcrime/securesms/service/DirectShareService.java index 990c9efd72..2cb55fd4b6 100644 --- a/src/org/thoughtcrime/securesms/service/DirectShareService.java +++ b/src/org/thoughtcrime/securesms/service/DirectShareService.java @@ -39,13 +39,13 @@ public class DirectShareService extends ChooserTargetService { List results = new LinkedList<>(); ComponentName componentName = new ComponentName(this, ShareActivity.class); ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this); - Cursor cursor = threadDatabase.getDirectShareList(); + Cursor cursor = threadDatabase.getRecentConversationList(10, false); try { ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor); ThreadRecord record; - while ((record = reader.getNext()) != null && results.size() < 10) { + while ((record = reader.getNext()) != null) { Recipient recipient = Recipient.resolved(record.getRecipient().getId()); String name = recipient.toShortString();