Swift Clean v1.0.9 保活与拉活反编译代码册#
样本:
com.swiftclean.phone.managerprov1.0.9 (11)
文档日期:2026-10-12
面向:Android 开发、测试与合规复核
标签:[S1]反编译直接证据;[I]合理判断;[U]动态/线上未验证。
1. 阅读结论#
这套实现应拆成三层理解:
- 保活/恢复执行层
[S1]:前台服务mowxgu+ 启动失败 JobJMgHOxJfa+ 15 分钟 JobScheduler + 15 分钟 WorkManager + Boot/package replaced + Alarm。 - 拉活/回前台层
[S1]:Activity 生命周期观察器在 App 从后台恢复时重开FirstPage;广告外跳时用通知返回;ongoing 通知提供 6 个功能快捷入口。 - 通知召回层
[S1]:系统广播、FileObserver、周期候选、通知拦截计数与 FCM 高优先级统一进入 ID 21 的通知管线。
[I] 多路代码提高“有机会恢复”的覆盖面,不等于可突破系统 Force Stop 或 OEM 后台策略。开发对标时应复制业务目标,不应直接复制混淆实现或无保护 exported 组件。
2. 原始代码位置#
- 普通完整反编译:
jadx/sources/ - 合并资源/Manifest:
jadx/resources/ - 关键失败方法 simple-mode 补证:
jadx-simple/
JADX 1.5.5 全量运行报告 61 个错误。以下所有关键方法均给出稳定路径和行号;simple-mode 仍可能有 goto/类型推断误差,因此本册把“直接代码”和“解释”分开。
3. 启动初始化与总装配#
3.1 cIPhUu.onCreate():进程级早启动#
源码:jadx-simple/crown.arithmetic.floor.cIPhUu.java:63-160
Manifest:jadx/resources/AndroidManifest.xml:253-257
职责 [S1]:
ContentProvider、initOrder=100,进程创建阶段早于常规页面执行。- 保存 Application Context 与专用 SharedPreferences。
- 从 Manifest metadata 反射加载
PageCellar回调配置。 - 记录首次基准时间。
- 注册
qf.rActivityLifecycleCallbacks。 - 请求 Adjust attribution / adid。
- 启动两个后台协程,再调用
qf.u.b(context)装配保活体系。
忠实逻辑摘要:
onCreate() {
appContext = getContext().getApplicationContext();
prefs = context.getSharedPreferences(packageName + "_logger", 0);
callback = reflectManifestMetadata("crown.cellar.config");
recordFirstTimeIfMissing();
application.registerActivityLifecycleCallbacks(qf.r.INSTANCE);
requestAttributionAndAdId();
launchStartupCoroutine();
qf.u.b(context);
}
3.2 TotalPage.onCreate():业务 Application#
源码:jadx/sources/crown/arithmetic/floor/TotalPage.java:49-73
- 注册
TotalPageObserver到 Activity 生命周期与 ProcessLifecycleOwner。 - 首次归因缺失时连接 Install Referrer。
- 初始化 Adjust production 环境、允许后台发送、读取 adid。
- 启动业务初始化协程。
初始化标识不在本文记录;开发如需核对只在授权环境查看源码,不应复制到文档或日志。
3.3 qf.u.b(Context):保活总开关#
源码:jadx/sources/qf/u.java:57-131
void initKeep(Context c) {
createNotificationChannels(c);
if (!notificationAllowed(c)) return;
ensureForegroundService();
scheduleAlarm(c);
registerRuntimeSystemReceivers(c);
registerReliveReceivers(c);
schedulePersistentJob(c);
schedulePeriodicWork(c);
}
关键边界 [S1]:通知不可用时,函数在创建 Channel 后不再进入主要 FGS/Alarm/Job/Work 装配。
静态配置集中在 jadx/sources/crown/arithmetic/floor/manager/PageCellar.java:39-55:Job 15 分钟、Work 15 分钟、业务通知追加间隔 3,500 ms、3 个 Channel、ongoing ID 20、业务 ID 21,以及两个公开后端地址。
4. 前台服务与自恢复#
4.1 qf.b.m():确保 FGS;失败转短 Job#
源码:jadx/sources/qf/b.java:213-282
if (notificationAllowed(context) && !mowxgu.running) {
try {
startForegroundService(explicitIntent(mowxgu.class));
} catch (Throwable startFailure) {
schedule JobInfo(
id = 22002,
service = JMgHOxJfa.class,
persisted = true,
minimumLatency = 5_000ms,
overrideDeadline = about 7_000ms,
priority = 400 on API 33+
);
}
}
4.2 mowxgu:主前台服务#
源码:jadx/sources/crown/arithmetic/floor/mowxgu.java:34-121
| 方法 | 行号 | 行为 |
|---|---|---|
a() |
34-83 | 构造 ongoing 通知;ID 20;API >29 使用 FGS type 1073741824(specialUse);设置 running |
onCreate() |
97-101 | 立即调用 a() |
onDestroy() |
103-109 | running=false、停止前台后调用 qf.b.m() 再尝试拉起 |
onStartCommand() |
111-115 | 再调用 a();API >=34 返回 2/START_NOT_STICKY,否则 1/START_STICKY |
onTaskRemoved() |
117-121 | 最近任务移除时调用 qf.b.m() |
mowxgu.a() 还包含一个隐藏调试开关:约 5 秒窗口内服务启动调用累计 10 次会翻转日志 flag;这不是业务保活条件 [S1]。
4.3 JMgHOxJfa:FGS 启动失败兜底 Job#
源码:
jadx/sources/crown/arithmetic/floor/JMgHOxJfa.java:44-119,121-153jadx/sources/qf/d.java:42-81
职责 [S1]:JobService 自己先用 ongoing ID 20 进入 foreground,然后显式启动 mowxgu;onStartJob() 启动协程,等待 15 秒后 jobFinished(params,false)。
5. 三种周期调度#
5.1 AlarmManager#
调度:jadx/sources/qf/b.java:295-346
接收:jadx/sources/crown/arithmetic/floor/kQuACgQQ.java:17-25
PendingIntent pi = getBroadcast(context, 18488, Intent(kQuACgQQ.class), flags);
alarm.cancel(pi);
LocalTime t = parseConfiguredTimeOrDefault(10, 0);
long delta = nextOccurrence(t) - System.currentTimeMillis();
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delta,
pi);
纠错重点:type=2 对应 ELAPSED_REALTIME_WAKEUP(唤醒型);调用 set() 而非 setExact*(),因此具 wakeup 但允许系统漂移/合并。receiver 触发后依次 ensureForegroundService()、进入周期回调、重新排下次 Alarm。
5.2 WorkManager#
调度:jadx/sources/qf/b.java:419-459
Worker:jadx/sources/crown/arithmetic/floor/ZOaubC.java:14-31
PeriodicWorkRequest request = periodic(
worker = ZOaubC.class,
interval = max(configMinutes, 15min),
flex = max(5min, allowedFlex)
);
enqueueUniquePeriodicWork(obfuscatedUniqueName, REPLACE_OR_KEEP_MODE_1, request);
doWork() {
ensureForegroundService();
enterPeriodicCallback("work");
return success();
}
5.3 JobScheduler#
调度:jadx/sources/qf/b.java:461-507
JobService:jadx/sources/crown/arithmetic/floor/vjfcJyUsQs.java:18-50
参数 [S1]:Job ID 20、无网络/充电/idle 要求、persisted、minimumLatency 15 分钟、overrideDeadline 约为 15 分钟 + 5 秒、API 33+ priority 400。Job 创建时确保 FGS并进入周期回调;onStartJob() 重新安排下一次。
6. Boot、升级、通知删除与循环广播#
| 类/方法 | 路径:行号 | 直接行为 |
|---|---|---|
weqTnpsB.onReceive() |
jadx/sources/crown/arithmetic/floor/weqTnpsB.java:18-35 |
Boot/package replaced/动态 action 后确保 FGS;按 action 进入不同周期回调或取消重复通知 |
CycleReceiver.onReceive() |
.../notify/CycleReceiver.java:13-23 |
收到 base.cycle.break 后发送 ongoing 通知对应 PendingIntent |
kQuACgQQ.onReceive() |
.../kQuACgQQ.java:17-25 |
Alarm 触发:确保 FGS、周期回调、重排 Alarm |
ZOaubC.doWork() |
.../ZOaubC.java:22-30 |
Work 触发:确保 FGS、周期回调 |
vjfcJyUsQs.onCreate/onStartJob() |
.../vjfcJyUsQs.java:18-45 |
Job 触发:确保 FGS、周期回调、重排 Job |
qf.c.onReceive() |
jadx/sources/qf/c.java:20-92 |
对 9 类动态系统广播做 500 ms 去重,然后确保 FGS并进入周期回调 |
qf.i.onReceive() |
jadx/sources/qf/i.java:19-42 |
设备解锁后调用 TotalPageObserver.e(),再反注册自身 |
Manifest 静态 action 直接确认 BOOT_COMPLETED、MY_PACKAGE_REPLACED、base.cycle.break。qf.u 中 qf.c 的 9 个动态 action 已通过常量解码与 hash 分支交叉确认 [S1]:USER_PRESENT、ACTION_POWER_CONNECTED、SCREEN_ON、SCREEN_OFF、PACKAGE_ADDED、PACKAGE_REMOVED、PACKAGE_REPLACED、CLOSE_SYSTEM_DIALOGS、CONFIGURATION_CHANGED。仍有少量删除/内部回调 action 名称未稳定恢复 [U]。
7. 生命周期拉回与广告恢复#
7.1 TotalPageObserver.e():恢复时重开 FirstPage#
源码:jadx-simple/crown.arithmetic.floor.TotalPageObserver.java:69-116
Activity top = currentActivity();
if (top == null || top instanceof AutoBackPage ||
top instanceof AgreePage || top instanceof FirstPage ||
isAdActivity(top)) return;
if (deviceLocked()) {
register USER_PRESENT receiver;
} else {
top.startActivity(Intent(top, FirstPage.class).addFlags(0x24000000));
}
onStateChanged() 的关键状态 [S1]:
ON_STOP:标记 App 后台;若正在广告页,处理广告跳过/结束;若广告状态标记存在,构造广告恢复通知。ON_RESUME:如果此前确实处于后台,清标记并调用e()。- 广告恢复:
notify_click_ad进入FirstPage;notify_click_applovin进入AutoBackPage。
源码:jadx-simple/...TotalPageObserver.java:225-365。
7.2 qf.r:Activity 计数、通知点击与后台任务#
源码:jadx/sources/qf/r.java:23-142
| 方法 | 行号 | 行为 |
|---|---|---|
a(Activity) |
23-46 | 消费通知点击 extras、记录 action、取消匹配的重复任务 |
onActivityStarted() |
75-135 | 检查通知权限、有限次数请求 FCM token/上传、再次装配保活、activityCount++、进入前台回调并启动网络协程 |
onActivityStopped() |
138-142 | activityCount--;FCM 用此判断 App 是否有活动页面 |
8. 系统事件与文件事件召回代码#
8.1 注册入口 qf.h.invokeSuspend()#
源码:jadx/sources/qf/h.java:43-182
- 初始化 Firebase Remote Config。
- Android 10+ 递归监听 Music、Podcasts、Ringtones、Alarms、Notifications、Movies、Downloads、Documents、Pictures、DCIM 与 Screenshot 目录。
- 注册 USER_PRESENT、SCREEN_OFF、CLOSE_SYSTEM_DIALOGS、CONFIGURATION_CHANGED、PACKAGE_ADDED/REMOVED、POWER_CONNECTED/DISCONNECTED、CONNECTIVITY_CHANGE。
8.2 广播分发 gd.c.onReceive()#
源码:jadx-simple/gd.c.java:75-218
| 系统事件 | 代码动作 |
|---|---|
PACKAGE_ADDED |
构造 notify_installapp;能取 label 时用动态文案 |
PACKAGE_REMOVED |
构造 notify_uninstallapp |
ACTION_POWER_CONNECTED |
构造 notify_startcharge |
ACTION_POWER_DISCONNECTED |
构造 notify_stopcharge |
USER_PRESENT |
启动 uf.a,2 秒后选择未清理天数或 4 个随机解锁模板 |
CLOSE_SYSTEM_DIALOGS/recentapps |
启动 uf.b,1.5 秒后 notify_recenttask |
CONNECTIVITY_CHANGE |
启动 uf.c,1.6 秒后仅在非蜂窝→蜂窝时 notify_SwitchTraffic |
8.3 FileObserver uf.d.onEvent()#
源码:jadx/sources/uf/d.java:30-105
- Screenshot 目录:取文件名与缩略图,构造
notify_screenshots。 - 其他公共目录:取文件名,构造
notify_downloadfile。 - 两类都继续进入通知总闸,不代表每个文件事件都会展示。
8.4 周期候选 tf.a0.invokeSuspend()#
源码:jadx-simple/tf.a0.java:24-87
delay(2_000ms);
action = randomOf(
"notify_timing_cache01",
"notify_timing_cache02",
"notify_timing_bigfile",
"notify_timing_appmanage"
);
buildLocalizedNotification(action);
NotifySender.send(context, config);
9. 通知总闸、Channel、重复刷新与路由#
9.1 a.a.r(Context, uf.i):全部本地通知总闸#
源码:jadx-simple/a.a.java:503-916
忠实伪代码:
sendLocalNotify(config) {
cancelPreviousRepeat(reason = 4);
if (!notificationAllowed()) return;
if (!appInBackground()) return;
if (deviceLocked()) return;
if (!isAdRecovery(config.action) && installAge < 5min) return;
if (attributionBranchFalse && action != HIGH_PRIORITY) {
if (0 < now - globalLastNotify < 2h) return;
} else if (action != HIGH_PRIORITY) {
if (!passesPerActionCooldown(action)) return;
}
postId21AndStartRepeat(config);
updateGlobalAndPerActionTimestamps();
}
完整逐 action 冷却见《拉活通知规则与文案全量报告》;代码行集中在 a.a.java:693-890。
9.2 qf.t#
源码:jadx/sources/qf/t.java
| 方法 | 行号 | 行为 |
|---|---|---|
a(Context) |
52-87 | 创建 ongoing、正常业务、静默业务 3 个 Channel |
b(Context) |
89-109 | 未锁屏时刷新 ongoing ID 20 |
c(...) |
111-196 | 构造业务自定义 Notification;选择 normal/silent Channel |
f(Context) |
234-299 | 构造 ongoing 通知与 6 个快捷入口 |
e(...) |
301-342 | 首发 ID 21,记录 action,启动重复 coroutine |
d(int) |
198-232 | 取消/终止正在重复的通知任务 |
9.3 qf.w.invokeSuspend():短时重复刷新#
源码:jadx-simple/qf.w.java:60-151
repeatCount = manufacturer.equalsIgnoreCase("samsung") ? 1 : 3;
for (i = 0; i < repeatCount; i++) {
delay(3_500ms);
if (!stillBackground || deviceLocked || landscape) break;
notify(id = 21, channel = silentChannel, sameContent);
}
9.4 uf.j 与 MainPage:点击路由#
源码:
jadx/sources/uf/j.java:23-97jadx/sources/crown/arithmetic/floor/page/MainPage.java:97-318
uf.j.a() 默认把业务通知点到 FirstPage;只有 notify_click_applovin 直达 AutoBackPage。MainPage.m() 再按 KEY_FROM 路由 Cache、Large File、App Manager、Screenshot、Network、Notification Clean 或 RAM。
10. Notification Listener 闭环#
源码:
- 监听/取消:
jadx/sources/crown/arithmetic/floor/notify/NotifyManagerServices.java:51-75 - 今日计数:
jadx-simple/crown.arithmetic.floor.notify.NotifyManagerServices.java:55-103
onNotificationPosted(sbn) {
if (thirdParty && !ongoing && !whitelisted) {
cancelNotification(sbn.key);
saveTitleAndTextToRoom();
long todayCount = queryTodayBlockedCount();
if (todayCount >= 20 && todayCount % 10 == 0) {
sendLocalNotify("notify_block_notification");
}
}
}
11. FCM 拉活通知代码#
源码:jadx-simple/crown.arithmetic.floor.wSfChcdBg.java:50-254
onMessageReceived(message) {
ensureForegroundService();
enterPeriodicCallback("fcm");
if (incomingPriority != HIGH) return;
if (!notificationAllowed()) return;
if (activityCount > 0) return;
if (landscape) return;
if (ageFromStartupBaseline < 5min) return;
if (localHour < 7 || localHour >= 23) return;
index = random(0..9);
content = localizedHighPriorityCopy(index);
postBusinessNotification(id = 21,
internalName = "notify_highpriority_" + index,
clickAction = "notify_highpriority");
recordDeliveredPriorityOrPriorityReduction();
}
onNewToken(token) {
forwardToAttributionSdkAndOwnBackend(token);
}
[U] simple-mode 未稳定恢复“锁屏直接拒绝”分支,因此伪代码不加入该条件;服务端发送策略不在 APK。
12. Remote Config、FCM token 与自有后端#
| 方法 | 路径:行号 | 保活/拉活相关职责 |
|---|---|---|
tf.u.c() |
jadx-simple/tf.u.java:221-300 |
RC 最短 fetch 3600 秒、fetch/activate、realtime listener |
tf.r.b() |
jadx/sources/tf/r.java:39-48 |
相关广告/配置 key 更新时重新应用 |
qf.r.onActivityStarted() |
jadx/sources/qf/r.java:75-135 |
有限次数获取/同步 FCM token,启动网络任务 |
qf.b.p() |
jadx/sources/qf/b.java:348-384 |
通知可用时向 FCM 订阅配置中的 topic;具体 topic 不写入文档 |
wSfChcdBg.d() |
jadx-simple/...wSfChcdBg.java:250-254 |
token 更新转交统一上传路径 |
qf.q.invokeSuspend() |
jadx/sources/qf/q.java:48-217 |
IP/条件后端,8 秒超时与指数退避 |
qf.p.invokeSuspend() |
jadx-simple/qf.p.java:57-246 |
包名 + 本地 ID/token 类值上报,8 秒超时与指数退避 |
报告不记录 SDK 初始化标识、topic、FCM token、设备标识或认证信息。
13. App 自有保活/拉活方法完整索引#
| 层 | 类/方法 | 源码范围 | 作用 |
|---|---|---|---|
| 启动 | cIPhUu.onCreate |
jadx-simple/crown.arithmetic.floor.cIPhUu.java:63-160 |
Provider 早启动、配置反射、生命周期、后台总装配 |
| 启动 | TotalPage.onCreate |
jadx/sources/crown/arithmetic/floor/TotalPage.java:49-73 |
归因、生命周期与业务初始化 |
| 配置 | PageCellar.<clinit> |
jadx/sources/crown/arithmetic/floor/manager/PageCellar.java:39-55 |
调度周期、后端、Channel、ID、追加间隔 |
| 总装配 | qf.u.b |
jadx/sources/qf/u.java:57-131 |
Channel、FGS、Alarm、receiver、Job、Work |
| 权限 | qf.e.a |
jadx/sources/qf/e.java:29-32 |
通知是否可用 |
| FGS | qf.b.m |
jadx/sources/qf/b.java:213-282 |
启动主 FGS;失败 Job 兜底 |
| FGS | mowxgu.a/onCreate/onDestroy/onStartCommand/onTaskRemoved |
.../mowxgu.java:34-121 |
ongoing、sticky 与主动重启 |
| 兜底 | JMgHOxJfa |
.../JMgHOxJfa.java:44-153 |
失败 Job 自己前台化并启动主 FGS |
| 兜底 | qf.d.invokeSuspend |
jadx/sources/qf/d.java:42-81 |
15 秒后结束失败 Job |
| Alarm | qf.b.o |
jadx/sources/qf/b.java:295-346 |
计算未来时刻并 ELAPSED_REALTIME_WAKEUP set() |
| Alarm | kQuACgQQ.onReceive |
.../kQuACgQQ.java:17-25 |
保活、周期回调、重排 |
| Work | qf.b.u |
jadx/sources/qf/b.java:419-459 |
15 分钟 unique periodic work |
| Work | ZOaubC.doWork |
.../ZOaubC.java:22-30 |
确保 FGS并进入周期回调 |
| Job | qf.b.v |
jadx/sources/qf/b.java:461-507 |
持久 15 分钟 Job ID 20 |
| Job | vjfcJyUsQs |
.../vjfcJyUsQs.java:18-50 |
确保 FGS、回调、重排 |
| Boot | weqTnpsB.onReceive |
.../weqTnpsB.java:18-35 |
Boot/升级/动态 action 后恢复 |
| Cycle | CycleReceiver.onReceive |
.../notify/CycleReceiver.java:13-23 |
发送 ongoing PendingIntent |
| 广播保活 | qf.c.onReceive |
jadx/sources/qf/c.java:20-92 |
9 类系统广播、500 ms 去重、确保 FGS |
| 解锁拉回 | qf.i.onReceive |
jadx/sources/qf/i.java:19-42 |
USER_PRESENT 后重进 TotalPageObserver.e() |
| 回调 | qf.v.d |
jadx/sources/qf/v.java:89-141 |
周期来源汇合、定时通知候选、事件上报/token 同步 |
| 生命周期 | qf.r |
jadx/sources/qf/r.java:23-142 |
点击消费、Activity 计数、前台任务、token 同步 |
| 生命周期 | TotalPageObserver.e/onStateChanged |
jadx-simple/...TotalPageObserver.java:69-116,225-365 |
热恢复重开 FirstPage、广告回跳通知 |
| 事件注册 | qf.h.invokeSuspend |
jadx/sources/qf/h.java:43-182 |
FileObserver + 7 类系统广播 |
| 广播 | gd.c.onReceive |
jadx-simple/gd.c.java:75-218 |
安装、卸载、充电、解锁、最近任务、网络触发 |
| 解锁 | uf.a.invokeSuspend |
jadx-simple/uf.a.java:42-136 |
2 秒后未清理/随机解锁候选 |
| 最近任务 | uf.b.invokeSuspend |
jadx/sources/uf/b.java:37-62 |
1.5 秒后候选 |
| 网络 | uf.c.invokeSuspend |
jadx/sources/uf/c.java:38-71 |
1.6 秒后蜂窝切换候选 |
| 文件 | uf.d.onEvent |
jadx/sources/uf/d.java:30-105 |
截图/新文件候选 |
| 定时通知 | tf.a0.invokeSuspend |
jadx-simple/tf.a0.java:24-87 |
2 秒后 4 选 1 |
| 通知总闸 | a.a.r |
jadx-simple/a.a.java:503-916 |
权限、后台、锁屏、安装时长、归因、冷却 |
| 通知构建 | qf.t.a/b/c/d/e/f |
jadx/sources/qf/t.java:52-342 |
Channel、ID20/21、自定义布局、重复控制 |
| 通知重复 | qf.w.invokeSuspend |
jadx-simple/qf.w.java:60-151 |
3.5 秒静默刷新 |
| 通知路由 | uf.j.a/c/d |
jadx/sources/uf/j.java:23-97 |
FirstPage/AutoBack 与 ongoing 快捷入口 |
| 通知路由 | MainPage.m |
.../page/MainPage.java:97-318 |
action → func |
| 通知监听 | NotifyManagerServices.onNotificationPosted/checkCount |
普通 :51-75;simple :55-103 |
取消/记录第三方通知,20/10 计数召回 |
| FCM | wSfChcdBg.c/d |
jadx-simple/...wSfChcdBg.java:50-254 |
高优先级通知、priority telemetry、token 更新 |
| RC | tf.u.c/e、tf.r.b |
simple tf.u:221-300;普通 tf/u.java:71-126、tf/r.java:39-48 |
拉取/实时应用广告与配置 |
| 后端 | qf.q.invokeSuspend |
jadx/sources/qf/q.java:48-217 |
条件检查、指数退避 |
| 后端 | qf.p.invokeSuspend |
jadx-simple/qf.p.java:57-246 |
ID/token 类数据上传、指数退避 |
14. 开发复核清单#
- 先按上述路径逐个打开源码,不要只看混淆类名。
- 对
a.a.r、gd.c、tf.a0、qf.w、wSfChcdBg、TotalPageObserver使用 simple-mode 文件;普通模式相应方法直接抛UnsupportedOperationException。 - 对 Alarm 明确按
ELAPSED_REALTIME_WAKEUP + 非 exact set()理解。 - 对 Android 14+ 的
specialUseFGS、通知拒绝、Doze、最近任务划掉、OEM、自启动和 Force Stop 单独做矩阵。 - 对 exported
mowxgu、CycleReceiver、kQuACgQQ、MainPage做显式 Intent/广播滥用测试。 - 抓包核对两个公开后端的字段与重试;任何 token、ID 或认证信息只在受控环境查看,不写报告。
15. 未验证项#
[U]simple-mode 的 goto/类型推断可能对极少数边缘分支有偏差;关键主路径已与 Manifest、资源和调用方交叉对照。[U]线上 Remote Config、FCM 服务端策略、topic、广告 waterfall 与后端响应未知。[U]本轮未操作设备,不能用本册单独证明划卡、Doze、待机桶、重启或 Force Stop 后的实际存活时长。[U]未对 Android 8–16/OEM 做兼容矩阵,也未做 exported 组件安全利用测试。