feat(launcher,lock): MeowOS 锁屏 4 位 PIN(system.pin 同源面板,错5锁5分钟持久化,唤醒/电源菜单手动锁)

- system.pin:4 位数字 PIN,sha256+salt 存 settings.conf(格式与面板 panel.pin 全等,绝无明文)。
  panel.pin 已设且 system.pin 未设时锁屏接受 panel.pin,首次验证成功后并入 system.pin。
- 锁屏时机:息屏唤醒后(默认开,system.pin_lock_on_wake=1 可关)+ 电源菜单「锁定」手动锁;
  开机不锁(boot 进主屏不拦)。
- 锁屏页:launcher 渲染系统级全屏页,App 不可见不可触;SDK 按钮画数字键盘(不调 IME),
  输入 4 位自动校验;● 遮罩不回显数字;错 5 次锁 5 分钟(持久化锁定戳/计数,重启不清)。
- 安全细节:锁屏页电源键=息屏(允许再睡),音量键不动,不响应左缘返回/通知中心手势。
  兜底:SSH root 删 system.pin 键即解锁(无其它后门)。HibyOS 不涉及。
- 宿主测试(test_lock_screen):设置/校验/错5锁定持久化(重载模拟重启)/唤醒触发/开机不锁
  /panel.pin 迁移,全 PASS;既有 settings_brightness/notif_panel/notif_tf/vol_ramp_jack 回归
  无碍;交叉 -Wall -Wextra 0 warning。meow_launcherd md5 670f978e71c1e81cfe86d47c21248c9d。
This commit is contained in:
AskaEth committed 2026-09-02 00:48:23 +08:00
1 parent 5a5e995ebd
commit e948a0a44e
14 files changed
+1011 -14

No files matched your search

+51
View File
@@ -1431,6 +1431,53 @@ static int run_app_notif_overlay(struct app *a, pid_t pid)
return 0;
}
/* M2.x 锁屏:App 前台会话唤醒后的锁屏叠加(复用电源菜单/通知中心 SIGSTOP+读回+叠加+接管模板)。
* 语义与 run_app_notif_overlay 同构:媒体保活(本 App 播放中)不 SIGSTOP(断供 PCM),SDK present
* 见 /tmp/meow_notif_active 自抑上屏;否则 SIGSTOP 冻结 App,run_lock_screen 全屏接管;解锁/SIGCONT。
* App 死亡不在本函数内探测(run_lock_screen 阻塞,waitpid 循环在返回后统一回收,杀死进程 SIGCONT 无害)。
* 返回 0(锁屏已结束;是否解锁/息屏由 run_lock_screen 返回值决定,本层不关心)。 */
static int run_app_lock_overlay(struct app *a, pid_t pid)
{
if (!back_buf_ok || !fb) { logmsg("lock-overlay: no back_buf (direct mode) skip"); return 0; }
int keep_running = meow_media_app_playing(a->id);
if (keep_running) {
logmsg("lock-overlay: open (app=%s pid=%d) PLAYING -> no SIGSTOP (SDK present suppressed)",
a->name, pid);
} else {
logmsg("lock-overlay: open (app=%s pid=%d) SIGSTOP", a->name, pid);
if (kill(pid, SIGSTOP) < 0) {
logmsg("lock-overlay: SIGSTOP %d fail: %s", pid, strerror(errno));
} else {
for (int i = 0; i < 100; i++) {
if (proc_is_stopped(pid)) break;
usleep(10000);
}
}
}
int nfd = open(NOTIF_ACTIVE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (nfd >= 0) { write(nfd, "1", 1); close(nfd); }
int pfd = open(POWMENU_ACTIVE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (pfd >= 0) { write(pfd, "1", 1); close(pfd); }
meow_sys_light();
meow_theme_reload();
pm_capture_app_frame();
int lr = run_lock_screen();
pm_capture_app_frame();
meow_ui_flush();
unlink(NOTIF_ACTIVE);
unlink(POWMENU_ACTIVE);
if (!keep_running) {
kill(pid, SIGCONT);
logmsg("lock-overlay: closed (lr=%d) -> SIGCONT app", lr);
} else {
logmsg("lock-overlay: closed (lr=%d) -> app never stopped (media keep-alive), no SIGCONT", lr);
}
return 0;
}
/* launch_app_chain:launch_app / launch_activity 的共享核心。
* chain 非空 → 向子进程注入 MEOW_ACTIVITY/MEOW_CHAIN 并初始化 nav_stack(M3);空/NULL → 裸启动。 */
static int launch_app_chain(struct app *a, const char *chain)
@@ -1909,6 +1956,8 @@ static int launch_app_chain(struct app *a, const char *chain)
meow_panel_on();
meow_auto_slept = 0;
fb_pan_buf0_force();
/* M2.x 锁屏:App 前台唤醒后若需锁屏 → SIGSTOP 叠加锁屏页;解锁/SIGCONT 回应用 */
if (lck_lock_required(1)) run_app_lock_overlay(a, pid);
}
}
if (screen_off_timeout > 0 && meow_screen_on && !meow_auto_slept && !fg_keep_awake()) {
@@ -1931,6 +1980,8 @@ static int launch_app_chain(struct app *a, const char *chain)
meow_panel_on();
meow_auto_slept = 0;
fb_pan_buf0_force();
/* M2.x 锁屏:App 前台唤醒后若需锁屏 → SIGSTOP 叠加锁屏页;解锁/SIGCONT 回应用 */
if (lck_lock_required(1)) run_app_lock_overlay(a, pid);
}
}
if (vold && !app_prev_vold) {