feat(font+sys): 字库内存纪律(agent-215)+sysui接管launcher监管(agent-216)
215: meow_font.c 流式分块解码(gbk峰值40→23.5MB, 逐字节校验一致) + 多字体槽5→4+16MB驻留预算; 量化: gbk稳态驻留17.3MB vs common 4.2MB(OOM主因); meow_font.a→67113c03 meow_ui.a→223d5401 216: bootmenu让位(sysui在则start launcher让位, 不在则exec兜底) + S70预置launcher.conf enabled=1(+旧设备升级迁移); launcher崩溃可自动拉起; bootmenu 4441822d / S70 e435affc / S90 e0ace111 216注: S70早启动与选单共存为真机重点观察项
This commit is contained in:
1 parent
90e28e7b7e
commit
c0f7a95719
10 files changed
+434
-92
No files matched your search
@@ -35,8 +35,12 @@
|
||||
* ============================================================================
|
||||
* WHY (设计见 BOOT_SELECTOR_DESIGN.md §3)
|
||||
* ============================================================================
|
||||
* - 开机最先显示选单(HibyOS / MeowOS),选择后 fork 播放器(HibyOS)或
|
||||
* exec MeowOS 主屏(MeowOS);HibyOS 模式热键(电源+音量减)杀播放器接管。
|
||||
* - 开机最先显示选单(HibyOS / MeowOS),选择后 fork 播放器(HibyOS)或进入
|
||||
* MeowOS 主屏;HibyOS 模式热键(电源+音量减)杀播放器接管。
|
||||
* - M2.83 launcher 监管迁移:MeowOS 主屏(meow_launcherd)生命周期已交 meow_sysui
|
||||
* (S70 起)。故选 MeowOS 时——sysui 在 → 让 sysui 拉起/监管 launcher,本进程让位退出
|
||||
* (rcS 推进,S92 见 mode=meow 跳过播放器);sysui 不在 → 本进程照旧 exec launcher(兜底,
|
||||
* 防开不了机)。选 HibyOS 时 sysui 在 → 让 sysui 停 launcher(不与播放器抢 fb0)。
|
||||
* - 本二进制 = 选单本体(M0)。M0 只做二进制自检:SSH 推 /data 独立跑,
|
||||
* **不进启动链**(不碰 S90/S92/播放器/SSH 顺序)。
|
||||
*
|
||||
@@ -898,8 +902,81 @@ static int sim_confirm_done = 0;
|
||||
static int sim_hk_done = 0;
|
||||
static int sim_hotkey_strict = 0; /* M2.14:--sim-hotkey-strict = 让 sim 热键走武装延迟/忙判门(测 pending) */
|
||||
|
||||
/* ======================================================================
|
||||
* M2.83 launcher 监管迁移:launcher 生命周期由 bootmenu 移交给 meow_sysui
|
||||
* - MeowOS 模式:sysui 在 → 让 sysui 拉起/监管 launcher,bootmenu 让位不 exec
|
||||
* (rcS 推进 → S92 见 mode=meow 跳过播放器);sysui 不在 → bootmenu 照旧 exec launcher(兜底)。
|
||||
* - HibyOS 模式:sysui 在 → 让 sysui 停 launcher(会话级 user_stopped,不自动重启),避免与播放器抢 fb0。
|
||||
* 双保险:sysui 拉 + launcher 崩 sysui 重启(restart=always);bootmenu 仅在 sysui 不在时兜底。
|
||||
* ====================================================================== */
|
||||
static int sysui_active(void)
|
||||
{
|
||||
/* sysui daemon 是否在跑:/tmp/meow_sysui.pid 存活,且 /proc/<pid>/comm=meow_sysui(防 pid 复用误判) */
|
||||
FILE *f = fopen("/tmp/meow_sysui.pid", "r");
|
||||
if (!f) return 0;
|
||||
long pid = -1;
|
||||
int n = fscanf(f, "%ld", &pid);
|
||||
fclose(f);
|
||||
if (n != 1 || pid <= 1) return 0;
|
||||
if (kill((pid_t)pid, 0) != 0) return 0; /* ESRCH → 不在 */
|
||||
char comm[64] = {0}, path[64];
|
||||
snprintf(path, sizeof path, "/proc/%ld/comm", pid);
|
||||
int fd = open(path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
ssize_t r = read(fd, comm, sizeof comm - 1);
|
||||
close(fd);
|
||||
if (r > 0) {
|
||||
char *nl = strchr(comm, '\n');
|
||||
if (nl) *nl = '\0';
|
||||
if (strncmp(comm, "meow_sysui", 10) != 0) return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sysui_cmd_launcher(const char *op)
|
||||
{
|
||||
/* 调 /usr/bin/meow_sysui start|stop launcher(best-effort:sysui 缺失/失效 → 无害退出)。
|
||||
* 等 CLI 返回(CLI 连 socket 快速回),避免僵尸;失败不致命。 */
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "bootmenu: sysui %s launcher: fork failed: %s\n", op, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (pid == 0) {
|
||||
execl("/usr/bin/meow_sysui", "/usr/bin/meow_sysui", op, "launcher", (char *)NULL);
|
||||
_exit(127); /* sysui 缺失/不可执行 → 无害退出(fallback 路径会用本地 exec) */
|
||||
}
|
||||
int st = 0;
|
||||
(void)waitpid(pid, &st, 0);
|
||||
}
|
||||
|
||||
static int enter_meow_launcher(void)
|
||||
{
|
||||
/* MeowOS 决策点:返回 0=已让位(launcher 由 sysui 继续管理,调用方正常退出/让 rcS 推进);
|
||||
* 否则已 exec launcher(本函数不返回)。 */
|
||||
if (sysui_active()) {
|
||||
fprintf(stderr, "bootmenu: sysui owns launcher -> hand off (start via sysui)\n");
|
||||
fflush(NULL);
|
||||
sysui_cmd_launcher("start");
|
||||
return 0;
|
||||
}
|
||||
/* 回退:sysui 不在 → bootmenu 照旧 exec launcher(防开不了机) */
|
||||
fprintf(stderr, "bootmenu: no sysui -> exec %s (fallback)\n", LAUNCHER_BIN);
|
||||
fflush(NULL);
|
||||
execv(LAUNCHER_BIN, (char *[]){ "meow_launcherd", NULL });
|
||||
fprintf(stderr, "bootmenu: exec launcher failed: %s\n", strerror(errno));
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
static void fork_hiby_player(void)
|
||||
{
|
||||
/* M2.83 迁移:HibyOS 模式下 launcher 不应与播放器抢 fb0——sysui 在则让 sysui 停 launcher */
|
||||
if (sysui_active()) {
|
||||
fprintf(stderr, "bootmenu: HibyOS selected -> stop launcher via sysui\n");
|
||||
fflush(NULL);
|
||||
sysui_cmd_launcher("stop");
|
||||
}
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) { fprintf(stderr, "fork player failed: %s\n", strerror(errno)); return; }
|
||||
if (pid == 0) {
|
||||
@@ -1278,13 +1355,17 @@ static void bootmenu_supervisor(int player_pid)
|
||||
}
|
||||
player_alive = 0;
|
||||
}
|
||||
/* 播放器已死:面板已在确认框点亮(brightness=saved)。写 mode=meow,
|
||||
* 然后 exec MeowOS 基础主屏(接管 fb0 画 buffer0+pan0)。 */
|
||||
/* 播放器已死:面板已在确认框点亮(brightness=saved)。写 mode=meow。
|
||||
* M2.83 迁移:MeowOS 基础主屏(launcher)已交 sysui 托管——sysui 在则让 sysui
|
||||
* 拉起 launcher(本 supervisor 让位退出,rcS 推进,S92 见 mode=meow 跳过播放器);
|
||||
* sysui 不在则照旧 exec launcher(兜底)。 */
|
||||
write_mode(0);
|
||||
fprintf(stderr, "supervisor: exec /usr/bin/meow_launcherd\n");
|
||||
fflush(NULL);
|
||||
execv(LAUNCHER_BIN, (char *[]){ "meow_launcherd", NULL });
|
||||
fprintf(stderr, "supervisor: exec launcher failed: %s\n", strerror(errno));
|
||||
if (enter_meow_launcher() == 0) {
|
||||
fprintf(stderr, "supervisor: launcher handed off to sysui, supervisor exits\n");
|
||||
fflush(NULL);
|
||||
_exit(0);
|
||||
}
|
||||
/* 不可达:enter_meow_launcher 在无 sysui 时已 exec launcher(不返回) */
|
||||
_exit(127);
|
||||
} else {
|
||||
/* ===== 否 / -1:留在 HibyOS =====
|
||||
@@ -1528,15 +1609,14 @@ static int run_menu(int sim_sel, int do_fork)
|
||||
fb_restore_player_frame();
|
||||
fb_close();
|
||||
/* M2(--fork):HibyOS→fork 播放器(父进程转监督者,阻塞 rcS);
|
||||
* MeowOS→exec meow_launcherd(MeowOS 基础主屏,接管 fb0)。 */
|
||||
* MeowOS→sysui 在则让 sysui 拉起 launcher 并让位(rcS 推进,S92 见 mode=meow 跳过播放器);
|
||||
* sysui 不在则 exec meow_launcherd(MeowOS 基础主屏,接管 fb0;兜底)。返回=已让位。 */
|
||||
if (do_fork) {
|
||||
if (choice == 1) {
|
||||
fork_hiby_player(); /* 父进程陷入 supervisor,永不返回 */
|
||||
} else {
|
||||
set_boot_default_meow(); /* Bug 1:选 MeowOS → 持久为开机默认 */
|
||||
execv(LAUNCHER_BIN, (char *[]){ "meow_launcherd", NULL });
|
||||
fprintf(stderr, "bootmenu: exec launcher failed: %s\n", strerror(errno));
|
||||
_exit(127);
|
||||
enter_meow_launcher(); /* 让位返回 0,或 exec launcher(不返回) */
|
||||
}
|
||||
}
|
||||
return 0; /* M0/M1(无 --fork):选单退出,rcS 推进 */
|
||||
@@ -1556,7 +1636,8 @@ static void usage(void)
|
||||
" --boot-only 跳过选单,直接取默认(boot_default)\n"
|
||||
" --timeout-ms N 覆写超时毫秒(测试钩子)\n"
|
||||
" --fork M2 开启:选 HibyOS 时 fork 播放器并转监督者;\n"
|
||||
" 选 MeowOS 时 exec /usr/bin/meow_launcherd(默认关)\n"
|
||||
" 选 MeowOS 时 sysui 在→让 sysui 拉起 launcher(本进程让位退出),\n"
|
||||
" 否则 exec /usr/bin/meow_launcherd(默认关)\n"
|
||||
" --sim-hotkey N 监督者启动 N ms 后模拟热键(M2 真机 verif)\n"
|
||||
" --sim-confirm Y|N 确认框打开 2s 后自动答 Y=是 / N=否\n"
|
||||
" --version 打印版本并退出\n",
|
||||
@@ -1617,9 +1698,7 @@ int main(int argc, char **argv)
|
||||
if (choice == 1) fork_hiby_player();
|
||||
else {
|
||||
set_boot_default_meow(); /* Bug 1:选 MeowOS → 持久为开机默认 */
|
||||
execv(LAUNCHER_BIN, (char *[]){ "meow_launcherd", NULL });
|
||||
fprintf(stderr, "bootmenu: exec launcher failed: %s\n", strerror(errno));
|
||||
_exit(127);
|
||||
enter_meow_launcher(); /* sysui 在→让位返回 0;否则 exec launcher(不返回) */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user