Commit graph

6383 commits

Author SHA1 Message Date
James Rich
57c612abce fix(ble): filter bonded picker list to Meshtastic devices
BluetoothAdapter.bondedDevices returns every paired BT device on the phone
(headphones, cars, watches, etc.). The picker's bondedBleFlow was mapping
the full set into DeviceListEntry.Ble with no filter, leaking non-Meshtastic
devices into the connection list.

Apply the existing Meshtastic name pattern (getMeshtasticShortName()) at the
use-case layer. Repository semantics are preserved so BleRadioTransport.findDevice()
can still resolve a saved address regardless of name conventions.

The active scan path (KableBleScanner) already filters by SERVICE_UUID and
is unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 11:51:41 -05:00
James Rich
8823995648 style: spotlessApply formatting
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 11:31:31 -05:00
James Rich
e0a946e427 chore: add .agent_artifacts to .gitignore
Agent-generated artifacts should not be committed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 11:29:24 -05:00
James Rich
f5cbaf8ad6 docs: fix KDoc inconsistencies in transport files
- BleReconnectPolicy: clarify maxFailures param documents Int.MAX_VALUE
  disables the give-up path; remove misleading 'give up permanently'
- StreamTransport.onDeviceDisconnect: fix confusing 'wait for it to come
  back' sentence in KDoc summary
- BleRadioTransportTest: import VerifyMode instead of fully-qualifying

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 11:29:13 -05:00
James Rich
805f9a3cd2 fix(serial): refresh USB device list on Android 12+ attach and resume
Android 12+ delivers ACTION_USB_DEVICE_ATTACHED only to manifest-declared
receivers; the runtime-registered UsbBroadcastReceiver inside UsbRepository
never sees this event. Forward it explicitly from MainActivity so the
serialDevices StateFlow refreshes and the device appears in the Connect →
Serial tab without requiring the user to replug.

Also re-poll in onResume() to handle process-restart or returning from
another app while a USB device was already attached.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 11:29:13 -05:00
James Rich
a6f8f456fd fix(serial): treat USB unplug and open failure as transient
Serial transports defaulted to isPermanent=true for any disconnect path,
including USB unplug and port-open failure. Both conditions can resolve
without explicit user re-selection: replug, OS re-enumeration, permission
grant. Only an explicit close() (user disconnects) is a true permanent
disconnect.

- StreamTransport: flip onDeviceDisconnect default isPermanent to false;
  close() now passes isPermanent=true explicitly.
- SerialRadioTransport (Android): pass isPermanent=false explicitly on
  USB unplug callback path.
- SerialTransport (JVM): flip both the open-failure path and the read-
  loop teardown to isPermanent=false; both are recoverable conditions.
2026-04-20 11:29:13 -05:00
James Rich
0e47dc6717 fix(tcp): stop emitting redundant permanent disconnect from close()
TcpRadioTransport.close() unconditionally emitted onDisconnect with
isPermanent=true. The 'closing' guard at the listener level already
suppresses the transient signal during teardown, and the explicit-
disconnect emit is owned by SharedRadioInterfaceService.stopTransportLocked.
The double-emit caused two terminal disconnect events for one user action
and prevented the auto-reconnect loop from cleanly owning its lifecycle.
2026-04-20 11:29:13 -05:00
James Rich
2137ef3410 fix(ble): never give up while user has device selected
The reconnect policy previously capped at 10 consecutive failures and
emitted a permanent disconnect, which terminated the reconnect loop and
required the user to manually re-select the device. BleRadioTransport is
only ever instantiated for the user-selected address (verified via
SharedRadioInterfaceService.startTransportLocked), so the only legitimate
permanent-disconnect path is explicit close() owned by the service layer.

- BleRadioTransport: pass maxFailures = Int.MAX_VALUE; backoff still
  caps at 60 s so battery impact remains bounded.
