Skip to content

fix: offer the wired path on the card when a Bluetooth pad's cable is plugged in - #163

Merged
emir-hasanbegovic merged 3 commits into
mainfrom
fix/bt-card-wired-affordance
Aug 18, 2026
Merged

fix: offer the wired path on the card when a Bluetooth pad's cable is plugged in#163
emir-hasanbegovic merged 3 commits into
mainfrom
fix/bt-card-wired-affordance

Conversation

@emir-hasanbegovic

@emir-hasanbegovic emir-hasanbegovic commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Description

A pad connected over Bluetooth and then plugged in over USB showed only a Bluetooth badge with no way to reach the wired path from the card (#153 comments, Amazon Luna Controller). The plugged pad is tracked by UsbGamepadManager but has no framework or synthetic device, so nothing rendered it.

  • New wiredUsbPresentFor in ui/main/WiredUsbPresence.kt: detects that tracked-but-unrendered USB entry and ties it to the Bluetooth card by vendor id, or by exact framework id when both links report the same VID:PID.
  • PathCard gains wiredSwitchAvailable; the card shows a "USB available" pill and a "Use wired" button that opens the existing wired setup flow.
  • No auto-switching. Path FSM unchanged. Strings added in all six locales, CHANGELOG under [Unreleased].

Commit 1 adds characterization tests that pass on main and pin the pre-fix behavior; commit 2 is the fix plus its tests.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Documentation update

How Has This Been Tested?

  • Unit tests
  • Instrumented tests
  • Manual testing on device/emulator

28 new tests: UsbDualPresenceGhostTest (9, FSM behavior before and after, unchanged), WiredUsbPresenceTest (13, the new signal), PathCardMapperTest (+6, card gating). ktlintCheck and detekt clean locally; full suite runs in CI.

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • Any non-obvious code explains why, not what
  • I have made corresponding changes to documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

A dual-mode pad already connected over Bluetooth that is then plugged in
over USB is tracked by UsbGamepadManager but never surfaces anywhere: the
attach-time auto path pick deliberately stays silent without permission,
so the entry parks in Routed with no framework id and no synthetic, and
no card offers the wired path (reported on the Amazon Luna Controller in
PR #153 discussion). These tests pin that mechanism at the FSM level so
the fix has the behavior it builds on spelled out; the FSM itself is
intentionally left unchanged.
A dual-mode pad connected over Bluetooth and then plugged in over USB
kept streaming over Bluetooth with nothing on its card acknowledging
the cable: transport resolution lets Bluetooth win, Bluetooth cards
hide the whole Standard/Direct section, and the tracked USB entry sits
in Routed with no framework or synthetic device representing it. The
only route to wired was knowing to walk the setup guide's Wired branch
(reported on the Amazon Luna Controller in the PR #153 discussion).

The card now surfaces that tracked-but-unrepresented USB entry: a
"USB available" pill on the connection row plus a "Use wired" action
that opens the wired setup flow, which already owns enumeration, the
permission prompt, and claim recovery. Association is by vendor, since
dual-mode pads may enumerate a different product id per link, and by
exact framework id for pads that report the same id on both links.
Nothing auto-switches: plugging in just to charge while playing over
Bluetooth behaves exactly as before, and the path FSM is untouched.
@emir-hasanbegovic
emir-hasanbegovic force-pushed the fix/bt-card-wired-affordance branch from db8dda4 to 9c26557 Compare August 18, 2026 02:10
The relaxed mock fed the new combine input a dead flow, so uiState never
emitted and 17 tests failed in CI. Stub it with a real MutableStateFlow
like the other inputs, and cover the wired-switch signal end to end.
@emir-hasanbegovic
emir-hasanbegovic force-pushed the fix/bt-card-wired-affordance branch from d14266d to 90a6009 Compare August 18, 2026 11:53
@emir-hasanbegovic
emir-hasanbegovic merged commit 1452933 into main Aug 18, 2026
9 checks passed
@emir-hasanbegovic
emir-hasanbegovic deleted the fix/bt-card-wired-affordance branch August 18, 2026 12:27
emir-hasanbegovic added a commit that referenced this pull request Aug 18, 2026
1.1.1 shipped 2026-08-17. Main has picked up two user-facing fixes
since: the Guide button on XInput wired pads (#162) and the "Use wired"
card action when a Bluetooth pad's cable is plugged in (#163). This keys
the release docs to 1.1.2 so the tag can ship them; tag 1.1.2 derives
versionCode 10102.

- CHANGELOG.md: retitle Unreleased to 1.1.2, dated 2026-08-18
- changelogs/10102.txt in all 5 locales, quoting each locale's actual UI
strings for the card badge and button

Validated locally: `EXPECTED_VERSION_CODE=10102 python
scripts/check_play_metadata.py` reports 0 errors (only the known 512x512
icon warnings).

## Releasing after merge

```
git fetch origin
git tag 1.1.2 origin/main
git push origin 1.1.2
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant