Bugfix/logical-flaw sweep: counting, races, baseline, pruning, RSSI
Root cause of the non-monotonic sighting count (60->29->63): MAC-rotating ecosystems mint a new tracker row per rotation, tracker rows were never pruned, and the UI re-sorts constantly, so different rows' counts read as one sequence. Compounded by no ingestion throttle and a lost-update race. Fixes: - ScanService: throttle the persisted path to <=1 sighting/device/15s (presence engine still sees every advert). Stops count inflation + DB hammering. @Volatile clone-alert ts; clear throttle map on stop. - TrackerRepository: Mutex around record() (was a lost-update race: concurrent observations did get()->compute->upsert() with no lock). Always compute the co-movement assessment for display. - VigilDatabase: prune stale non-approved tracker rows (were never deleted); +lastRssi/peakRssi/distinctPlaces/effectiveSightings for grounding; version 2. - BaselineManager: count DWELL (one visit per 10-min window), not per-sighting. Old per-sighting count let a busy street or chatty tracker mint a fake 'home' in seconds and auto-trust a real stalker — a safety flaw. - BleTrackerScanner: Apple filter now matches only Find My type 0x12, not every Apple device (iPhones/Watches/AirPods). - UI: show distinct places + last RSSI on cards; detail sheet shows last/peak RSSI, distinct places, co-movement sightings, adverts logged; Active list filters to devices seen in the last 10 min so rotated identities drop off. - Tests: CoMovementEvaluatorTest locks dedup, the RSSI gate, and the place/separated thresholds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0187UiEtasyowhEBYs6s9iF5
This commit is contained in:
@@ -45,8 +45,16 @@ class BleTrackerScanner(
|
||||
.build()
|
||||
|
||||
private val filters: List<ScanFilter> = buildList {
|
||||
// Apple Find My — match presence of Apple manufacturer data.
|
||||
add(ScanFilter.Builder().setManufacturerData(TrackerSignatures.APPLE_COMPANY_ID, ByteArray(0)).build())
|
||||
// Apple Find My — match ONLY the offline-finding message type (0x12), not
|
||||
// every Apple device (iPhones/Watches/AirPods all advertise company 0x004C).
|
||||
// Data+mask apply from the first manufacturer-data byte, which is the type.
|
||||
add(
|
||||
ScanFilter.Builder().setManufacturerData(
|
||||
TrackerSignatures.APPLE_COMPANY_ID,
|
||||
byteArrayOf(TrackerSignatures.APPLE_TYPE_FINDMY.toByte()),
|
||||
byteArrayOf(0xFF.toByte())
|
||||
).build()
|
||||
)
|
||||
// FMDN / Samsung / Tile / DULT — match their service UUIDs.
|
||||
for (uuid in TrackerSignatures.trackerServiceUuids) {
|
||||
add(ScanFilter.Builder().setServiceUuid(uuid).build())
|
||||
|
||||
Reference in New Issue
Block a user