Package-level declarations

OptiViewAds and its configuration (OptiViewAdsConfig, SessionConfig, GamConfig), the event types, the diagnostics types, and the platform seams with their default JVM implementations (HttpManifestSource, CoroutineSchedulerTicker).

Types

Link copied to clipboard
data class AdBeginEvent(val break_: Break, val assetId: String, val adIndex: Int, val totalAds: Int, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null, val adId: String? = null, val creativeId: String? = null, val podPosition: Int? = null) : OptiViewAdsEvent

An individual ad starts playing. A GAM pod reports one adbegin per ad it was filled with.

Link copied to clipboard
data class AdBreakBeginEvent(val break_: Break, val timestamp: Long, val tuneIn: TuneInInfo? = null, val format: BreakFormat? = null, val elapsedSec: Double = 0.0, val remainingSec: Double = break_.duration) : OptiViewAdsEvent

An ad break starts and content is paused (or, for lshape_content and overlay breaks, keeps playing).

Link copied to clipboard
data class AdBreakEndEvent(val break_: Break, val timestamp: Long, val format: BreakFormat? = null) : OptiViewAdsEvent

An ad break ends and content resumes.

Link copied to clipboard

Lifecycle phase reported by AdBreakStatus. Mirrors the TS AdBreakPhase.

Link copied to clipboard
data class AdBreakStatus(val phase: AdBreakPhase, val break_: Break?, val format: BreakFormat? = null, val secondsUntilBreak: Int? = null, val breakRemainingSec: Double? = null, val adIndex: Int? = null, val totalAds: Int? = null, val adsRemaining: Int? = null, val ticking: Boolean, val warningSec: Int? = null)

Playback-gated snapshot of an ad break for UI countdowns — the Kotlin mirror of the web AdBreakStatus (packages/core/src/types/Events.ts). The SDK owns the timebase and the player-gated ticking flag; the application renders the badge/overlay. Emitted on the AdBreakStatusEvent and returned by OptiViewAds.getAdBreakStatus.

Link copied to clipboard
data class AdBreakStatusEvent(val status: AdBreakStatus, val timestamp: Long) : OptiViewAdsEvent

Event emitted when the status of the current or upcoming ad break changes. Carries a complete AdBreakStatus snapshot. Mirrors the TS AdBreakStatusEvent.

Link copied to clipboard
data class AdChannelChangeEvent(val previousChannelId: String?, val channelId: String?, val reason: AdChannelChangeReason, val manifestUrl: String, val previousDeliveryMode: DeliveryMode, val deliveryMode: DeliveryMode, val timestamp: Long) : OptiViewAdsEvent

A polled manifest described a different ads channel and the SDK re-aligned its ad setup to it while the session and content playback continued. Fires once per switch, after a break in progress has finished and the new manifest is applied.

Link copied to clipboard
data class AdClickEvent(val break_: Break, val assetId: String, val clickThrough: String? = null, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null) : OptiViewAdsEvent

The viewer clicked/tapped the ad on screen (or the application called OptiViewAds.clickAd programmatically) — the Kotlin mirror of the iOS/web adclick event. Carries the asset's declared interaction.clickThrough URL when the manifest supplies one; the SDK deliberately does NOT open it — that is the application's decision.

Link copied to clipboard
data class AdCreativeIdentity(val adId: String? = null, val creativeId: String? = null, val podPosition: Int? = null)

The creative identity IMA reports for an ad of a GAM pod (PLAYG-361/362). Absent for every other asset kind, where the manifest asset already identifies the ad.

Link copied to clipboard
data class AdEndEvent(val break_: Break, val assetId: String, val adIndex: Int, val totalAds: Int, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null, val adId: String? = null, val creativeId: String? = null) : OptiViewAdsEvent

An individual ad finishes.

Link copied to clipboard
data class AdErrorEvent(val source: PlaybackSource, val break_: Break?, val assetId: String?, val error: Throwable, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null) : OptiViewAdsEvent

Playback failed. Emitted for both the content player and the SDK's ad player; source tells them apart. An ad error is not fatal: the SDK skips the asset and continues the break or resumes content.

Link copied to clipboard
data class AdFirstQuartileEvent(val break_: Break, val assetId: String, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null, val adIndex: Int? = null, val totalAds: Int? = null) : OptiViewAdsEvent

An ad reached 25% completion.

Link copied to clipboard

Ad insertion strategy. auto resolves per device (iPhone/iPod → adaptive or shared-element; otherwise overlay). On Android this resolves to OVERLAY.

Link copied to clipboard
data class AdMidpointEvent(val break_: Break, val assetId: String, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null, val adIndex: Int? = null, val totalAds: Int? = null) : OptiViewAdsEvent

