Add learned profile name event.

This commit is contained in:
Cody Henthorne 2024-03-06 10:51:27 -05:00 committed by Alex Hart
parent f702338129
commit 184c1b67cc
5 changed files with 78 additions and 14 deletions

View file

@ -996,8 +996,10 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
fun insertProfileNameChangeMessages(recipient: Recipient, newProfileName: String, previousProfileName: String) {
writableDatabase.withinTransaction { db ->
val groupRecords = groups.getGroupsContainingMember(recipient.id, false)
val profileChangeDetails = ProfileChangeDetails(profileNameChange = ProfileChangeDetails.StringChange(previous = previousProfileName, newValue = newProfileName))
.encode()
val extras = MessageExtras(
profileChangeDetails = ProfileChangeDetails(profileNameChange = ProfileChangeDetails.StringChange(previous = previousProfileName, newValue = newProfileName))
)
val threadIdsToUpdate = mutableListOf<Long?>().apply {
add(threads.getThreadIdFor(recipient.id))
@ -1020,7 +1022,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
READ to 1,
TYPE to MessageTypes.PROFILE_CHANGE_TYPE,
THREAD_ID to threadId,
BODY to Base64.encodeWithPadding(profileChangeDetails)
MESSAGE_EXTRAS to extras.encode()
)
db.insert(TABLE_NAME, null, values)
notifyConversationListeners(threadId)
@ -1029,6 +1031,33 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
}
}
fun insertLearnedProfileNameChangeMessage(recipient: Recipient, previousDisplayName: String) {
val threadId: Long? = SignalDatabase.threads.getThreadIdFor(recipient.id)
if (threadId != null) {
val extras = MessageExtras(
profileChangeDetails = ProfileChangeDetails(learnedProfileName = ProfileChangeDetails.StringChange(previous = previousDisplayName))
)
writableDatabase
.insertInto(TABLE_NAME)
.values(
FROM_RECIPIENT_ID to recipient.id.serialize(),
FROM_DEVICE_ID to 1,
TO_RECIPIENT_ID to Recipient.self().id.serialize(),
DATE_RECEIVED to System.currentTimeMillis(),
DATE_SENT to System.currentTimeMillis(),
READ to 1,
TYPE to MessageTypes.PROFILE_CHANGE_TYPE,
THREAD_ID to threadId,
MESSAGE_EXTRAS to extras.encode()
)
.run()
notifyConversationListeners(threadId)
}
}
fun insertGroupV1MigrationEvents(recipientId: RecipientId, threadId: Long, membershipChange: GroupMigrationMembershipChange) {
insertGroupV1MigrationNotification(recipientId, threadId)
if (!membershipChange.isEmpty) {

View file

@ -227,7 +227,7 @@ public abstract class MessageRecord extends DisplayRecord {
if (isOutgoing()) return fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_unverified, r.getDisplayName(context)), R.drawable.ic_update_info_16);
else return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_unverified_from_another_device, r.getDisplayName(context)), R.drawable.ic_update_info_16);
} else if (isProfileChange()) {
return staticUpdateDescription(getProfileChangeDescription(context), R.drawable.ic_update_profile_16);
return getProfileChangeDescription(context);
} else if (isChangeNumber()) {
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_changed_their_phone_number, r.getDisplayName(context)), R.drawable.ic_phone_16);
} else if (isBoostRequest()) {
@ -299,7 +299,7 @@ public abstract class MessageRecord extends DisplayRecord {
return selfCreatedGroup(change);
}
@Nullable public MessageExtras getMessageExtras() {
public @Nullable MessageExtras getMessageExtras() {
return messageExtras;
}
@ -432,27 +432,41 @@ public abstract class MessageRecord extends DisplayRecord {
return UpdateDescription.staticDescription(string, iconResource, lightTint, darkTint);
}
private @NonNull String getProfileChangeDescription(@NonNull Context context) {
try {
byte[] decoded = Base64.decode(getBody());
ProfileChangeDetails profileChangeDetails = ProfileChangeDetails.ADAPTER.decode(decoded);
private @NonNull UpdateDescription getProfileChangeDescription(@NonNull Context context) {
ProfileChangeDetails profileChangeDetails = null;
MessageExtras extras = getMessageExtras();
if (extras != null) {
profileChangeDetails = extras.profileChangeDetails;
} else {
try {
byte[] decoded = Base64.decode(getBody());
profileChangeDetails = ProfileChangeDetails.ADAPTER.decode(decoded);
} catch (IOException e) {
Log.w(TAG, "Profile name change details could not be read", e);
}
}
if (profileChangeDetails != null) {
if (profileChangeDetails.profileNameChange != null) {
String displayName = getFromRecipient().getDisplayName(context);
String newName = StringUtil.isolateBidi(ProfileName.fromSerialized(profileChangeDetails.profileNameChange.newValue).toString());
String previousName = StringUtil.isolateBidi(ProfileName.fromSerialized(profileChangeDetails.profileNameChange.previous).toString());
String updateMessage;
if (getFromRecipient().isSystemContact()) {
return context.getString(R.string.MessageRecord_changed_their_profile_name_from_to, displayName, previousName, newName);
updateMessage = context.getString(R.string.MessageRecord_changed_their_profile_name_from_to, displayName, previousName, newName);
} else {
return context.getString(R.string.MessageRecord_changed_their_profile_name_to, previousName, newName);
updateMessage = context.getString(R.string.MessageRecord_changed_their_profile_name_to, previousName, newName);
}
return staticUpdateDescription(updateMessage, R.drawable.ic_update_profile_16);
} else if (profileChangeDetails.learnedProfileName != null) {
return staticUpdateDescription(context.getString(R.string.MessageRecord_started_this_chat, profileChangeDetails.learnedProfileName.previous), R.drawable.symbol_thread_16);
}
} catch (IOException e) {
Log.w(TAG, "Profile name change details could not be read", e);
}
return context.getString(R.string.MessageRecord_changed_their_profile, getFromRecipient().getDisplayName(context));
return staticUpdateDescription(context.getString(R.string.MessageRecord_changed_their_profile, getFromRecipient().getDisplayName(context)), R.drawable.ic_update_profile_16);
}
private UpdateDescription getGroupMigrationEventDescription(@NonNull Context context) {

View file

@ -54,6 +54,12 @@ class RetrieveProfileJob private constructor(parameters: Parameters, private val
constructor(recipientIds: Set<RecipientId>) : this(
Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.apply {
if (recipientIds.size < 5) {
setQueue(recipientIds.map { it.toLong() }.sorted().joinToString(separator = "_", prefix = QUEUE_PREFIX))
setMaxInstancesForQueue(2)
}
}
.setMaxAttempts(3)
.build(),
recipientIds.toMutableSet()
@ -364,6 +370,16 @@ class RetrieveProfileJob private constructor(parameters: Parameters, private val
val remoteProfileName = ProfileName.fromSerialized(plaintextProfileName)
val localProfileName = recipient.profileName
if (localProfileName.isEmpty &&
!recipient.isSystemContact &&
recipient.isProfileSharing &&
!recipient.isGroup &&
!recipient.isSelf
) {
Log.i(TAG, "Learned profile name for first time, insert event")
SignalDatabase.messages.insertLearnedProfileNameChangeMessage(recipient, recipient.getDisplayName(context))
}
if (remoteProfileName != localProfileName) {
Log.i(TAG, "Profile name updated. Writing new value.")
SignalDatabase.recipients.setProfileName(recipient.id, remoteProfileName)
@ -490,6 +506,7 @@ class RetrieveProfileJob private constructor(parameters: Parameters, private val
private val TAG = Log.tag(RetrieveProfileJob::class.java)
private const val KEY_RECIPIENTS = "recipients"
private const val DEDUPE_KEY_RETRIEVE_AVATAR = KEY + "_RETRIEVE_PROFILE_AVATAR"
private const val QUEUE_PREFIX = "RetrieveProfileJob_"
/**
* Submits the necessary job to refresh the profile of the requested recipient. Works for any

View file

@ -73,6 +73,7 @@ message ProfileChangeDetails {
}
StringChange profileNameChange = 1;
StringChange learnedProfileName = 2;
}
message BodyRangeList {
@ -379,6 +380,7 @@ message MessageExtras {
oneof extra {
GV2UpdateDescription gv2UpdateDescription = 1;
signalservice.GroupContext gv1Context = 2;
ProfileChangeDetails profileChangeDetails = 3;
}
}

View file

@ -1386,6 +1386,8 @@
<string name="MessageRecord_changed_their_profile_name_to">%1$s changed their profile name to %2$s.</string>
<string name="MessageRecord_changed_their_profile_name_from_to">%1$s changed their profile name from %2$s to %3$s.</string>
<string name="MessageRecord_changed_their_profile">%1$s changed their profile.</string>
<!-- Conversation update event message shown when you've started a conversation by phone number or username and then learn their profile name. placeholder is username or phone number -->
<string name="MessageRecord_started_this_chat">You started this chat with %1$s.</string>
<!-- GV2 specific -->
<string name="MessageRecord_you_created_the_group">You created the group.</string>