Skip to content

Add an Arbiter/TPA demo: CloudX vs AdMob through Trusted Arbiter - #7

Open
antonurankar-moloco wants to merge 3 commits into
mainfrom
tomi-arbiter-tpa-demo
Open

Add an Arbiter/TPA demo: CloudX vs AdMob through Trusted Arbiter#7
antonurankar-moloco wants to merge 3 commits into
mainfrom
tomi-arbiter-tpa-demo

Conversation

@antonurankar-moloco

@antonurankar-moloco antonurankar-moloco commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Implements the third demo flow behind the Options screen's Arbiter/TPA button: CloudX and AdMob load in parallel for all four formats and CloudXSdk.Arbiter decides which one is shown, following docs.cloudx.io -> Unity -> Trusted Arbiter.

What is in the change

  • Assets/Scripts/Arbiter/ (new, self-contained like FirstLook/):
    • ArbiterAdController - shared base: ids, the loaded CloudXAd, the arbiter call with its in-flight guard, the AdMob bid, and the required AdMob OnAdPaid -> ReportRevenueData forwarding.
    • ArbiterFullscreenController + interstitial/rewarded concretes - prepare-ahead: arbitrate when both candidates settle, store the winner, show it at the placement with no network call, restart the cycle on close.
    • ArbiterInlineController + banner/MREC concretes - arbitrate-then-render with a 25 s refresh cycle: only the winner's view is ever shown, the loser keeps its fill, auto-refresh is off on both sides (Stop*AutoRefresh before create; AdMob has no API, console setting).
    • ArbiterScreen - initialization, status lines for interstitial and rewarded (which sides loaded, what the arbiter returned over how many bids, what is showing), banner and MREC buttons whose labels carry the platform on screen and the bid count (Hide Banner (AdMob, 2 bids)), and the inline refresh clock.
    • ArbiterConfig - refresh interval and a ForceCloudXNoFill switch that turns every round into a single AdMob bid.
  • ArbiterScene (copy of the First Look scene with the screen script swapped), registered in the build settings; the Options button routes to it.
  • Google's AdMob test ad unit ids move from FirstLookConfig to DemoConfig, next to the CloudX ids, so both demo folders read them from one place.
  • README: Arbiter/TPA section (how it differs from First Look, the rules, file table, the dashboard prerequisite, the AdMob paid-event requirement, the Automatic-refresh callout), updated flow diagram, scene table and screenshots.

Behaviour worth knowing

  • The SDK owns the arbiter timeout and fallback; the controllers never time the call or compare prices. One bid wins without a service call; with no service the SDK falls back locally, where an AdMob bid with no reported revenue yet cannot win.
  • The screen retries with backoff only while a controller has nothing loaded, loading or decided; in every other state the controller re-requests fills itself, so a sustained no-fill never turns into a tight loop.
  • One deliberate deviation from the docs' inline cycle: the docs reload the winner the moment its impression fires. Both Unity plugins reload into the existing view, and on device that replaced the visible creative within a second of showing it and fired an AdMob impression no round had selected. The demo keeps the shown creative up for the whole interval, then hides it, reloads it together with any network that has no fill, and lets the next round decide what appears; the slot is empty for the load latency (about half a second on the emulator).
  • A show in progress blocks further Show() and Load() calls until the close or show-failure callback, so a double tap cannot reload or destroy the ad that is opening.

Verified

