diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt index 8df8478cb..9ac561e48 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt @@ -46,6 +46,10 @@ import kotlinx.coroutines.launch class CallActivity : AppCompatActivity() { val isInPipMode = mutableStateOf(false) + // Tracks whether we entered PiP at least once, so we can distinguish + // "user swiped PiP away" from "user pressed Home from full-screen call". + private var wasInPipMode = false + private val pipActionReceiver = object : BroadcastReceiver() { @OptIn(DelicateCoroutinesApi::class) @@ -112,26 +116,24 @@ class CallActivity : AppCompatActivity() { enterPipIfActive() } - @OptIn(DelicateCoroutinesApi::class) override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) { super.onPictureInPictureModeChanged(isInPictureInPictureMode) isInPipMode.value = isInPictureInPictureMode - if (!isInPictureInPictureMode) { - // User pressed the X button on PiP or expanded it. - // If the activity is finishing (user dismissed PiP), hang up. - if (isFinishing) { - GlobalScope.launch { ActiveCallHolder.callManager?.hangup() } - } + if (isInPictureInPictureMode) { + wasInPipMode = true } } @OptIn(DelicateCoroutinesApi::class) override fun onStop() { super.onStop() - // When PiP is dismissed (X button), Android stops the activity. - // If we're not in PiP anymore and the activity is stopping, hang up and finish. - if (!isInPictureInPictureMode) { + // Only hang up if the user dismissed PiP (swiped it away). + // When PiP is dismissed, Android calls onStop with isInPictureInPictureMode == false + // after the activity was previously in PiP mode. + // We must NOT hang up when the user simply presses Home from the full-screen + // call UI (that enters PiP via onUserLeaveHint instead). + if (wasInPipMode && !isInPictureInPictureMode) { val state = ActiveCallHolder.callManager?.state?.value if (state is CallState.Connected || state is CallState.Connecting || state is CallState.Offering) { GlobalScope.launch { ActiveCallHolder.callManager?.hangup() } @@ -140,17 +142,8 @@ class CallActivity : AppCompatActivity() { } } - @OptIn(DelicateCoroutinesApi::class) override fun onDestroy() { unregisterPipReceiver() - - // If the activity is being destroyed while still in an active call - // (e.g. user swiped PiP away), hang up the call. - val state = ActiveCallHolder.callManager?.state?.value - if (state is CallState.Connected || state is CallState.Connecting || state is CallState.Offering) { - GlobalScope.launch { ActiveCallHolder.callManager?.hangup() } - } - super.onDestroy() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallNotificationReceiver.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallNotificationReceiver.kt index 1c4f62425..ac6f7e1ca 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallNotificationReceiver.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallNotificationReceiver.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.call import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import com.vitorpamplona.amethyst.commons.call.CallState import com.vitorpamplona.amethyst.service.notifications.NotificationUtils import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope @@ -36,22 +37,26 @@ class CallNotificationReceiver : BroadcastReceiver() { ) { when (intent.action) { ACTION_ACCEPT_CALL -> { + NotificationUtils.cancelCallNotification(context) + val callController = ActiveCallHolder.callController val callManager = ActiveCallHolder.callManager - val state = callManager?.state?.value - if (state is com.vitorpamplona.amethyst.commons.call.CallState.IncomingCall) { - callController?.acceptIncomingCall(state.sdpOffer) + if (callController == null || callManager == null) return + + val state = callManager.state.value + if (state is CallState.IncomingCall) { + callController.acceptIncomingCall(state.sdpOffer) + CallActivity.launch(context) } - NotificationUtils.cancelCallNotification(context) - CallActivity.launch(context) } ACTION_REJECT_CALL -> { - val callManager = ActiveCallHolder.callManager - GlobalScope.launch { - callManager?.rejectCall() - } NotificationUtils.cancelCallNotification(context) + + val callManager = ActiveCallHolder.callManager ?: return + GlobalScope.launch { + callManager.rejectCall() + } } } }