Skip to content

Commit

Permalink
fix: crash when starting foreground service for calling from backgrou…
Browse files Browse the repository at this point in the history
…nd (WPB-11112) 🍒 (#3459)

Co-authored-by: Oussama Hassine <[email protected]>
  • Loading branch information
github-actions[bot] and ohassine authored Sep 24, 2024
1 parent f850b2e commit d7c8bc9
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 268 deletions.
24 changes: 12 additions & 12 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@
android:theme="@style/AppTheme" />

<activity
android:name=".ui.WireActivity"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.SplashScreen"
android:windowSoftInputMode="adjustResize|stateHidden">
android:name=".ui.WireActivity"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.SplashScreen"
android:windowSoftInputMode="adjustResize|stateHidden">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down Expand Up @@ -149,12 +149,12 @@
android:scheme="wire" />

<data
android:host="conversation"
android:scheme="wire" />
android:host="conversation"
android:scheme="wire" />

<data
android:host="user"
android:scheme="wire" />
android:host="user"
android:scheme="wire" />

<data
android:host="other-user-profile"
Expand Down Expand Up @@ -351,7 +351,7 @@
android:foregroundServiceType="specialUse" />

<service
android:name=".services.OngoingCallService"
android:name=".services.CallService"
android:exported="false"
android:foregroundServiceType="phoneCall|microphone" />
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.wire.android.R
import com.wire.android.appLogger
import com.wire.android.util.dispatchers.DispatcherProvider
import com.wire.kalium.logic.data.call.Call
import com.wire.kalium.logic.data.call.CallStatus
import com.wire.kalium.logic.data.conversation.Conversation
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.id.QualifiedID
Expand Down Expand Up @@ -62,7 +63,6 @@ class CallNotificationManager @Inject constructor(
private val notificationManager = NotificationManagerCompat.from(context)
private val scope = CoroutineScope(SupervisorJob() + dispatcherProvider.default())
private val incomingCallsForUsers = MutableStateFlow<Map<UserId, Call>>(mapOf())
private val outgoingCallForUsers = MutableStateFlow<Map<UserId, Call>>(mapOf())
private val reloadCallNotification = MutableSharedFlow<CallNotificationIds>()

init {
Expand All @@ -81,25 +81,6 @@ class CallNotificationManager @Inject constructor(
}
}
}
scope.launch {
outgoingCallForUsers
.map { it.entries.firstOrNull()?.toCallNotificationData() }
.distinctUntilChanged()
.reloadIfNeeded()
.collectLatest { outgoingCallData ->
if (outgoingCallData == null) {
hideOutgoingCallNotification()
} else {
appLogger.i("$TAG: showing outgoing call")
showOutgoingCallNotification(
outgoingCallData.copy(
conversationName = outgoingCallData.conversationName
?: context.getString(R.string.username_unavailable_label)
)
)
}
}
}
}

fun reloadIfNeeded(data: CallNotificationData): Flow<CallNotificationData> = reloadCallNotification
Expand All @@ -126,14 +107,6 @@ class CallNotificationManager @Inject constructor(
}
}

fun handleOutgoingCallNotifications(calls: List<Call>, userId: UserId) {
if (calls.isEmpty()) {
outgoingCallForUsers.update { it.filter { it.key != userId } }
} else {
outgoingCallForUsers.update { it.filter { it.key != userId } + (userId to calls.first()) }
}
}

fun hideAllNotifications() {
hideIncomingCallNotification()
}
Expand All @@ -149,11 +122,6 @@ class CallNotificationManager @Inject constructor(
notificationManager.cancel(NotificationIds.CALL_INCOMING_NOTIFICATION_ID.ordinal)
}

private fun hideOutgoingCallNotification() {
appLogger.i("$TAG: hiding outgoing call")
notificationManager.cancel(NotificationIds.CALL_OUTGOING_NOTIFICATION_ID.ordinal)
}

@SuppressLint("MissingPermission")
@VisibleForTesting
internal fun showIncomingCallNotification(data: CallNotificationData) {
Expand All @@ -165,17 +133,6 @@ class CallNotificationManager @Inject constructor(
)
}

@SuppressLint("MissingPermission")
@VisibleForTesting
internal fun showOutgoingCallNotification(data: CallNotificationData) {
appLogger.i("$TAG: showing outgoing call notification for user ${data.userId.toLogString()}")
val notification = builder.getOutgoingCallNotification(data)
notificationManager.notify(
NotificationIds.CALL_OUTGOING_NOTIFICATION_ID.ordinal,
notification
)
}

// Notifications

companion object {
Expand All @@ -199,7 +156,7 @@ class CallNotificationBuilder @Inject constructor(
fun getOutgoingCallNotification(data: CallNotificationData): Notification {
val userIdString = data.userId.toString()
val conversationIdString = data.conversationId.toString()
val channelId = NotificationConstants.getIncomingChannelId(data.userId)
val channelId = NotificationConstants.getOutgoingChannelId(data.userId)

return NotificationCompat.Builder(context, channelId)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
Expand Down Expand Up @@ -263,6 +220,7 @@ class CallNotificationBuilder @Inject constructor(
.setSmallIcon(R.drawable.notification_icon_small)
.setAutoCancel(true)
.setOngoing(true)
.setUsesChronometer(true)
.addAction(getHangUpCallAction(context, conversationIdString, userIdString))
.addAction(getOpenOngoingCallAction(context, conversationIdString))
.setFullScreenIntent(openOngoingCallPendingIntent(context, conversationIdString), true)
Expand All @@ -272,15 +230,15 @@ class CallNotificationBuilder @Inject constructor(
}

/**
* @return placeholder Notification for OngoingCall, that can be shown immediately after starting the Service
* @return placeholder Notification for CallService, that can be shown immediately after starting the Service
* (e.g. in [android.app.Service.onCreate]). It has no any [NotificationCompat.Action], on click - just opens the app.
* This notification should be replace by the user-specific notification (with corresponding [NotificationCompat.Action],
* [android.content.Intent] and title) once it's possible (e.g. in [android.app.Service.onStartCommand])
*/
fun getOngoingCallPlaceholderNotification(): Notification {
fun getCallServicePlaceholderNotification(): Notification {
val channelId = NotificationConstants.ONGOING_CALL_CHANNEL_ID
return NotificationCompat.Builder(context, channelId)
.setContentText(context.getString(R.string.notification_ongoing_call_content))
.setContentText(context.getString(R.string.notification_outgoing_call_tap_to_return))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
Expand Down Expand Up @@ -326,6 +284,7 @@ data class CallNotificationData(
val conversationType: Conversation.Type,
val callerName: String?,
val callerTeamName: String?,
val callStatus: CallStatus
) {
constructor(userId: UserId, call: Call) : this(
userId,
Expand All @@ -334,6 +293,7 @@ data class CallNotificationData(
call.conversationType,
call.callerName,
call.callerTeamName,
call.status
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ object NotificationConstants {
// Notification IDs (has to be unique!)
enum class NotificationIds {
CALL_INCOMING_NOTIFICATION_ID,
CALL_OUTGOING_NOTIFICATION_ID,
CALL_ONGOING_NOTIFICATION_ID,
CALL_OUTGOING_ONGOING_NOTIFICATION_ID,
PERSISTENT_NOTIFICATION_ID,
MESSAGE_SYNC_NOTIFICATION_ID,
MIGRATION_NOTIFICATION_ID,
Expand Down
Loading

0 comments on commit d7c8bc9

Please sign in to comment.