## Context

在 phase-1（init + 统一事件通道）之上实现激励视频。**权威设计在 SPACE，本文只引用不复制**：

- L1 API：SPACE **§4.5 `ATRewardVideoAd`** + **§4.6 `ATRewardVideoAutoAd`**
- TurboModule 方法：SPACE **§7.2**（激励）
- callbackName 全量：SPACE **§17.3.2**（21 个，已落地在 `android/.../utils/Const.java` 的 `RewardVideoCallback`）
- 执行步骤：实施规范 **Step 2-A**
- 对拍：`docs/android-rn-parity.md` §3
- 移植坑 / 线程：`docs/RN-SDK-开工前调研补遗.md`

## Goals / Non-Goals

**Goals:**
- Android 激励 load → show → 激励发放 全链路真实可跑（ADX 源）。
- 回调经唯一 `ATReactNativeEventEmitter`（callName `RewardedVideoCall`），由 `ATAdEvents` 按 placementID 分发到 `ATRewardVideoAd.setAdListener`。
- again（再看一次）、AdSource（竞价/瀑布）、destroy、Auto 加载覆盖。
- iOS 编译过 + 路由 log 可见。

**Non-Goals:**
- 插屏/开屏/Banner/Native（后续 Phase）。
- iOS 真实激励业务（iOS 同事后补）。
- 新错误码枚举（复用 phase-1 的 `Const.BridgeError`）。

## Decisions

- **移植而非重写**（实施规范 R2）：Flutter `reward/` 三个类 1:1 搬，仅改包名 `com.anythink.reactnative`：
  `ATAdRewardVideoManger → ATRewardVideoManager`（路由 + placement→Helper 字典）、`ATRewardVideoHelper`（类名不变，持 `ATRewardVideoAd` 实例 + Listener）、`ATAutoLoadRewardVideoHelper`。Listener 回调内把 `ATAdInfo`/`AdError` 转字典 → `ATReactNativeEventEmitter.sendCallback(RewardedVideoCall, callbackName, placementId, ...)`。
- **一 placementId 一 Helper**（R3）：`ConcurrentHashMap<placementId, Helper>`，禁止另建 Cache 类。
- **错误只走 Event**（F5/R-F08）：load/show 失败 → `rewardedVideoDidFailToLoad` 事件 + `requestMessage = AdError.getFullErrorInfo()`，**不** `Promise.reject`。`reject` 仅用于参数非法 / Activity 空 / 未 init（`SDK_NOT_INITIALIZED`）。
- **show 需 Activity**：桥内 `getCurrentActivity()`，空则 reject `ACTIVITY_NULL` + log（WARN）。
- **AdSource 回调异步线程**：Flutter 用 singleThreadExecutor 串行发送（避免阻塞）；RN 沿用，最终 emit 仍切主线程（EventEmitter 内已守护）。
- **下行参数结构化对象**：load 的 extra（userId/userData/atAdRequest 底价等）走 ReadableMap；复杂嵌套（atAdRequest）经 `BridgeJsonMapUtil`，简单走直转（沿用 phase-1 RNMapUtil）。
- **iOS stub**：`ios/.../Reward/` 各方法空实现 + NSLog；getRewardedVideoValidAds 等查询返回空；真实实现留 iOS 同事。

## Risks / Trade-offs

- [ADX 源不 fill → 验证不到 show] → 用 ADX 测试位 `b5fdc16c943b7f`（后台已配 ADX 源）；no-fill 时验 `rewardedVideoDidFailToLoad` + requestMessage 路径也算达标。
- [rewardedvideo 模块版本与 core 6.5.73.3 不匹配] → apply 时查 jfrog china_sdk 确认匹配版本；编译/运行报错按日志修。
- [iOS play-fail 错名坑] → Android 本期真实实现，按 §17.3.2 正确用 `rewardedVideoDidFailToPlay`（不照抄 Flutter iOS 的 FailToLoad 错误）；iOS stub 阶段也用正确常量。
- [Listener 回调线程] → 全部经 EventEmitter 主线程守护 emit（phase-1 已验证）。
