From 0841a0a33f7970f7af4ecbd469e829d70b7d14c6 Mon Sep 17 00:00:00 2001 From: KaraZajac Date: Thu, 7 May 2026 23:24:56 -0400 Subject: [PATCH] =?UTF-8?q?v0.3.0=20=E2=80=94=20floating=20threat-circle?= =?UTF-8?q?=20overlay=20(chat-bubble=20style)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A 140dp draggable bubble shows the same map / tier scrim / user dot / ALPR dots that the in-app circle does, on top of any other app, while scanning is on. Tap = brings the host app forward; drag = repositions. - Manifest: add SYSTEM_ALERT_WINDOW (special-access — granted via system Settings page, not the runtime prompt). - Settings: add overlayEnabled flag (default off) + a "Display over other apps" section in SettingsScreen. Flipping the toggle to on fires Settings.ACTION_MANAGE_OVERLAY_PERMISSION so the user can grant via the system page; if they deny or revoke, the OverlayMgr re-checks canDrawOverlays() at every show() call and silently no-ops, no crash. - New OverlayManager: owns the WindowManager view at TYPE_APPLICATION_OVERLAY with FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL so touches outside the bubble pass through and the bubble never steals IME focus. Custom OverlayOwner implementing LifecycleOwner + SavedStateRegistryOwner since LifecycleService doesn't satisfy SSR (Compose's ComposeView requires both via the view tree). - Drag/tap handler at the View layer: rawX/rawY math for the drag, TAP_SLOP_PX guard to discriminate tap from drag, tap launches MainActivity (FLAG_ACTIVITY_NEW_TASK | SINGLE_TOP). - New OverlayBubble composable: smaller (140dp) self-contained version of the in-app threat circle that pulls running/threat/location/ mapPoints/proximity from the same companion StateFlows. Shared dot-drawable helper extracted into ui/MarkerIcons.kt. - DetectionService observes settings.overlayEnabled in beginScanning and toggles the overlay; endScanning hides it. --- app/build.gradle.kts | 4 +- app/src/main/AndroidManifest.xml | 6 + .../overwatch/data/settings/Settings.kt | 9 + .../overwatch/service/DetectionService.kt | 15 ++ .../overwatch/service/OverlayManager.kt | 193 ++++++++++++++++++ .../org/soulstone/overwatch/ui/MainScreen.kt | 28 +-- .../org/soulstone/overwatch/ui/MarkerIcons.kt | 29 +++ .../soulstone/overwatch/ui/OverlayBubble.kt | 163 +++++++++++++++ .../soulstone/overwatch/ui/SettingsScreen.kt | 32 +++ 9 files changed, 451 insertions(+), 28 deletions(-) create mode 100644 app/src/main/kotlin/org/soulstone/overwatch/service/OverlayManager.kt create mode 100644 app/src/main/kotlin/org/soulstone/overwatch/ui/MarkerIcons.kt create mode 100644 app/src/main/kotlin/org/soulstone/overwatch/ui/OverlayBubble.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 21ee91d..e7ff756 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "org.soulstone.overwatch" minSdk = 26 targetSdk = 35 - versionCode = 11 - versionName = "0.2.2" + versionCode = 12 + versionName = "0.3.0" } buildTypes { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0268574..6f20a16 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,12 @@ + + +