Merge remote-tracking branch 'origin/dev' into closed_groups

# Conflicts:
#	app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
#	app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt
This commit is contained in:
SessionHero01 2024-10-28 11:03:41 +11:00
commit b77a35a171
No known key found for this signature in database
6 changed files with 32 additions and 26 deletions

View File

@ -131,8 +131,10 @@ class ProfilePictureView @JvmOverloads constructor(
this.recipient = Recipient.from(context, Address.fromSerialized(publicKey), false) this.recipient = Recipient.from(context, Address.fromSerialized(publicKey), false)
this.recipient!! this.recipient!!
} }
if (profilePicturesCache[imageView] == recipient) return if (profilePicturesCache[imageView] == recipient) return
profilePicturesCache[imageView] = recipient // recipient is mutable so without cloning it the line above always returns true as the changes to the underlying recipient happens on both shared instances
profilePicturesCache[imageView] = recipient.clone()
val signalProfilePicture = recipient.contactPhoto val signalProfilePicture = recipient.contactPhoto
val avatar = (signalProfilePicture as? ProfileContactPhoto)?.avatarObject val avatar = (signalProfilePicture as? ProfileContactPhoto)?.avatarObject

View File

@ -238,11 +238,6 @@ open class Storage @Inject constructor(
return Profile(displayName, profileKey, profilePictureUrl) return Profile(displayName, profileKey, profilePictureUrl)
} }
override fun setProfileAvatar(recipient: Recipient, profileAvatar: String?) {
val database = recipientDatabase
database.setProfileAvatar(recipient, profileAvatar)
}
override fun setProfilePicture(recipient: Recipient, newProfilePicture: String?, newProfileKey: ByteArray?) { override fun setProfilePicture(recipient: Recipient, newProfilePicture: String?, newProfileKey: ByteArray?) {
val db = recipientDatabase val db = recipientDatabase
db.setProfileAvatar(recipient, newProfilePicture) db.setProfileAvatar(recipient, newProfilePicture)
@ -263,7 +258,7 @@ open class Storage @Inject constructor(
preferences.setProfilePictureURL(newProfilePicture) preferences.setProfilePictureURL(newProfilePicture)
if (newProfileKey != null) { if (newProfileKey != null) {
JobQueue.shared.add(RetrieveProfileAvatarJob(newProfilePicture, ourRecipient.address)) JobQueue.shared.add(RetrieveProfileAvatarJob(newProfilePicture, ourRecipient.address, newProfileKey))
} }
} }

View File

@ -69,12 +69,9 @@ class ProfileManager @Inject constructor(
.getAllJobs(RetrieveProfileAvatarJob.KEY).any { .getAllJobs(RetrieveProfileAvatarJob.KEY).any {
(it.value as? RetrieveProfileAvatarJob)?.recipientAddress == recipient.address (it.value as? RetrieveProfileAvatarJob)?.recipientAddress == recipient.address
} }
val resolved = recipient.resolve()
storage.get().setProfilePicture( recipient.resolve()
recipient = resolved,
newProfileKey = profileKey,
newProfilePicture = profilePictureURL
)
val accountID = recipient.address.serialize() val accountID = recipient.address.serialize()
var contact = contactDatabase.getContactWithAccountID(accountID) var contact = contactDatabase.getContactWithAccountID(accountID)
if (contact == null) contact = Contact(accountID) if (contact == null) contact = Contact(accountID)
@ -86,7 +83,7 @@ class ProfileManager @Inject constructor(
} }
contactUpdatedInternal(contact) contactUpdatedInternal(contact)
if (!hasPendingDownload) { if (!hasPendingDownload) {
val job = RetrieveProfileAvatarJob(profilePictureURL, recipient.address) val job = RetrieveProfileAvatarJob(profilePictureURL, recipient.address, profileKey)
JobQueue.shared.add(job) JobQueue.shared.add(job)
} }
} }

View File

