## Context

全项目最复杂样式（自渲染 + viewTag 绑定 + video）。**权威设计在 SPACE，本文只引用不复制**：

- L1 两类 + Fabric props：SPACE **§4.10**（ATNative / NativeAd / ATNativeAdViewProps）
- 自渲染 prepareInfo key：SPACE **§17.4.6**（appIcon/mainImage/title/desc/adLogo/cta/dislike/parent/elementsView/customView/isAdaptiveHeight）
- Fabric 视图层 / 自渲染托管：SPACE **§8.7**、§9.5
- callbackName（16 个）：Const.java `NativeCallback`（callName `NativeCall`）
- **Fabric 落地参考**：`docs/RN-SDK-Fabric落地参考与待写文档.md` Part A（A.5 自渲染要点）
- **2d Banner 实现**（同源 Fabric 地基）：`openspec/changes/archive/2026-06-11-phase-2d-banner/` + `docs/superpowers/plans/2026-06-11-phase-2d-banner.md`

## Goals / Non-Goals

**Goals:**
- Android `<ATNativeAdView>` 内嵌；**自渲染**：开发者 RN 拼布局，`prepare/renderAdContainer` 经 viewTag 把 RN 视图绑给 SDK，点击/曝光生效（N-F02）。
- **模板**模式：SDK 整体渲染（N-F03）。
- 两类 L1：`ATNative`（加载器）+ `NativeAd`（已加载，prepare/destroy）严格对齐 §4.10。
- 事件经 `NativeCall` 通道 → `ATAdEvents` 按 placementID 分发（含 video/AdSource）。
- 列表多 item 不串位（N-F07）；deeplink/下载确认对齐 Demo（N-F05/F06）。
- iOS 编译过 + 路由 log 可见。

**Non-Goals:**
- iOS 真实自渲染；Flutter 独有非标方法；视频/下载控制超出 Android NativeAd public API。

## Decisions

- **两类职责**：`ATNative`（按 placementId 一个加载器，持 ATNativeManager 路由）；`getNativeAd()` resolve 一个 `NativeAd` 句柄（桥内 ATNativeHelper 持原生 NativeAd），无广告 resolve(null)。`NativeAd.prepare/renderAdContainer` 把 prepareInfo 下发原生绑定。
- **自渲染 viewTag 绑定（核心，A.5）**：
  - L1 `prepareInfo` 的元素（appIcon/title/cta…）值为 **RN ref → `findNodeHandle(ref)` 得到的 viewTag(number)**；`elementsView` 为 viewTag 数组。
  - 桥内（UI 线程）`UIManagerModule.resolveView(tag)` 取 RN 原生 view，移植 Flutter `SelfRenderViewUtil` 把它们组装成 `ATNativePrepareInfo`（原生）注册给 `NativeAd.renderAdView/prepare`，SDK 据此做点击/曝光。
  - `parent` = Fabric 容器（ATNativeAdView 的 view）；自渲染时广告内容由 RN 子树渲染，SDK 只注册元素。
- **模板模式**：prepareInfo 不给 elementsView（或给 customView），SDK `renderAdView` 整体渲染进容器（类似 banner）。
- **Fabric 复用 2d**：`ATNativeAdViewManager` 照 `ATBannerViewManager`——三层结构、**容器 requestLayout 强制 measure/layout**、props 延迟 init、dp→px、onDropViewInstance→destroy。Package `createViewManagers` 加注册。
- **codegen**：新增 `src/specs/ATNativeAdViewNativeComponent.ts`（`codegenNativeComponent('ATNativeAdView')` + 复用 codegen 深路径 shim）。命令式桥方法加进 `NativeATBridge.ts`。
- **尺寸（§4.10 props + Android 可选宽高）**：`ATNativeAdView` props = §4.10 的 placementID/sceneID/isAdaptiveHeight/extraMap，**外加可选 `adWidth?`/`adHeight?`**（Android 原生 native 支持可选 AD_WIDTH/AD_HEIGHT，Demo 实证）。语义：
  - 给了 adWidth/adHeight → dp→px → `ATAdConst.KEY.AD_WIDTH/AD_HEIGHT` 下发 SDK（模板模式定尺寸）；
  - 未给 → 回退 isAdaptiveHeight / RN 布局测量尺寸（自渲染由 RN 布局定大小）。
  两者皆**可选**，不破坏 §4.10 对齐（附加项），也不像 banner 那样必填。
- **事件**：移植 ATNativeHelper 的 listener（含 video onAdVideoStart/End/Progress、onAdCloseButtonClick、deeplink、AdSource 6、MultipleLoaded）→ emit NativeCall。L1 ATNative 实例内按 callbackName 分流（AdSource/multipleLoaded 拆出）。
- **移植**：Flutter `ATAdNativeManger→ATNativeManager`（ConcurrentHashMap<pid,Helper>）、`ATNativeHelper`（持 ATNative loader + NativeAd + Listener）、`ATNativeViewFactory/ATAndroidNativeView→ATNativeAdViewManager+view`、`SelfRenderViewUtil`、`ViewInfo`。沿用 load(atAdRequest)/lazy-cache/Promise/scenarioId。
- **iOS stub**：native ViewManager + view 空实现 + 命令式 stub + NSLog；prepareInfo 双端兼容（iOS 无 elementsView，L1 形态保持但 iOS 侧忽略）。

## Risks / Trade-offs

- [自渲染 viewTag 时序] RN 视图要先挂载布局好才能 resolveView/绑定 → `prepare/renderAdContainer` 在 RN 子树 mount 后调用；时序问题 apply 时按真机调（参考 Flutter SelfRenderViewUtil 的时机）。
- [viewTag→native view 解析] New Arch 用 `UIManagerModule.resolveView(tag)`（或 Fabric 的等价）；与 ViewManager 协作，apply 按编译/运行报错接。
- [iOS prepareInfo key 差异] iOS 无 elementsView → L1 prepareInfo 形态对双端兼容（标准元素 key + elementsView 可选）；iOS stub 忽略，真实由 iOS 同事。
- [Native API 是否在 core] 应在 core-taku:6.5.73.3（同 banner，grep 混淆假阴）；apply 编译确认，缺则加 nativead-taku。
- [Fabric 容器布局] 复用 2d 的 requestLayout 强制 measure/layout 修复（自渲染容器同样需要）。
- [本 Phase 最复杂] propose 后**务必 writing-plans**：两类 API 时序、elementsView viewTag 绑定、双端 ViewManager、iOS prepareInfo 差异都要砸实再 apply。
