## Context

在 phase-2a/2b（激励/插屏，已验证的五步法模板）之上实现开屏。**权威设计在 SPACE，本文只引用不复制**：

- L1 API：SPACE **§4.11 `ATSplashAd`**
- TurboModule 方法：SPACE **§7.6**（开屏）
- callbackName 全量：SPACE **§17.3**（开屏 15 个，已落地在 `Const.java` 的 `SplashCallback`）
- 执行步骤：实施规范 **Step 2-C**
- 对拍：`docs/android-rn-parity.md`

## Goals / Non-Goals

**Goals:**
- Android 开屏 load → show（容器内）→ close 全链路真实可跑（ADX 源）。
- **容器高度可配**（全屏 / 半屏），不引 Fabric。
- 加载超时语义：`fetchAdTimeout` + `onAdLoaded(isTimeout)` 透传 + `splashDidTimeout`。
- 回调经唯一 `ATReactNativeEventEmitter`（callName `SplashCall`），按 placementID 分发到 `ATSplashAd.setAdListener`。
- iOS 编译过 + 路由 log 可见。

**Non-Goals:**
- Banner/Native（Fabric 视图，留 2d/2e）；iOS 真实开屏；开屏 AutoLoad（开屏无 Auto）。
- 新错误码 / 新 EventEmitter（复用既有）。

## Decisions

- **照搬 phase-2a/2b 模式**：开屏两件套与激励/插屏对应，仅类型/字典/容器不同：
  `ATAdSplashManger → ATSplashManager`（路由 + `ConcurrentHashMap<placementId, Helper>` + Promise/init/Activity 门控 + RN 类型转换）、
  `ATSplashHelper`（持 `ATSplashAd` + `ATSplashExListener` + AdSource listener，回调经 `emit(SplashCall, callbackKey, pid, adInfo→Map, errMsg, extra)`）。**无 AutoHelper**。
- **callName 字段**：原生用 `Const.CallbackMethodCall.SplashCall`。
- **开屏 listener 映射**：`onAdLoaded(isTimeout)`→Loaded（extra 带 isTimeout）、`onAdLoadTimeout`→Timeout、`onNoAdError`→LoadFail、`onAdShow`→Show、`onAdClick`→Click、`onAdDismiss`→Close、`onDeeplinkCallback`→Deeplink。展示失败→ShowFailed。**无 video/reward/again**。
- **容器（核心决策）**：「桥内容器 + 高度可配」——`showSplash(pid, showConfig)` 解析 `heightRatio`(0~1)/`heightPx`，在**主线程**往 `activity.findViewById(android.R.id.content)` 加一个该高度的 `FrameLayout`（不传则 `MATCH_PARENT` 全屏），调 `ATSplashAd.show(activity, container[, scenario])`；`onAdDismiss` 时主线程 `removeView` 容器（防泄漏）。skip 区用 `ATSplashSkipInfo` 默认或不传。**不引 Fabric**（Banner/Native 2d/2e 再上 Fabric 视图）。
- **load 超时**：settings 含 `fetchAdTimeout`(ms) 时用 `new ATSplashAd(activity, pid, listener, fetchAdTimeout)`，否则默认构造；`isTimeout` 经 onAdLoaded 的 extra 透传给 JS。
- **错误只走 Event**：load 失败/超时 → `splashDidFailToLoad`/`splashDidTimeout` + `requestMessage`，不 reject；reject 仅用于未 init（`SDK_NOT_INITIALIZED`）/无 Activity（`ACTIVITY_NULL`）。
- **下行结构化对象**：load 的 extra 走 ReadableMap；复杂嵌套经 `BridgeJsonMapUtil`，简单走 `RNMapUtil`（沿用 2a/2b）。
- **iOS stub**：开屏桥方法空实现 + NSLog；查询返回 false；真实实现留 iOS 同事。

## Risks / Trade-offs

- [容器泄漏] → `onAdDismiss`/`onAdShowFailed` 都在主线程移除容器；Helper 持容器引用，show 前先移除旧容器。
- [验收文档 callbackName 简写] → 一律以 **Const.java/§17.3 为准**（如 `splashDidShowSuccess`/`splashDidClose`），spec 用真实名。
- [ADX 开屏不 fill / 超时] → 用开屏 ADX 测试位 `b5fdc16eb9e2ee`；no-fill/timeout 时验失败/超时事件也算达标。
- [ATSplashExListener 接口方法集与 6.5.73 差异] → 移植后编译报错按真实接口调整（同 2a/2b 流程，用户本机编译反馈）。
- [半屏布局错乱] → 容器宽 `MATCH_PARENT`、高按 ratio/px；半屏时下方留白由宿主放 logo（Example 演示）。
