Skip to content

feat(android): run on Android TV, driven by a remote - #150

Merged
Origami74 merged 1 commit into
mainfrom
feat/android-tv
Oct 19, 2026
Merged

Origami74 merged 1 commit into
mainfrom
feat/android-tv

Conversation

@Origami74

@Origami74 Origami74 commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Makes Myco usable on Android TV, driven by a remote. Developed and measured on a budget TV (CVTE board, HiSilicon Hi3751V350: 4×1.2 GHz, 32-bit userspace, 1 GB RAM, Android 14).

What changes

  • Leanback: LEANBACK_LAUNCHER entry and a 320×180 banner; touchscreen, leanback and bluetooth_le declared optional (that TV's firmware disables Bluetooth outright). The portrait lock is lifted on TV; tabs move to a NavigationRail in landscape.
  • Remote input (ui/theme/TvFocus.kt, TV only):
    • every plain clickable draws a focus ring (LocalIndication), Material components get a strong focused overlay (LocalRippleConfiguration);
    • the mesh-setup dialog focuses its first control on each step (TvAutoFocus);
    • Menu or a held OK opens the long-press menus on app tiles and Circle bubbles (remoteLongClick);
    • the Wi-Fi panel fallback no longer throws where the panel is missing.
  • Intro: OK/Enter skips it (on any device; harmless on phones).
  • Napplet / nsite windows (TV only): the WebView pauses while its window is off screen — a TV has nothing that sends a backgrounded app to sleep, so a game kept playing music — and gets focus once content shows, so the first D-pad press reaches the page.
  • 32-bit TV boxes: ABIs come from -Pmyco.abis=… / MYCO_ABIS (default arm64-v8a); buildRustArm64 → buildRust. On 32-bit, the relay and event-cache LMDB maps are 256 MiB (1 GiB doesn't fit next to ART) and cache defaults are 128 MiB events / 512 MiB blobs.
  • tv build type: release code, debug-signed, not debuggable — for measuring on a weak device.
  • Docs: build.md §5 (ABIs, tv build type), README, CHANGELOG. CLAUDE.md, build.md and flake.nix no longer call arm64-v8a locked (it's the default; CI builds arm64 only). napplet-runtime.md §5.5 notes the TV pause.

Builds on #149 (the .fips resolver fix, which the TV needs to reach Circle peers), now in main. The redraw/perf work is already in main (#140–#144). A 32-bit build needs jmcorgan/fips#191.

Testing

  • cargo fmt --check, cargo clippy --workspace --all-targets -D warnings, cargo ndk -t armeabi-v7a check -p myco-core (with fips#191), ./gradlew :app:testDebugUnitTest :app:compileDebugKotlin.
  • On the TV (via test/tv-perf, same Android code): install from the home row, full mesh-setup with the remote incl. the system VPN dialog, LAN peering with a phone and a tablet, Circle pairing, menus via Menu/hold-OK, napplets pausing on Home. Idle on Apps for 30 s with the tv build: 271 → ~0 frames with perf(ui): read the no-peers pulse in the draw phase, skip it on low-RAM and TV #140–perf(android): drop Apps search focus when the keyboard closes #144.
  • Phones: the TV paths are gated on FEATURE_LEANBACK / keyboard input mode; installed on a Pixel 7 Pro (arm64 debug) with no visible change.

@Origami74
Origami74 changed the base branch from main to fix/fips-names-in-process October 15, 2026 16:55
@Origami74
Origami74 force-pushed the fix/fips-names-in-process branch from 053cc21 to a1f221f Compare October 19, 2026 14:34
Base automatically changed from fix/fips-names-in-process to main October 19, 2026 14:41
- Leanback: LEANBACK_LAUNCHER entry and banner; touchscreen, leanback and
  bluetooth_le declared optional. The portrait lock is lifted on TV and the
  tabs move to a side rail in landscape.
- Remote input: on TV every clickable gets a focus ring (LocalIndication)
  and Material components a strong focused overlay; dialogs (mesh setup)
  focus their first control; Menu or a held OK opens the long-press menus
  on app tiles and Circle bubbles; the Wi-Fi panel fallback is guarded for
  TVs without it. OK/Enter also skips the intro (on any device).
- Napplet and nsite windows pause their WebView while off screen on TV (a TV
  has nothing that sends a backgrounded app to sleep) and give it focus once
  content shows, so the first D-pad press reaches the page.
- 32-bit TV boxes: the ABI list is a Gradle property (-Pmyco.abis, or
  MYCO_ABIS), arm64-v8a by default; the buildRustArm64 task is now buildRust.
  On 32-bit the relay and event-cache LMDB maps are 256 MiB and the cache
  defaults smaller, to fit the address space and a TV's flash.
- A `tv` build type: release code, debug-signed and not debuggable, for
  measuring on a weak TV.
- Docs: CLAUDE.md, build.md and flake.nix no longer call arm64-v8a locked
  (it is the default; CI still builds arm64 only and a 32-bit build needs
  jmcorgan/fips#191). napplet-runtime.md §5.5 notes the TV pause, and the
  NappletActivity comment points there instead of §7.2.
@Origami74
Origami74 merged commit bbcbe8f into main Oct 19, 2026
4 checks passed
@Origami74
Origami74 deleted the feat/android-tv branch October 19, 2026 14:52
Origami74 added a commit that referenced this pull request Oct 23, 2026
The performance work that came out of Android TV support (#140-#144, and
#150's TV pause and 32-bit sizing) gets its own section.
Origami74 added a commit that referenced this pull request Oct 23, 2026
* chore: v0.12.0 release prep

Cut [Unreleased] into [0.12.0] - 2026-10-23 (update notices, private
data for napplets, NAP-FS picker, grouped permissions, the compact app
menu and copyable share link, blossom-local uploads, napplet.link,
Android TV, and fixes). Add the missing entry for a napplet's Copy
button (#155). Rewrite RELEASE-NOTES.md for v0.12.0; roadmap status says
it shipped.

* chore: v0.12.0 release notes: faster on slow devices

The performance work that came out of Android TV support (#140-#144, and
#150's TV pause and 32-bit sizing) gets its own section.
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