diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt index 8d2a88573..d5945607a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt @@ -9,6 +9,8 @@ import android.text.TextUtils import androidx.annotation.WorkerThread import org.signal.contacts.ContactLinkConfiguration import org.signal.contacts.SystemContactsRepository +import org.signal.contacts.SystemContactsRepository.ContactIterator +import org.signal.contacts.SystemContactsRepository.ContactPhoneDetails import org.signal.core.util.StringUtil import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.BuildConfig @@ -130,7 +132,11 @@ object ContactDiscovery { @JvmStatic @WorkerThread fun syncRecipientInfoWithSystemContacts(context: Context) { - syncRecipientsWithSystemContacts(context, emptyMap()) + syncRecipientsWithSystemContacts( + context = context, + rewrites = emptyMap(), + clearInfoForMissingContacts = true + ) } private fun phoneNumberFormatter(context: Context): (String) -> String { @@ -156,22 +162,24 @@ object ContactDiscovery { addSystemContactLinks(context, result.registeredIds, removeSystemContactLinksIfMissing) stopwatch.split("contact-links") + val useFullSync = removeSystemContactLinksIfMissing && result.registeredIds.size > FULL_SYSTEM_CONTACT_SYNC_THRESHOLD syncRecipientsWithSystemContacts( context = context, rewrites = result.rewrites, contactsProvider = { - if (result.registeredIds.size > FULL_SYSTEM_CONTACT_SYNC_THRESHOLD) { - Log.d(TAG, "Doing a full system contact sync because there are ${result.registeredIds.size} contacts to get info for.") + if (useFullSync) { + Log.d(TAG, "Doing a full system contact sync. There are ${result.registeredIds.size} contacts to get info for.") SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter(context)) } else { - Log.d(TAG, "Doing a partial system contact sync because there are ${result.registeredIds.size} contacts to get info for.") + Log.d(TAG, "Doing a partial system contact sync. There are ${result.registeredIds.size} contacts to get info for.") SystemContactsRepository.getContactDetailsByQueries( context = context, queries = Recipient.resolvedList(result.registeredIds).mapNotNull { it.e164.orElse(null) }, e164Formatter = phoneNumberFormatter(context) ) } - } + }, + clearInfoForMissingContacts = useFullSync ) stopwatch.split("contact-sync") @@ -282,15 +290,18 @@ object ContactDiscovery { private fun syncRecipientsWithSystemContacts( context: Context, rewrites: Map, - contactsProvider: () -> SystemContactsRepository.ContactIterator = { SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter(context)) } + contactsProvider: () -> ContactIterator = { SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter(context)) }, + clearInfoForMissingContacts: Boolean ) { - val handle = SignalDatabase.recipients.beginBulkSystemContactUpdate() + val localNumber: String = SignalStore.account().e164 ?: "" + val handle = SignalDatabase.recipients.beginBulkSystemContactUpdate(clearInfoForMissingContacts) try { contactsProvider().use { iterator -> while (iterator.hasNext()) { val details = iterator.next() + val phoneDetailsWithoutSelf: List = details.numbers.filter { it.number != localNumber } - for (phoneDetails in details.numbers) { + for (phoneDetails in phoneDetailsWithoutSelf) { val realNumber: String = Util.getFirstNonEmpty(rewrites[phoneDetails.number], phoneDetails.number) val profileName: ProfileName = if (!StringUtil.isEmpty(details.givenName)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt index d9353a6b3..1d5b0ca4c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt @@ -1162,15 +1162,23 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : return out } - fun beginBulkSystemContactUpdate(): BulkOperationsHandle { - val db = writableDatabase - val contentValues = ContentValues(1).apply { - put(SYSTEM_INFO_PENDING, 1) + /** + * @param clearInfoForMissingContacts If true, this will clear any saved contact details for any recipient that hasn't been updated + * by the time finish() is called. Basically this should be true for full syncs and false for + * partial syncs. + */ + fun beginBulkSystemContactUpdate(clearInfoForMissingContacts: Boolean): BulkOperationsHandle { + writableDatabase.beginTransaction() + + if (clearInfoForMissingContacts) { + writableDatabase + .update(TABLE_NAME) + .values(SYSTEM_INFO_PENDING to 1) + .where("$SYSTEM_CONTACT_URI NOT NULL") + .run() } - db.beginTransaction() - db.update(TABLE_NAME, contentValues, "$SYSTEM_CONTACT_URI NOT NULL", null) - return BulkOperationsHandle(db) + return BulkOperationsHandle(writableDatabase) } fun onUpdatedChatColors(chatColors: ChatColors) { @@ -3212,19 +3220,18 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : } private fun clearSystemDataForPendingInfo() { - val query = "$SYSTEM_INFO_PENDING = ?" - val args = arrayOf("1") - val values = ContentValues(5).apply { - put(SYSTEM_INFO_PENDING, 0) - put(SYSTEM_GIVEN_NAME, null as String?) - put(SYSTEM_FAMILY_NAME, null as String?) - put(SYSTEM_JOINED_NAME, null as String?) - put(SYSTEM_PHOTO_URI, null as String?) - put(SYSTEM_PHONE_LABEL, null as String?) - put(SYSTEM_CONTACT_URI, null as String?) - } - - database.update(TABLE_NAME, values, query, args) + database.update(TABLE_NAME) + .values( + SYSTEM_INFO_PENDING to 0, + SYSTEM_GIVEN_NAME to null, + SYSTEM_FAMILY_NAME to null, + SYSTEM_JOINED_NAME to null, + SYSTEM_PHOTO_URI to null, + SYSTEM_PHONE_LABEL to null, + SYSTEM_CONTACT_URI to null + ) + .where("$SYSTEM_INFO_PENDING = ?", 1) + .run() } }