Android emulator (Pixel 6, API 35) and iOS simulator (iPhone 17 Pro), both with the demo app key, for which the init config carries the arbiter endpoint (Arbiter enabled: https://sdk.cloudx.io/arbitration in both native logs):

  • Two-bid rounds for all four formats reach the service and return a winner (AdMob in this run); status lines read Arbiter: AdMob (2 bids).
  • Interstitial and rewarded show the stored winner, forward the AdMob paid event (ReportRevenueData ... accepted=True), and reload only the consumed side on close before re-arbitrating.
  • Banner and MREC show only the winner (CloudX and AdMob rounds both captured), re-arbitrate every 25 s, and hide both views on Hide. A transient connection reset on the emulator exercised the local fallback (arbiter comparison failed, using plaintext fallback -> CloudX) and a 60 s AdMob timeout exercised the one-bid recovery, both without intervention.
  • ForceCloudXNoFill = true: every round is one AdMob bid, the SDK logs arbiter has one bid, skipping service, AdMob wins all four formats.
  • CloudX inline views never start a refresh timer (stopAutoRefresh() on Android, Auto-refresh disabled - not starting timer and zero Immediate refresh on iOS).
  • Rotation keeps labels and status; First Look still loads all four formats from CloudX after the config move.

CloudX and AdMob load in parallel for all four formats and CloudXSdk.Arbiter
picks the platform to show. Interstitial and rewarded prepare the winner ahead
of the placement; banner and MREC arbitrate and then render on a 25 s cycle
with auto-refresh off on both sides and only the winner's view ever shown.
AdMob paid events are forwarded through ReportRevenueData, as the docs require.

The Options button routes to the new ArbiterScene. Google's AdMob test ad unit
ids move from FirstLookConfig to DemoConfig so both demo folders share them.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Fullscreen reentrancy and inline hide/show races can disrupt ad presentation, while inline status results are missing from the UI.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a Trusted Arbiter demo where CloudX and AdMob load concurrently across four ad formats.

Changes:

  • Adds fullscreen and inline arbitration controllers with AdMob revenue forwarding.
  • Adds and routes the new Arbiter scene.
  • Centralizes AdMob test IDs and documents the flow.
File summaries
File Description
README.md Documents the Arbiter demo.
ProjectSettings/EditorBuildSettings.asset Registers the Arbiter scene.
Assets/Scripts/OptionsScreen.cs Routes the Arbiter button.
Assets/Scripts/FirstLook/FirstLookScreen.cs Uses shared AdMob IDs.
Assets/Scripts/FirstLook/FirstLookConfig.cs Removes duplicated IDs.
Assets/Scripts/DemoConfig.cs Centralizes AdMob IDs.
Assets/Scripts/Arbiter/ArbiterScreen.cs.meta Registers screen asset metadata.
Assets/Scripts/Arbiter/ArbiterScreen.cs Initializes and coordinates the demo.
Assets/Scripts/Arbiter/ArbiterRewardedController.cs.meta Registers rewarded metadata.
Assets/Scripts/Arbiter/ArbiterRewardedController.cs Implements rewarded arbitration.
Assets/Scripts/Arbiter/ArbiterMrecController.cs.meta Registers MREC metadata.
Assets/Scripts/Arbiter/ArbiterMrecController.cs Implements MREC integration.
Assets/Scripts/Arbiter/ArbiterInterstitialController.cs.meta Registers interstitial metadata.
Assets/Scripts/Arbiter/ArbiterInterstitialController.cs Implements interstitial arbitration.
Assets/Scripts/Arbiter/ArbiterInlineController.cs.meta Registers inline-base metadata.
Assets/Scripts/Arbiter/ArbiterInlineController.cs Manages inline arbitration cycles.
Assets/Scripts/Arbiter/ArbiterFullscreenController.cs.meta Registers fullscreen-base metadata.
Assets/Scripts/Arbiter/ArbiterFullscreenController.cs Manages prepared fullscreen winners.
Assets/Scripts/Arbiter/ArbiterConfig.cs.meta Registers configuration metadata.
Assets/Scripts/Arbiter/ArbiterConfig.cs Defines demo switches and refresh timing.
Assets/Scripts/Arbiter/ArbiterBannerController.cs.meta Registers banner metadata.
Assets/Scripts/Arbiter/ArbiterBannerController.cs Implements banner integration.
Assets/Scripts/Arbiter/ArbiterAdController.cs.meta Registers shared-base metadata.
Assets/Scripts/Arbiter/ArbiterAdController.cs Provides arbitration and revenue plumbing.
Assets/Scripts/Arbiter.meta Registers the Arbiter folder.
Assets/Scenes/ArbiterScene.unity.meta Registers scene metadata.
Assets/Scenes/ArbiterScene.unity Defines the Arbiter demo UI.
Review details

Files not reviewed (11)

  • Assets/Scenes/ArbiterScene.unity.meta: Generated file
  • Assets/Scripts/Arbiter.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterAdController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterBannerController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterConfig.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterFullscreenController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterInlineController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterInterstitialController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterMrecController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterRewardedController.cs.meta: Generated file
  • Assets/Scripts/Arbiter/ArbiterScreen.cs.meta: Generated file
  • Files reviewed: 16/30 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Assets/Scripts/Arbiter/ArbiterFullscreenController.cs
Comment thread Assets/Scripts/Arbiter/ArbiterInlineController.cs
Comment thread Assets/Scripts/Arbiter/ArbiterScreen.cs Outdated
Comment thread Assets/Scripts/Arbiter/ArbiterScreen.cs Outdated
- Fullscreen: track the show in progress so a second tap or a retry cannot
  reload or destroy the ad that is opening; the close or show-failure callback
  restarts the cycle.
- Inline: when the interval elapses, hide the consumed winner before its reload
  (an in-place reload rendered a creative no round had selected) and re-request
  every network without a fill, not only the winner. A round invalidated by
  Hide() resumes arbitration if Show() was tapped again meanwhile.
- Screen: banner and MREC labels carry the arbiter result and bid count, since
  those formats have no status line.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants