Skip to content

Catch-up P1: launch past Guide programmes through service-owned playback intent #305

Description

@MrFr3di

Parent: #184
Follows: completed #285 / merged #304.

Objective

Complete the next M3U catch-up product slice: selecting a past EPG programme in Guide must start provider catch-up through the existing service-owned playback/recovery path, without constructing provider URLs in Guide/Compose and without introducing a second player, retry loop, or seek authority.

Confirmed current gap

  • Guide programme cells currently call onOpenChannel(channelId) for every click, so past programmes collapse to ordinary Live playback.
  • PlaybackCatalog.resolveIntent() and persisted M3U archive resolution are implemented, but PlaybackStartRequest is still Live/channel-only.
  • MuxTvPlaybackService resolves candidates through PlaybackCandidateResolver.resolveCandidate(...), so resolving catch-up in presentation before the service would bypass the accepted bounded recovery owner.
  • Guide presentation clips visible programme bounds to the viewport; catch-up must use the original EPG programme start/end, not clipped display bounds.

Architecture

  • Keep PlaybackStartRequest provider-neutral and extend it with PlaybackIntent, while preserving the existing Live constructor/source compatibility.
  • Preserve the existing service-owned candidate ordering/recovery. Add an intent-aware candidate-resolution seam with a Live default; RoomPlaybackCatalog resolves archive intent for the exact candidate selected by the service.
  • Media3/session command transport serializes only semantic intent fields; no locator/template/token/header crosses this boundary.
  • Guide emits only a provider-neutral selection: current/status -> Live, completed programme -> CatchupProgram, future programme -> no launch.
  • App navigation stores only bounded semantic identities/timestamps and reconstructs PlaybackIntent at the player entry point.
  • Playback: measured seek/rebuffer, back-buffer and optional cache residuals after single service-owned seek authority #132 remains the sole active seek mutation authority. No initial UI-owned seek is introduced.

TDD sequence

  1. RED: PlaybackStartRequest + Media3 Bundle codec preserve CatchupProgram/CatchupPosition semantics and keep Live wire compatibility.
  2. RED: service candidate resolution uses the exact selected candidate with archive intent and keeps bounded fallback.
  3. RED: Guide selection uses original programme bounds, maps past/current/future correctly, and never constructs provider transport.
  4. Minimal GREEN implementation.
  5. Exact-head host validation plus canonical API26/API36/focused TV evidence appropriate to changed surfaces.

Acceptance

  • clicking a completed Guide programme starts PlaybackIntent.CatchupProgram with original EPG start/end;
  • current programme and non-programme/status cells preserve Live behavior;
  • future programme does not start playback;
  • service still owns candidate ordering, bounded fallback, generation cancellation and Media3 installation;
  • archive-unavailable candidate can fall through to another eligible candidate under the existing recovery bounds;
  • M3U/Kodi template syntax stays out of Guide, navigation and player:media3;
  • no raw locator/query/token/Cookie/Authorization value enters navigation, Bundle diagnostics, UI semantics or logs;
  • local-network and exact-origin cleartext gates still run on the final materialized archive locator;
  • no Room migration;
  • no second player/retry/seek owner;
  • canonical persistent AVD set remains exactly API26 + API36.

Non-goals

Xtream catch-up, local timeshift, DVR, VOD/Series, new provider framework/module, new seek model, new persistent AVD, buffer tuning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions