From dd11873f67206f44c9d30eb72cc86b55529a69db Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Thu, 3 Apr 2025 17:21:18 +0300 Subject: [PATCH] Improved contacts implementation --- .../tutpro/baresip/BaresipContactActivity.kt | 18 +++----- .../com/tutpro/baresip/BaresipService.kt | 20 +++++--- .../com/tutpro/baresip/ConfigActivity.kt | 12 ++--- .../main/kotlin/com/tutpro/baresip/Contact.kt | 46 +++++++++---------- .../com/tutpro/baresip/ContactsActivity.kt | 11 ++--- 5 files changed, 52 insertions(+), 55 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipContactActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipContactActivity.kt index ac24f3af..a78c3418 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipContactActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipContactActivity.kt @@ -231,7 +231,7 @@ class BaresipContactActivity : ComponentActivity() { imageAvatarUri = Uri.fromFile(tmpFile).toString() } } catch (e: Exception) { - Log.e(TAG, "Could not read avatar image: $e") + Log.e(TAG, "Could not read avatar image: ${e.message}") } } @@ -498,10 +498,6 @@ class BaresipContactActivity : ComponentActivity() { Contact.updateBaresipContact(contact) } - Contact.contactsUpdate() - - Contact.saveBaresipContacts() - BaresipService.activities.remove("baresip contact,$new,$uriOrName") val i = Intent(ctx, MainActivity::class.java) @@ -595,7 +591,7 @@ class BaresipContactActivity : ComponentActivity() { try { ctx.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) } catch (e: Exception) { - Log.e(TAG, "Adding of contact ${contact.name} failed") + Log.e(TAG, "Adding of contact ${contact.name} failed: ${e.message}") return false } return true @@ -625,7 +621,7 @@ class BaresipContactActivity : ComponentActivity() { try { contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) } catch (e: Exception) { - Log.e(TAG, "Adding of SIP URI $uri failed") + Log.e(TAG, "Adding of SIP URI $uri failed: ${e.message}") } } @@ -641,7 +637,7 @@ class BaresipContactActivity : ComponentActivity() { return try { contentResolver.update(ContactsContract.Data.CONTENT_URI, contentValues, where, null) } catch (e: Exception) { - Log.e(TAG, "Update of Android URI $uri failed") + Log.e(TAG, "Update of Android URI $uri failed: ${e.message}") 0 } } @@ -660,7 +656,7 @@ class BaresipContactActivity : ComponentActivity() { try { contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) } catch (e: Exception) { - Log.e(TAG, "Adding of Android photo failed") + Log.e(TAG, "Adding of Android photo failed: ${e.message}") } } } @@ -677,7 +673,7 @@ class BaresipContactActivity : ComponentActivity() { return try { contentResolver.update(ContactsContract.Data.CONTENT_URI, contentValues, where, null) } catch (e: Exception) { - Log.e(TAG, "updateAndroidPhoto failed") + Log.e(TAG, "updateAndroidPhoto failed: ${e.message}") 0 } } @@ -691,7 +687,7 @@ class BaresipContactActivity : ComponentActivity() { out.close() out.toByteArray() } catch (e: Exception) { - Log.w(TAG, "Unable to serialize photo: $e") + Log.w(TAG, "Unable to serialize photo: ${e.message}") null } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 117f8bbd..542d4940 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -412,7 +412,7 @@ class BaresipService: Service() { try { File(filesPath).mkdirs() } catch (e: Error) { - Log.e(TAG, "Failed to create directory: $e") + Log.e(TAG, "Failed to create directory: ${e.message}") } } for (a in assets) { @@ -618,6 +618,7 @@ class BaresipService: Service() { sendBroadcast(Intent("com.tutpro.baresip.Restart")) } + @Suppress("unused") @SuppressLint("UnspecifiedImmutableFlag", "DiscouragedApi") @Keep fun uaEvent(event: String, uap: Long, callp: Long) { @@ -1092,6 +1093,7 @@ class BaresipService: Service() { } } + @Suppress("unused") @SuppressLint("UnspecifiedImmutableFlag") @Keep fun messageEvent(uap: Long, peerUri: String, cType: String, msg: ByteArray) { @@ -1105,13 +1107,13 @@ class BaresipService: Service() { val charsetString = Utils.paramValue(cType.replace(" ", ""), "charset") val charset = try { Charset.forName(charsetString) - } catch (e: Exception) { + } catch (_: Exception) { StandardCharsets.UTF_8 } val text = try { String(msg, charset) } catch (e: Exception) { - val error = "Decoding of message failed using charset $charset from $cType!" + val error = "Decoding of message failed using charset $charset from $cType: ${e.message}!" Log.w(TAG, error) error } @@ -1194,6 +1196,7 @@ class BaresipService: Service() { } } + @Suppress("unused") @Keep fun started() { Log.d(TAG, "Received 'started' from baresip") @@ -1207,6 +1210,7 @@ class BaresipService: Service() { updateStatusNotification() } + @Suppress("unused") @Keep fun stopped(error: String) { Log.d(TAG, "Received 'stopped' from baresip with start error '$error'") @@ -1262,7 +1266,7 @@ class BaresipService: Service() { else startForeground(STATUS_NOTIFICATION_ID, snb.build()) } catch (e: Exception) { - Log.e(TAG, "Failed to start foreground service") + Log.e(TAG, "Failed to start foreground service: ${e.message}") } } @@ -1564,7 +1568,7 @@ class BaresipService: Service() { true, androidContactsObserver) androidContactsObserverRegistered = true } catch (e: SecurityException) { - Log.i(TAG, "No Contacts permission") + Log.i(TAG, "No Contacts permission: ${e.message}") } } @@ -1609,6 +1613,7 @@ class BaresipService: Service() { external fun baresipStop(force: Boolean) + @SuppressLint("MutableCollectionMutableState") companion object { var isServiceRunning = false @@ -1631,7 +1636,7 @@ class BaresipService: Service() { val uas = mutableStateOf(emptyList()) val uasStatus = mutableStateOf(emptyMap()) - var contacts by mutableStateOf(emptyList()) + var contacts by mutableStateOf(mutableListOf()) val darkTheme = mutableStateOf(false) var messages by mutableStateOf(emptyList()) @@ -1640,7 +1645,8 @@ class BaresipService: Service() { val messageUpdate = MutableLiveData() val contactUpdate = MutableLiveData() val registrationUpdate = MutableLiveData() - val baresipContacts = mutableStateOf(emptyList()) + @SuppressLint("MutableCollectionMutableState") + val baresipContacts = mutableStateOf(mutableListOf()) val androidContacts = mutableStateOf(emptyList()) val contactNames = mutableStateOf(emptyList()) var contactsMode = "baresip" diff --git a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt index 132d372a..72102ec8 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt @@ -140,7 +140,7 @@ class ConfigActivity : ComponentActivity() { } catch (e: Error) { Utils.alertView( this, getString(R.string.error), - getString(R.string.read_cert_error) + getString(R.string.read_cert_error) + ": " + e.message ) newTlsCertificateFile = false } @@ -165,7 +165,7 @@ class ConfigActivity : ComponentActivity() { } catch (e: Error) { Utils.alertView( this, getString(R.string.error), - getString(R.string.read_ca_certs_error) + getString(R.string.read_ca_certs_error) + ": " + e.message ) newCaFile = false } @@ -222,7 +222,7 @@ class ConfigActivity : ComponentActivity() { val caCertsFile = File(BaresipService.filesPath + "/ca_certs.crt") oldCaFile = caCertsFile.exists() - powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager + powerManager = getSystemService(POWER_SERVICE) as PowerManager oldBatteryOptimizations = powerManager .isIgnoringBatteryOptimizations(packageName) == false @@ -814,7 +814,7 @@ class ConfigActivity : ComponentActivity() { try { androidSettingsRequest.launch(Intent("android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS")) } catch (e: ActivityNotFoundException) { - Log.e(TAG, "ActivityNotFound exception: $e") + Log.e(TAG, "ActivityNotFound exception: ${e.message}") } } ) @@ -857,7 +857,7 @@ class ConfigActivity : ComponentActivity() { try { dialerRoleRequest.launch(Intent("android.settings.MANAGE_DEFAULT_APPS_SETTINGS")) } catch (e: ActivityNotFoundException) { - Log.e(TAG, "ActivityNotFound exception: $e") + Log.e(TAG, "ActivityNotFound exception: ${e.message}") } } } @@ -1173,7 +1173,7 @@ class ConfigActivity : ComponentActivity() { baresipService.action = "Stop Content Observer" } "android" -> { - BaresipService.baresipContacts.value = listOf() + BaresipService.baresipContacts.value = mutableListOf() Contact.loadAndroidContacts(this) baresipService.action = "Start Content Observer" } diff --git a/app/src/main/kotlin/com/tutpro/baresip/Contact.kt b/app/src/main/kotlin/com/tutpro/baresip/Contact.kt index ecd490f9..8c4362fd 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Contact.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Contact.kt @@ -53,9 +53,9 @@ sealed class Contact { } when (this) { is BaresipContact -> - (copy as BaresipContact).avatarImage = avatarImage + (copy as BaresipContact).avatarImage = this.avatarImage is AndroidContact -> - (copy as AndroidContact).uris.addAll(uris) + (copy as AndroidContact).uris.addAll(this.uris) } return copy } @@ -211,8 +211,7 @@ sealed class Contact { val contacts = String(content) var contactNo = 0 val baseId = System.currentTimeMillis() - val restored = mutableListOf() - BaresipService.baresipContacts.value = listOf() + BaresipService.baresipContacts.value = mutableListOf() contacts.lines().forEach { val parts = it.split("\"") if (parts.size == 3) { @@ -242,53 +241,50 @@ sealed class Contact { if (contact.avatarImage == null) Log.d(TAG, "Contact $id avatarImage is null") } catch (e: Exception) { - Log.e(TAG, "Could not read avatar image from '$id.png") + Log.e(TAG, "Could not read avatar image from file $id.png: ${e.message}") } } - restored.add(contact) + BaresipService.baresipContacts.value.add(contact) } } - BaresipService.baresipContacts.value = restored.toList() return true } fun contactsUpdate() { - val newList = mutableListOf() + BaresipService.contacts = mutableListOf() if (BaresipService.contactsMode != "android") for (c in BaresipService.baresipContacts.value) - newList.add(c.copy()) + BaresipService.contacts.add(c.copy()) if (BaresipService.contactsMode != "baresip") for (c in BaresipService.androidContacts.value) - if (!nameExists(c.name, newList, true)) - newList.add(c.copy()) - newList.sortBy{ when (it) { + if (!nameExists(c.name, BaresipService.contacts, true)) + BaresipService.contacts.add(c.copy()) + BaresipService.contacts.sortBy{ when (it) { is BaresipContact -> if (it.favorite) "0" + it.name else "1" + it.name is AndroidContact -> if (it.favorite) "0" + it.name else "1" + it.name }} - BaresipService.contacts = newList.toList() generateContactNames() - //BaresipService.contactUpdate.postValue(System.nanoTime()) } fun addBaresipContact(contact: BaresipContact) { - val updatedList = BaresipService.baresipContacts.value.toMutableList() - updatedList.add(contact) - BaresipService.baresipContacts.value = updatedList.toList() + BaresipService.baresipContacts.value.add(contact) + saveBaresipContacts() + contactsUpdate() } fun updateBaresipContact(contact: BaresipContact) { - val updatedList = BaresipService.baresipContacts.value.toMutableList() - val contactCopy = contact.copy() - updatedList.removeIf { it.id == contact.id } - updatedList.add(contactCopy as BaresipContact) - BaresipService.baresipContacts.value = updatedList.toList() + val newContact = contact.copy() as BaresipContact + BaresipService.baresipContacts.value.removeIf { it.id == contact.id } + newContact.id = System.currentTimeMillis() + BaresipService.baresipContacts.value.add(newContact) + saveBaresipContacts() + contactsUpdate() } fun removeBaresipContact(contact: BaresipContact) { - val updatedList = BaresipService.baresipContacts.value.toMutableList() - updatedList.removeIf { it.id == contact.id } - BaresipService.baresipContacts.value = updatedList.toList() + BaresipService.baresipContacts.value.removeIf { it.id == contact.id } saveBaresipContacts() + contactsUpdate() } private fun generateContactNames () { diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactsActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactsActivity.kt index 4eccbec6..8d8a8717 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactsActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactsActivity.kt @@ -83,7 +83,6 @@ class ContactsActivity : ComponentActivity() { if (it.data != null && it.data!!.hasExtra("name")) newAndroidName = it.data!!.getStringExtra("name") } - Contact.contactsUpdate() } public override fun onCreate(savedInstanceState: Bundle?) { @@ -107,11 +106,11 @@ class ContactsActivity : ComponentActivity() { ContactsContract.Contacts.DISPLAY_NAME + "='" + newAndroidName + "'", null ) } catch (e: Exception) { - Log.e(TAG, "Update of Android favorite failed") + Log.e(TAG, "Update of Android favorite failed: ${e.message}") } newAndroidName = null } - Contact.contactsUpdate() + //Contact.contactsUpdate() } BaresipService.contactUpdate.observe(this, androidContactsObserver) @@ -207,7 +206,7 @@ class ContactsActivity : ComponentActivity() { state = lazyListState, verticalArrangement = Arrangement.spacedBy(10.dp), ) { - items(BaresipService.contacts, key = { contact -> contact.id() }) { contact -> + items(BaresipService.contacts, key = { it.id() }) { contact -> val name = contact.name() @@ -336,12 +335,12 @@ class ContactsActivity : ComponentActivity() { } catch (e: IOException) { Log.e( TAG, - "Could not delete file '$id.png" + "Could not delete file $id.png: ${e.message}" ) } } Contact.removeBaresipContact(contact) - Contact.contactsUpdate() + //Contact.contactsUpdate() } DialogInterface.BUTTON_NEUTRAL -> {