@ -47,7 +47,6 @@ interface StorageProtocol {
fun getUserED25519KeyPair(): KeyPair? fun getUserED25519KeyPair(): KeyPair?
fun getUserX25519KeyPair(): ECKeyPair fun getUserX25519KeyPair(): ECKeyPair
fun getUserProfile(): Profile fun getUserProfile(): Profile
fun setProfileAvatar(recipient: Recipient, profileAvatar: String?)
fun setProfilePicture(recipient: Recipient, newProfilePicture: String?, newProfileKey: ByteArray?) fun setProfilePicture(recipient: Recipient, newProfilePicture: String?, newProfileKey: ByteArray?)
fun setBlocksCommunityMessageRequests(recipient: Recipient, blocksMessageRequests: Boolean) fun setBlocksCommunityMessageRequests(recipient: Recipient, blocksMessageRequests: Boolean)
fun setUserProfilePicture(newProfilePicture: String?, newProfileKey: ByteArray?) fun setUserProfilePicture(newProfilePicture: String?, newProfileKey: ByteArray?)

View File

@ -19,7 +19,10 @@ import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.util.concurrent.ConcurrentSkipListSet import java.util.concurrent.ConcurrentSkipListSet
class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipientAddress: Address): Job { class RetrieveProfileAvatarJob(
private val profileAvatar: String?, val recipientAddress: Address,
private val profileKey: ByteArray?
): Job {
override var delegate: JobDelegate? = null override var delegate: JobDelegate? = null
override var id: String? = null override var id: String? = null
override var failureCount: Int = 0 override var failureCount: Int = 0
@ -32,6 +35,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
// Keys used for database storage // Keys used for database storage
private const val PROFILE_AVATAR_KEY = "profileAvatar" private const val PROFILE_AVATAR_KEY = "profileAvatar"
private const val RECEIPIENT_ADDRESS_KEY = "recipient" private const val RECEIPIENT_ADDRESS_KEY = "recipient"
private const val PROFILE_KEY = "profileKey"
val errorUrls = ConcurrentSkipListSet<String>() val errorUrls = ConcurrentSkipListSet<String>()
@ -43,7 +47,6 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
val context = MessagingModuleConfiguration.shared.context val context = MessagingModuleConfiguration.shared.context
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
val recipient = Recipient.from(context, recipientAddress, true) val recipient = Recipient.from(context, recipientAddress, true)
val profileKey = recipient.resolve().profileKey
if (profileKey == null || (profileKey.size != 32 && profileKey.size != 16)) { if (profileKey == null || (profileKey.size != 32 && profileKey.size != 16)) {
return delegate.handleJobFailedPermanently(this, dispatcherName, Exception("Recipient profile key is gone!")) return delegate.handleJobFailedPermanently(this, dispatcherName, Exception("Recipient profile key is gone!"))
@ -69,7 +72,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
} }
AvatarHelper.delete(context, recipient.address) AvatarHelper.delete(context, recipient.address)
storage.setProfileAvatar(recipient, null) storage.setProfilePicture(recipient, null, null)
return return
} }
@ -87,7 +90,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
setProfilePictureURL(context, profileAvatar) setProfilePictureURL(context, profileAvatar)
} }
storage.setProfileAvatar(recipient, profileAvatar) storage.setProfilePicture(recipient, profileAvatar, profileKey)
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Loki", "Failed to download profile avatar", e) Log.e("Loki", "Failed to download profile avatar", e)
if (failureCount + 1 >= maxFailureCount) { if (failureCount + 1 >= maxFailureCount) {
@ -101,10 +104,15 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
} }
override fun serialize(): Data { override fun serialize(): Data {
return Data.Builder() val data = Data.Builder()
.putString(PROFILE_AVATAR_KEY, profileAvatar) .putString(PROFILE_AVATAR_KEY, profileAvatar)
.putString(RECEIPIENT_ADDRESS_KEY, recipientAddress.serialize()) .putString(RECEIPIENT_ADDRESS_KEY, recipientAddress.serialize())
.build()
if (profileKey != null) {
data.putByteArray(PROFILE_KEY, profileKey)
}
return data.build()
} }
override fun getFactoryKey(): String { override fun getFactoryKey(): String {
@ -115,7 +123,8 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
override fun create(data: Data): RetrieveProfileAvatarJob { override fun create(data: Data): RetrieveProfileAvatarJob {
val profileAvatar = if (data.hasString(PROFILE_AVATAR_KEY)) { data.getString(PROFILE_AVATAR_KEY) } else { null } val profileAvatar = if (data.hasString(PROFILE_AVATAR_KEY)) { data.getString(PROFILE_AVATAR_KEY) } else { null }
val recipientAddress = Address.fromSerialized(data.getString(RECEIPIENT_ADDRESS_KEY)) val recipientAddress = Address.fromSerialized(data.getString(RECEIPIENT_ADDRESS_KEY))
return RetrieveProfileAvatarJob(profileAvatar, recipientAddress) val profileKey = data.getByteArray(PROFILE_KEY)
return RetrieveProfileAvatarJob(profileAvatar, recipientAddress, profileKey)
} }
} }
} }

View File

@ -59,7 +59,7 @@ import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
public class Recipient implements RecipientModifiedListener { public class Recipient implements RecipientModifiedListener, Cloneable {
private static final String TAG = Recipient.class.getSimpleName(); private static final String TAG = Recipient.class.getSimpleName();
private static final RecipientProvider provider = new RecipientProvider(); private static final RecipientProvider provider = new RecipientProvider();
@ -1156,5 +1156,9 @@ public class Recipient implements RecipientModifiedListener {
} }
@NonNull
@Override
public Recipient clone() throws CloneNotSupportedException {
return (Recipient) super.clone();
}
} }