Skip to content

feat(service): add a Quick Settings tile for the radio connection - #7662

Draft
jamesarich wants to merge 2 commits into
mainfrom
feat/quick-settings-tile
Draft

jamesarich wants to merge 2 commits into
mainfrom
feat/quick-settings-tile

Conversation

@jamesarich

@jamesarich jamesarich commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

On Android the foreground service owns the radio link, so a Quick Settings tile can show the live connection and connect or disconnect from the shade. Apple's new Control Center controls (Meshtastic-Apple#2668) can only open the app.

🌟 New Features

  • Meshtastic Quick Settings tile (active tile): on with our node's short name when connected, on with "Connecting" while connecting, off when disconnected or sleeping, "No device selected" otherwise.
  • A tap disconnects the same way the Connect tab does, reconnects through the reselect path while the service runs, and otherwise starts the service. With no radio selected, or if Android refuses the start, it opens the Connect tab.

🛠️ Refactoring & Architecture

  • New ServiceStartTrigger.QuickSettingsTile. SystemUI temp-allowlists the app for a tile click ("tile onclick", 15 s), so ForegroundStartPolicy always attempts it; MeshService.startService now returns whether the start went through, so a refusal falls back to opening the app.
  • The tile requests a refresh in onTileAdded; an active tile is bound only on request, so one added while the state was steady stayed blank.
  • The tile service joins BundledSqliteGuardTest's expected entry points. MeshService.kt picks up a spotless reformat of scheduleDeviceAddressResolution.

📝 Documentation

  • Connections page: a Quick Settings Tile section.

Testing Performed

  • QuickSettingsTileStateTest (new): the state mapping for every connection state, for no radio selected, and for a stopped service. ForegroundStartPolicyTest: a tile tap is attempted from the background on every restricted level.
  • Full baseline (spotlessApply spotlessCheck detekt detektTypeResolved assembleDebug test allTests kmpSmokeCompile -PwarningsAsErrors=true) green locally.
  • Emulator, API 36, against a simulated TCP radio:
    • Connected: tile on with the short name. Tap disconnects; the tile goes off with "No device selected".
    • App force-stopped, tile tapped from the launcher: Background started FGS: Allowed ... tile onclick, the service started and reconnected, the app stayed in the background.
  • Not seen: API 31 to 35, where the tap allowlist is unverified and the fallback to opening the app is what covers a refusal.
Connected No device selected
connected no-device

Constitution Check

  • I: Android framework integration in core:service/androidMain only.
  • II: spotless, detekt and detektTypeResolved pass.
  • III: no new Compose UI; subtitles reuse shared Compose strings.
  • IV: no names or addresses logged.
  • V: monochrome system icon; SystemUI draws the tile. Android-only, so there's no cross-platform spec.
  • VI: Connections page updated, last_updated bumped.
  • VII: baseline green before push.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 18, 2026
The foreground service owns the radio link on Android, so the tile shows
live connection state and connects or disconnects the selected radio
instead of only opening the app.

- `MeshQuickSettingsTileService` is an active tile, refreshed through
  `TileService.requestListeningState` whenever the mapped state changes.
- `quickSettingsTileState` maps connection state, the selected radio and
  our short name onto the tile and the tap action.
- A tap disconnects the same way the Connect tab does (deselect the
  radio), reconnects through the reselect repair path while the service
  runs, and otherwise starts the service with a new `QuickSettingsTile`
  trigger. The platform lists no exemption for a tile tap, so that start
  is allowed only while the app is visible or exempt from battery
  optimizations; when refused, or with no radio selected, the tile opens
  the Connect tab.
- `MeshService.startService` now reports whether the start went through.
An active tile is bound only when the app requests it, so one added while
the connection was steady stayed blank until the next state change; it now
requests a refresh in `onTileAdded`.

SystemUI temp-allowlists the app for a tile click ("tile onclick", seen on
API 36), so the tile now always attempts the foreground start and falls
back to opening the app when the platform refuses it. The battery
optimization check is gone.
@jamesarich
jamesarich force-pushed the feat/quick-settings-tile branch from 21c0cdf to fbe4a2e Compare October 18, 2026 17:08

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant