From 36d153150cd8276e86a74547aa7f98e60a909391 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 6 Apr 2026 16:38:32 +0000 Subject: [PATCH] fix: request microphone/camera permissions when accepting call from notification When accepting an incoming WebRTC call via the notification's Accept button, CallActivity now checks for RECORD_AUDIO and CAMERA permissions before proceeding. If permissions are missing, the system permission dialog is shown and the call is accepted only after permissions are granted. This prevents the crash that occurred when accepting calls from the notification without prior permission grants. https://claude.ai/code/session_0193KQShzBh4puYh74dHgSbE --- .../amethyst/ui/call/CallActivity.kt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) 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 7e1e291e1..a82a2ce6d 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 @@ -33,6 +33,7 @@ import android.os.Bundle import android.util.Rational import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.lifecycleScope @@ -55,6 +56,16 @@ class CallActivity : AppCompatActivity() { // "user swiped PiP away" from "user pressed Home from full-screen call". private var wasInPipMode = false + // Launcher for requesting call permissions when accepting from notification + private val permissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { results -> + if (hasCallPermissions(this, isVideo = pendingAcceptIsVideo)) { + acceptCall() + } + } + + private var pendingAcceptIsVideo = false + private val pipActionReceiver = object : BroadcastReceiver() { @OptIn(DelicateCoroutinesApi::class) @@ -142,6 +153,21 @@ class CallActivity : AppCompatActivity() { com.vitorpamplona.amethyst.service.notifications.NotificationUtils .cancelCallNotification(this) + val callManager = ActiveCallHolder.callManager ?: return + val state = callManager.state.value + if (state !is CallState.IncomingCall) return + + val isVideo = state.callType == com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallType.VIDEO + pendingAcceptIsVideo = isVideo + + if (hasCallPermissions(this, isVideo)) { + acceptCall() + } else { + permissionLauncher.launch(buildCallPermissions(isVideo)) + } + } + + private fun acceptCall() { val callController = ActiveCallHolder.callController ?: return val callManager = ActiveCallHolder.callManager ?: return val state = callManager.state.value