feat(amsd): meow_amsd 活动管理器一期 + am CLI (agent-212, 用户定案) — svcd托管(trigger=boot); 生命周期注册表(状态/时长/退出码/信号/崩溃计数+历史环形); launcher launch/exit/stdout管道捕获上报(logcat式,崩溃尾巴drain不丢); am status/list/history/start/kill(root门); crash双保险转发; S89预置conf

amsd f8d7f61b / am cfc4cbd4 / launcher 97c1b222(含字库扫描签名门控修CPU100%)
宿主+qemu全链路验证通过
This commit is contained in:
MeowOS committed 2026-08-31 12:45:29 +08:00
1 parent b81e7438e4
commit 5fbf30755c
16 files changed
+1722 -4

No files matched your search

+76 -1
View File
@@ -683,6 +683,33 @@ static unsigned long long apps_dir_sig(void)
return sig;
}
/* M2.83 修补:字库目录签名(根+各 family 目录 mtime)。meow_font_scan_presets 内含逐套
* sha256 校验(gbk 套 6.8MB 级),绝不能每 2s 轮询全量扫——只在目录签名变化时扫。 */
static unsigned long long fonts_dir_sig(void)
{
char root[300];
snprintf(root, sizeof root, "/usr/data/mnt/sd_0/%s", MEOW_FONTS_CFG);
unsigned long long sig = 1469598103934665603ULL;
struct stat st;
if (stat(root, &st) != 0) return 0;
sig ^= (unsigned long long)st.st_mtime; sig *= 1099511628211ULL;
DIR *d = opendir(root);
if (d) {
struct dirent *de;
while ((de = readdir(d))) {
if (de->d_name[0] == '.') continue;
char p[400];
snprintf(p, sizeof p, "%s/%s", root, de->d_name);
if (stat(p, &st) == 0 && S_ISDIR(st.st_mode)) {
sig ^= (unsigned long long)st.st_mtime * 256 + (unsigned char)de->d_name[0];
sig *= 1099511628211ULL;
}
}
closedir(d);
}
return sig;
}
static void run_menu(struct app apps[MAX_APPS], int napps, int state,
long sim_tap_ms, long sim_exit_ms)
{
@@ -700,6 +727,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
long sim_tap_done = 0, sim_exit_done = 0;
long meow_last_poll = 0; /* M2.2:MeowOS 后台拔营(卡/网)轮询时间戳 */
unsigned long long apps_sig = 0; /* M2.77:应用目录签名(0=未初始化,首圈建立基线) */
unsigned long long fonts_sig = 0; /* M2.83:字库目录签名(门控 scan_presets,防 2s 轮询 sha256 风暴) */
load_config(); /* meow.conf on the card: bg_color etc. */
menu_icons_load(apps, napps); /* MD3:应用图标解码一次进缓存(不每帧解码) */
@@ -824,6 +852,45 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
/* 阶段 D · M0:菜单/主屏循环内排空 IPC(非阻塞;应用可随时查询/声明路由) */
meow_ipc_process();
/* AMSD_DESIGN §4.3:amsd `am start` → 消费 pending-start(仅菜单态/无前台 App 时拉起)。
* 镜像 sim-tap 启动路径:launch 后 menu_after_app_exit + dirty 重绘菜单。 */
{
char spkg[MEOW_APP_ID_MAX], sact[MEOW_ACT_MAX];
if (meow_ams_take_start(spkg, sizeof spkg, sact, sizeof sact)) {
if (state != 0) {
snprintf(toast, sizeof toast, "AMS START: app list not ready");
toast_ms = TOAST_MS;
} else {
int idx = -1;
for (int i = 0; i < napps; i++)
if (!strcmp(apps[i].id, spkg)) { idx = i; break; }
if (idx < 0) {
snprintf(toast, sizeof toast, "AMS START: NO APP %s", spkg);
toast_ms = TOAST_MS;
} else {
int ret;
if (sact[0]) {
char chain[MEOW_CHAIN_MAX]; int depth;
if (resolve_chain(spkg, sact, chain, &depth) == MEOW_OK)
ret = launch_activity(&apps[idx], chain);
else {
snprintf(toast, sizeof toast, "AMS: NO ROUTE %s/%s", spkg, sact);
toast_ms = TOAST_MS; ret = 0;
}
} else {
ret = launch_app(&apps[idx]);
}
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s", apps[idx].name);
toast_ms = TOAST_MS;
}
menu_after_app_exit(ret == 0);
last_input_ms = now_ms(); /* M2.17:回主界面即视为输入 */
dirty = 1;
}
}
}
}
meow_notif_tick(); /* M2a:通知 TTL 10s 转储(§8)*/
meow_media_tick(); /* 阶段D附录B:媒体源死亡(播放中无 META 超时)清槽回空态 */
@@ -898,7 +965,15 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
int was_nocard = (state == 1);
if (!mfont_ready && meow_font_ensure()) { dirty = 1; logmsg("hotplug: font loaded late"); }
if (mfont_ready) meow_font_reload_multifont(); /* M2.5x:卡挂载后重配多字体(此前无全局可配) */
meow_font_scan_presets(); /* M2.82+:卡就绪后重扫字库(启动时卡未挂载会只有默认项) */
/* M2.83 修补:字库重扫改为签名门控——扫描含逐套 sha256(gbk 套 6.8MB 级),
* 每 2s 全量扫会把 CPU 烧满(真机实测 100%)。只在字体目录签名变化时扫。 */
{
unsigned long long fsig = fonts_dir_sig();
if (fsig != fonts_sig) {
fonts_sig = fsig;
meow_font_scan_presets();
}
}
if (was_nocard || state != 0 || napps == 0) {
struct app fresh[MAX_APPS];
int fn = scan_apps(fresh);