An ad reached 50% completion.

Link copied to clipboard

Ad preload strategy. auto resolves at runtime (decoder-limited devices → SINGLE_DECODER, otherwise PARALLEL).

Link copied to clipboard
interface 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.

Link copied to clipboard
data class AdThirdQuartileEvent(val break_: Break, val assetId: String, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null, val adIndex: Int? = null, val totalAds: Int? = null) : OptiViewAdsEvent

An ad reached 75% completion.

Link copied to clipboard
data class AdTimeupdateEvent(val break_: Break, val assetId: String, val currentTime: Double, val duration: Double, val timestamp: Long, val format: BreakFormat? = null, val asset: Asset? = null) : OptiViewAdsEvent

Ad playback progressed; fires on each time update of the ad player (about 4 Hz). For a GAM pod the times describe the whole pod, not the ad on screen.

Link copied to clipboard

Progress callbacks the renderer fires across a single break. Ad-level callbacks carry the asset id (String), matching the portable brain's id-based break/asset model and the conformance sdkSequence shape.

Link copied to clipboard
typealias ChainResolver = (currentBreakId: String) -> Break?

Resolves the break chained immediately after the break with the given id, or null when none/disabled.

Link copied to clipboard
data class ConfigSummary(val manifestOrigin: String? = null, val adPreload: String, val adInsertion: String, val chainingEnabled: Boolean, val chainingMaxGapSeconds: Double, val tuneInEnabled: Boolean, val tuneInMinBreakDurationSeconds: Double, val ptsSource: String = PtsSource.MEDIA_TIME.value, val continueContentDuringBreak: Boolean = false, val gam: GamSummary? = null)

Redacted SDK configuration summary; secrets and PII-bearing fields are stripped.

Link copied to clipboard
class CoroutineSchedulerTicker(scope: CoroutineScope, intervalMs: Long = DEFAULT_TICK_INTERVAL_MS) : SchedulerTicker

Default SchedulerTicker: drives BreakScheduler.tick() from a coroutine delay loop on the supplied scope, every intervalMs ms. Pure Kotlin/JVM (no Android dependency); on Android the scope is typically the SDK's main-dispatcher scope so ticks land on the main thread.

Link copied to clipboard
class DiagnosticBuffer(size: Int = DEFAULT_DIAGNOSTICS_BUFFER_SIZE)

A bounded, in-memory ring buffer of DiagnosticEvents. Retains the most recent capacity records so OptiViewAds.exportDiagnostics can produce a self-contained report without unbounded growth on long-running live sessions.

Link copied to clipboard
data class DiagnosticEvent(val ts: Long, val level: DiagnosticLevel, val code: String, val category: DiagnosticCategory, val message: String, val context: Map<String, Any?>? = null)

A single structured diagnostic record.

Link copied to clipboard

Handler for the structured diagnostic stream.

Link copied to clipboard
data class DiagnosticReport(val sdkVersion: String, val generatedAt: Long, val userAgent: String?, val config: ConfigSummary, val diagnostics: List<DiagnosticEvent>)

A self-contained, redacted diagnostic report suitable for support/AI tooling.

Link copied to clipboard
data class DiagnosticsConfig(val bufferSize: Int = DEFAULT_DIAGNOSTICS_BUFFER_SIZE)

Structured diagnostics configuration.

Link copied to clipboard
class FetchedManifest(val body: ByteArray, val signatureHeader: String?)

A fetched manifest response: the exact body bytes (after transfer/content decoding) plus the detached-JWS signature header, both needed to verify the manifest before it is parsed.

Link copied to clipboard
data class GamConfig(val enabled: Boolean = true, val streamActivityMonitorId: String? = null)

Configuration for Google Ad Manager pod serving.

Link copied to clipboard

GAM/IMA quartile callbacks forwarded to the public SDK event stream. The adIndex/totalAds arguments attribute the quartile to a specific ad of a GAM pod (PLAYG-362); null outside per-ad pod reporting.

Link copied to clipboard
data class GamSummary(val hasAssetParameters: Boolean, val streamActivityMonitorId: String? = null)

Redacted GAM summary for a DiagnosticReport (ad-tag-parameter VALUES omitted).

Link copied to clipboard

Default ManifestSource: fetches the manifest over HTTP (via an injectable ManifestFetcher), decodes JSON, and validates it through the portable, conformance-locked core ManifestService. Polling is a coroutine loop on the supplied scope. Pure Kotlin/JVM — no Android dependency.

Link copied to clipboard
fun interface ManifestFetcher

Fetches the raw manifest response for a URL. Injected so HttpManifestSource can be unit-tested without real networking; the default is OkHttpManifestFetcher.

