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

+43 -3
View File
@@ -1141,10 +1141,31 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
if (meow_screen_on) {
/* M2.8 Bug 3-residual:唤醒不是 draw 事件,LCDC 在 FBIOBLANK(4)->(0)
* 后指向的内容可能已失效/为空;必须把当前界面(应用列表)整体重绘到
* buffer0 并强制 re-pan,而非仅翻页/仅 dirty 重绘(M2.7 仍黑屏根因)。 */
* buffer0 并强制 re-pan,而非仅翻页/仅 dirty 重绘(M2.7 仍黑屏根因)。
* M2.x 锁屏:唤醒后若需锁屏(system.pin_lock_on_wake=1 且已配 PIN)→
* 先弹阻塞式锁屏页;解锁才重绘主屏,息屏则留 dirty 下次再锁。 */
meow_auto_slept = 0; /* M2.17:手动/自动息屏后电源单击唤醒均清自动态 */
last_input_ms = now_ms(); /* M2.18 Bug 1:用真实墙钟(防 t 过期回绕) */
meow_repaint_surface(apps, napps, state, cursor);
if (lck_lock_required(1)) {
int lr = run_lock_screen();
/* 重播按键防抖基线(阻塞期间按键可能已变化,防误判新边沿) */
memset(&kd_pwr, 0, sizeof kd_pwr);
memset(&kd_vold, 0, sizeof kd_vold);
memset(&kd_volu, 0, sizeof kd_volu);
memset(&kd_play, 0, sizeof kd_play);
kp_poll(&kp_power, NULL, NULL);
kp_poll(&kp_keys, NULL, NULL);
m_prev_pwr = kp_is_down(&kp_power, KEY_POWER);
m_prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN);
m_prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP);
m_prev_play = kp_is_down(&kp_keys, KEY_PLAYPAUSE);
if (lr == 1)
meow_repaint_surface(apps, napps, state, cursor); /* 已解锁重绘主屏 */
else
dirty = 1; /* 锁屏期间电源息屏 → 屏已关,留 dirty 下次亮屏再锁 */
} else {
meow_repaint_surface(apps, napps, state, cursor);
}
} else {
dirty = 1; /* 息屏:面板已黑,留 dirty 供下次亮屏重绘 */
last_input_ms = now_ms(); /* M2.18 Bug 1:用真实墙钟 */
@@ -1531,7 +1552,26 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
meow_panel_on();
meow_auto_slept = 0;
last_input_ms = now_ms();
meow_repaint_surface(apps, napps, state, cursor); /* M2.8 唤醒重绘 */
/* M2.x 锁屏:自动息屏唤醒后若需锁屏 → 弹阻塞式锁屏页;解锁才重绘,息屏留 dirty */
if (lck_lock_required(1)) {
int lr = run_lock_screen();
memset(&kd_pwr, 0, sizeof kd_pwr);
memset(&kd_vold, 0, sizeof kd_vold);
memset(&kd_volu, 0, sizeof kd_volu);
memset(&kd_play, 0, sizeof kd_play);
kp_poll(&kp_power, NULL, NULL);
kp_poll(&kp_keys, NULL, NULL);
m_prev_pwr = kp_is_down(&kp_power, KEY_POWER);
m_prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN);
m_prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP);
m_prev_play = kp_is_down(&kp_keys, KEY_PLAYPAUSE);
if (lr == 1)
meow_repaint_surface(apps, napps, state, cursor); /* 已解锁重绘主屏 */
else
dirty = 1; /* 锁屏期间电源息屏 → 屏已关,留 dirty 下次亮屏再锁 */
} else {
meow_repaint_surface(apps, napps, state, cursor); /* M2.8 唤醒重绘 */
}
}
if (screen_off_timeout > 0 && meow_screen_on && !meow_auto_slept && !fg_keep_awake()) {
/* M2.18 Bug 1: 用 idle_ms_since 取差,杜绝 t<last_input 无符号回绕误判「空闲30s」。 */