session-android/app/src/main/java/org/thoughtcrime/securesms/util/AvatarPlaceholderGenerator.kt

102 lines
3.8 KiB
Kotlin
Raw Normal View History

2021-07-09 05:18:48 +02:00
package org.thoughtcrime.securesms.util
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.text.TextPaint
import android.text.TextUtils
import network.loki.messenger.R
Add Session Id blinding (#862) * feat: Add Session Id blinding Including modified version of lazysodium-android to expose missing libsodium functions, we could build from a fork which we still need to setup. * Add v4 onion request handling * Update SOGS signature construction * Fix SOGS signature construction * Update onion request * Update signature data * Keep path prefixes for v4 endpoints * Update SOGS signature message * Rename to remove api version suffix * Update onion response parsing * Refactor file download paths * Implement request batching * Refactor batch response handling * Handle batch endpoint responses * Update batch endpoint responses * Update attachment download handling * Handle file downloads * Handle inbox messages * Fix issue with file downloads * Preserve image bytearray encoding * Refactor * Open group message requests * Check id blinding in user detail bottom sheet rather * Message validation refactor * Cache last inbox/outbox server ids * Update message encryption/decryption * Refactor * Refactor * Bypass user details bottom sheet in open groups for blinded session ids * Fix capabilities call auth * Refactor * Revert default server details * Update sodium dependency to forked repo * Fix attachment upload * Revert "Update sodium dependency to forked repo" This reverts commit c7db9529f900d09585ab94e440f6645faa88544e. * Add signed sodium lib * Update contact id truncation and mention logic * Open group inbox messaging fix * Refactor * Update blinded id check * Fix open group message sends * Fix crash on open group direct message send * Direct message refactor * Direct message encrypt/decrypt fixes * Use updated curve25519 version * Updated lazysodium dependency * Update encryption/decryption calls * Handle direct message parse errors * Minor refactor * Existing chat refactor * Update encryption & decryption parameters * Fix authenticated ciphertext size * Set direct message sync target * Update direct message thread lookup * Add blinded id mapping table * Add blinded id mapping table * Update threads after sends * Update open group message timestamp handling * Filter unblinded contacts * Format blinded id mentions * Add message deleted field * Hide open group inbox id * Update message request response handling * Update message request response sender handling * Fix mentions of blinded ids * Handle open group poll failure * fix: add log for failed open group onion request, add decoding body for blinding required error at destination * fix: change the error check * Persist group members * Reschedule polling after capabilities update * Retry on other exceptions * Minor refactor * Open group profile fix * Group member db schema update * Fix ban request key * Update ban response type * Ban endpoint updates * Ban endpoint updates * Delete messages Co-authored-by: charles <charles@oxen.io> Co-authored-by: jubb <hjubb@users.noreply.github.com>
2022-08-10 10:17:48 +02:00
import org.session.libsignal.utilities.IdPrefix
import java.math.BigInteger
import java.security.MessageDigest
import java.util.Locale
object AvatarPlaceholderGenerator {
2020-09-18 04:29:20 +02:00
private const val EMPTY_LABEL = "0"
@JvmStatic
fun generate(context: Context, pixelSize: Int, hashString: String, displayName: String?): BitmapDrawable {
val hash: Long
if (hashString.length >= 12 && hashString.matches(Regex("^[0-9A-Fa-f]+\$"))) {
2020-09-18 04:29:20 +02:00
hash = getSha512(hashString).substring(0 until 12).toLong(16)
} else {
hash = 0
}
// Do not cache color array, it may be different depends on the current theme.
2020-09-09 05:57:22 +02:00
val colorArray = context.resources.getIntArray(R.array.profile_picture_placeholder_colors)
val colorPrimary = colorArray[(hash % colorArray.size).toInt()]
val labelText = when {
!TextUtils.isEmpty(displayName) -> extractLabel(displayName!!.capitalize(Locale.ROOT))
!TextUtils.isEmpty(hashString) -> extractLabel(hashString)
else -> EMPTY_LABEL
}
val bitmap = Bitmap.createBitmap(pixelSize, pixelSize, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
// Draw background/frame
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
2020-09-18 04:29:20 +02:00
paint.color = colorPrimary
canvas.drawCircle(pixelSize.toFloat() / 2, pixelSize.toFloat() / 2, pixelSize.toFloat() / 2, paint)
// Draw text
val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
textPaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
textPaint.textSize = pixelSize * 0.5f
textPaint.color = Color.WHITE
val areaRect = Rect(0, 0, pixelSize, pixelSize)
val textBounds = RectF(areaRect)
textBounds.right = textPaint.measureText(labelText)
textBounds.bottom = textPaint.descent() - textPaint.ascent()
textBounds.left += (areaRect.width() - textBounds.right) * 0.5f
textBounds.top += (areaRect.height() - textBounds.bottom) * 0.5f
canvas.drawText(labelText, textBounds.left, textBounds.top - textPaint.ascent(), textPaint)
return BitmapDrawable(context.resources, bitmap)
}
fun extractLabel(content: String): String {
val trimmedContent = content.trim()
if (trimmedContent.isEmpty()) return EMPTY_LABEL
Add Session Id blinding (#862) * feat: Add Session Id blinding Including modified version of lazysodium-android to expose missing libsodium functions, we could build from a fork which we still need to setup. * Add v4 onion request handling * Update SOGS signature construction * Fix SOGS signature construction * Update onion request * Update signature data * Keep path prefixes for v4 endpoints * Update SOGS signature message * Rename to remove api version suffix * Update onion response parsing * Refactor file download paths * Implement request batching * Refactor batch response handling * Handle batch endpoint responses * Update batch endpoint responses * Update attachment download handling * Handle file downloads * Handle inbox messages * Fix issue with file downloads * Preserve image bytearray encoding * Refactor * Open group message requests * Check id blinding in user detail bottom sheet rather * Message validation refactor * Cache last inbox/outbox server ids * Update message encryption/decryption * Refactor * Refactor * Bypass user details bottom sheet in open groups for blinded session ids * Fix capabilities call auth * Refactor * Revert default server details * Update sodium dependency to forked repo * Fix attachment upload * Revert "Update sodium dependency to forked repo" This reverts commit c7db9529f900d09585ab94e440f6645faa88544e. * Add signed sodium lib * Update contact id truncation and mention logic * Open group inbox messaging fix * Refactor * Update blinded id check * Fix open group message sends * Fix crash on open group direct message send * Direct message refactor * Direct message encrypt/decrypt fixes * Use updated curve25519 version * Updated lazysodium dependency * Update encryption/decryption calls * Handle direct message parse errors * Minor refactor * Existing chat refactor * Update encryption & decryption parameters * Fix authenticated ciphertext size * Set direct message sync target * Update direct message thread lookup * Add blinded id mapping table * Add blinded id mapping table * Update threads after sends * Update open group message timestamp handling * Filter unblinded contacts * Format blinded id mentions * Add message deleted field * Hide open group inbox id * Update message request response handling * Update message request response sender handling * Fix mentions of blinded ids * Handle open group poll failure * fix: add log for failed open group onion request, add decoding body for blinding required error at destination * fix: change the error check * Persist group members * Reschedule polling after capabilities update * Retry on other exceptions * Minor refactor * Open group profile fix * Group member db schema update * Fix ban request key * Update ban response type * Ban endpoint updates * Ban endpoint updates * Delete messages Co-authored-by: charles <charles@oxen.io> Co-authored-by: jubb <hjubb@users.noreply.github.com>
2022-08-10 10:17:48 +02:00
return if (trimmedContent.length > 2 && IdPrefix.fromValue(trimmedContent) != null) {
trimmedContent[2].toString()
} else {
val splitWords = trimmedContent.split(Regex("\\W"))
if (splitWords.size < 2) {
trimmedContent.take(2)
} else {
splitWords.filter { word -> word.isNotEmpty() }.take(2).map { it.first() }.joinToString("")
}
}.uppercase()
}
2020-09-18 04:29:20 +02:00
private fun getSha512(input: String): String {
val messageDigest = MessageDigest.getInstance("SHA-512").digest(input.toByteArray())
// Convert byte array into signum representation
val no = BigInteger(1, messageDigest)
// Convert message digest into hex value
var hashText: String = no.toString(16)
2021-01-29 03:49:28 +01:00
// Add preceding 0s to make it 32 bytes
if (hashText.length < 128) {
2020-09-18 04:29:20 +02:00
val sb = StringBuilder()
2021-01-29 03:49:28 +01:00
for (i in 0 until 128 - hashText.length) {
2020-09-18 04:29:20 +02:00
sb.append('0')
}
hashText = sb.append(hashText).toString()
}
return hashText
}
}