Three landing together.
Bottom-clear sweep:
Channel + Search + Subs feed + History + Playlists + Downloads
all had content rendering under the system nav bar and the
minibar overlay. Added a shared `util/BottomInsets.kt`
`rememberBottomContentPadding()` that combines nav-bar inset +
reactive 72dp minibar reserve (zero when nothing's playing).
Plumbed into every LazyColumn's contentPadding. Same pattern
Settings vc=50 used, lifted into a reusable helper.
DASH/HLS max-resolution cap:
Round-7 audit MED-3 — the user's max-resolution preference only
affected the videoOnly/combined picker. DASH manifests bypassed
the cap because Media3's ABR picked variants freely. New
Player.applyMaxResolutionCap() pushes TrackSelectionParameters
.setMaxVideoSize(MAX, ceiling) into the controller before
prepare(). Auto = MAX_VALUE = unconstrained. Mid-stream setting
changes take effect on next video.
Pause on headphone disconnect:
User-reported bug — wired headphones died, player switched to
phone speaker instead of pausing. ExoPlayer's
setHandleAudioBecomingNoisy honors Android's AUDIO_BECOMING_NOISY
broadcast and pauses on the standard "headphones pulled" event.
Wired into PlaybackService at construction + StrawApp.globalScope
collector so flipping the setting mid-session takes effect on
the already-built ExoPlayer. New Settings → Pause on headphone
disconnect toggle, default on (matches every other Android
media app's UX).