Skip to content

ad_flow 5.2.0

Choose a tag to compare

@faizahmaddae faizahmaddae released this 21 Jul 12:53
26370ba

A focused reliability release. Backward-compatible — no migration.

Never load while Mobile Ads init is in flight

No ad request is ever sent while the real MobileAds.initialize() future is still running, on every path:

  • Ordinary first-frame fail-open / vacuous config — the request-config gate no longer honours fail-open while init is still running; it blocks with AdBlockReason.requestConfigNotApplied and fail-open applies only after init has genuinely completed (a config attempted and failed for real).
  • The forwardConsent-starts-init-later path — for a mediation forwardConsent adopter the SDK's init only starts after forwarding succeeds, i.e. after the first config check already ran. The gate now re-settles request configuration after the forwarding barrier, so a placement can no longer slip through on the forwarding-path init-wait timeout while init is still in flight. Forward-before-init is preserved.
  • Prompt recovery — when init completes late, request configuration is applied at once and blocked slots recover automatically (no app code, no long cooldown, no duplicate config calls or load storms). A never-completing init leaves slots in an honest blocked state, never AdLoading, never a request. Startup stays fully non-blocking.

In-flight disableAds() (Remove-Ads) protection

A disableAds() that lands after a load passed the gate but before the SDK returned its handle no longer publishes the late handle as loaded or keeps it warm. Banner, Native, Interstitial, Rewarded, Rewarded Interstitial, and App Open now re-check the current permission synchronously immediately before installing the handle, drop it if ads are disabled (AdBlocked(adsDisabled)), and re-warm on enableAds(). A transient indeterminate read never drops good inventory.

SSV backend-security guidance

Rewarded / rewarded-interstitial docs now explain, operationally: onReward is a client-side signal, not proof; attaching userId/customData does not prove backend verification; the backend must verify Google's callback signature and key_id, validate user / ad-unit / reward / custom data, and process transaction_id idempotently; the two fulfillment strategies; a no-double-grant warning; and a link to Google's official Flutter SSV guide.

Public API

  • +AdGate.isEnabled — one additive getter (mirrors AdGate.consentGeneration). This is the entire delta; no removals, no signature/enum/default changes; hence a correct minor. No migration.

Known limitation

The upstream google_mobile_ads 9.0.0 App Open failed-load leak remains (the plugin omits dispose() on that branch and its callback carries no ad reference, so the seam cannot fix it) — low-severity, process-bounded.

Verification

543 tests pass; analyze & format clean; pana 160/160; publish dry-run 0 warnings; Android and iOS simulator example builds pass. No physical-device run was performed — not required for this pure-Dart lifecycle change.