From 724fd1040566dedb508615145b14812659e82fd7 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Apr 2026 20:47:56 +0000 Subject: [PATCH] feat: full-screen incoming call UI over lock screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable proper full-screen call experience when the phone is locked or the app is in the background: - CallActivity shows over lock screen (setShowWhenLocked/turnScreenOn) - Manifest adds showOnLockScreen and turnScreenOn attributes - Remove setSilent(true) from notification — it was blocking the full-screen intent from triggering (channel silence is enough) - Populate ActiveCallHolder eagerly in initCallController() so the full-screen intent can launch CallActivity even when the Compose UI is paused in the background https://claude.ai/code/session_01Ak5tTkujpjNG1r5ASuPipZ --- amethyst/src/main/AndroidManifest.xml | 2 ++ .../service/notifications/NotificationUtils.kt | 1 - .../vitorpamplona/amethyst/ui/call/CallActivity.kt | 12 ++++++++++++ .../amethyst/ui/screen/loggedIn/AccountViewModel.kt | 5 +++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/AndroidManifest.xml b/amethyst/src/main/AndroidManifest.xml index 2e748720d..d03cf083a 100644 --- a/amethyst/src/main/AndroidManifest.xml +++ b/amethyst/src/main/AndroidManifest.xml @@ -213,6 +213,8 @@ android:launchMode="singleTop" android:exported="false" android:resizeableActivity="true" + android:showOnLockScreen="true" + android:turnScreenOn="true" android:theme="@style/Theme.Amethyst" /> diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt index 0fb7094ea..3f92bd0ca 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt @@ -602,7 +602,6 @@ object NotificationUtils { .setOngoing(true) .setTimeoutAfter(60_000) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setSilent(true) .addAction(R.drawable.amethyst, stringRes(applicationContext, R.string.call_reject), rejectPendingIntent) .addAction(R.drawable.amethyst, stringRes(applicationContext, R.string.call_accept), acceptPendingIntent) 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 c94a32329..8df8478cb 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 @@ -70,6 +70,18 @@ class CallActivity : AppCompatActivity() { enableEdgeToEdge() super.onCreate(savedInstanceState) + // Show over lock screen and turn screen on for incoming calls + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + setShowWhenLocked(true) + setTurnScreenOn(true) + } else { + @Suppress("DEPRECATION") + window.addFlags( + android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or + android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, + ) + } + val callManager = ActiveCallHolder.callManager val callController = ActiveCallHolder.callController val accountViewModel = ActiveCallHolder.accountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 70818f512..07d432511 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -224,6 +224,11 @@ class AccountViewModel( callManager.onAnswerReceived = { event -> controller.onCallAnswerReceived(event.sdpAnswer()) } callManager.onIceCandidateReceived = { event -> controller.onIceCandidateReceived(event) } callController = controller + + // Populate ActiveCallHolder so CallActivity can launch even when the app + // is in the background (e.g. full-screen incoming call intent). + com.vitorpamplona.amethyst.ui.call.ActiveCallHolder + .set(callManager, controller, this) } val eventSync =