README: bring up to date with v0.1.7
Stale items corrected: - Architecture file list referenced WazeClient.kt and WazeScanner.kt (deleted) and CDN-tile DeflockClient (now Overpass POST). Added the missing CitizenClient/CitizenScanner/SourceHealth/ThreatLevel files. - Permissions table said "DeFlock CDN + Waze API" — now Overpass + Citizen. Added VIBRATE row. - Settings section listed Waze instead of Citizen; missing the new Vibrate-on-escalation toggle and Restart-to-apply button. - Status said "Phases 1-5 complete as of v0.1.0" — bumped to v0.1.7 with a per-version changelog of what landed. Added: - Hero paragraph mentions notification + vibration alerting. - New "How alerts work" section explaining notification updates, vibration cadence, drill-down sheet, and Open-in-Maps. - Idle-visual note in scoring section. - START_NOT_STICKY note in architecture. - Open-app-settings recovery note in permissions section.
This commit is contained in:
@@ -4,27 +4,31 @@
|
|||||||
A native Android (Kotlin) **passive surveillance-detection** app. Open it, hit
|
A native Android (Kotlin) **passive surveillance-detection** app. Open it, hit
|
||||||
**START**, and a circle turns **green / yellow / orange / red** depending on
|
**START**, and a circle turns **green / yellow / orange / red** depending on
|
||||||
how confident the engine is that there's a Flock Safety ALPR, an Axon body
|
how confident the engine is that there's a Flock Safety ALPR, an Axon body
|
||||||
camera, or police presence near you.
|
camera, or active police presence near you. With the screen locked, the
|
||||||
|
foreground notification updates with the current tier and the phone vibrates
|
||||||
|
on upward escalations — you don't have to be looking at the screen.
|
||||||
|
|
||||||
> **Passive defense only.** OVERWATCH only listens — it does not transmit,
|
> **Passive defense only.** OVERWATCH only listens — it does not transmit,
|
||||||
> probe, jam, or interfere with any device or network. The Axon
|
> probe, jam, or interfere with any device or network. The Axon
|
||||||
> advertise/fuzz code from one of the reference projects is intentionally
|
> advertise/fuzz code from one of the reference projects is intentionally
|
||||||
> excluded.
|
> excluded.
|
||||||
|
|
||||||
|
Latest release: [v0.1.7](https://github.com/KaraZajac/OVERWATCH/releases) (debug-signed APK, sideload).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## What it detects
|
## What it detects
|
||||||
|
|
||||||
| Source | What it looks at | Where it comes from |
|
| Source | What it looks at | Where it comes from |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **BLE** | Bluetooth-LE advertisements: vendor MAC OUIs (Axon, Flock Penguin / Raven, XUNTONG mfg id `0x09C8`, "TN" serial pattern), Raven service UUIDs, device-name patterns | Local radio scan (BLE callback API) |
|
| **BLE** | Bluetooth-LE advertisements: vendor MAC OUIs (Axon, Flock Penguin / Raven, XUNTONG mfg id `0x09C8`, "TN" serial pattern), Raven service UUIDs, device-name patterns | Local radio scan (BLE callback API). Iterates every manufacturer-specific data entry to find XUNTONG, not just the first. |
|
||||||
| **WiFi** | BSSID OUI prefixes for Flock infrastructure (31-prefix superset), `Flock-XXXX` and other generic SSID patterns | `WifiManager.getScanResults()` polled every 35 s (just under the Android 11+ 4-scans/2-min throttle) |
|
| **WiFi** | BSSID OUI prefixes for Flock infrastructure (31-prefix superset), `Flock-XXXX` and other generic SSID patterns | `WifiManager.getScanResults()` polled every 35 s (just under the Android 11+ 4-scans/2-min throttle) |
|
||||||
| **DEFLOCK** | Crowdsourced ALPR locations within configurable proximity (default 200 m) | POST to Overpass API (`overpass.deflock.org` → fallback `overpass-api.de`) for `man_made=surveillance + surveillance:type=ALPR` in a 5 km bbox; 24 h on-disk cache by 0.05° grid cell. Refetches when the user moves > 1.5 km from the last fetch center. |
|
| **DEFLOCK** | Crowdsourced ALPR locations within configurable proximity (default 200 m) | POST to Overpass API (`overpass.deflock.org` → fallback `overpass-api.de`) for `man_made=surveillance + surveillance:type=ALPR` in a 5 km bbox; 24 h on-disk cache by 0.05° grid cell. Refetches when the user moves > 1.5 km from the last fetch center. Backoffs after Overpass failures; treats `{"remark": "...timed out..."}` 200-responses as failure so timeouts don't poison the cache. |
|
||||||
| **CITIZEN** | Real-time public-safety incidents (police-relevant only — fire/medical-only events filtered out) within configurable proximity, < 30 min old | `citizen.com/api/incident/trending` (bbox) polled every 60 s, then per-incident detail via `/api/incident/{id}` with an in-memory cache so each incident is fetched once per session. |
|
| **CITIZEN** | Real-time public-safety incidents (police-relevant only — fire/medical-only events filtered out) within configurable proximity, < 30 min old | `citizen.com/api/incident/trending` (bbox) polled every 60 s, then per-incident detail via `/api/incident/{id}` with an in-memory cache so each incident is fetched once per session. First poll fires immediately on the first location fix. |
|
||||||
|
|
||||||
> **Why no Waze?** Waze added reCAPTCHA gating to its `live-map/api/georss` endpoint in 2025/2026. Mobile clients receive HTTP 403, and the only known workarounds (Selenium proxy on a home server, Waze for Cities partner program) aren't viable for a phone-deployed app. Citizen replaces it.
|
> **Why no Waze?** Waze added reCAPTCHA gating to its `live-map/api/georss` endpoint in 2025/2026. Mobile clients receive HTTP 403, and the only known workarounds (Selenium proxy on a home server, Waze for Cities partner program) aren't viable for a phone-deployed app. Citizen replaces it as the police-presence source.
|
||||||
|
|
||||||
Every observation is scored 0-100 by `ConfidenceEngine`. The on-screen tier is
|
Every observation is scored 0–100 by `ConfidenceEngine`. The on-screen tier is
|
||||||
the maximum live score across all sources:
|
the maximum live score across all sources:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -36,32 +40,55 @@ RED 85 + certain
|
|||||||
|
|
||||||
The user-facing circle uses the full 4-tier mapping. Cross-source corroboration
|
The user-facing circle uses the full 4-tier mapping. Cross-source corroboration
|
||||||
naturally pushes the global max upward (a BLE OUI hit *and* a DeFlock map
|
naturally pushes the global max upward (a BLE OUI hit *and* a DeFlock map
|
||||||
match in the same area produce a higher tier than either alone).
|
match in the same area produce a higher tier than either alone). When idle,
|
||||||
|
the circle shows muted gray with `IDLE` text so it's distinguishable at a
|
||||||
|
glance from "scanning, all clear."
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How alerts work
|
||||||
|
|
||||||
|
- **In-app**: the threat circle pulses while scanning; tap it to open the
|
||||||
|
bottom-sheet drill-down with per-source rows. DEFLOCK and CITIZEN events
|
||||||
|
carry coordinates — each row has a tap-to-open Maps icon (`geo:` intent).
|
||||||
|
- **Foreground notification**: rebuilt on every threat-tier change. Title
|
||||||
|
becomes `OVERWATCH • RED` (or whatever tier); text shows the top
|
||||||
|
detection's score + label. Notification priority bumps to HIGH on RED so
|
||||||
|
the system can surface it as a heads-up.
|
||||||
|
- **Vibration**: on upward tier transitions only. Short pulse for YELLOW,
|
||||||
|
double for ORANGE, escalating triple for RED. Toggle in Settings → Alerts.
|
||||||
|
- **Per-source health**: the drill-down sheet shows orange `Source unreachable`
|
||||||
|
text on a row when its scanner couldn't reach its data source — silent
|
||||||
|
empty results vs. real failures are distinguishable.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
ui/MainScreen.kt circle + START/STOP + tap-to-open bottom sheet
|
ui/MainScreen.kt circle + START/STOP + tap-to-open bottom sheet
|
||||||
ui/SettingsScreen.kt per-source toggles, distance sliders, theme
|
ui/SettingsScreen.kt source toggles, distance sliders, vibrate, theme
|
||||||
service/DetectionService.kt foreground service — owns scanners + store
|
ui/theme/Theme.kt Material 3 dark/light + threat colors
|
||||||
scan/BleScanner.kt BLE callback scanner
|
service/DetectionService.kt foreground service — owns scanners, notification, vibration
|
||||||
scan/WifiScanner.kt WifiManager poller + SCAN_RESULTS receiver
|
scan/BleScanner.kt BLE callback scanner
|
||||||
scan/DeflockClient.kt CDN tile fetch + 24h cache
|
scan/WifiScanner.kt WifiManager poller + SCAN_RESULTS receiver
|
||||||
scan/DeflockScanner.kt location-driven proximity check
|
scan/DeflockClient.kt Overpass POST (deflock.org → overpass-api.de) + 24h cache
|
||||||
scan/WazeClient.kt live-map/api/georss bbox fetch
|
scan/DeflockScanner.kt location-driven proximity check + failure backoff
|
||||||
scan/WazeScanner.kt 60s poller + age/distance gate
|
scan/CitizenClient.kt GET /api/incident/trending + /api/incident/{id}
|
||||||
fusion/ConfidenceEngine.kt scoring (one place)
|
scan/CitizenScanner.kt 60 s poller, fire/medical filter, per-id cache
|
||||||
fusion/RssiTracker.kt rise-peak-fall stationary-signal detector
|
fusion/ConfidenceEngine.kt scoring (one place — BLE / WiFi / DeFlock / Citizen)
|
||||||
fusion/DetectionStore.kt in-memory dedup, 5-min retention
|
fusion/RssiTracker.kt rise-peak-fall stationary-signal detector
|
||||||
|
fusion/DetectionStore.kt in-memory dedup, 5-min retention, max-tier flow
|
||||||
|
fusion/SourceHealth.kt per-source OK/FAILED registry for the drill-down
|
||||||
|
fusion/ThreatLevel.kt 4-tier enum + DetectionSource enum
|
||||||
data/location/LocationProvider.kt FusedLocationProviderClient wrapper
|
data/location/LocationProvider.kt FusedLocationProviderClient wrapper
|
||||||
data/settings/Settings.kt SharedPreferences-backed StateFlow settings
|
data/settings/Settings.kt SharedPreferences-backed StateFlow settings
|
||||||
data/targets/ BleOuis, WifiOuis, RavenUuids, Patterns, Manufacturers
|
data/targets/ BleOuis, WifiOuis, RavenUuids, Patterns, Manufacturers
|
||||||
```
|
```
|
||||||
|
|
||||||
No detection-history database. All state is in-memory and clears on stop, by
|
No detection-history database. All state is in-memory and clears on stop, by
|
||||||
design.
|
design. Service uses `START_NOT_STICKY` — system kill doesn't auto-restart
|
||||||
|
into a stuck state.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -83,7 +110,7 @@ export JAVA_HOME=/usr/local/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home
|
|||||||
./gradlew :app:installDebug
|
./gradlew :app:installDebug
|
||||||
```
|
```
|
||||||
|
|
||||||
Or download the latest signed APK from
|
Or download the latest debug-signed APK from
|
||||||
[Releases](https://github.com/KaraZajac/OVERWATCH/releases).
|
[Releases](https://github.com/KaraZajac/OVERWATCH/releases).
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -94,14 +121,18 @@ Or download the latest signed APK from
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `BLUETOOTH_SCAN`, `BLUETOOTH_CONNECT` (API 31+) | BLE scanning |
|
| `BLUETOOTH_SCAN`, `BLUETOOTH_CONNECT` (API 31+) | BLE scanning |
|
||||||
| `BLUETOOTH`, `BLUETOOTH_ADMIN` (≤ API 30) | BLE scanning, legacy |
|
| `BLUETOOTH`, `BLUETOOTH_ADMIN` (≤ API 30) | BLE scanning, legacy |
|
||||||
| `ACCESS_FINE_LOCATION` | Required for BLE pre-S, WiFi pre-T, and DeFlock proximity |
|
| `ACCESS_FINE_LOCATION` | Required for BLE pre-S, WiFi pre-T, and DeFlock/Citizen proximity |
|
||||||
| `NEARBY_WIFI_DEVICES` (API 33+) | WiFi scan results without using location |
|
| `NEARBY_WIFI_DEVICES` (API 33+) | WiFi scan results without using location |
|
||||||
| `ACCESS_WIFI_STATE`, `CHANGE_WIFI_STATE` | Trigger and read scan results |
|
| `ACCESS_WIFI_STATE`, `CHANGE_WIFI_STATE` | Trigger and read scan results |
|
||||||
| `INTERNET`, `ACCESS_NETWORK_STATE` | DeFlock CDN + Waze API |
|
| `INTERNET`, `ACCESS_NETWORK_STATE` | DeFlock Overpass + Citizen API |
|
||||||
| `FOREGROUND_SERVICE`, `FOREGROUND_SERVICE_CONNECTED_DEVICE`, `FOREGROUND_SERVICE_LOCATION` | Keep scanning with the screen off |
|
| `FOREGROUND_SERVICE`, `FOREGROUND_SERVICE_CONNECTED_DEVICE`, `FOREGROUND_SERVICE_LOCATION` | Keep scanning with the screen off |
|
||||||
| `POST_NOTIFICATIONS` (API 33+) | Foreground-service notification |
|
| `POST_NOTIFICATIONS` (API 33+) | Foreground-service notification |
|
||||||
|
| `VIBRATE` | Haptic alert on threat-tier escalation |
|
||||||
|
|
||||||
Requested at runtime when you press START for the first time.
|
Requested at runtime when you press START for the first time. If you
|
||||||
|
permanently deny a required permission ("don't ask again"), the START button
|
||||||
|
swaps to **Open app settings** which fires the per-app system-settings page
|
||||||
|
so you can grant manually.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -109,11 +140,14 @@ Requested at runtime when you press START for the first time.
|
|||||||
|
|
||||||
Tap the gear icon in the top-right.
|
Tap the gear icon in the top-right.
|
||||||
|
|
||||||
- **Detection sources**: toggle BLE / WiFi / DeFlock / Waze independently. Takes
|
- **Detection sources**: toggle BLE / WiFi / DeFlock / Citizen independently.
|
||||||
effect on next Start.
|
Changes take effect on the next Start. While scanning, a **Restart scan to
|
||||||
- **Proximity thresholds**:
|
apply** button appears that does `stop()` + `start()` in one tap.
|
||||||
|
- **Proximity thresholds** (sliders commit on release, not per-pixel):
|
||||||
- DeFlock: 50 m – 1600 m (default 200 m)
|
- DeFlock: 50 m – 1600 m (default 200 m)
|
||||||
- Waze: 100 m – 5000 m (default 500 m)
|
- Citizen: 100 m – 5000 m (default 500 m)
|
||||||
|
- **Alerts**:
|
||||||
|
- Vibrate on threat escalation (default on)
|
||||||
- **Appearance**: System / Dark / Light (default Dark)
|
- **Appearance**: System / Dark / Light (default Dark)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -125,15 +159,23 @@ These live under `REFERENCES/` (gitignored):
|
|||||||
- **AxonCadabra** — BLE scanner skeleton (scan side only; advertise/fuzz code excluded)
|
- **AxonCadabra** — BLE scanner skeleton (scan side only; advertise/fuzz code excluded)
|
||||||
- **flock-detection** — confidence-scoring algorithm (highest reusability), RSSI rise-peak-fall, OUIs + UUIDs + patterns
|
- **flock-detection** — confidence-scoring algorithm (highest reusability), RSSI rise-peak-fall, OUIs + UUIDs + patterns
|
||||||
- **flock-you** — 31-OUI WiFi superset (promiscuous-mode tricks not portable to Android)
|
- **flock-you** — 31-OUI WiFi superset (promiscuous-mode tricks not portable to Android)
|
||||||
- **deflock** + **deflock-app** — CDN tile scheme, proximity-alert pattern
|
- **deflock** + **deflock-app** — Overpass query format + proximity-alert pattern (the Flutter app uses Overpass directly, not the CDN tiles, which the OVERWATCH client mirrors)
|
||||||
- **wazepolice** — live-map/api/georss recipe, Chrome header spoofing
|
- **wazepolice** — live-map/api/georss recipe; informed v0.1.0–v0.1.5 Waze integration that has since been removed (endpoint is reCAPTCHA-gated)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Phases 1–5 (skeleton, BLE, WiFi, DeFlock, Waze, polish) complete as of v0.1.0.
|
Phases 1–5 (skeleton, BLE, WiFi, DeFlock, Citizen, polish) complete and
|
||||||
Field-test-ready, not yet field-validated.
|
field-tested. Current release **v0.1.7** addresses two full audit passes
|
||||||
|
(see release notes for v0.1.2, v0.1.3, v0.1.6). Notable changes since v0.1.0:
|
||||||
|
|
||||||
|
- v0.1.2 — Android 14+ foreground service type fix (location was being silently revoked); NaN-coordinate filter on map data.
|
||||||
|
- v0.1.3 — DeFlock CDN replaced by direct Overpass calls (Cloudflare-blocked).
|
||||||
|
- v0.1.4 — Citizen.com added as 5th source, per-source health registry.
|
||||||
|
- v0.1.5 — Waze removed (reCAPTCHA-gated; no clean mobile workaround).
|
||||||
|
- v0.1.6 — Dynamic notification with tier + label, haptic alerts on escalation, Open-in-Maps for geo events, idle visual differentiated from "scanning, all clear", permanent-deny recovery via Open Settings.
|
||||||
|
- v0.1.7 — System back from Settings returns to MAIN instead of exiting.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user