AdRenderer
The ad-rendering boundary — the Kotlin counterpart of the web AdPlayerController. The orchestrator (OptiViewAds) stays player-agnostic and delegates everything that touches a media surface, an overlay, or GAM/IMA to an AdRenderer. The Android runtime renderer (Media3 ad player + overlay + IMA DAI) implements this in P4b; tests and the conformance driver supply a fake.
Intra-break ad-event ordering itself is decided by the portable AdBreakSequencer in :ads-sdk-core; the renderer is responsible only for actually loading/playing assets and reporting back through BreakPlaybackCallbacks in that sequencer-defined order.
Functions
End the in-progress break NOW because it was REMOVED from a polled manifest — the manifest spec's "early return". Same balanced cut path as skipBreak (adend + adbreakend), with two differences the renderer must honor: content resumes at break.start + resumeOffsetSec (the seconds the break already played — overriding the DAR/DAI defaults and forcing the seek in replacement mode), and a chained successor must NOT begin now (the scheduler triggers it at its own start time). No-op when no break is playing. Default no-op so fakes need not override.
Tear down the active GAM/IMA session (on session end).
Tear down the active manifest-steered ssai session (on session end).
Forward an in-stream timed-metadata cue from the CONTENT player to IMA so a steered ssai session fires its ad-tracking beacons.
Hide the pause ad (on resume or duration cap), fading it out. Default no-op.
One-time overlay/surface setup, called once at construction.
Whether an ad is currently on screen (used for overlap suppression / control gating).
Whether a GAM/IMA pod-serving session is configured for this renderer.
Whether the surface currently shows AD content, as opposed to the main content.
Play a whole break, reporting progress via callbacks; suspends until the break ends. effectiveDurationSec, when non-null, is the remaining duration to present a tune-in (join-in-progress) break for — used for the GAM pod URL and any backdrop hold — instead of the full break.duration.
Await the installed ad-request preparer (see setAdRequestPreparer) outside an ad request, for a caller about to push parameters to the live IMA session. No-op without a preparer.
Show the resume/close controls of the mounted pause ad (the viewer may resume content). Default no-op.
Install the handler the renderer invokes when the viewer taps/clicks the ad surface during a break. The orchestrator routes it into the public adclick event. Default no-op so renderers/fakes without a click surface need not override.
Set the resolved ad-preload mode for the session.
Install a hook the renderer awaits before it builds an ad request (VAST tag URL or GAM parameters), so a host whose macro values live outside this thread — the React Native bridge, which asks JS for them — can refresh them first. Null (the default) skips the wait.
Set the safety margin (seconds) added to a break's effective duration before the break-cut timer hard-cuts back to content.
Set the per-session break resume policy: the ad insertion type (DAR/DAI) and the manifest timebase. Drives the content resume point computed when a break that paused content ends. Mirrors the web AdPlayerController.setBreakResumePolicy. Default no-op so renderers and fakes that never resume content need not override.
Install the resolver the renderer calls to soft-end into the break chained after the current one; null disables chaining.
Install the sink the renderer reports structured diagnostics to (e.g. VAST CSAI guard/error codes). Mirrors the web AdPlayerController.setDiagnoseHandler. Default no-op so renderers/fakes that emit no diagnostics need not override.
Which side keeps audio during a double-format break.
Install the GAM quartile callbacks the renderer fires during ad playback.
Install the manifest session layer (vendorConfiguration[gam].sgai[0].assetParameters, or ssai[0].assetParameters for a stitched stream). Called at session start and on every manifest poll; a changed layer is pushed to the live IMA session without recreating it.
Invoked with the break id when a video pause-ad creative ends or cannot play. null detaches. Default no-op.
Tell the renderer whether the content player is currently in picture-in-picture.
Install the sink the renderer reports picture-in-picture transitions UP through.
Install the customer asset-parameter macros (SessionConfig.assetParameterMacros) for the session about to start. Each callback resolves the $-prefixed name it is keyed by; a null result leaves the name unresolved.
Install the session layer of the asset parameters (SessionConfig.assetParameters) for the session about to start. Independent of startGamSession because VAST assets consume the same layers without a GAM session.
Set how long the renderer animates the picture change at the edges of a break, in milliseconds; 0 means cut with no animation.
Inject a reporter for sub-phase checkpoints inside a break transition, used to attribute transition cost (PLAYG-344 — mirror of the web AdPlayerController.setTransitionPhaseReporter). Pass null to disable, which is the default — the SDK only wires this in debug mode, so production DA-BREAK-TRANSITION reports keep their existing shape. Default no-op.
Show a full-screen pause ad over the (paused) content, fading it in. The orchestrator's com.dolby.optiview.ads.core.PauseAdController decides when this is called; the renderer resolves the image source (static URL or vast CompanionAds), fires any creativeView impressions, and draws the overlay with a resume affordance. Default no-op so non-overlay renderers/fakes need not override. com.dolby.optiview.ads.core.PauseAdResolution carries the break, image asset, and source.
Cut the in-progress break short NOW (viewer skip). The renderer must end the break through its normal cut path so the sequencer still emits the balanced adend + adbreakend steps — exactly like the break-cut timer. No-op when no break is playing. The orchestrator (OptiViewAds.skipAd) owns the skip POLICY (controls.skipOffset gating); the renderer only performs the cut. Default no-op so renderers/fakes without a skip surface need not override.
Initialize the GAM/IMA stream session for identity; suspends until ready.
Open a full-service IMA DAI session for the manifest-steered ssai stream vendor describes and return the stitched stream URL to play on the CONTENT player (ADS-326). Suspends until IMA returns the URL.
Merge customer macros by name; null removes a name so the built-in applies again. The update is pushed to the live IMA session when one is active.
Replace the live-update layer of the asset parameters for the active session (no re-init).
The variant-selection context this renderer plays breaks under: the detected device class plus the CONTEXTUAL playable-format set (narrowed while content is in picture-in-picture). The orchestrator feeds it into the portable selection both for its pre-adbreakbegin gate and for the public events' declared format. Defaults to "unknown device, every renderable format" so fakes and tests keep compiling.