From 5a37f15bc765dca22d6ab83e547aed14fb3318a9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 Apr 2024 14:08:23 +0200 Subject: [PATCH] Fixed issues with incoming call notification not being dismissed in some cases + fixed toast in case of remote provisioning issue --- app/src/main/AndroidManifest.xml | 1 + .../java/org/linphone/core/CoreContext.kt | 10 +-- .../NotificationBroadcastReceiver.kt | 1 - .../notifications/NotificationsManager.kt | 61 +++++++++++++------ .../org/linphone/telecom/TelecomManager.kt | 2 - .../java/org/linphone/ui/main/MainActivity.kt | 46 +++++++++++--- app/src/main/res/values-fr/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 +- 8 files changed, 92 insertions(+), 35 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 74a8e2dd2..45828a0a1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -97,6 +97,7 @@ + diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index ed04ca06d..c3b629cbd 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -120,15 +120,15 @@ class CoreContext @UiThread constructor(val context: Context) : HandlerThread("C status: ConfiguringState?, message: String? ) { - Log.i("$TAG Configuring state changed [$status]") + Log.i("$TAG Configuring state changed [$status], message is [$message]") if (status == ConfiguringState.Successful) { val text = context.getString( - org.linphone.R.string.assistant_qr_code_provisioning_done + org.linphone.R.string.toast_remote_provisioning_config_applied ) greenToastToShowEvent.postValue(Event(Pair(text, org.linphone.R.drawable.smiley))) } else if (status == ConfiguringState.Failed) { val text = context.getString( - org.linphone.R.string.assistant_qr_code_provisioning_done + org.linphone.R.string.toast_remote_provisioning_config_failed ) redToastToShowEvent.postValue( Event(Pair(text, org.linphone.R.drawable.warning_circle)) @@ -505,7 +505,9 @@ class CoreContext @UiThread constructor(val context: Context) : HandlerThread("C fun terminateCall(call: Call) { if (call.dir == Call.Dir.Incoming && LinphoneUtils.isCallIncoming(call.state)) { val reason = if (call.core.callsNb > 1) Reason.Busy else Reason.Declined - Log.i("$TAG Declining call [${call.remoteAddress.asStringUriOnly()}] with reason [$reason]") + Log.i( + "$TAG Declining call [${call.remoteAddress.asStringUriOnly()}] with reason [$reason]" + ) call.decline(reason) } else { Log.i("$TAG Terminating call [${call.remoteAddress.asStringUriOnly()}]") diff --git a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt index 36683fcfb..1f21a7ad9 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt @@ -26,7 +26,6 @@ import android.content.Context import android.content.Intent import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.core.tools.Log -import org.linphone.utils.LinphoneUtils class NotificationBroadcastReceiver : BroadcastReceiver() { companion object { diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index a52932c14..2860b5a4e 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -97,6 +97,8 @@ class NotificationsManager @MainThread constructor(private val context: Context) private var currentForegroundServiceNotificationId = -1 + private var currentlyRingingCallRemoteAddress: Address? = null + private val notificationManager: NotificationManagerCompat by lazy { NotificationManagerCompat.from(context) } @@ -117,14 +119,32 @@ class NotificationsManager @MainThread constructor(private val context: Context) showCallNotification(call, true) } Call.State.Connected -> { + if (call.dir == Call.Dir.Incoming) { + Log.i( + "$TAG Connected call was incoming (so it was answered), removing incoming call notification" + ) + removeIncomingCallNotification() + } + Log.i( "$TAG Showing connected call notification for [${call.remoteAddress.asStringUriOnly()}]" ) showCallNotification(call, false) } Call.State.End, Call.State.Error -> { + val remoteSipAddress = call.remoteAddress + if (call.dir == Call.Dir.Incoming && currentlyRingingCallRemoteAddress?.weakEqual( + remoteSipAddress + ) == true + ) { + Log.i( + "$TAG Incoming call has been declined, cancelling incoming call notification" + ) + removeIncomingCallNotification() + } + Log.i( - "$TAG Removing terminated call notification for [${call.remoteAddress.asStringUriOnly()}]" + "$TAG Removing terminated/declined call notification for [${remoteSipAddress.asStringUriOnly()}]" ) dismissCallNotification(call) } @@ -415,25 +435,31 @@ class NotificationsManager @MainThread constructor(private val context: Context) core.removeListener(coreListener) } + @WorkerThread + fun removeIncomingCallNotification() { + if (currentForegroundServiceNotificationId == INCOMING_CALL_ID) { + if (coreService != null) { + Log.i( + "$TAG Service found, stopping it as foreground before cancelling notification" + ) + coreService?.stopForeground(STOP_FOREGROUND_REMOVE) + } else { + Log.w("$TAG Incoming call foreground notification Service wasn't found, weird...") + } + currentForegroundServiceNotificationId = -1 + } else { + Log.i( + "$TAG Incoming call notification wasn't used to keep running Service as foreground" + ) + } + + cancelNotification(INCOMING_CALL_ID) + currentlyRingingCallRemoteAddress = null + } + @WorkerThread private fun showCallNotification(call: Call, isIncoming: Boolean) { val notifiable = getNotifiableForCall(call) - if (!isIncoming && call.dir == Call.Dir.Incoming) { - if (currentForegroundServiceNotificationId == INCOMING_CALL_ID) { - // This is an accepted incoming call, remove notification before adding it again to change channel - Log.i( - "$TAG Incoming call with notification ID [${notifiable.notificationId}] was accepted, cancelling notification before adding it again to the right channel" - ) - if (coreService != null) { - Log.i( - "$TAG Service found, stopping it as foreground before cancelling notification" - ) - coreService?.stopForeground(STOP_FOREGROUND_REMOVE) - } - cancelNotification(INCOMING_CALL_ID) - currentForegroundServiceNotificationId = -1 - } - } val callNotificationIntent = Intent(context, CallActivity::class.java) callNotificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -458,6 +484,7 @@ class NotificationsManager @MainThread constructor(private val context: Context) isIncoming ) if (isIncoming) { + currentlyRingingCallRemoteAddress = call.remoteAddress notify(INCOMING_CALL_ID, notification) if (currentForegroundServiceNotificationId == -1) { startIncomingCallForeground(notification) diff --git a/app/src/main/java/org/linphone/telecom/TelecomManager.kt b/app/src/main/java/org/linphone/telecom/TelecomManager.kt index 2663b3be4..09e2630a5 100644 --- a/app/src/main/java/org/linphone/telecom/TelecomManager.kt +++ b/app/src/main/java/org/linphone/telecom/TelecomManager.kt @@ -21,7 +21,6 @@ package org.linphone.telecom import android.content.Context import android.net.Uri -import android.telecom.DisconnectCause import androidx.annotation.WorkerThread import androidx.core.telecom.CallAttributesCompat import androidx.core.telecom.CallsManager @@ -34,7 +33,6 @@ import org.linphone.core.AudioDevice import org.linphone.core.Call import org.linphone.core.Core import org.linphone.core.CoreListenerStub -import org.linphone.core.Reason import org.linphone.core.tools.Log import org.linphone.utils.LinphoneUtils diff --git a/app/src/main/java/org/linphone/ui/main/MainActivity.kt b/app/src/main/java/org/linphone/ui/main/MainActivity.kt index 1b74cb401..1819de03c 100644 --- a/app/src/main/java/org/linphone/ui/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/ui/main/MainActivity.kt @@ -184,6 +184,22 @@ class MainActivity : GenericActivity() { Log.e("$TAG Security exception when doing reportFullyDrawn(): $se") } } + + coreContext.greenToastToShowEvent.observe(this) { + it.consume { pair -> + val message = pair.first + val icon = pair.second + showGreenToast(message, icon) + } + } + + coreContext.redToastToShowEvent.observe(this) { + it.consume { pair -> + val message = pair.first + val icon = pair.second + showRedToast(message, icon) + } + } } override fun onPostCreate(savedInstanceState: Bundle?) { @@ -204,14 +220,6 @@ class MainActivity : GenericActivity() { } } - coreContext.greenToastToShowEvent.observe(this) { - it.consume { pair -> - val message = pair.first - val icon = pair.second - showGreenToast(message, icon) - } - } - if (intent != null) { handleIntent(intent, false) } else { @@ -394,7 +402,15 @@ class MainActivity : GenericActivity() { Intent.ACTION_SEND_MULTIPLE -> { handleSendIntent(intent, true) } - Intent.ACTION_VIEW, Intent.ACTION_DIAL, Intent.ACTION_CALL -> { + Intent.ACTION_VIEW -> { + val uri = intent.data?.toString() ?: "" + if (uri.startsWith("linphone-config:")) { + handleConfigIntent(uri) + } else { + handleCallIntent(intent) + } + } + Intent.ACTION_DIAL, Intent.ACTION_CALL -> { handleCallIntent(intent) } Intent.ACTION_VIEW_LOCUS -> { @@ -627,6 +643,18 @@ class MainActivity : GenericActivity() { } } + @MainThread + private fun handleConfigIntent(uri: String) { + val remoteConfigUri = uri.substring("linphone-config:".length) + coreContext.postOnCoreThread { core -> + coreContext.core.provisioningUri = remoteConfigUri + Log.w("$TAG Remote provisioning URL set to [$remoteConfigUri], restarting Core now") + coreContext.core.stop() + coreContext.core.start() + Log.i("$TAG Core restarted after remote provisioning URL was applied") + } + } + private fun loadContacts() { coreContext.contactsManager.loadContacts(this) } diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 488c9b08e..37b595118 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -102,6 +102,8 @@ Appel en cours de transfert L\'appel a été transferré Le transfert a échoué ! + Configuration appliquée avec succès + Erreur durant la récupération ou l\'application de la configuration Conditions de service & politique de confidentialité @@ -110,7 +112,6 @@ Êtes-vous sûr de vouloir utiliser ce numéro de téléphone ? Connexion Scanner un QR code - Configuration téléchargée avec succès J\'ai un compte SIP tiers Single sign on Pas encore de compte ? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0342d6e7a..dbd550702 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -137,6 +137,8 @@ Call is being transferred Call has been successfully transferred Call transfer failed! + Configuration successfully applied + Error while trying to download and apply remote configuration General terms & privacy policy @@ -145,7 +147,6 @@ Are you sure you want to use this phone number? Login Scan QR code - Configuration successfully applied+ Use a third party SIP account Single sign on No account yet?