review: M0/M1 成果审查后的质量加固
三路独立审查:桥引擎(对照 lzyzsd 逐字)与契约 SSOT(对照原 Android 44 handler) 两个命门维度【零问题】;以下为架构/质量改进项的修复: - [安全红线] BridgeGameContainer setWebDebuggingAccess 加 AppEnv.isDebug() 守卫 (common 新增 AppEnv,用 bundleManager.appInfo.debug 运行时判断,release 自动关闭, 消除 CLAUDE.md 附录B 红线违反) - [生命周期] BridgeController 加 dispose() 清回执表/注册表/启动队列;HandlerRegistry 加 clear();容器 aboutToDisappear 先 dispose 桥再 dispose adapter 并置空,防残留命中/泄漏 - [事件总线] EventBus.on/once 返回取消函数支持 per-subscriber 精确退订;off→offAll 并 标注谨慎(避免 M3 多容器订阅 appservice 时误注销他人回调) - [单测] 加强 escape 断言覆盖内层 " 加倍(命门);新增 dispose 用例;16 用例全通过, 桥核心覆盖率 89.0% - [记录] Index.pageMap param as 运行期不校验,M4 外部 scheme 唤起时需补校验(已注释) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
74b302e131
commit
bdb920f61e
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 运行环境判断(生产加固,对应 CLAUDE.md 附录 B 红线)。
|
||||
*
|
||||
* isDebug():是否为 debug 包(debug 签名)。用于守卫仅 debug 可开的能力,
|
||||
* 如 setWebDebuggingAccess——release 包 appInfo.debug 为 false,自动关闭远程调试。
|
||||
* 等价 BuildProfile.DEBUG 的意图,但用运行时签名信息判断、不依赖构建期字段注入。
|
||||
*/
|
||||
import { bundleManager } from '@kit.AbilityKit';
|
||||
|
||||
export class AppEnv {
|
||||
private static debugCache: boolean | undefined = undefined;
|
||||
|
||||
static isDebug(): boolean {
|
||||
if (AppEnv.debugCache === undefined) {
|
||||
try {
|
||||
const info = bundleManager.getBundleInfoForSelfSync(
|
||||
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
|
||||
AppEnv.debugCache = info.appInfo.debug;
|
||||
} catch (e) {
|
||||
AppEnv.debugCache = false; // 取不到时保守按 release(不开调试)
|
||||
}
|
||||
}
|
||||
return AppEnv.debugCache;
|
||||
}
|
||||
}
|
||||
@@ -11,18 +11,27 @@ import { emitter } from '@kit.BasicServicesKit';
|
||||
export type EventPayload = Record<string, Object>;
|
||||
|
||||
export class EventBus {
|
||||
/** 持续订阅。 */
|
||||
static on(eventId: string, callback: (payload?: EventPayload) => void): void {
|
||||
emitter.on(eventId, (ev: emitter.EventData) => {
|
||||
/** 持续订阅。返回取消函数——调用它仅注销本次订阅(per-subscriber,不影响其他订阅者)。
|
||||
* 多容器/多订阅者共享同一 eventId(如 appservice 前后台)时务必用返回值退订,勿用 off(eventId)。 */
|
||||
static on(eventId: string, callback: (payload?: EventPayload) => void): () => void {
|
||||
const wrapper = (ev: emitter.EventData) => {
|
||||
callback(ev.data);
|
||||
});
|
||||
};
|
||||
emitter.on(eventId, wrapper);
|
||||
return () => {
|
||||
emitter.off(eventId, wrapper);
|
||||
};
|
||||
}
|
||||
|
||||
/** 单次订阅,触发后自动取消。 */
|
||||
static once(eventId: string, callback: (payload?: EventPayload) => void): void {
|
||||
emitter.once(eventId, (ev: emitter.EventData) => {
|
||||
/** 单次订阅,触发后自动取消。返回取消函数(触发前可主动退订)。 */
|
||||
static once(eventId: string, callback: (payload?: EventPayload) => void): () => void {
|
||||
const wrapper = (ev: emitter.EventData) => {
|
||||
callback(ev.data);
|
||||
});
|
||||
};
|
||||
emitter.once(eventId, wrapper);
|
||||
return () => {
|
||||
emitter.off(eventId, wrapper);
|
||||
};
|
||||
}
|
||||
|
||||
/** 发布事件。 */
|
||||
@@ -31,8 +40,8 @@ export class EventBus {
|
||||
emitter.emit(eventId, data);
|
||||
}
|
||||
|
||||
/** 取消该事件的全部订阅。 */
|
||||
static off(eventId: string): void {
|
||||
/** ⚠ 取消该事件的【全部】订阅(粗粒度)。多订阅者场景请改用 on() 返回的取消函数。 */
|
||||
static offAll(eventId: string): void {
|
||||
emitter.off(eventId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user