From cd2fcd951d5a026b2bef26d000058075d6646d2f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 10 Nov 2025 10:16:29 +0100 Subject: [PATCH] Trying multiple devices ringing mode --- app/src/main/assets/linphonerc_factory | 2 +- .../java/org/linphone/core/CoreContext.kt | 59 ++++++++++++++++--- .../java/org/linphone/core/CorePreferences.kt | 4 ++ .../java/org/linphone/utils/AudioUtils.kt | 8 +-- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/app/src/main/assets/linphonerc_factory b/app/src/main/assets/linphonerc_factory index 9002c427b..31d406b17 100644 --- a/app/src/main/assets/linphonerc_factory +++ b/app/src/main/assets/linphonerc_factory @@ -26,7 +26,7 @@ update_presence_model_timestamp_before_publish_expires_refresh=1 [sound] #remove this property for any application that is not Linphone public version itself ec_calibrator_cool_tones=1 -disable_ringing=0 +disable_ringing=1 [audio] android_disable_audio_focus_requests=1 diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 487e9b42e..fc406de13 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -25,9 +25,11 @@ import android.app.PendingIntent import android.content.Context import android.content.Context.POWER_SERVICE import android.content.Intent +import android.media.AudioAttributes import android.media.AudioDeviceCallback import android.media.AudioDeviceInfo import android.media.AudioManager +import android.media.MediaPlayer import android.os.Handler import android.os.HandlerThread import android.os.Looper @@ -48,7 +50,7 @@ import org.linphone.compatibility.Compatibility import org.linphone.contacts.ContactsManager import org.linphone.core.tools.Log import org.linphone.notifications.NotificationsManager -import org.linphone.telecom.TelecomManager +// import org.linphone.telecom.TelecomManager import org.linphone.ui.call.CallActivity import org.linphone.utils.ActivityMonitor import org.linphone.utils.AppUtils @@ -73,7 +75,7 @@ class CoreContext val notificationsManager = NotificationsManager(context) - val telecomManager = TelecomManager(context) + // val telecomManager = TelecomManager(context) @get:AnyThread val sdkVersion: String by lazy { @@ -149,14 +151,14 @@ class CoreContext ) } - if (telecomManager.getCurrentlyFollowedCalls() <= 0) { + /*if (telecomManager.getCurrentlyFollowedCalls() <= 0) { Log.i("$TAG No call found in Telecom's CallsManager, reloading sound devices in 500ms") postOnCoreThreadDelayed({ core.reloadSoundDevices() }, 500) } else { Log.i( "$TAG At least one active call in Telecom's CallsManager, let it handle the added device(s)" ) - } + }*/ } } @@ -169,14 +171,14 @@ class CoreContext "$TAG Removed device [${device.id}][${device.productName}][${device.type}]" ) } - if (telecomManager.getCurrentlyFollowedCalls() <= 0) { + /*if (telecomManager.getCurrentlyFollowedCalls() <= 0) { Log.i("$TAG No call found in Telecom's CallsManager, reloading sound devices in 500ms") postOnCoreThreadDelayed({ core.reloadSoundDevices() }, 500) } else { Log.i( "$TAG At least one active call in Telecom's CallsManager, let it handle the removed device(s)" ) - } + }*/ } } } @@ -320,6 +322,36 @@ class CoreContext answerCall(call, true) }, autoAnswerDelay.toLong()) } + } else { + val mediaPlayer1 = MediaPlayer().apply { + try { + setAudioAttributes( + AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .build() + ) + setDataSource(corePreferences.ringtone) + prepare() + } catch (e: Exception) { + Log.e("$TAG Failed to prepare message received sound file $e") + } + } + mediaPlayer1.start() + + val mediaPlayer2 = MediaPlayer().apply { + try { + setAudioAttributes( + AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) + .setUsage(AudioAttributes.USAGE_MEDIA) + .build() + ) + setDataSource(corePreferences.ringtone) + prepare() + } catch (e: Exception) { + Log.e("$TAG Failed to prepare message received sound file $e") + } + } + mediaPlayer2.start() } } Call.State.IncomingEarlyMedia -> { @@ -639,6 +671,17 @@ class CoreContext computeUserAgent() Log.i("$TAG Core has been configured with user-agent [${core.userAgent}], starting it") + + // Required for multi device ringing + core.isNativeRingingEnabled = false + for (device in core.extendedAudioDevices) { + if (device.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) { + Log.i("$TAG Using device [${device.deviceName}]([${device.type}]) as ringing device") + device.useForRinging = true + } + } + core.ring = corePreferences.ringtone + core.start() } @@ -676,7 +719,7 @@ class CoreContext } contactsManager.onCoreStarted(core) - telecomManager.onCoreStarted(core) + // telecomManager.onCoreStarted(core) notificationsManager.onCoreStarted(core, oldVersion < 600000) // Re-create channels when migrating from a non 6.0 version Log.i("$TAG Started contacts, telecom & notifications managers") @@ -704,7 +747,7 @@ class CoreContext private fun onCoreStopped() { Log.w("$TAG Core is being shut down, notifying managers so they can remove their listeners and do some cleanup if needed") contactsManager.onCoreStopped(core) - telecomManager.onCoreStopped(core) + // telecomManager.onCoreStopped(core) notificationsManager.onCoreStopped(core) } diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index 953931de7..d767f7d39 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -449,6 +449,10 @@ class CorePreferences val messageReceivedInVisibleConversationNotificationSound: String get() = context.filesDir.absolutePath + "/share/sounds/linphone/incoming_chat.wav" + @get:AnyThread + val ringtone: String + get() = context.filesDir.absolutePath + "/share/sounds/linphone/toy-mono.wav" + @UiThread fun copyAssetsFromPackage() { copy("linphonerc_default", configPath) diff --git a/app/src/main/java/org/linphone/utils/AudioUtils.kt b/app/src/main/java/org/linphone/utils/AudioUtils.kt index 3ac0268cf..5f01edb23 100644 --- a/app/src/main/java/org/linphone/utils/AudioUtils.kt +++ b/app/src/main/java/org/linphone/utils/AudioUtils.kt @@ -98,14 +98,14 @@ class AudioUtils { if (!skipTelecom) { val callId = currentCall?.callLog?.callId.orEmpty() Log.i("$TAG Trying to change audio endpoint using Telecom Manager APIs") - val success = coreContext.telecomManager.applyAudioRouteToCallWithId(types, callId) + /*val success = coreContext.telecomManager.applyAudioRouteToCallWithId(types, callId) if (!success) { - Log.w("$TAG Failed to change audio endpoint to [$types] for call ID [$callId]") + Log.w("$TAG Failed to change audio endpoint to [$types] for call ID [$callId]")*/ applyAudioRouteChange(currentCall, types, output, skipTelecom = true) - } else { + /*} else { Log.i("$TAG It seems audio endpoint update using Telecom Manager was successful") return - } + }*/ } else { Log.i("$TAG Trying to change audio endpoint directly in Linphone SDK") applyAudioRouteChangeInLinphone(currentCall, types, output)