Skip to content

Commit

Permalink
Use the PublicKey type for public keys in the database
Browse files Browse the repository at this point in the history
This means a lot of conversions go away.
  • Loading branch information
robinlinden committed Feb 9, 2025
1 parent a600d44 commit bb6a698
Show file tree
Hide file tree
Showing 49 changed files with 289 additions and 258 deletions.
9 changes: 6 additions & 3 deletions atox/src/androidTest/kotlin/ui/AvatarFactoryTest.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022-2025 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: GPL-3.0-only

Expand All @@ -7,16 +7,19 @@ package ltd.evilcorp.atox.ui
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import kotlin.test.Test
import ltd.evilcorp.core.vo.PublicKey
import org.junit.runner.RunWith

private val pk = PublicKey("123")

@RunWith(AndroidJUnit4::class)
class AvatarFactoryTest {
@Test
fun emptyName() {
AvatarFactory.create(
InstrumentationRegistry.getInstrumentation().targetContext.resources,
name = "",
publicKey = "123",
pk = pk,
)
}

Expand All @@ -25,7 +28,7 @@ class AvatarFactoryTest {
AvatarFactory.create(
InstrumentationRegistry.getInstrumentation().targetContext.resources,
name = "a ",
publicKey = "123",
pk = pk,
)
}
}
10 changes: 5 additions & 5 deletions atox/src/main/kotlin/ActionReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,18 @@ class ActionReceiver : BroadcastReceiver() {
Log.e(TAG, "Got intent without required key $KEY_CONTACT_PK $intent")
return@launch
}
if (!contactRepository.exists(pk.string())) {
if (!contactRepository.exists(pk)) {
notificationHelper.dismissNotifications(pk)
notificationHelper.dismissCallNotification(pk)
return@launch
}

RemoteInput.getResultsFromIntent(intent)?.let { results ->
results.getCharSequence(KEY_TEXT_REPLY)?.toString()?.let { input ->
contactRepository.setHasUnreadMessages(pk.string(), false)
contactRepository.setHasUnreadMessages(pk, false)
chatManager.sendMessage(pk, input)
notificationHelper.showMessageNotification(
Contact(pk.string(), tox.getName()),
Contact(pk, tox.getName()),
input,
outgoing = true,
)
Expand All @@ -103,7 +103,7 @@ class ActionReceiver : BroadcastReceiver() {
}
Action.CallIgnore -> callManager.removePendingCall(pk)
Action.MarkAsRead -> {
contactRepository.setHasUnreadMessages(pk.string(), false)
contactRepository.setHasUnreadMessages(pk, false)
notificationHelper.dismissNotifications(pk)
}
null -> Log.e(TAG, "Missing action in intent $intent")
Expand All @@ -117,7 +117,7 @@ class ActionReceiver : BroadcastReceiver() {
it
} else {
Log.e(TAG, "Unable to get contact ${pk.fingerprint()} for call notification")
Contact(publicKey = pk.string(), name = pk.fingerprint())
Contact(publicKey = pk, name = pk.fingerprint())
}
}

Expand Down
4 changes: 2 additions & 2 deletions atox/src/main/kotlin/ToxService.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2024 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2019-2025 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2022 aTox contributors
//
// SPDX-License-Identifier: GPL-3.0-only
Expand Down Expand Up @@ -139,7 +139,7 @@ class ToxService : LifecycleService() {
}

lifecycleScope.launch(Dispatchers.Default) {
userRepository.get(tox.publicKey.string())
userRepository.get(tox.publicKey)
.filterNotNull()
.filter { it.connectionStatus != connectionStatus }
.flowWithLifecycle(lifecycle)
Expand Down
21 changes: 9 additions & 12 deletions atox/src/main/kotlin/tox/EventListenerCallbacks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ private fun isImage(filename: String) = try {
false
}

private const val FINGERPRINT_LEN = 8
private fun String.fingerprint() = this.take(FINGERPRINT_LEN)

@Singleton
class EventListenerCallbacks @Inject constructor(
private val ctx: Context,
Expand All @@ -73,7 +70,7 @@ class EventListenerCallbacks @Inject constructor(
private var audioPlayer: AudioPlayer? = null
private val scope = CoroutineScope(Dispatchers.Default)

private suspend fun tryGetContact(pk: String, tag: String) = contactRepository.get(pk).firstOrNull().let {
private suspend fun tryGetContact(pk: PublicKey, tag: String) = contactRepository.get(pk).firstOrNull().let {
if (it == null) Log.e(TAG, "$tag -> unable to get contact for ${pk.fingerprint()}")
it
}
Expand Down Expand Up @@ -147,7 +144,7 @@ class EventListenerCallbacks @Inject constructor(
}

fileRecvHandler = { publicKey, fileNo, kind, fileSize, filename ->
val name = if (kind == FileKind.Avatar.ordinal) publicKey else filename
val name = if (kind == FileKind.Avatar.ordinal) publicKey.string() else filename

val id = fileTransferManager.add(FileTransfer(publicKey, fileNo, kind, fileSize, name, outgoing = false))

Expand All @@ -168,16 +165,16 @@ class EventListenerCallbacks @Inject constructor(
}
}

fileRecvControlHandler = { publicKey: String, fileNo: Int, control: ToxFileControl ->
fileTransferManager.setStatus(publicKey, fileNo, control)
fileRecvControlHandler = { pk: PublicKey, fileNo: Int, control: ToxFileControl ->
fileTransferManager.setStatus(pk, fileNo, control)
}

fileChunkRequestHandler = { publicKey: String, fileNo: Int, position: Long, length: Int ->
fileTransferManager.sendChunk(publicKey, fileNo, position, length)
fileChunkRequestHandler = { pk: PublicKey, fileNo: Int, position: Long, length: Int ->
fileTransferManager.sendChunk(pk, fileNo, position, length)
}

selfConnectionStatusHandler = { status ->
userRepository.updateConnection(tox.publicKey.string(), status)
userRepository.updateConnection(tox.publicKey, status)
}

friendTypingHandler = { publicKey, isTyping ->
Expand All @@ -201,8 +198,8 @@ class EventListenerCallbacks @Inject constructor(
audioPlayer?.stop()
audioPlayer?.release()
audioPlayer = null
notificationHelper.dismissCallNotification(PublicKey(pk))
callManager.endCall(PublicKey(pk))
notificationHelper.dismissCallNotification(pk)
callManager.endCall(pk)
}
}

Expand Down
8 changes: 5 additions & 3 deletions atox/src/main/kotlin/ui/AvatarFactory.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2019-2022 aTox contributors
// SPDX-FileCopyrightText: 2019-2025 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2022 aTox contributors
//
// SPDX-License-Identifier: GPL-3.0-only

Expand All @@ -14,6 +15,7 @@ import android.graphics.RectF
import android.graphics.Typeface
import kotlin.math.abs
import ltd.evilcorp.atox.R
import ltd.evilcorp.core.vo.PublicKey

internal object AvatarFactory {

Expand All @@ -27,7 +29,7 @@ internal object AvatarFactory {
fun create(
resources: Resources,
name: String,
publicKey: String,
pk: PublicKey,
size: Px = Px(resources.getDimension(R.dimen.default_avatar_size).toInt()),
): Bitmap {
val defaultAvatarSize = resources.getDimension(R.dimen.default_avatar_size)
Expand All @@ -37,7 +39,7 @@ internal object AvatarFactory {
val canvas = Canvas(bitmap)
val rect = RectF(0f, 0f, bitmap.width.toFloat(), bitmap.height.toFloat())
val colors = resources.getIntArray(R.array.contactBackgrounds)
val backgroundPaint = Paint().apply { color = colors[abs(publicKey.hashCode()).rem(colors.size)] }
val backgroundPaint = Paint().apply { color = colors[abs(pk.hashCode()).rem(colors.size)] }

val textPaint = Paint().apply {
color = Color.WHITE
Expand Down
5 changes: 3 additions & 2 deletions atox/src/main/kotlin/ui/AvatarImageView.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: 2022 aTox contributors
// SPDX-FileCopyrightText: 2022-2024 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022-2025 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: GPL-3.0-only

Expand All @@ -21,6 +21,7 @@ import kotlin.math.sqrt
import ltd.evilcorp.atox.R
import ltd.evilcorp.core.vo.ConnectionStatus
import ltd.evilcorp.core.vo.Contact
import ltd.evilcorp.core.vo.PublicKey
import ltd.evilcorp.core.vo.UserStatus

private const val STATUS_INDICATOR_SIZE_RATIO_WITH_AVATAR = 12f / 50
Expand Down Expand Up @@ -50,7 +51,7 @@ class AvatarImageView @JvmOverloads constructor(context: Context, attrs: Attribu
}

private var name = ""
private var publicKey = ""
private var publicKey = PublicKey("")
private var avatarUri = ""

fun setFrom(contact: Contact) {
Expand Down
35 changes: 20 additions & 15 deletions atox/src/main/kotlin/ui/NotificationHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
.setSmallIcon(android.R.drawable.sym_action_chat)
.setContentTitle(contact.name.ifEmpty { context.getText(R.string.contact_default_name) })
.setContentText(message)
.setContentIntent(deepLinkToChat(PublicKey(contact.publicKey)))
.setContentIntent(deepLinkToChat(contact.publicKey))
.setAutoCancel(true)
.setSilent(silent)

Expand All @@ -151,13 +151,15 @@ class NotificationHelper @Inject constructor(private val context: Context) {

val chatPartner = Person.Builder()
.setName(contact.name.ifEmpty { context.getText(R.string.contact_default_name) })
.setKey(if (outgoing) "myself" else contact.publicKey)
.setKey(if (outgoing) "myself" else contact.publicKey.string())
.setIcon(icon)
.setImportant(true)
.build()

val style =
notifierOld.activeNotifications.find { it.notification.group == contact.publicKey }?.notification?.let {
notifierOld.activeNotifications.find {
it.notification.group == contact.publicKey.string()
}?.notification?.let {
NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(it)
} ?: NotificationCompat.MessagingStyle(chatPartner)

Expand All @@ -167,7 +169,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {

notificationBuilder
.setStyle(style)
.setGroup(contact.publicKey)
.setGroup(contact.publicKey.string())
}

// I can't find it in the documentation for RemoteInput or anything, but per
Expand All @@ -182,7 +184,10 @@ class NotificationHelper @Inject constructor(private val context: Context) {
PendingIntentCompat.getBroadcast(
context,
contact.publicKey.hashCode(),
Intent(context, ActionReceiver::class.java).putExtra(KEY_CONTACT_PK, contact.publicKey),
Intent(context, ActionReceiver::class.java).putExtra(
KEY_CONTACT_PK,
contact.publicKey.string(),
),
PendingIntent.FLAG_UPDATE_CURRENT,
mutable = true,
),
Expand All @@ -202,7 +207,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
.Builder(
IconCompat.createWithResource(context, R.drawable.ic_send),
context.getString(R.string.reply),
deepLinkToChat(PublicKey(contact.publicKey), focusMessageBox = true),
deepLinkToChat(contact.publicKey, focusMessageBox = true),
)
.setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
.build(),
Expand All @@ -217,7 +222,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
context,
"${contact.publicKey}_mark_as_read".hashCode(),
Intent(context, ActionReceiver::class.java)
.putExtra(KEY_CONTACT_PK, contact.publicKey)
.putExtra(KEY_CONTACT_PK, contact.publicKey.string())
.putExtra(KEY_ACTION, Action.MarkAsRead),
PendingIntent.FLAG_UPDATE_CURRENT,
),
Expand Down Expand Up @@ -266,7 +271,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
return
}

dismissCallNotification(PublicKey(contact.publicKey))
dismissCallNotification(contact.publicKey)
val notificationBuilder = NotificationCompat.Builder(context, CALL)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setSmallIcon(android.R.drawable.ic_menu_call)
Expand All @@ -282,8 +287,8 @@ class NotificationHelper @Inject constructor(private val context: Context) {
.setContentIntent(
NavDeepLinkBuilder(context)
.setGraph(R.navigation.nav_graph)
.addDestination(R.id.chatFragment, bundleOf(CONTACT_PUBLIC_KEY to contact.publicKey))
.addDestination(R.id.callFragment, bundleOf(CONTACT_PUBLIC_KEY to contact.publicKey))
.addDestination(R.id.chatFragment, bundleOf(CONTACT_PUBLIC_KEY to contact.publicKey.string()))
.addDestination(R.id.callFragment, bundleOf(CONTACT_PUBLIC_KEY to contact.publicKey.string()))
.createPendingIntent(),
)
.addAction(
Expand All @@ -295,7 +300,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
context,
"${contact.publicKey}_end_call".hashCode(),
Intent(context, ActionReceiver::class.java)
.putExtra(KEY_CONTACT_PK, contact.publicKey)
.putExtra(KEY_CONTACT_PK, contact.publicKey.string())
.putExtra(KEY_ACTION, Action.CallEnd),
PendingIntent.FLAG_UPDATE_CURRENT,
),
Expand Down Expand Up @@ -323,7 +328,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
.setSmallIcon(android.R.drawable.ic_menu_call)
.setContentTitle(context.getString(R.string.incoming_call))
.setContentText(context.getString(R.string.incoming_call_from, c.name))
.setContentIntent(deepLinkToChat(PublicKey(c.publicKey)))
.setContentIntent(deepLinkToChat(c.publicKey))
.addAction(
NotificationCompat.Action
.Builder(
Expand All @@ -333,7 +338,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
context,
"${c.publicKey}_accept_call".hashCode(),
Intent(context, ActionReceiver::class.java)
.putExtra(KEY_CONTACT_PK, c.publicKey)
.putExtra(KEY_CONTACT_PK, c.publicKey.string())
.putExtra(KEY_ACTION, Action.CallAccept),
PendingIntent.FLAG_UPDATE_CURRENT,
),
Expand All @@ -350,7 +355,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
context,
"${c.publicKey}_reject_call".hashCode(),
Intent(context, ActionReceiver::class.java)
.putExtra(KEY_CONTACT_PK, c.publicKey)
.putExtra(KEY_CONTACT_PK, c.publicKey.string())
.putExtra(KEY_ACTION, Action.CallReject),
PendingIntent.FLAG_UPDATE_CURRENT,
),
Expand All @@ -362,7 +367,7 @@ class NotificationHelper @Inject constructor(private val context: Context) {
context,
"${c.publicKey}_ignore_call".hashCode(),
Intent(context, ActionReceiver::class.java)
.putExtra(KEY_CONTACT_PK, c.publicKey)
.putExtra(KEY_CONTACT_PK, c.publicKey.string())
.putExtra(KEY_ACTION, Action.CallIgnore),
PendingIntent.FLAG_UPDATE_CURRENT,
),
Expand Down
4 changes: 2 additions & 2 deletions atox/src/main/kotlin/ui/addcontact/AddContactFragment.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2024 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2019-2025 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2020 aTox contributors
//
// SPDX-License-Identifier: GPL-3.0-only
Expand Down Expand Up @@ -84,7 +84,7 @@ class AddContactFragment : BaseFragment<FragmentAddContactBinding>(FragmentAddCo
}

if (toxId.error == null) {
if (contacts.find { it.publicKey == input.toPublicKey().string() } != null) {
if (contacts.find { it.publicKey == input.toPublicKey() } != null) {
toxId.error = getString(R.string.tox_id_error_already_exists)
}
}
Expand Down
8 changes: 5 additions & 3 deletions atox/src/main/kotlin/ui/addcontact/AddContactViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2019-2022 aTox contributors
// SPDX-FileCopyrightText: 2019-2025 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022 aTox contributors
//
// SPDX-License-Identifier: GPL-3.0-only

Expand All @@ -16,6 +17,7 @@ import ltd.evilcorp.core.repository.MessageRepository
import ltd.evilcorp.core.vo.Contact
import ltd.evilcorp.core.vo.Message
import ltd.evilcorp.core.vo.MessageType
import ltd.evilcorp.core.vo.PublicKey
import ltd.evilcorp.core.vo.Sender
import ltd.evilcorp.domain.feature.ContactManager
import ltd.evilcorp.domain.tox.Tox
Expand All @@ -35,7 +37,7 @@ class AddContactViewModel @Inject constructor(
fun isToxRunning() = tox.started
fun tryLoadTox(): Boolean = toxStarter.tryLoadTox(null) == ToxSaveStatus.Ok

private fun addToChatLog(publicKey: String, message: String) = scope.launch {
private fun addToChatLog(publicKey: PublicKey, message: String) = scope.launch {
messageRepository.add(
Message(
publicKey,
Expand All @@ -50,6 +52,6 @@ class AddContactViewModel @Inject constructor(

fun addContact(toxId: ToxID, message: String) {
contactManager.add(toxId, message)
addToChatLog(toxId.toPublicKey().string(), message)
addToChatLog(toxId.toPublicKey(), message)
}
}
Loading

0 comments on commit bb6a698

Please sign in to comment.