Link copied to clipboard
data class ManifestFetchEvidence(val url: String, val host: String, val outcome: String, val status: Int?, val ms: Long, val hostOk: Int, val hostFail: Int)

What a failed manifest read can say for itself. Twin of ManifestFetchEvidence in packages/core/src/services/ManifestService.ts — see there for why the field set is this small and no smaller.

Link copied to clipboard
data class ManifestInterceptContext(val url: String)

Context passed to a ManifestResponseInterceptor alongside the manifest.

Link copied to clipboard
typealias ManifestInterceptDiagnose = (code: String, message: String, context: Map<String, Any?>) -> Unit

Diagnostic sink a ManifestSource uses to surface a failed interceptor.

Link copied to clipboard

A mocked manifest response. When a ManifestRequestInterceptor returns this, the SDK skips the network and uses body (raw JSON) as the fetched manifest body — parsed + validated exactly as a real network response would be.

Link copied to clipboard
data class ManifestRequest(val url: String, val headers: Map<String, String> = emptyMap()) : ManifestRequestResult

The outgoing manifest request the SDK is about to make. A ManifestRequestInterceptor may return a (modified) copy to redirect the fetch (url) and/or attach headers.

Link copied to clipboard
data class ManifestRequestContext(val url: String)

Context passed to a ManifestRequestInterceptor alongside the request.

Link copied to clipboard

Customer hook to inspect/modify the manifest HTTP request before the SDK fetches it — invoked on the initial fetch and every poll, before the network call. Return a ManifestRequest to redirect/add headers, a ManifestMockResponse to short-circuit the network with a raw body (parsed + validated normally), or null to fetch unchanged. May suspend. If it throws, the SDK emits DA-MANIFEST-REQUEST-INTERCEPT-FAILED and falls back to the normal network fetch. Mirrors the web ManifestRequestInterceptor.

Link copied to clipboard
sealed interface ManifestRequestResult

What a ManifestRequestInterceptor may return: a redirect/header override or a mock response.

Link copied to clipboard

Customer hook to inspect/modify the break manifest after the SDK has fetched and validated it, before it is scheduled/used. Invoked on the initial fetch and on every poll, with the already-parsed, typed BreakManifest — never raw JSON. Returns the manifest to use (modified or unchanged); the returned value is used directly without re-validation. May suspend. If it throws, the SDK emits DA-MANIFEST-INTERCEPT-FAILED and falls back to the un-modified parsed manifest (the fetch does not fail). Mirrors the web ManifestResponseInterceptor.

Link copied to clipboard
interface ManifestSource

The manifest fetch + poll boundary. The portable :ads-sdk-core ManifestService only parses + validates a decoded manifest (so its validation stays conformance-locked across platforms); the actual network fetch and the polling timer are platform concerns and live behind this interface. HttpManifestSource is the default implementation (OkHttp + coroutine poll loop); tests and the conformance driver supply a fake.

Link copied to clipboard
class OkHttpManifestFetcher(client: OkHttpClient = defaultClient()) : ManifestFetcher

OkHttp-backed ManifestFetcher. The blocking call runs on Dispatchers.IO.

Link copied to clipboard
class OptiViewAds(config: OptiViewAdsConfig, renderer: AdRenderer, manifestSource: ManifestSource, ticker: SchedulerTicker, scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default), clock: Clock = systemClock)

The OptiView Ads SDK entry point: one instance per content player, living as long as the player. It polls the Break Manifest of the current session, schedules the breaks against the player's timeline through the configured PlayerAdapter, plays them through the AdRenderer, and reports what happens on the event stream (addEventListener) and the diagnostics stream (onDiagnostic, exportDiagnostics).

Link copied to clipboard
data class OptiViewAdsConfig(val player: PlayerAdapter, val adPreload: AdPreloadMode = AdPreloadMode.AUTO, val doubleBoxAudio: DoubleBoxAudio = DoubleBoxAudio.AD, val adInsertion: AdInsertionMode = AdInsertionMode.AUTO, val transition: TransitionConfig = TransitionConfig(), val chaining: ChainingConfig = ChainingConfig(enabled = true, maxGapSeconds = 2.0), val tuneIn: TuneInConfig = TuneInConfig(enabled = true, minBreakDurationSeconds = 5.0), val breakWarnings: BreakWarningsConfig = BreakWarningsConfig(), val pdtGraceSeconds: Double = DEFAULT_PDT_GRACE_SECONDS, val ptsSource: PtsSource = PtsSource.MEDIA_TIME, val continueContentDuringBreak: Boolean = false, val diagnostics: DiagnosticsConfig = DiagnosticsConfig(), val debug: Boolean = false, val gam: GamConfig? = null, val deliveryMode: DeliveryMode? = null, val adBreakCutSafetyMarginSec: Double = DEFAULT_AD_BREAK_CUT_SAFETY_MARGIN_SEC, val interceptManifestResponse: ManifestResponseInterceptor? = null, val interceptManifestRequest: ManifestRequestInterceptor? = null)

