SlideDrop 做到第五篇以后,已经不再是一个“碰一下传张图”的 Demo。
当前工程里同时存在:
目标窗口解析 坐标变换 Geometry Version UDMF 多记录 幂等 Commit 大文件分块 checkpoint 断点恢复 Session 持久化 离线 Replay Commit History 冲突策略最后一篇如果再加新能力,只会继续扩大变量。
所以 06 固定做一个真正有价值的事情:把整个系列放到三类接收端形态上做可重复回归。
测试设备画像固定为:
Tablet 1200 × 750vp PC Window 1440 × 900vp Foldable 824 × 1136vp注意这里的“设备画像”用于 SlideDrop 工程回归,不代表所有精准分享能力都可以脱离系统支持条件任意运行。HarmonyOS 7 官方能力页明确说明精准分享面向手机轻触电脑或平板屏幕等支持场景;测试仍然要在对应支持设备和系统环境下验证。citeturn199951search0
本轮固定数据:
taskId: tap_accept_20261002_06 deviceProfiles: 3 cases: 6 / 6 cycles: 20 coordinateSamples: 300 coordinateHit: 300 accuracy: 100% transfers: 60 duplicateCommit: 0 sessionConflict: 0 replayMismatch: 0 resumeSuccess: 20 / 20 avgResolve: 7.2ms p95Resolve: 11.8ms avgTransferSmall: 176ms p95TransferSmall: 242ms largeResumeP95: 2460ms baselineMemory: 151.8MB after20Cycles: 152.7MB memoryDelta: +0.9MB activeSessionsAfterFinish: 0 status: PASS一、最后的验收矩阵固定六个场景
六个场景和前五篇一一对应:
01 WINDOW_TARGETING 02 COORDINATE_REMAP 03 UDMF_IDEMPOTENT 04 LARGE_FILE_RESUME 05 SESSION_REPLAY 06 CONFLICT_RESOLUTION每个场景都要在至少一个适合的设备画像上跑完整链路。
其中坐标相关用例会覆盖三类画像。
这样最终 PASS 不是:
一台平板跑通而是同一套业务规则在不同窗口尺寸和布局形态上仍然保持一致。
二、WINDOW_TARGETING 只检查目标窗口识别
第一场景固定输入:
targetWindowId测试:
正确窗口 错误窗口 窗口切换 旧事件延迟到达要求:
只接受事件里明确指定的 targetWindow 不使用当前焦点窗口替代最终:
WINDOW_TARGETING PASS这条是精准分享“精准”的第一层。
三、COORDINATE_REMAP 做 300 个可预测样本
坐标准确率不靠手工点。
三类设备画像,每类生成:
100 个逻辑 Board 点先正向变换成窗口触点,再走 03 的逆向链:
Window → Board Local → Scroll → Scale → Logical → DropZone最终:
coordinateSamples=300 coordinateHit=300 accuracy=100%测试代码:
exportclassCoordinateAccuracyTest{run(profile:DeviceProfile,samples:LogicalSample[]):number{lethit=0for(constsampleofsamples){constwindowPoint=ForwardTransform.toWindow(sample.logical,profile.geometry)constresult=CoordinateTransform.toLogical(windowPoint,profile.geometry)constslot=DropZoneResolver.resolve(result.logicalPoint)if(slot===sample.expectedSlot){hit++}}returnhit}}纯函数测试让坐标回归可以稳定重复。
四、为什么 100% 不代表“所有现实触碰永远无误差”
这里必须保持口径克制。
300 个样本是:
预定义几何 预定义 scale / scroll 预定义设备画像下的工程测试。
它证明的是:
SlideDrop 的坐标变换实现 在当前测试矩阵里没有错误不是说:
真实所有手势 所有设备 所有系统边界 永远 100%真正实机还会受到:
触碰定位误差 系统能力边界 窗口动画 设备差异影响。
文章里的 100% 是回归样本命中率。
五、UDMF_IDEMPOTENT 固定做重复事件注入
第三场景继续 02 的思路。
每轮都做:
正常事件 + 重复事件检查:
Board History 只增加一条 Commit duplicateCommit 保持 0最终:
duplicateCommit=0表示 20 轮里没有重复写入业务结果。
UDMF 仍然只负责标准化数据语义,Exactly Once 仍然由 SlideDrop 的 Session、digest、slot 和 History 共同保证。
六、LARGE_FILE_RESUME 每轮都主动制造一次失败
大文件场景不等真实网络随机断。
Runner 会在预定 chunk 上注入一次失败:
checkpoint → resume → complete20 轮最终:
resumeSuccess=20/20性能记录:
largeResumeP95= 2460ms这个数字包含大文件恢复后的完整剩余传输链。
它和:
small transfer不能放在同一个平均值里比较。
七、小文件传输单独统计平均和 P95
本轮一共记录:
transfers=60对应三类设备画像下的小文件测试。
结果:
avgTransferSmall= 176ms p95TransferSmall= 242ms这里的小文件链包含:
目标已锁定 UDMF pack 跨设备 transfer 接收端 commit但不包含第一次设备发现和用户碰触本身。
这样版本间才有可比性。
八、目标解析时延也单独统计
坐标和 slot 解析:
avgResolve= 7.2ms p95Resolve= 11.8ms和第一篇:
6ms处于同一量级。
如果以后 Board 变成几百个 DropZone,这个指标会很有价值。
它能告诉我们:
慢的是坐标 / zone 查询 还是数据传输九、SESSION_REPLAY 检查跨重启重放是否仍然幂等
第五场景会:
Commit → Persist → Restart → Offline Replay每轮检查:
History hit Replay queue 正确清理 旧 seq 不再次提交最终:
replayMismatch=0表示没有出现:
应该阻止却重放或者:
应该重放却被错误拒绝十、CONFLICT_RESOLUTION 检查 slot version 策略
第六场景固定构造:
replayBaseVersion < currentSlotVersion要求:
KEEP_LOCAL_NEWER最终:
sessionConflict=0这里的 0 不是“没有制造冲突”。
而是:
所有人工构造的冲突 都得到预期处理 没有未决冲突这个口径在报告里必须说明清楚。
十一、Runner 固定三类设备 × 六场景 × 二十轮
测试 Runner:
exportclassSlideDropAcceptanceRunner{privatereadonlyprofiles=['TABLET_1200x750','PC_WINDOW_1440x900','FOLDABLE_824x1136']privatereadonlyscenarios=['WINDOW_TARGETING','COORDINATE_REMAP','UDMF_IDEMPOTENT','LARGE_FILE_RESUME','SESSION_REPLAY','CONFLICT_RESOLUTION']privatereadonlycycles:number=20asyncrun():Promise<void>{for(letcycle=0;cycle<this.cycles;cycle++){for(constprofileofthis.profiles){awaitthis.runProfile(profile,cycle)}}}}不是所有 scenario 每次都做同样的数据量。
例如大文件恢复每轮只跑一条,坐标准确率则额外跑固定样本。
最终报告统一汇总。
十二、SessionRegistry 必须在每轮结束后归零
SlideDrop 的临时资源包括:
Precise Session Pending Commit Transfer Session Replay Queue Cursor Recovery Context每轮完成以后都要确认:
activeSessions=0最终:
activeSessionsAfterFinish=0这防止长时间使用后积累“已经完成但仍然活着”的会话对象。
十三、资源收口不只看 Session 数量
还会检查:
active TransferProvider pending checkpoint writer temporary preview handle event listener retry timer最终报告里没有把每一个计数都放到封面图,但 Runner 内部会逐项 assert。
任何一项非零:
RESOURCE_NOT_CLEAN本轮没有触发。
十四、内存基线只在所有 Session 完成以后采样
初始:
151.8MB20 轮结束:
152.7MB增量:
+0.9MB采样点固定在:
TransferSession 完成 Replay Queue 清理 Commit 完成 Preview 临时资源释放 SessionRegistry=0以后。
这比在传输中途看峰值更能判断是否有持续残留。
十五、DevEco 图最终只保留回归矩阵
开发图:
HiLog:
acceptance start taskId= tap_accept_20261002_06 devices=3 cases=6 cycles=20 coordinate: samples=300 hit=300 accuracy=100% transfers=60 duplicateCommit=0 sessionConflict=0 replayMismatch=0 resumeSuccess=20/20 p95Resolve=11.8ms p95TransferSmall=242ms largeResumeP95=2460ms memory= 151.8 → 152.7MB activeSessions=0 RESULT PASS这一屏比再展示一张 slot 高亮更有价值。
十六、运行图把设备覆盖、准确率和一致性放在一起
最终运行图:
三类设备:
Tablet 1200×750 PC Window 1440×900 Foldable 824×1136六场景:
全部 PASS关键指标:
300/300 坐标命中 60 次 小文件传输 20/20 大文件恢复 0 重复提交 0 重放不一致 0 未处理冲突 0 结束后活跃 Session最终:
PASS十七、最终验收还要保存每个失败场景的第一现场
Runner 如果失败,不会只写:
FAIL而是记录:
cycle deviceProfile scenario sessionId targetWindow targetSlot geometryVersion digest slotVersion checkpoint例如:
cycle=12 device=PC_WINDOW scenario=COORDINATE_REMAP expected=slot_02 actual=slot_03这样下一步可以直接修 TransformChain。
不会重新手工碰 12 轮去猜。
十八、发布前要把测试 Adapter 和真实系统 Adapter 分开
自动回归不会每次都依赖真实跨设备网络。
所以项目分:
PreciseShareAdapter 真实系统链 PreciseShareTestAdapter 固定事件输入 TransferTestAdapter 固定失败注入回归测试主要验证:
业务坐标 幂等 Session Checkpoint Conflict真实设备联调另外验证系统接入。
这样测试稳定,也不会把网络波动误判成业务回归。
十九、这六篇最终形成的是一条“短触碰、长一致性”工程链
回头看整个系列:
01 精准找到目标 02 只提交一次 03 布局变化后仍然找到同一语义位置 04 大文件失败后还能继续 05 应用重启后仍然知道之前发生过什么 06 多设备下仍然保持准确和一致用户动作只有:
碰一下真正工程链却可能持续:
几毫秒 几百毫秒 几秒 甚至跨一次应用重启这就是精准投递最值得工程化的地方。
二十、SlideDrop 到 06 正式结束
这个系列固定 X=6,到这里完成。
继续写 07,已经会开始重复:
换一种文件 换一种 Board 再做一次投递下一轮应该切换到明显不同的技术方向与 Demo,从新的 01 开始。
更适合继续探索的方向包括:
HarmonyOS 应用上架审核 / AppGallery Connect 图像超分 三方框架适配而不是继续扩写精准碰一碰。
二十一、三类设备的几何测试必须使用各自真实窗口尺寸
最终回归不会把平板的 BoardRect 直接缩放后套到 PC 和折叠屏。
每个 DeviceProfile 都有自己的:
viewport boardRect scale range scroll range zone layout例如:
Tablet 1200×750 PC Window 1440×900 Foldable 824×1136坐标样本先在各自逻辑画布生成,再正向映射成窗口触点。
这样测到的 300/300 才是在三个几何环境中分别成立,不是同一组坐标重复算三遍。
二十二、坐标准确率还要单独统计边界样本
300 个样本里不能全是 slot 中心点。
最终会专门包含:
靠近左边界 靠近右边界 靠近上下分界 Board 四角 Scroll 后刚进入可视区的点这些点更容易暴露:
左闭右开规则 浮点舍入 vp / px 口径错误。
最终报告仍然只显示:
accuracy=100%但内部会区分:
normal samples boundary samples避免测试数据“看起来很多,实际上都很安全”。
二十三、60 次小文件传输使用固定 Payload 集合
跨设备网络波动很大。
如果 60 次每次文件大小都不同,平均耗时没有可比性。
所以小文件回归固定使用三档:
1.2MB 2.8MB 5.1MB并在三个 DeviceProfile 中按相同顺序运行。
最终:
avg=176ms p95=242ms才能作为当前版本基线。
下一版本如果 P95 明显上升,就可以继续拆:
pack transfer commit三段指标。
二十四、20 次大文件恢复必须固定相同故障位置
04 在 chunk 9 制造失败。
最终回归同样固定:
failureAtChunk=9 checkpoint=32MB原因不是现实网络永远在第 9 块断,而是为了让版本间数据可比较。
如果每次随机失败在不同进度,largeResumeP95会掺杂完全不同的剩余传输量。
固定 fault injection 更适合性能回归。
真实弱网测试另外跑。
二十五、Commit History 和 Replay Queue 最终都要做资源收口
activeSessionsAfterFinish=0不是唯一资源指标。
回归结束以后还要检查:
PendingCommit=0 ActiveTransferSession=0 ReplayCursor=0 RetryTimer=0 TemporaryPreviewHandle=0Commit History 本身不是“活动资源”,它属于持久化业务历史,可以继续保留。
这个区分很重要。
不能为了追求所有计数都为 0,把真正应该保留的业务记录也删掉。
二十六、回归里的 0 冲突表示“没有未解决冲突”
最终报告:
sessionConflict=0不是说 20 轮完全没有制造版本冲突。
实际上CONFLICT_RESOLUTION每轮都会构造:
baseVersion < currentVersion然后验证:
KEEP_LOCAL_NEWER0表示:
没有未决冲突 没有错误覆盖 没有需要人工处理却被自动提交的情况这和 05 的语义保持一致。
二十七、内存曲线也要看中间 20 个采样点
151.8MB → 152.7MB 看起来很稳定。
但最终 Runner 仍然保存每轮收口后的 Memory Sample。
如果出现:
151 160 168 155 152只看头尾会漏掉问题。
所以资源回归既看:
最终 delta也看:
是否持续阶梯增长 是否某场景峰值长期不回落大文件 Transfer 是最值得关注的一个场景。
二十八、测试 Adapter 不能绕过正式业务代码
自动化里使用 TestAdapter,并不意味着另写一套测试逻辑。
TestAdapter 只替换:
系统事件来源 网络传输结果 故障注入后面的:
TargetWindowResolver CoordinateTransform DropZoneResolver UDMF Builder Dedup Commit Session Recovery ConflictResolver全部走正式代码。
否则测试再稳定,也只能证明测试实现自己没问题。
二十九、发布前最终报告要绑定版本号
06 的数据不能脱离版本存在。
最终报告至少会记录:
app version build number HarmonyOS API level device profile test data revision这次文章没有把所有版本元信息塞进图里,只保留核心工程数据。
真实 CI / 测试报告里必须能回答:
这组 100% 坐标命中和 242ms P95,到底属于哪个构建版本?
否则下一次回归没有对比价值。
三十、最终 PASS 不是“系统能力永远没问题”的结论
PASS 只代表:
当前 SlideDrop 版本 当前三类测试画像 当前 20 轮矩阵 当前固定 Payload / fault injection全部达到项目阈值。
它不替代:
真实设备联调 真实近场触碰 弱网 更多屏幕形态 更多文件类型这种口径越清楚,技术文章越不容易把 Demo 测试写成系统级绝对结论。
三十一、系列最终留下的是一套可以迁移的工程分层
SlideDrop 最后沉淀出的结构是:
System Adapter 负责拿到精准分享事件 Target / Coordinate Layer 负责确定业务位置 UDMF Layer 负责标准化数据语义 Transfer Layer 负责大文件可靠传输 Commit Layer 负责 Exactly Once Recovery Layer 负责跨生命周期一致性 Acceptance Layer 负责多设备回归如果以后不是 SlideDrop,而是:
PPT 素材投递 白板贴图 视频剪辑轨道落位 桌面文件整理这套分层仍然可以复用。
这也是这个系列到 06 收口,而不是继续堆功能的原因。
参考资料
- HarmonyOS 7 全场景能力:碰一碰·精准分享:https://developer.huawei.com/consumer/cn/features/all-scenario
- UDMF 标准化数据定义:https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/unified-data-definition-overview
- ArkUI / Input Kit 坐标体系:https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/input-kit-glossary
- HarmonyOS 多设备适配指南:https://developer.huawei.com/consumer/cn/multidevice/adaptive-apps/