diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 231e36a5ed6..1852b912776 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -1309,7 +1309,7 @@ private void handleManualMmsRequired() { } private void handleUnverifiedRecipients() { - List unverifiedRecipients = identityRecords.getUnverifiedRecipients(this); + List unverifiedRecipients = identityRecords.getUnverifiedRecipients(); List unverifiedRecords = identityRecords.getUnverifiedRecords(); String message = IdentityUtil.getUnverifiedSendDialogDescription(this, unverifiedRecipients); @@ -1332,7 +1332,7 @@ public void onFailure(ExecutionException e) { } private void handleUntrustedRecipients() { - List untrustedRecipients = identityRecords.getUntrustedRecipients(this); + List untrustedRecipients = identityRecords.getUntrustedRecipients(); List untrustedRecords = identityRecords.getUntrustedRecords(); String untrustedMessage = IdentityUtil.getUntrustedSendDialogDescription(this, untrustedRecipients); @@ -1633,31 +1633,25 @@ private ListenableFuture initializeIdentityRecords() { new AsyncTask>() { @Override protected @NonNull Pair doInBackground(Recipient... params) { - IdentityDatabase identityDatabase = DatabaseFactory.getIdentityDatabase(ConversationActivity.this); - IdentityRecordList identityRecordList = new IdentityRecordList(); - List recipients = new LinkedList<>(); + IdentityDatabase identityDatabase = DatabaseFactory.getIdentityDatabase(ConversationActivity.this); + List recipients; if (params[0].isGroup()) { - recipients.addAll(DatabaseFactory.getGroupDatabase(ConversationActivity.this) - .getGroupMembers(params[0].requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF)); + recipients = DatabaseFactory.getGroupDatabase(ConversationActivity.this) + .getGroupMembers(params[0].requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); } else { - recipients.add(params[0]); + recipients = Collections.singletonList(params[0]); } - long startTime = System.currentTimeMillis(); - StringBuilder logBuilder = new StringBuilder(); + long startTime = System.currentTimeMillis(); + IdentityRecordList identityRecordList = identityDatabase.getIdentities(recipients); - for (Recipient recipient : recipients) { - logBuilder.append(recipient.getId()).append(" "); - identityRecordList.add(identityDatabase.getIdentity(recipient.getId())); - } - - Log.i(TAG, String.format(Locale.ENGLISH, "Loaded %d identities in %d ms: %s", recipients.size(), System.currentTimeMillis() - startTime, logBuilder.toString())); + Log.i(TAG, String.format(Locale.US, "Loaded %d identities in %d ms", recipients.size(), System.currentTimeMillis() - startTime)); String message = null; if (identityRecordList.isUnverified()) { - message = IdentityUtil.getUnverifiedBannerDescription(ConversationActivity.this, identityRecordList.getUnverifiedRecipients(ConversationActivity.this)); + message = IdentityUtil.getUnverifiedBannerDescription(ConversationActivity.this, identityRecordList.getUnverifiedRecipients()); } return new Pair<>(identityRecordList, message); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java index 27d5709a089..fda98b7a1a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java @@ -19,6 +19,7 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -26,6 +27,7 @@ import org.greenrobot.eventbus.EventBus; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; +import org.thoughtcrime.securesms.database.identity.IdentityRecordList; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.Base64; @@ -35,6 +37,7 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.io.IOException; +import java.util.List; public class IdentityDatabase extends Database { @@ -111,6 +114,31 @@ public Optional getIdentity(@NonNull RecipientId recipientId) { return Optional.absent(); } + public @NonNull IdentityRecordList getIdentities(@NonNull List recipients) { + IdentityRecordList identityRecordList = new IdentityRecordList(); + SQLiteDatabase database = databaseHelper.getReadableDatabase(); + String[] selectionArgs = new String[1]; + + database.beginTransaction(); + try { + for (Recipient recipient : recipients) { + selectionArgs[0] = recipient.getId().serialize(); + + try (Cursor cursor = database.query(TABLE_NAME, null, RECIPIENT_ID + " = ?", selectionArgs, null, null, null)) { + if (cursor.moveToFirst()) { + identityRecordList.add(getIdentityRecord(cursor)); + } + } catch (InvalidKeyException | IOException e) { + throw new AssertionError(e); + } + } + } finally { + database.endTransaction(); + } + + return identityRecordList; + } + public void saveIdentity(@NonNull RecipientId recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus, boolean firstUse, long timestamp, boolean nonBlockingApproval) { @@ -181,7 +209,7 @@ private boolean hasMatchingStatus(@NonNull RecipientId id, IdentityKey identityK } } - private IdentityRecord getIdentityRecord(@NonNull Cursor cursor) throws IOException, InvalidKeyException { + private static @NonNull IdentityRecord getIdentityRecord(@NonNull Cursor cursor) throws IOException, InvalidKeyException { long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID)); String serializedIdentity = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY)); long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/identity/IdentityRecordList.java b/app/src/main/java/org/thoughtcrime/securesms/database/identity/IdentityRecordList.java index 100bb80042c..26a980eb901 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/identity/IdentityRecordList.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/identity/IdentityRecordList.java @@ -1,30 +1,25 @@ package org.thoughtcrime.securesms.database.identity; - -import android.content.Context; +import androidx.annotation.NonNull; import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; import org.thoughtcrime.securesms.recipients.Recipient; -import org.whispersystems.libsignal.util.guava.Optional; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; -public class IdentityRecordList { - - private static final String TAG = IdentityRecordList.class.getSimpleName(); +public final class IdentityRecordList { private final List identityRecords = new LinkedList<>(); - public void add(Optional identityRecord) { - if (identityRecord.isPresent()) { - identityRecords.add(identityRecord.get()); - } + public void add(@NonNull IdentityRecord identityRecord) { + identityRecords.add(identityRecord); } - public void replaceWith(IdentityRecordList identityRecordList) { + public void replaceWith(@NonNull IdentityRecordList identityRecordList) { identityRecords.clear(); identityRecords.addAll(identityRecordList.identityRecords); } @@ -59,8 +54,8 @@ public boolean isUntrusted() { return false; } - public List getUntrustedRecords() { - List results = new LinkedList<>(); + public @NonNull List getUntrustedRecords() { + List results = new ArrayList<>(identityRecords.size()); for (IdentityRecord identityRecord : identityRecords) { if (isUntrusted(identityRecord)) { @@ -71,8 +66,8 @@ public List getUntrustedRecords() { return results; } - public List getUntrustedRecipients(Context context) { - List untrusted = new LinkedList<>(); + public @NonNull List getUntrustedRecipients() { + List untrusted = new ArrayList<>(identityRecords.size()); for (IdentityRecord identityRecord : identityRecords) { if (isUntrusted(identityRecord)) { @@ -84,7 +79,7 @@ public List getUntrustedRecipients(Context context) { } public List getUnverifiedRecords() { - List results = new LinkedList<>(); + List results = new ArrayList<>(identityRecords.size()); for (IdentityRecord identityRecord : identityRecords) { if (identityRecord.getVerifiedStatus() == VerifiedStatus.UNVERIFIED) { @@ -95,8 +90,8 @@ public List getUnverifiedRecords() { return results; } - public List getUnverifiedRecipients(Context context) { - List unverified = new LinkedList<>(); + public List getUnverifiedRecipients() { + List unverified = new ArrayList<>(identityRecords.size()); for (IdentityRecord identityRecord : identityRecords) { if (identityRecord.getVerifiedStatus() == VerifiedStatus.UNVERIFIED) { @@ -107,7 +102,7 @@ public List getUnverifiedRecipients(Context context) { return unverified; } - private boolean isUntrusted(IdentityRecord identityRecord) { + private static boolean isUntrusted(@NonNull IdentityRecord identityRecord) { return !identityRecord.isApprovedNonBlocking() && System.currentTimeMillis() - identityRecord.getTimestamp() < TimeUnit.SECONDS.toMillis(5); }