diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 54c282900..0d4543bbe 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -118,6 +118,7 @@ class NotificationsManager @MainThread constructor(private val context: Context) private val notificationsMap = HashMap() private var currentlyDisplayedChatRoomId: String = "" + private var currentlyDisplayedIncomingCallFragment: Boolean = false private val contactsListener = object : ContactsListener { @WorkerThread @@ -439,6 +440,11 @@ class NotificationsManager @MainThread constructor(private val context: Context) } } + @AnyThread + fun setIncomingCallFragmentCurrentlyDisplayed(visible: Boolean) { + currentlyDisplayedIncomingCallFragment = visible + } + @WorkerThread fun setCurrentlyDisplayedChatRoomId(id: String) { Log.i( @@ -658,8 +664,19 @@ class NotificationsManager @MainThread constructor(private val context: Context) @WorkerThread private fun startInCallForegroundService(call: Call) { - Log.i("$TAG Trying to start/update foreground Service using call notification") + if (LinphoneUtils.isCallIncoming(call.state)) { + val notification = notificationsMap[INCOMING_CALL_ID] + if (notification != null) { + startIncomingCallForegroundService(notification) + } else { + Log.w( + "$TAG Failed to find notification for incoming call with ID [$INCOMING_CALL_ID]" + ) + } + return + } + Log.i("$TAG Trying to start/update foreground Service using call notification") val service = inCallService if (service == null) { Log.w("$TAG Core Foreground Service hasn't started yet...") @@ -1138,7 +1155,11 @@ class NotificationsManager @MainThread constructor(private val context: Context) } val isIncoming = LinphoneUtils.isCallIncoming(call.state) - val notification = notificationsMap[notifiable.notificationId] + val notification = if (isIncoming) { + notificationsMap[INCOMING_CALL_ID] + } else { + notificationsMap[notifiable.notificationId] + } if (notification == null) { Log.w( "$TAG Failed to find notification with ID [${notifiable.notificationId}], creating a new one" @@ -1156,8 +1177,14 @@ class NotificationsManager @MainThread constructor(private val context: Context) friend ) if (isIncoming) { - Log.i("$TAG Updating incoming call notification with ID [$INCOMING_CALL_ID]") - notify(INCOMING_CALL_ID, newNotification) + if (!currentlyDisplayedIncomingCallFragment) { + Log.i("$TAG Updating incoming call notification with ID [$INCOMING_CALL_ID]") + notify(INCOMING_CALL_ID, newNotification) + } else { + Log.i( + "$TAG Incoming call fragment is visible, do not re-send an incoming call notification" + ) + } } else { Log.i("$TAG Updating call notification with ID [${notifiable.notificationId}]") notify(notifiable.notificationId, newNotification) diff --git a/app/src/main/java/org/linphone/ui/call/fragment/IncomingCallFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/IncomingCallFragment.kt index 235bfc116..8dcdcdff1 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/IncomingCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/IncomingCallFragment.kt @@ -25,6 +25,7 @@ import android.view.View import android.view.ViewGroup import androidx.annotation.UiThread import androidx.lifecycle.ViewModelProvider +import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.databinding.CallIncomingFragmentBinding import org.linphone.ui.call.viewmodel.CurrentCallViewModel @@ -53,4 +54,16 @@ class IncomingCallFragment : GenericCallFragment() { binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = callViewModel } + + override fun onResume() { + super.onResume() + + coreContext.notificationsManager.setIncomingCallFragmentCurrentlyDisplayed(true) + } + + override fun onPause() { + coreContext.notificationsManager.setIncomingCallFragmentCurrentlyDisplayed(false) + + super.onPause() + } } diff --git a/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt b/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt index ce37436bb..92e87d982 100644 --- a/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt +++ b/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt @@ -34,6 +34,7 @@ import kotlinx.coroutines.withContext import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R +import org.linphone.contacts.ContactsManager.ContactsListener import org.linphone.core.Address import org.linphone.core.AudioDevice import org.linphone.core.Call @@ -46,6 +47,7 @@ import org.linphone.core.Conference import org.linphone.core.ConferenceParams import org.linphone.core.Core import org.linphone.core.CoreListenerStub +import org.linphone.core.Friend import org.linphone.core.MediaDirection import org.linphone.core.MediaEncryption import org.linphone.core.SecurityLevel @@ -235,6 +237,28 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { lateinit var currentCall: Call + private val contactsListener = object : ContactsListener { + @WorkerThread + override fun onContactsLoaded() { + } + + @WorkerThread + override fun onContactFoundInRemoteDirectory(friend: Friend) { + val address = contact.value?.address + address ?: return + + val addressMatch = friend.addresses.find { + it.weakEqual(address) + } + if (addressMatch != null) { + Log.i("$TAG Updating current call contact model") + displayedName.postValue(friend.name) + val model = ContactAvatarModel(friend, address) + contact.postValue(model) + } + } + } + private val callListener = object : CallListenerStub() { @WorkerThread override fun onEncryptionChanged(call: Call, on: Boolean, authenticationToken: String?) { @@ -509,6 +533,8 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { proximitySensorEnabled.value = false coreContext.postOnCoreThread { core -> + coreContext.contactsManager.addListener(contactsListener) + core.addListener(coreListener) isRecordingEnabled.postValue(!corePreferences.disableCallRecordings) @@ -556,6 +582,7 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { coreContext.postOnCoreThread { core -> core.removeListener(coreListener) + coreContext.contactsManager.removeListener(contactsListener) conferenceModel.destroy() contact.value?.destroy() @@ -1130,7 +1157,6 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { coreContext.contactsManager.getContactAvatarModelForConferenceInfo(conferenceInfo) } else { // Do not use contact avatar model from ContactsManager - // coreContext.contactsManager.getContactAvatarModelForAddress(address) val friend = coreContext.contactsManager.findContactByAddress(address) if (friend != null) { ContactAvatarModel(friend, address) @@ -1138,7 +1164,7 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { val fakeFriend = coreContext.core.createFriend() fakeFriend.name = LinphoneUtils.getDisplayName(address) fakeFriend.address = address - ContactAvatarModel(fakeFriend) + ContactAvatarModel(fakeFriend, address) } }