Org-level SDK configuration, fixed for the lifetime of the OptiViewAds instance. Chaining uses the brain's already-resolved ChainingConfig; the default below matches the web DEFAULT_CHAINING (enabled, 2s gap). tuneIn matches the web DEFAULT_TUNE_IN (enabled, 5s minimum remaining duration).

Link copied to clipboard
sealed class OptiViewAdsEvent

Base type for all SDK events.

Link copied to clipboard
Link copied to clipboard

The SDK event type tags (mirrors the TS OptiViewAdsEventType).

Link copied to clipboard

Which player a playback event originated from.

Link copied to clipboard
data class PlayingEvent(val source: PlaybackSource, val break_: Break?, val assetId: String?, val timestamp: Long, val asset: Asset? = null) : OptiViewAdsEvent

Playback started or resumed after stalling or pausing, on the content player or the ad player.

Link copied to clipboard
data class PresentationState(val pictureInPicture: Boolean, val showing: PresentationSurface)

What the SDK is presenting right now, returned by OptiViewAds.getPresentationState.

Link copied to clipboard

Which media the SDK currently has on the player surface.

Link copied to clipboard

Selects how PTS-timebase break starts are resolved.

Link copied to clipboard
typealias RendererAdClickHandler = () -> Unit

Invoked by a renderer when the viewer taps/clicks the ad surface during a break. The orchestrator resolves the current break/asset + clickThrough and emits the public adclick event.

Link copied to clipboard
typealias RendererDiagnoseHandler = (code: String, message: String, context: Map<String, Any?>?) -> Unit

Sink for structured diagnostics emitted by a renderer. The orchestrator wires this to its own diagnose(...) so renderer-side codes (e.g. DA-VAST-*) flow through the same diagnostic stream/buffer as the SDK's.

Link copied to clipboard
interface SchedulerTicker

Drives the portable BreakScheduler.tick() on a fixed cadence.

Link copied to clipboard
data class SessionConfig(val manifestUrl: String, val assetParameters: Map<String, String> = emptyMap(), val assetParameterMacros: Map<String, () -> String?> = emptyMap(), val assetParameterMacroValues: Map<String, AssetParameterMacro> = emptyMap(), val adInsertionType: AdInsertionType? = null)

Per-session configuration passed to OptiViewAds.startSession. Changes per piece of content / channel switch.

Link copied to clipboard
data class TransitionConfig(val type: TransitionType = TransitionType.FADE, val durationMs: Long = DEFAULT_TRANSITION_MS)

How the picture changes at the edges of a break — content to ad and back.

Link copied to clipboard

How a break transition is played.

Link copied to clipboard
data class TuneInInfo(val elapsedSec: Double, val remainingSec: Double)

Tune-in (join-in-progress) detail attached to an AdBreakBeginEvent when the viewer joined while the break was already in progress. remainingSec is the effective duration the break is presented for.

Link copied to clipboard
data class VolumeChangeEvent(val muted: Boolean, val volume: Double, val timestamp: Long) : OptiViewAdsEvent

Unified audio state changed — the Kotlin mirror of the TS VolumeChangeEvent.

Link copied to clipboard
data class WaitingEvent(val source: PlaybackSource, val break_: Break?, val assetId: String?, val timestamp: Long, val asset: Asset? = null) : OptiViewAdsEvent

Playback stalled for buffering, on the content player or the ad player.

Properties

Link copied to clipboard

Default ad-break-cut safety margin, in seconds. A break is always hard-cut back to content at effectiveDuration + this margin at the latest, no matter how long the inserted ad media runs — the SDK never depends on the ad stream reaching its own end before returning to content. The small margin is grace so an ad whose length is close to the break duration can finish cleanly instead of having its final second(s) chopped at the exact boundary. Mirrors the web DEFAULT_AD_BREAK_CUT_SAFETY_MARGIN_SEC.

Link copied to clipboard

Default in-memory diagnostics ring-buffer size.

Link copied to clipboard

Default scheduler tick cadence (ms) — mirrors the web scheduler's 250 ms setInterval.

Link copied to clipboard
const val DEFAULT_TRANSITION_MS: Long = 300

Default break-transition duration, in milliseconds. The same 300ms the web core uses (AdPlayerController.TRANSITION_MS) and iOS (layoutTransitionSec), so a break looks the same on every platform unless an integrator says otherwise.

Functions

Link copied to clipboard

Dependency-free JSON serialization for DiagnosticReport.