Do not show contact info for non-discoverable contacts.

This commit is contained in:
Greyson Parrelli
2024-01-12 13:22:30 -05:00
parent 846e398577
commit 64fff2adb2
4 changed files with 83 additions and 25 deletions

View File

@@ -182,9 +182,12 @@ object ContactDiscoveryRefreshV2 {
val existingIds: Set<RecipientId> = SignalDatabase.recipients.getAllPossiblyRegisteredByE164(recipientE164s + rewrites.values)
stopwatch.split("get-ids")
val inactiveIds: Set<RecipientId> = (existingIds - registeredIds).removePossiblyRegisteredButUnlisted()
val inactiveIds: Set<RecipientId> = (existingIds - registeredIds).removePossiblyRegisteredButUndiscoverable()
stopwatch.split("registered-but-unlisted")
val missingFromCds: Set<RecipientId> = existingIds - registeredIds
SignalDatabase.recipients.updatePhoneNumberDiscoverability(registeredIds, missingFromCds)
SignalDatabase.recipients.bulkUpdatedRegisteredStatus(registeredIds, inactiveIds)
stopwatch.split("update-registered")
@@ -199,13 +202,13 @@ object ContactDiscoveryRefreshV2 {
}
/**
* If an account is unlisted, it won't come back in the CDS response. So just because we're missing a entry doesn't mean they've become unregistered.
* If an account is undiscoverable, it won't come back in the CDS response. So just because we're missing a entry doesn't mean they've become unregistered.
* This function removes people from the list that both have a serviceId and some history of communication. We consider this a good heuristic for
* "maybe this person just removed themselves from CDS". We'll rely on profile fetches that occur during chat opens to check registered status and clear
* actually-unregistered users out.
*/
@WorkerThread
private fun Set<RecipientId>.removePossiblyRegisteredButUnlisted(): Set<RecipientId> {
private fun Set<RecipientId>.removePossiblyRegisteredButUndiscoverable(): Set<RecipientId> {
val selfId = Recipient.self().id
return this - Recipient.resolvedList(this)
.filter {

View File

@@ -16,6 +16,7 @@ import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.delete
import org.signal.core.util.exists
import org.signal.core.util.forEach
import org.signal.core.util.logging.Log
import org.signal.core.util.nullIfBlank
import org.signal.core.util.optionalString
@@ -178,6 +179,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
const val NEEDS_PNI_SIGNATURE = "needs_pni_signature"
const val REPORTING_TOKEN = "reporting_token"
const val PHONE_NUMBER_SHARING = "phone_number_sharing"
const val PHONE_NUMBER_DISCOVERABLE = "phone_number_discoverable"
const val SEARCH_PROFILE_NAME = "search_signal_profile"
const val SORT_NAME = "sort_name"
@@ -244,7 +246,8 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
$BADGES BLOB DEFAULT NULL,
$NEEDS_PNI_SIGNATURE INTEGER DEFAULT 0,
$REPORTING_TOKEN BLOB DEFAULT NULL,
$PHONE_NUMBER_SHARING INTEGER DEFAULT ${PhoneNumberSharingState.UNKNOWN.id}
$PHONE_NUMBER_SHARING INTEGER DEFAULT ${PhoneNumberSharingState.UNKNOWN.id},
$PHONE_NUMBER_DISCOVERABLE INTEGER DEFAULT ${PhoneNumberDiscoverableState.UNKNOWN.id}
)
"""
@@ -3662,6 +3665,24 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
}
fun updatePhoneNumberDiscoverability(presentInCds: Set<RecipientId>, missingFromCds: Set<RecipientId>) {
SqlUtil.buildCollectionQuery(ID, presentInCds).forEach { query ->
writableDatabase
.update(TABLE_NAME)
.values(PHONE_NUMBER_DISCOVERABLE to PhoneNumberDiscoverableState.DISCOVERABLE.id)
.where(query.where, query.whereArgs)
.run()
}
SqlUtil.buildCollectionQuery(ID, missingFromCds).forEach { query ->
writableDatabase
.update(TABLE_NAME)
.values(PHONE_NUMBER_DISCOVERABLE to PhoneNumberDiscoverableState.UNDISCOVERABLE.id)
.where(query.where, query.whereArgs)
.run()
}
}
private fun updateExtras(recipientId: RecipientId, updater: java.util.function.Function<RecipientExtras.Builder, RecipientExtras.Builder>) {
val db = writableDatabase
db.beginTransaction()
@@ -4168,16 +4189,16 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
put(SYSTEM_CONTACT_URI, systemContactUri)
}
val updatedValues = update(id, refreshQualifyingValues)
if (updatedValues) {
val updateQuery = SqlUtil.buildTrueUpdateQuery("$ID = ? AND $PHONE_NUMBER_DISCOVERABLE != ?", SqlUtil.buildArgs(id, PhoneNumberDiscoverableState.UNDISCOVERABLE.id), refreshQualifyingValues)
if (update(updateQuery, refreshQualifyingValues)) {
pendingRecipients.add(id)
}
val otherValues = ContentValues().apply {
put(SYSTEM_INFO_PENDING, 0)
}
update(id, otherValues)
writableDatabase
.update(TABLE_NAME)
.values(SYSTEM_INFO_PENDING to 0)
.where("$ID = ? AND $PHONE_NUMBER_DISCOVERABLE != ?", id, PhoneNumberDiscoverableState.UNDISCOVERABLE.id)
.run()
}
fun finish() {
@@ -4203,18 +4224,25 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
private fun clearSystemDataForPendingInfo() {
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()
writableDatabase.rawQuery(
"""
UPDATE $TABLE_NAME
SET
$SYSTEM_INFO_PENDING = 0,
$SYSTEM_GIVEN_NAME = NULL,
$SYSTEM_FAMILY_NAME = NULL,
$SYSTEM_JOINED_NAME = NULL,
$SYSTEM_PHOTO_URI = NULL,
$SYSTEM_PHONE_LABEL = NULL,
$SYSTEM_CONTACT_URI = NULL
WHERE $SYSTEM_INFO_PENDING = 1
RETURNING $ID
""",
null
).forEach { cursor ->
val id = RecipientId.from(cursor.requireLong(ID))
ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id)
}
}
}
@@ -4519,6 +4547,16 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
}
enum class PhoneNumberDiscoverableState(val id: Int) {
UNKNOWN(0), DISCOVERABLE(1), UNDISCOVERABLE(2);
companion object {
fun fromId(id: Int): PhoneNumberDiscoverableState {
return PhoneNumberDiscoverableState.values()[id]
}
}
}
data class CdsV2Result(
val pni: PNI,
val aci: ACI?

View File

@@ -73,6 +73,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V212_RemoveDistribu
import org.thoughtcrime.securesms.database.helpers.migration.V213_FixUsernameInE164Column
import org.thoughtcrime.securesms.database.helpers.migration.V214_PhoneNumberSharingColumn
import org.thoughtcrime.securesms.database.helpers.migration.V215_RemoveAttachmentUniqueId
import org.thoughtcrime.securesms.database.helpers.migration.V216_PhoneNumberDiscoverable
/**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@@ -148,10 +149,11 @@ object SignalDatabaseMigrations {
212 to V212_RemoveDistributionListUniqueConstraint,
213 to V213_FixUsernameInE164Column,
214 to V214_PhoneNumberSharingColumn,
215 to V215_RemoveAttachmentUniqueId
215 to V215_RemoveAttachmentUniqueId,
216 to V216_PhoneNumberDiscoverable
)
const val DATABASE_VERSION = 215
const val DATABASE_VERSION = 216
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {

View File

@@ -0,0 +1,15 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
object V216_PhoneNumberDiscoverable : SignalDatabaseMigration {
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("""ALTER TABLE recipient ADD COLUMN phone_number_discoverable INTEGER DEFAULT 0""")
}
}