Trying multiple devices ringing mode

This commit is contained in:
Sylvain Berfini 2025-11-10 10:16:29 +01:00
parent a6f568497d
commit cd2fcd951d
4 changed files with 60 additions and 13 deletions

View file

@ -26,7 +26,7 @@ update_presence_model_timestamp_before_publish_expires_refresh=1
[sound] [sound]
#remove this property for any application that is not Linphone public version itself #remove this property for any application that is not Linphone public version itself
ec_calibrator_cool_tones=1 ec_calibrator_cool_tones=1
disable_ringing=0 disable_ringing=1
[audio] [audio]
android_disable_audio_focus_requests=1 android_disable_audio_focus_requests=1

View file

@ -25,9 +25,11 @@ import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Context.POWER_SERVICE import android.content.Context.POWER_SERVICE
import android.content.Intent import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioDeviceCallback import android.media.AudioDeviceCallback
import android.media.AudioDeviceInfo import android.media.AudioDeviceInfo
import android.media.AudioManager import android.media.AudioManager
import android.media.MediaPlayer
import android.os.Handler import android.os.Handler
import android.os.HandlerThread import android.os.HandlerThread
import android.os.Looper import android.os.Looper
@ -48,7 +50,7 @@ import org.linphone.compatibility.Compatibility
import org.linphone.contacts.ContactsManager import org.linphone.contacts.ContactsManager
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.notifications.NotificationsManager import org.linphone.notifications.NotificationsManager
import org.linphone.telecom.TelecomManager // import org.linphone.telecom.TelecomManager
import org.linphone.ui.call.CallActivity import org.linphone.ui.call.CallActivity
import org.linphone.utils.ActivityMonitor import org.linphone.utils.ActivityMonitor
import org.linphone.utils.AppUtils import org.linphone.utils.AppUtils
@ -73,7 +75,7 @@ class CoreContext
val notificationsManager = NotificationsManager(context) val notificationsManager = NotificationsManager(context)
val telecomManager = TelecomManager(context) // val telecomManager = TelecomManager(context)
@get:AnyThread @get:AnyThread
val sdkVersion: String by lazy { 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") Log.i("$TAG No call found in Telecom's CallsManager, reloading sound devices in 500ms")
postOnCoreThreadDelayed({ core.reloadSoundDevices() }, 500) postOnCoreThreadDelayed({ core.reloadSoundDevices() }, 500)
} else { } else {
Log.i( Log.i(
"$TAG At least one active call in Telecom's CallsManager, let it handle the added device(s)" "$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}]" "$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") Log.i("$TAG No call found in Telecom's CallsManager, reloading sound devices in 500ms")
postOnCoreThreadDelayed({ core.reloadSoundDevices() }, 500) postOnCoreThreadDelayed({ core.reloadSoundDevices() }, 500)
} else { } else {
Log.i( Log.i(
"$TAG At least one active call in Telecom's CallsManager, let it handle the removed device(s)" "$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) answerCall(call, true)
}, autoAnswerDelay.toLong()) }, 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 -> { Call.State.IncomingEarlyMedia -> {
@ -639,6 +671,17 @@ class CoreContext
computeUserAgent() computeUserAgent()
Log.i("$TAG Core has been configured with user-agent [${core.userAgent}], starting it") 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() core.start()
} }
@ -676,7 +719,7 @@ class CoreContext
} }
contactsManager.onCoreStarted(core) 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 notificationsManager.onCoreStarted(core, oldVersion < 600000) // Re-create channels when migrating from a non 6.0 version
Log.i("$TAG Started contacts, telecom & notifications managers") Log.i("$TAG Started contacts, telecom & notifications managers")
@ -704,7 +747,7 @@ class CoreContext
private fun onCoreStopped() { 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") 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) contactsManager.onCoreStopped(core)
telecomManager.onCoreStopped(core) // telecomManager.onCoreStopped(core)
notificationsManager.onCoreStopped(core) notificationsManager.onCoreStopped(core)
} }

View file

@ -449,6 +449,10 @@ class CorePreferences
val messageReceivedInVisibleConversationNotificationSound: String val messageReceivedInVisibleConversationNotificationSound: String
get() = context.filesDir.absolutePath + "/share/sounds/linphone/incoming_chat.wav" 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 @UiThread
fun copyAssetsFromPackage() { fun copyAssetsFromPackage() {
copy("linphonerc_default", configPath) copy("linphonerc_default", configPath)

View file

@ -98,14 +98,14 @@ class AudioUtils {
if (!skipTelecom) { if (!skipTelecom) {
val callId = currentCall?.callLog?.callId.orEmpty() val callId = currentCall?.callLog?.callId.orEmpty()
Log.i("$TAG Trying to change audio endpoint using Telecom Manager APIs") 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) { 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) applyAudioRouteChange(currentCall, types, output, skipTelecom = true)
} else { /*} else {
Log.i("$TAG It seems audio endpoint update using Telecom Manager was successful") Log.i("$TAG It seems audio endpoint update using Telecom Manager was successful")
return return
} }*/
} else { } else {
Log.i("$TAG Trying to change audio endpoint directly in Linphone SDK") Log.i("$TAG Trying to change audio endpoint directly in Linphone SDK")
applyAudioRouteChangeInLinphone(currentCall, types, output) applyAudioRouteChangeInLinphone(currentCall, types, output)