mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Added enable/disable speaker to active call notification
This commit is contained in:
parent
ae39d79420
commit
8148354901
5 changed files with 110 additions and 36 deletions
|
|
@ -13,6 +13,7 @@ Group changes to describe their impact on the project, as follows:
|
|||
## [6.1.0] - Unreleased
|
||||
|
||||
### Added
|
||||
- Added toggle speaker action in active call notification
|
||||
- Added a vu meter for recording & playback volumes (disabled by default, must be enabled in CorePreferences)
|
||||
- Added a setting for user to choose whether to sort contacts by first name or last name
|
||||
- Added a setting to hide contacts that have neither a SIP address nor a phone number
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.AudioDevice
|
||||
import org.linphone.core.ConferenceParams
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.AudioUtils
|
||||
|
||||
class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||
companion object {
|
||||
|
|
@ -36,47 +38,69 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val notificationId = intent.getIntExtra(NotificationsManager.INTENT_NOTIF_ID, 0)
|
||||
Log.i(
|
||||
"$TAG Got notification broadcast for ID [$notificationId]"
|
||||
)
|
||||
val action = intent.action
|
||||
Log.i("$TAG Got notification broadcast for ID [$notificationId] with action [$action]")
|
||||
|
||||
// Wait for coreContext to be ready to handle intent
|
||||
while (!coreContext.isReady()) {
|
||||
Thread.sleep(50)
|
||||
}
|
||||
|
||||
if (intent.action == NotificationsManager.INTENT_ANSWER_CALL_NOTIF_ACTION || intent.action == NotificationsManager.INTENT_HANGUP_CALL_NOTIF_ACTION) {
|
||||
handleCallIntent(intent, notificationId)
|
||||
} else if (intent.action == NotificationsManager.INTENT_REPLY_MESSAGE_NOTIF_ACTION || intent.action == NotificationsManager.INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION) {
|
||||
handleChatIntent(context, intent, notificationId)
|
||||
if (
|
||||
action == NotificationsManager.INTENT_ANSWER_CALL_NOTIF_ACTION ||
|
||||
action == NotificationsManager.INTENT_HANGUP_CALL_NOTIF_ACTION ||
|
||||
action == NotificationsManager.INTENT_TOGGLE_SPEAKER_CALL_NOTIF_ACTION
|
||||
) {
|
||||
handleCallIntent(intent, notificationId, action)
|
||||
} else if (
|
||||
action == NotificationsManager.INTENT_REPLY_MESSAGE_NOTIF_ACTION ||
|
||||
action == NotificationsManager.INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION
|
||||
) {
|
||||
handleChatIntent(context, intent, notificationId, action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleCallIntent(intent: Intent, notificationId: Int) {
|
||||
val remoteSipAddress = intent.getStringExtra(NotificationsManager.INTENT_REMOTE_ADDRESS)
|
||||
if (remoteSipAddress == null) {
|
||||
private fun handleCallIntent(intent: Intent, notificationId: Int, action: String) {
|
||||
val remoteSipUri = intent.getStringExtra(NotificationsManager.INTENT_REMOTE_SIP_URI)
|
||||
if (remoteSipUri == null) {
|
||||
Log.e("$TAG Remote SIP address is null for call notification ID [$notificationId]")
|
||||
return
|
||||
}
|
||||
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val call = core.calls.find {
|
||||
it.remoteAddress.asStringUriOnly() == remoteSipAddress
|
||||
it.remoteAddress.asStringUriOnly() == remoteSipUri
|
||||
}
|
||||
if (call == null) {
|
||||
Log.e("$TAG Couldn't find call from remote address [$remoteSipAddress]")
|
||||
Log.e("$TAG Couldn't find call from remote address [$remoteSipUri]")
|
||||
} else {
|
||||
if (intent.action == NotificationsManager.INTENT_ANSWER_CALL_NOTIF_ACTION) {
|
||||
coreContext.answerCall(call)
|
||||
} else {
|
||||
coreContext.terminateCall(call)
|
||||
when (action) {
|
||||
NotificationsManager.INTENT_ANSWER_CALL_NOTIF_ACTION -> {
|
||||
Log.i("$TAG Answering call with remote address [$remoteSipUri]")
|
||||
coreContext.answerCall(call)
|
||||
}
|
||||
NotificationsManager.INTENT_HANGUP_CALL_NOTIF_ACTION -> {
|
||||
Log.i("$TAG Declining/terminating call with remote address [$remoteSipUri]")
|
||||
coreContext.terminateCall(call)
|
||||
}
|
||||
NotificationsManager.INTENT_TOGGLE_SPEAKER_CALL_NOTIF_ACTION -> {
|
||||
val audioDevice = call.outputAudioDevice
|
||||
val isUsingSpeaker = audioDevice?.type == AudioDevice.Type.Speaker
|
||||
if (isUsingSpeaker) {
|
||||
Log.i("$TAG Routing audio to earpiece for call [$remoteSipUri]")
|
||||
AudioUtils.routeAudioToEarpiece(call)
|
||||
} else {
|
||||
Log.i("$TAG Routing audio to speaker for call [$remoteSipUri]")
|
||||
AudioUtils.routeAudioToSpeaker(call)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleChatIntent(context: Context, intent: Intent, notificationId: Int) {
|
||||
val remoteSipAddress = intent.getStringExtra(NotificationsManager.INTENT_REMOTE_ADDRESS)
|
||||
private fun handleChatIntent(context: Context, intent: Intent, notificationId: Int, action: String) {
|
||||
val remoteSipAddress = intent.getStringExtra(NotificationsManager.INTENT_REMOTE_SIP_URI)
|
||||
if (remoteSipAddress == null) {
|
||||
Log.e("$TAG Remote SIP address is null for notification ID [$notificationId]")
|
||||
return
|
||||
|
|
@ -88,7 +112,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
}
|
||||
|
||||
val reply = getMessageText(intent)?.toString()
|
||||
if (intent.action == NotificationsManager.INTENT_REPLY_MESSAGE_NOTIF_ACTION) {
|
||||
if (action == NotificationsManager.INTENT_REPLY_MESSAGE_NOTIF_ACTION) {
|
||||
if (reply == null) {
|
||||
Log.e("$TAG Couldn't get reply text")
|
||||
return
|
||||
|
|
@ -128,13 +152,13 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
return@postOnCoreThread
|
||||
}
|
||||
|
||||
if (intent.action == NotificationsManager.INTENT_REPLY_MESSAGE_NOTIF_ACTION) {
|
||||
if (action == NotificationsManager.INTENT_REPLY_MESSAGE_NOTIF_ACTION) {
|
||||
val msg = room.createMessageFromUtf8(reply)
|
||||
msg.userData = notificationId
|
||||
msg.addListener(coreContext.notificationsManager.chatMessageListener)
|
||||
msg.send()
|
||||
Log.i("$TAG Reply sent for notif id [$notificationId]")
|
||||
} else if (intent.action == NotificationsManager.INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION) {
|
||||
} else if (action == NotificationsManager.INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION) {
|
||||
Log.i("$TAG Marking chat room from notification id [$notificationId] as read")
|
||||
room.markAsRead()
|
||||
if (!coreContext.notificationsManager.dismissChatNotification(room)) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import org.linphone.contacts.ContactsManager.ContactsListener
|
|||
import org.linphone.contacts.getAvatarBitmap
|
||||
import org.linphone.contacts.getPerson
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.AudioDevice
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.core.ChatMessage
|
||||
import org.linphone.core.ChatMessageListener
|
||||
|
|
@ -86,13 +87,14 @@ class NotificationsManager
|
|||
|
||||
const val INTENT_HANGUP_CALL_NOTIF_ACTION = "org.linphone.HANGUP_CALL_ACTION"
|
||||
const val INTENT_ANSWER_CALL_NOTIF_ACTION = "org.linphone.ANSWER_CALL_ACTION"
|
||||
const val INTENT_TOGGLE_SPEAKER_CALL_NOTIF_ACTION = "org.linphone.TOGGLE_SPEAKER_CALL_ACTION"
|
||||
const val INTENT_REPLY_MESSAGE_NOTIF_ACTION = "org.linphone.REPLY_ACTION"
|
||||
const val INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION = "org.linphone.MARK_AS_READ_ACTION"
|
||||
const val INTENT_NOTIF_ID = "NOTIFICATION_ID"
|
||||
|
||||
const val KEY_TEXT_REPLY = "key_text_reply"
|
||||
const val INTENT_LOCAL_IDENTITY = "LOCAL_IDENTITY"
|
||||
const val INTENT_REMOTE_ADDRESS = "REMOTE_ADDRESS"
|
||||
const val INTENT_REMOTE_SIP_URI = "REMOTE_ADDRESS"
|
||||
|
||||
const val CHAT_TAG = "Chat"
|
||||
private const val MISSED_CALL_TAG = "Missed call"
|
||||
|
|
@ -151,7 +153,12 @@ class NotificationsManager
|
|||
Log.i(
|
||||
"$TAG Found call [${addressMatch.asStringUriOnly()}] with contact in notifications, updating it"
|
||||
)
|
||||
updateCallNotification(notifiable, addressMatch, friend)
|
||||
val call = coreContext.core.getCallByRemoteAddress2(addressMatch)
|
||||
if (call == null) {
|
||||
Log.e("$TAG Failed to get Call from Core using remote address [${addressMatch.asStringUriOnly()}]")
|
||||
return
|
||||
}
|
||||
updateCallNotification(notifiable, call, friend)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -276,6 +283,18 @@ class NotificationsManager
|
|||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onAudioDeviceChanged(core: Core, audioDevice: AudioDevice) {
|
||||
if (core.callsNb == 0) return
|
||||
|
||||
val call = core.currentCall ?: core.calls.firstOrNull()
|
||||
if (call != null) {
|
||||
Log.i("$TAG Audio device changed, updating call [${call.remoteAddress.asStringUriOnly()}] notification")
|
||||
val notifiable = getNotifiableForCall(call)
|
||||
updateCallNotification(notifiable, call, null)
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onMessagesReceived(
|
||||
core: Core,
|
||||
|
|
@ -1292,22 +1311,33 @@ class NotificationsManager
|
|||
setFullScreenIntent(pendingIntent, true)
|
||||
}
|
||||
|
||||
if (!isIncoming) {
|
||||
val toggleSpeakerIntent = getCallToggleSpeakerPendingIntent(notifiable)
|
||||
|
||||
val audioDevice = call.outputAudioDevice
|
||||
val isUsingSpeaker = audioDevice?.type == AudioDevice.Type.Speaker
|
||||
|
||||
val toggleSpeakerAction = if (isUsingSpeaker) {
|
||||
Log.i("$TAG Call is using speaker, adding action to disable it")
|
||||
val text = AppUtils.getString(R.string.notification_disable_speaker_for_call)
|
||||
NotificationCompat.Action.Builder(R.drawable.speaker_slash, text, toggleSpeakerIntent).build()
|
||||
} else {
|
||||
Log.i("$TAG Call is not using speaker, adding action to enable it")
|
||||
val text = AppUtils.getString(R.string.notification_enable_speaker_for_call)
|
||||
NotificationCompat.Action.Builder(R.drawable.speaker_high, text, toggleSpeakerIntent).build()
|
||||
}
|
||||
builder.addAction(toggleSpeakerAction)
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun updateCallNotification(
|
||||
notifiable: Notifiable,
|
||||
remoteAddress: Address,
|
||||
friend: Friend
|
||||
call: Call,
|
||||
friend: Friend?
|
||||
) {
|
||||
val call = coreContext.core.getCallByRemoteAddress2(remoteAddress)
|
||||
if (call == null) {
|
||||
Log.w(
|
||||
"$TAG Failed to find call with remote SIP URI [${remoteAddress.asStringUriOnly()}]"
|
||||
)
|
||||
return
|
||||
}
|
||||
val isIncoming = LinphoneUtils.isCallIncoming(call.state)
|
||||
|
||||
val notification = if (isIncoming) {
|
||||
|
|
@ -1469,7 +1499,7 @@ class NotificationsManager
|
|||
val hangupIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
hangupIntent.action = INTENT_HANGUP_CALL_NOTIF_ACTION
|
||||
hangupIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
hangupIntent.putExtra(INTENT_REMOTE_ADDRESS, notifiable.remoteAddress)
|
||||
hangupIntent.putExtra(INTENT_REMOTE_SIP_URI, notifiable.remoteAddress)
|
||||
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
|
|
@ -1484,7 +1514,7 @@ class NotificationsManager
|
|||
val answerIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
answerIntent.action = INTENT_ANSWER_CALL_NOTIF_ACTION
|
||||
answerIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
answerIntent.putExtra(INTENT_REMOTE_ADDRESS, notifiable.remoteAddress)
|
||||
answerIntent.putExtra(INTENT_REMOTE_SIP_URI, notifiable.remoteAddress)
|
||||
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
|
|
@ -1494,6 +1524,21 @@ class NotificationsManager
|
|||
)
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
fun getCallToggleSpeakerPendingIntent(notifiable: Notifiable): PendingIntent {
|
||||
val answerIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
answerIntent.action = INTENT_TOGGLE_SPEAKER_CALL_NOTIF_ACTION
|
||||
answerIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
answerIntent.putExtra(INTENT_REMOTE_SIP_URI, notifiable.remoteAddress)
|
||||
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
4,
|
||||
answerIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun displayReplyMessageNotification(message: ChatMessage, notifiable: Notifiable) {
|
||||
Log.i(
|
||||
|
|
@ -1535,7 +1580,7 @@ class NotificationsManager
|
|||
replyIntent.action = INTENT_REPLY_MESSAGE_NOTIF_ACTION
|
||||
replyIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notifiable.localIdentity)
|
||||
replyIntent.putExtra(INTENT_REMOTE_ADDRESS, notifiable.remoteAddress)
|
||||
replyIntent.putExtra(INTENT_REMOTE_SIP_URI, notifiable.remoteAddress)
|
||||
|
||||
// PendingIntents attached to actions with remote inputs must be mutable
|
||||
val replyPendingIntent = PendingIntent.getBroadcast(
|
||||
|
|
@ -1562,7 +1607,7 @@ class NotificationsManager
|
|||
markAsReadIntent.action = INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION
|
||||
markAsReadIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
markAsReadIntent.putExtra(INTENT_LOCAL_IDENTITY, notifiable.localIdentity)
|
||||
markAsReadIntent.putExtra(INTENT_REMOTE_ADDRESS, notifiable.remoteAddress)
|
||||
markAsReadIntent.putExtra(INTENT_REMOTE_SIP_URI, notifiable.remoteAddress)
|
||||
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@
|
|||
<item quantity="other">%s fichiers en cours de réception</item>
|
||||
</plurals>
|
||||
<string name="notification_keep_app_alive_message">Cliquez pour ouvrir</string>
|
||||
<string name="notification_enable_speaker_for_call">Activer haut-parleur</string>
|
||||
<string name="notification_disable_speaker_for_call">Désactiver haut-parleur</string>
|
||||
|
||||
<!-- First screens user see when app is installed and started -->
|
||||
<string name="welcome_page_title">Bienvenue</string>
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@
|
|||
</plurals>
|
||||
<string name="notification_file_transfer_upload_download_message" translatable="false">%s, %s</string>
|
||||
<string name="notification_keep_app_alive_message">Click to open</string>
|
||||
<string name="notification_enable_speaker_for_call">Turn on speaker</string>
|
||||
<string name="notification_disable_speaker_for_call">Turn off speaker</string>
|
||||
|
||||
<!-- First screens user see when app is installed and started -->
|
||||
<string name="welcome_page_title">Welcome</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue