Fixed methods called from wrong thread, other code cleanup / improvements

This commit is contained in:
Sylvain Berfini 2025-08-19 10:33:29 +02:00
parent a27c251d7a
commit 4982c3e81d
17 changed files with 47 additions and 29 deletions

View file

@ -175,7 +175,7 @@ class VFS {
val cipher = Cipher.getInstance(TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey())
val iv = cipher.iv
return Pair<ByteArray, ByteArray>(
return Pair(
iv,
cipher.doFinal(textToEncrypt.toByteArray(StandardCharsets.UTF_8))
)
@ -193,7 +193,7 @@ class VFS {
@Throws(java.lang.Exception::class)
private fun encryptToken(token: String): Pair<String?, String?> {
val encryptedData = encryptData(token)
return Pair<String?, String?>(
return Pair(
Base64.encodeToString(encryptedData.first, Base64.DEFAULT),
Base64.encodeToString(encryptedData.second, Base64.DEFAULT)
)

View file

@ -1781,7 +1781,7 @@ class NotificationsManager
@AnyThread
fun foregroundServiceTypeMaskToString(mask: Int): String {
var stringBuilder = StringBuilder()
val stringBuilder = StringBuilder()
val values = hashMapOf(
"PHONE_CALL" to Compatibility.FOREGROUND_SERVICE_TYPE_PHONE_CALL,
"MICROPHONE" to Compatibility.FOREGROUND_SERVICE_TYPE_MICROPHONE,

View file

@ -24,6 +24,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
@ -65,6 +66,7 @@ class ConferenceAddParticipantsFragment : GenericAddressPickerFragment() {
return false
}
@WorkerThread
override fun onSingleAddressSelected(address: Address, friend: Friend) {
Log.e("$TAG This shouldn't happen as we should always be in multiple selection mode here!")
}

View file

@ -175,7 +175,9 @@ class ConferenceParticipantsListFragment : GenericCallFragment() {
model.confirmEvent.observe(viewLifecycleOwner) {
it.consume {
viewModel.conferenceModel.kickParticipant(participant)
coreContext.postOnCoreThread {
viewModel.conferenceModel.kickParticipant(participant)
}
val message = getString(R.string.conference_participant_was_kicked_out_toast)
val icon = R.drawable.check
(requireActivity() as GenericActivity).showGreenToast(message, icon)

View file

@ -156,7 +156,7 @@ class ConferenceViewModel
} else {
Log.w("$TAG Notified active speaker participant device is null, using first one that's not us")
val firstNotUs = participantDevices.value.orEmpty().find {
it.isMe == false
!it.isMe
}
if (firstNotUs != null) {
Log.i("$TAG Newly active speaker participant is [${firstNotUs.name}]")

View file

@ -47,7 +47,6 @@ import org.linphone.ui.main.history.viewmodel.StartCallViewModel
import org.linphone.utils.ConfirmationDialogModel
import org.linphone.utils.AppUtils
import org.linphone.utils.DialogUtils
import org.linphone.utils.LinphoneUtils
import org.linphone.utils.RecyclerViewHeaderDecoration
import org.linphone.utils.hideKeyboard
import org.linphone.utils.setKeyboardInsetListener
@ -233,8 +232,10 @@ class TransferCallFragment : GenericCallFragment() {
}
viewModel.initiateBlindTransferEvent.observe(viewLifecycleOwner) {
it.consume { address ->
showConfirmBlindTransferDialog(address, LinphoneUtils.getDisplayName(address))
it.consume { pair ->
val address = pair.first
val displayName = pair.second
showConfirmBlindTransferDialog(address, displayName)
}
}

View file

@ -251,7 +251,7 @@ class MainActivity : GenericActivity() {
viewModel.clearFilesOrTextPendingSharingEvent.observe(this) {
it.consume {
sharedViewModel.filesToShareFromIntent.value = arrayListOf<String>()
sharedViewModel.filesToShareFromIntent.value = arrayListOf()
sharedViewModel.textToShareFromIntent.value = ""
}
}

View file

@ -544,8 +544,8 @@ open class ConversationFragment : SlidingPaneChildFragment() {
"$TAG Voice record playback finished, looking for voice record in next message"
)
val list = viewModel.eventsList
val model = list.find {
(it.model as? MessageModel)?.id == id
val model = list.find { eventLogModel ->
(eventLogModel.model as? MessageModel)?.id == id
}
if (model != null) {
val index = list.indexOf(model)
@ -770,13 +770,15 @@ open class ConversationFragment : SlidingPaneChildFragment() {
viewModel.sipUriToCallEvent.observe(viewLifecycleOwner) {
it.consume { sipUri ->
if (messageLongPressViewModel.visible.value == true) return@consume
val address = coreContext.core.interpretUrl(sipUri, false)
if (address != null) {
Log.i("$TAG Starting audio call to parsed SIP URI [${address.asStringUriOnly()}]")
coreContext.startAudioCall(address)
} else {
Log.w("$TAG Failed to parse [$sipUri] as SIP URI")
coreContext.postOnCoreThread {
if (messageLongPressViewModel.visible.value == true) return@postOnCoreThread
val address = coreContext.core.interpretUrl(sipUri, false)
if (address != null) {
Log.i("$TAG Starting audio call to parsed SIP URI [${address.asStringUriOnly()}]")
coreContext.startAudioCall(address)
} else {
Log.w("$TAG Failed to parse [$sipUri] as SIP URI")
}
}
}
}

View file

@ -251,8 +251,8 @@ class ConversationsListFragment : AbstractMainFragment() {
sharedViewModel.updateConversationLastMessageEvent.observe(viewLifecycleOwner) {
it.consume { conversationId ->
val model = listViewModel.conversations.value.orEmpty().find {
it.id == conversationId
val model = listViewModel.conversations.value.orEmpty().find { conversationModel ->
conversationModel.id == conversationId
}
model?.updateLastMessageInfo()
}

View file

@ -280,7 +280,6 @@ class SendMessageInConversationViewModel
voiceMessage.send()
} else {
message.addContent(content)
contentAdded = true
}
} else {
Log.e("$TAG Voice recording content couldn't be created!")

View file

@ -197,7 +197,10 @@ class ContactsListViewModel
fun toggleFavouritesVisibility() {
val show = showFavourites.value == false
showFavourites.value = show
corePreferences.showFavoriteContacts = show
coreContext.postOnCoreThread {
corePreferences.showFavoriteContacts = show
}
}
@UiThread

View file

@ -35,6 +35,7 @@ import androidx.navigation.fragment.findNavController
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener
import com.google.android.material.textfield.TextInputLayout
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.core.tools.Log
@ -192,7 +193,9 @@ abstract class AbstractMainFragment : GenericMainFragment() {
sharedViewModel.forceUpdateAvailableNavigationItems.observe(viewLifecycleOwner) {
it.consume {
viewModel.updateAvailableMenus()
coreContext.postOnCoreThread {
viewModel.updateAvailableMenus()
}
}
}
}

View file

@ -25,6 +25,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
@ -91,6 +92,7 @@ class AddParticipantsFragment : GenericAddressPickerFragment() {
return false
}
@WorkerThread
override fun onSingleAddressSelected(address: Address, friend: Friend) {
Log.e("$TAG This shouldn't happen as we should always be in multiple selection mode here!")
}

View file

@ -80,8 +80,8 @@ class StartCallViewModel
MutableLiveData<Event<Boolean>>()
}
val initiateBlindTransferEvent: MutableLiveData<Event<Address>> by lazy {
MutableLiveData<Event<Address>>()
val initiateBlindTransferEvent: MutableLiveData<Event<Pair<Address, String>>> by lazy {
MutableLiveData<Event<Pair<Address, String>>>()
}
private val conferenceListener = object : ConferenceListenerStub() {
@ -153,7 +153,7 @@ class StartCallViewModel
LinphoneUtils.applyInternationalPrefix()
)
if (address != null) {
initiateBlindTransferEvent.postValue(Event(address))
initiateBlindTransferEvent.postValue(Event(Pair(address, LinphoneUtils.getDisplayName(address))))
leaveFragmentEvent.postValue(Event(true))
} else {
Log.e("$TAG Failed to parse [$suggestion] as SIP address")

View file

@ -187,7 +187,7 @@ class MeetingsListFragment : AbstractMainFragment() {
adapter.meetingLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
val isUserOrganizer = model.isOrganizer() && !model.isCancelled
val isUserOrganizer = model.isMyselfOrganizer && !model.isCancelled
val modalBottomSheet = MeetingsMenuDialogFragment(
isUserOrganizer,
{ // onDismiss

View file

@ -55,6 +55,8 @@ class MeetingModel
val time = "$startTime - $endTime"
val isMyselfOrganizer = isOrganizer()
val isBroadcast = MutableLiveData<Boolean>()
val subject = MutableLiveData<String>()
@ -90,7 +92,7 @@ class MeetingModel
}
@WorkerThread
fun isOrganizer(): Boolean {
private fun isOrganizer(): Boolean {
return coreContext.core.accountList.find { account ->
val address = account.params.identityAddress
address != null && conferenceInfo.organizer?.weakEqual(address) == true

View file

@ -866,7 +866,9 @@ class SettingsViewModel
if (newValue.isNotEmpty()) {
try {
val delay = newValue.toInt()
corePreferences.autoAnswerDelay = delay
coreContext.postOnCoreThread {
corePreferences.autoAnswerDelay = delay
}
} catch (nfe: NumberFormatException) {
Log.e("$TAG Ignoring new auto answer incoming calls delay as it can't be converted to int: $nfe")
}