Skip to main content

BBFontProvider

class BBFontProvider internal constructor(
private val _loader: TypefaceLoader,
private val _frozen: Boolean
)

One owner's answer to "what Typeface goes on this TextView?" (#20290). An owner is a BBNativePlayerView (fed by its playout) or a BBNativeShortsView (fed by the Shorts app config, serving the shelf in list mode).

Deliberately not a singleton: two BBNativePlayerViews on one screen can be on different playouts, and a shared role -> face map would let one repaint the other. The only global part is [BBFontRegistry], a path -> Typeface cache, which carries no role state.

Two independent roles, per #20288:

HEADING video title (start/pause/end), "Related videos", CTA label, Shorts title
BODY everything else - times, LIVE, settings, ads, dates, authors, related items, ...

A role that resolves to nothing renders in Lato, exactly as the SDK did before this ticket. The [BBFontStyle] axis only ever picks between the three bundled Lato files; a custom file is used as-is (heading) or with OS-synthesised bold (body).

Properties​

currentSpecs​

var currentSpecs: Map<FontRole, FontSpec>

The specs the owner last asked for, per role. Kept here so the runtime-playout delta ([FontPlayoutDelta]) has a "current" to compare an incoming payload against - an absent key means "leave this role alone", which is only expressible against a remembered state.

unavailableRoles​

val unavailableRoles: Set<FontRole>

Roles whose last applied [FontResolution] was [FontResolution.Unavailable] - a transient failure (network hiccup, or the shared module's resolution timeout) rather than a final answer. The download for these keeps running in the background and lands in the cache, but nobody asks again unless prompted (#20290: BBNativePlayerView retries once on a timer, and re-resolves a re-sent playout even when its specs did not change). [FontResolution.Unusable] is a permanent, contractual answer and must never show up here.

Functions​

hasUnavailableRole​

fun hasUnavailableRole() : Boolean

True while at least one role is stuck on [FontResolution.Unavailable] (see [unavailableRoles]).

typeface​

fun typeface(role: FontRole, style: BBFontStyle) : Typeface

The Typeface for [role] at [style]. Never null: it falls all the way back to the platform default if even Lato fails to load.

apply​

fun apply(heading: FontResolution, body: FontResolution)

Both roles at once, one listener fire. This is what a [FontResolution] pair lands in.

applyRole​

fun applyRole(role: FontRole, resolution: FontResolution)

One role. The other keeps whatever it had - the roles never cover for each other.

addListener​

fun addListener(listener: () -> Unit)

Called exactly once after every [apply] / [applyRole], so owners can re-sweep their view trees. Fired even when nothing changed: a re-apply is also how a freshly inflated subtree gets its fonts, and a redundant sweep is cheaper than a missed one. Listeners run on whatever thread called apply - in practice the resolver's callbackDispatcher, i.e. Main.

latoFallback​

fun latoFallback(context: Context) : BBFontProvider

A shared, frozen, Lato-only provider for views that have not been handed their owner's provider yet (a screen's init block runs before BBNativePlayerView can inject one). It refuses [apply], so it can never pick up another player's font, and its loader holds the application context, so it leaks nothing.