Call notification: add missed call icons. Also set tint.

This commit is contained in:
ganfra 2021-07-20 12:28:07 +02:00
parent c59967fb6c
commit 88cc7471a8
7 changed files with 85 additions and 27 deletions

View file

@ -37,6 +37,7 @@ import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.popup.IncomingCallAlert
import im.vector.app.features.popup.PopupAlertManager
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
import org.matrix.android.sdk.api.util.MatrixItem
import timber.log.Timber
@ -47,7 +48,7 @@ class CallService : VectorService() {
private val connections = mutableMapOf<String, CallConnection>()
private val knownCalls = mutableSetOf<CallInformation>()
private val ongoingCallIds = mutableSetOf<String>()
private val connectedCallIds = mutableSetOf<String>()
private lateinit var notificationManager: NotificationManagerCompat
private lateinit var notificationUtils: NotificationUtils
@ -204,15 +205,12 @@ class CallService : VectorService() {
mediaSession?.isActive = false
myStopSelf()
}
val wasOngoing = ongoingCallIds.remove(callId)
if (wasOngoing || isRejected) {
val notification = notificationUtils.buildCallEndedNotification()
val wasConnected = connectedCallIds.remove(callId)
if (wasConnected || terminatedCall.isOutgoing || isRejected) {
val notification = notificationUtils.buildCallEndedNotification(terminatedCall.isVideoCall)
notificationManager.notify(callId.hashCode(), notification)
} else {
val notification = notificationUtils.buildCallMissedNotification(
roomId = terminatedCall.nativeRoomId,
title = terminatedCall.matrixItem?.getBestName() ?: terminatedCall.opponentUserId
)
val notification = notificationUtils.buildCallMissedNotification(terminatedCall)
notificationManager.cancel(callId.hashCode())
notificationManager.notify(MISSED_CALL_TAG, terminatedCall.nativeRoomId.hashCode(), notification)
}
@ -252,7 +250,7 @@ class CallService : VectorService() {
private fun displayCallInProgressNotification(intent: Intent) {
Timber.v("## VOIP displayCallInProgressNotification")
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
ongoingCallIds.add(callId)
connectedCallIds.add(callId)
val call = callManager.getCallById(callId) ?: return Unit.also {
handleUnexpectedState(callId)
}
@ -277,7 +275,7 @@ class CallService : VectorService() {
if (callId != null) {
notificationManager.cancel(callId.hashCode())
}
val notification = notificationUtils.buildCallEndedNotification()
val notification = notificationUtils.buildCallEndedNotification(false)
startForeground(DEFAULT_NOTIFICATION_ID, notification)
if (knownCalls.isEmpty()) {
mediaSession?.isActive = false
@ -296,15 +294,19 @@ class CallService : VectorService() {
opponentUserId = this.mxCall.opponentUserId,
matrixItem = vectorComponent().activeSessionHolder().getSafeActiveSession()?.let {
this.getOpponentAsMatrixItem(it)
}
},
isVideoCall = this.mxCall.isVideoCall,
isOutgoing = this.mxCall.isOutgoing
)
}
private data class CallInformation(
data class CallInformation(
val callId: String,
val nativeRoomId: String,
val opponentUserId: String,
val matrixItem: MatrixItem?
val matrixItem: MatrixItem?,
val isVideoCall: Boolean,
val isOutgoing: Boolean,
)
companion object {

View file

@ -48,6 +48,7 @@ import androidx.fragment.app.Fragment
import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.services.CallService
import im.vector.app.core.utils.startNotificationChannelSettingsIntent
import im.vector.app.features.call.VectorCallActivity
import im.vector.app.features.call.service.CallHeadsUpActionReceiver
@ -298,12 +299,14 @@ class NotificationUtils @Inject constructor(private val context: Context,
.apply {
if (call.mxCall.isVideoCall) {
setContentText(stringProvider.getString(R.string.incoming_video_call))
setSmallIcon(R.drawable.ic_call_answer_video)
} else {
setContentText(stringProvider.getString(R.string.incoming_voice_call))
setSmallIcon(R.drawable.ic_call_answer)
}
}
.setSmallIcon(R.drawable.incoming_call_notification_transparent)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
.setLights(accentColor, 500, 500)
.setOngoing(true)
@ -339,8 +342,6 @@ class NotificationUtils @Inject constructor(private val context: Context,
builder.addAction(
NotificationCompat.Action(
R.drawable.ic_call_answer,
// IconCompat.createWithResource(applicationContext, R.drawable.ic_call)
// .setTint(ContextCompat.getColor(applicationContext, R.color.vctr_positive_accent)),
getActionText(R.string.call_notification_answer, R.attr.colorPrimary),
answerCallPendingIntent
)
@ -360,10 +361,15 @@ class NotificationUtils @Inject constructor(private val context: Context,
.setContentTitle(ensureTitleNotEmpty(title))
.apply {
setContentText(stringProvider.getString(R.string.call_ring))
if (call.mxCall.isVideoCall) {
setSmallIcon(R.drawable.ic_call_answer_video)
} else {
setSmallIcon(R.drawable.ic_call_answer)
}
}
.setSmallIcon(R.drawable.incoming_call_notification_transparent)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setLights(accentColor, 500, 500)
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
.setOngoing(true)
val contentIntent = VectorCallActivity.newIntent(
@ -407,11 +413,13 @@ class NotificationUtils @Inject constructor(private val context: Context,
.apply {
if (call.mxCall.isVideoCall) {
setContentText(stringProvider.getString(R.string.video_call_in_progress))
setSmallIcon(R.drawable.ic_call_answer_video)
} else {
setContentText(stringProvider.getString(R.string.call_in_progress))
setSmallIcon(R.drawable.ic_call_answer)
}
}
.setSmallIcon(R.drawable.incoming_call_notification_transparent)
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
.setCategory(NotificationCompat.CATEGORY_CALL)
val rejectCallPendingIntent = buildRejectCallPendingIntent(call.callId)
@ -450,11 +458,18 @@ class NotificationUtils @Inject constructor(private val context: Context,
/**
* Build a temporary (because service will be stopped just after) notification for the CallService, when a call is ended
*/
fun buildCallEndedNotification(): Notification {
fun buildCallEndedNotification(isVideoCall: Boolean): Notification {
return NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID)
.setContentTitle(stringProvider.getString(R.string.call_ended))
.apply {
if (isVideoCall) {
setSmallIcon(R.drawable.ic_call_answer_video)
} else {
setSmallIcon(R.drawable.ic_call_answer)
}
}
.setTimeoutAfter(2000)
.setSmallIcon(R.drawable.ic_material_call_end_grey)
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
.setCategory(NotificationCompat.CATEGORY_CALL)
.build()
}
@ -462,17 +477,26 @@ class NotificationUtils @Inject constructor(private val context: Context,
/**
* Build notification for the CallService, when a call is missed
*/
fun buildCallMissedNotification(roomId: String, title: String): Notification {
val builder = NotificationCompat.Builder(context, NOISY_NOTIFICATION_CHANNEL_ID)
.setContentTitle(title)
.setContentText(stringProvider.getString(R.string.call_missed))
.setSmallIcon(R.drawable.ic_material_call_end_grey)
fun buildCallMissedNotification(callInformation: CallService.CallInformation): Notification {
val builder = NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID)
.setContentTitle(callInformation.matrixItem?.getBestName() ?: callInformation.opponentUserId)
.apply {
if (callInformation.isVideoCall) {
setContentText(stringProvider.getString(R.string.missed_video_call))
setSmallIcon(R.drawable.ic_missed_video_call)
} else {
setContentText(stringProvider.getString(R.string.missed_audio_call))
setSmallIcon(R.drawable.ic_missed_voice_call)
}
}
.setShowWhen(true)
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
.setAutoCancel(true)
.setCategory(NotificationCompat.CATEGORY_CALL)
val contentPendingIntent = TaskStackBuilder.create(context)
.addNextIntentWithParentStack(HomeActivity.newIntent(context))
.addNextIntent(RoomDetailActivity.newIntent(context, RoomDetailArgs(roomId)))
.addNextIntent(RoomDetailActivity.newIntent(context, RoomDetailArgs(callInformation.nativeRoomId)))
.getPendingIntent(System.currentTimeMillis().toInt(), PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(contentPendingIntent)

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="16">
<path
android:pathData="M0,3.2273C0,1.6457 1.3432,0.3636 3,0.3636H14C15.6569,0.3636 17,1.6457 17,3.2273V12.7727C17,14.3543 15.6569,15.6364 14,15.6364H3C1.3431,15.6364 0,14.3543 0,12.7727V3.2273ZM19,5.1364L22.3753,2.5589C23.0301,2.0589 24,2.5038 24,3.3042V12.6958C24,13.4962 23.0301,13.9412 22.3753,13.4412L19,10.8637V5.1364ZM5.5288,8.8219C5.5288,9.2423 5.1848,9.5863 4.7644,9.5863C4.344,9.5863 4,9.2423 4,8.8219V5.7644C4,5.344 4.344,5 4.7644,5H7.8219C8.2423,5 8.5863,5.344 8.5863,5.7644C8.5863,6.1848 8.2423,6.5288 7.8219,6.5288H6.5989L9.3125,9.2423L13.0961,5.4586C13.3942,5.1605 13.8758,5.1605 14.1739,5.4586C14.472,5.7567 14.472,6.2383 14.1739,6.5364L9.8475,10.8628C9.5494,11.1609 9.0679,11.1609 8.7697,10.8628L5.5288,7.6218V8.8219Z"
android:fillColor="#737D8C"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,4 @@
<vector android:height="10.666667dp" android:viewportHeight="16"
android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#737D8C" android:fillType="evenOdd" android:pathData="M0,3.2273C0,1.6457 1.3432,0.3636 3,0.3636H14C15.6569,0.3636 17,1.6457 17,3.2273V12.7727C17,14.3543 15.6569,15.6364 14,15.6364H3C1.3431,15.6364 0,14.3543 0,12.7727V3.2273ZM19,5.1364L22.3753,2.5589C23.0301,2.0589 24,2.5038 24,3.3042V12.6958C24,13.4962 23.0301,13.9412 22.3753,13.4412L19,10.8637V5.1364ZM5.5288,8.8219C5.5288,9.2423 5.1848,9.5863 4.7644,9.5863C4.344,9.5863 4,9.2423 4,8.8219V5.7644C4,5.344 4.344,5 4.7644,5H7.8219C8.2423,5 8.5863,5.344 8.5863,5.7644C8.5863,6.1848 8.2423,6.5288 7.8219,6.5288H6.5989L9.3125,9.2423L13.0961,5.4586C13.3942,5.1605 13.8758,5.1605 14.1739,5.4586C14.472,5.7567 14.472,6.2383 14.1739,6.5364L9.8475,10.8628C9.5494,11.1609 9.0679,11.1609 8.7697,10.8628L5.5288,7.6218V8.8219Z"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,9C6.55,9 7,8.55 7,8V6.43L11.24,10.67C11.63,11.06 12.26,11.06 12.65,10.67L18.31,5.01C18.7,4.62 18.7,3.99 18.31,3.6C17.92,3.21 17.29,3.21 16.9,3.6L11.95,8.55L8.4,5H10C10.55,5 11,4.55 11,4C11,3.45 10.55,3 10,3H6C5.45,3 5,3.45 5,4V8C5,8.55 5.45,9 6,9Z"
android:fillColor="#818A98"/>
<path
android:pathData="M12.0084,13.0065C10.3211,12.9416 6.8514,13.3795 6.0078,13.6013C5.9579,13.6144 5.9004,13.6291 5.8362,13.6455C4.541,13.9761 0.4827,15.0118 0.0442,18.2936C-0.2955,20.8362 1.4058,21.6058 2.2562,21.4886C2.8448,21.4148 4.5301,21.1483 6.0872,20.8689C7.6163,20.5946 7.6155,19.5859 7.615,18.9038C7.615,18.8913 7.615,18.8788 7.615,18.8665L7.615,17.4953C7.615,17.1461 7.9432,16.9442 8.3958,16.8896C9.9982,16.672 11.3359,16.6713 12.0055,16.6713L12.0112,16.6713C12.6807,16.6713 14.0018,16.672 15.6042,16.8896C16.0569,16.9442 16.385,17.1461 16.385,17.4953L16.385,18.8665C16.385,18.8789 16.385,18.8913 16.385,18.9038C16.3845,19.5859 16.3837,20.5946 17.9128,20.869C19.4699,21.1483 21.1552,21.4148 21.7438,21.4886C22.5942,21.6058 24.2955,20.8362 23.9558,18.2936C23.5173,15.0118 19.459,13.9761 18.1638,13.6455C18.0996,13.6291 18.0421,13.6145 17.9922,13.6013C17.1487,13.3795 13.6956,12.9416 12.0084,13.0065Z"
android:fillColor="#818A98"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="16dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#818A98" android:pathData="M6,9C6.55,9 7,8.55 7,8V6.43L11.24,10.67C11.63,11.06 12.26,11.06 12.65,10.67L18.31,5.01C18.7,4.62 18.7,3.99 18.31,3.6C17.92,3.21 17.29,3.21 16.9,3.6L11.95,8.55L8.4,5H10C10.55,5 11,4.55 11,4C11,3.45 10.55,3 10,3H6C5.45,3 5,3.45 5,4V8C5,8.55 5.45,9 6,9Z"/>
<path android:fillColor="#818A98" android:pathData="M12.0084,13.0065C10.3211,12.9416 6.8514,13.3795 6.0078,13.6013C5.9579,13.6144 5.9004,13.6291 5.8362,13.6455C4.541,13.9761 0.4827,15.0118 0.0442,18.2936C-0.2955,20.8362 1.4058,21.6058 2.2562,21.4886C2.8448,21.4148 4.5301,21.1483 6.0872,20.8689C7.6163,20.5946 7.6155,19.5859 7.615,18.9038C7.615,18.8913 7.615,18.8788 7.615,18.8665L7.615,17.4953C7.615,17.1461 7.9432,16.9442 8.3958,16.8896C9.9982,16.672 11.3359,16.6713 12.0055,16.6713L12.0112,16.6713C12.6807,16.6713 14.0018,16.672 15.6042,16.8896C16.0569,16.9442 16.385,17.1461 16.385,17.4953L16.385,18.8665C16.385,18.8789 16.385,18.8913 16.385,18.9038C16.3845,19.5859 16.3837,20.5946 17.9128,20.869C19.4699,21.1483 21.1552,21.4148 21.7438,21.4886C22.5942,21.6058 24.2955,20.8362 23.9558,18.2936C23.5173,15.0118 19.459,13.9761 18.1638,13.6455C18.0996,13.6291 18.0421,13.6145 17.9922,13.6013C17.1487,13.3795 13.6956,12.9416 12.0084,13.0065Z"/>
</vector>

View file

@ -727,7 +727,8 @@
<string name="call_connected">Call connected</string>
<string name="call_connecting">Call connecting…</string>
<string name="call_ended">Call ended</string>
<string name="call_missed">Missed call</string>
<string name="missed_audio_call">Missed audio call</string>
<string name="missed_video_call">Missed video call</string>
<string name="call_ring">Calling…</string>
<string name="incoming_call">Incoming Call</string>
<string name="incoming_video_call">Incoming Video Call</string>