- BleExceptionClassifier: flip UnmetRequirementException (BT off /
  permission missing) to non-permanent — both can resolve without the
  user re-selecting the device.
- Test: replace the old 'gives up after DEFAULT_MAX_FAILURES' test with
  an inverted contract test that runs past the legacy threshold and
  asserts the policy never emits isPermanent=true on its own.
2026-04-20 11:29:13 -05:00
James Rich
a6f3a6b4a5 fix(serial): assert DTR/RTS on Android USB-CDC open
Empirically, RAK4631/nRF52840 firmware does not respond to WAKE_BYTES
unless DTR is asserted on open. DTR maps to USB SET_CONTROL_LINE_STATE,
which the firmware uses to detect host presence and activate its serial-
side Meshtastic protocol. Bridge-chip boards (CH340, CP210x, FTDI)
tolerate the assertion.
2026-04-20 11:29:13 -05:00
James Rich
646858cc39 fix(handshake): use 60 s stall guard for Stage 2 to match SDK behavior
Stage 2 of the handshake drains the full node database, which on meshes
with 50+ nodes can comfortably exceed the previous 30 s stall guard and
trigger a spurious want_config_id retry mid-drain. The meshtastic-client
KMP SDK uses a 60 s timeout for this stage for the same reason.

Split HANDSHAKE_TIMEOUT into HANDSHAKE_TIMEOUT_STAGE1 (30 s) and
HANDSHAKE_TIMEOUT_STAGE2 (60 s) and thread the duration through
startHandshakeStallGuard so each call site picks the right value.
2026-04-20 11:29:13 -05:00
James Rich
6135166ea5 test(ble): fix BleRadioTransportTest virtual-time budgets for 3 s settle
The settle-delay bump in 3bf1dd868 changed the iteration cadence but the
two virtual-time budgets in BleRadioTransportTest still assumed 1 s
settles, so the threshold/max-failure assertions fired before any
onDisconnect call had been made. Recompute the budgets (3 iterations now
finish at ~24 001 ms; 10 iterations at ~405 000 ms) and update the KDoc
breakdowns to match. Also picks up a trivial spotless reflow in
BleReconnectPolicy's KDoc.
2026-04-20 11:29:13 -05:00
James Rich
d16b04382f fix(ble): bump DEFAULT_SETTLE_DELAY 1 s → 3 s
With a 1 s pause between disconnect/reconnect cycles, 3–4 out of 5
attempts failed mid-handshake (Stage1Draining timeouts) because the
firmware had not yet released its GATT session. 3 s is a conservative
compromise validated against a strong (-53 dBm) RAK4631 link.
2026-04-20 11:29:13 -05:00
Copilot
7492a33cf8
Fix node-details remove action to preserve confirmation flow (#5192)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jamesarich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: James Rich <james.a.rich@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 15:59:20 +00:00
James Rich
2b47da3b61
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5193)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-20 07:40:08 -05:00
renovate[bot]
3322257cfd
chore(deps): update plugin com.gradle.develocity to v4.4.1 (#5194)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 11:47:09 +00:00
James Rich
99e7407a90
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5189)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-19 20:07:52 +00:00
renovate[bot]
9dd57725f2
chore(deps): update vico to v3.2.0-next.1 (#5191)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-19 12:31:11 -05:00
renovate[bot]
2c1984ace5
chore(deps): update fastlane to v2.233.0 (#5190)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-19 16:30:34 +00:00
James Rich
94856d257f
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5186)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-18 12:09:22 +00:00
James Rich
84fe24467f
fix(widget): drive updates via debounced state observer (#5185)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-18 04:11:32 +00:00
renovate[bot]
68a414b75b
chore(deps): update compose-multiplatform to v1.11.0-rc01 (#5184)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 22:00:34 -05:00
James Rich
4257e7b7e4
chore(deps): split androidx-compose version ref from CMP (#5183)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 21:41:36 -05:00
James Rich
14e86b90f1
feat(mqtt): adopt mqttastic-client-kmp 0.2.0 — disconnect reasons + Test Connection (#5181)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 21:33:55 -05:00
James Rich
ef0e159abb
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5177)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-17 21:20:58 -05:00
James Rich
61d7f6fef3
fix(deps): pin androidx-compose runtime-tracing/ui-test to CMP version (#5179)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 15:46:59 -05:00
James Rich
a273dc6623
Revert "diag(r8): disable minify for release builds (animation-freeze diagnostic)" (#5176)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 15:07:54 -05:00
James Rich
c866f60b59
diag(r8): disable minify for release builds (animation-freeze diagnostic) (#5174)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 18:36:33 +00:00
James Rich
10bc58d417
chore(strings): remove 4 unused string resources (#5173)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 17:36:32 +00:00
James Rich
dd74e501f3
fix(ui): finish accessibility roles and action labels for clickable surfaces (#5170)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 17:33:38 +00:00
James Rich
56cbc3670d
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5163)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-17 17:13:27 +00:00
James Rich
15a7c19b74
chore(r8): remove redundant keep rules covered by consumer rules (#5172)
Co-authored-by: GitHub Copilot CLI <223556219+Copilot@users.noreply.github.com>
2026-04-17 17:13:26 +00:00
James Rich
b979663e24
refactor: consolidate metric formatting through MetricFormatter (#5169)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 17:13:01 +00:00
James Rich
9f3fe865e3
test: migrate MigrationTest to runTest and add missing repository fakes (#5171)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 16:35:41 +00:00
James Rich
90f6e21a9c
fix(ui): stable LazyColumn keys, semantic roles, and content descriptions (#5168)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 16:24:18 +00:00
James Rich
cdeb1ac532
fix: redact MeshLog proto secrets and centralize Compose keep-rules (#5166)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 16:20:50 +00:00
James Rich
adfe3bfed1
refactor: use injected ioDispatcher and ApplicationCoroutineScope (#5167)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 16:18:45 +00:00
James Rich
a97f704300
feat(mqtt): migrate to MQTTastic-Client-KMP (#5165)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 15:19:08 +00:00
James Rich
df3b5365f9
fix(node): don't recreate Vico CartesianChartModelProducer on channel switch (#5160)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 02:40:17 +00:00
James Rich
a6a889430b
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5159)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-16 21:43:35 -05:00
renovate[bot]
65b885a073
chore(deps): update core/proto/src/main/proto digest to 4d5b500 (#5161)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 21:41:36 -05:00
James Rich
17e69c6d4c
chore: review-cleanup fleet (audit + fix + hardening) (#5158) 2026-04-17 00:02:59 +00:00
James Rich
872c566ef1
chore: Scheduled updates (Firmware, Hardware, Translations, Graphs) (#5157)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2026-04-16 20:25:12 +00:00
renovate[bot]
3a2f2fc56b
chore(deps): update kotlin to v2.3.21-rc2 (#5155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 16:33:25 +00:00
renovate[bot]
50896d455b
chore(deps): update dd.sdk.android to v3.9.0 (#5156)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 16:33:13 +00:00
James Rich
a580cd0467
chore(analytics): disable Datadog Compose action tracking (#5153)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 23:09:21 +00:00
James Rich
8e5d99410c
refactor(di): adopt @KoinApplication with startKoin<T>() compiler plugin API (#5152)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-15 22:52:59 +00:00
renovate[bot]
0f900fe7d7
chore(deps): update core/proto/src/main/proto digest to c9067da (#5151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-15 13:12:53 -05:00
James Rich
9ac02cf851
fix(app): disable R8 optimization to fix Compose animation freeze (#5150)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 17:45:27 +00:00
James Rich
878905aea3
perf(messaging): batch node + reply lookups in message loading (#5149)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 15:48:26 +00:00
James Rich
dea364dd17
fix(app): add R8 keep rules for Compose animation/runtime/ui (#5146)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 14:30:33 +00:00