feat(launcher,lock): 锁屏补充三定案—面板一次性解锁恢复口 / 设置页 PIN 管理 / 电源菜单主动锁强化
- 面板一次性解锁恢复口:/tmp/meow_pin_unlock_once 存在即被锁屏页消费删除并放行一次 (不校验 PIN、不清 system.pin、不重置失败计数;重启标志自然消失;lck_unlock_once_consume, launcher 侧只做检查/消费,panel 端点由主会话另实现)。 - 系统设置「安全 → 锁屏 PIN」页(lock_settings.c,subpage.c 脚手架):状态(未设置/已设置/ 锁定中+剩余)/ 设置(4 位双输确认)/ 修改(需旧 PIN 一次)/ 清除(**免旧 PIN**,仅二次确认弹窗) / system.pin_lock_on_wake 开关;数字输入用 SDK 按钮键盘(lck_input_pin_modal)。 - 电源菜单「锁定」主动锁强化:立即熄屏 + 写 /tmp/meow_pin_locked(主动锁标志,重启消失, 唤醒时无论 pin_lock_on_wake 是否开都必锁屏)+ rm /tmp/meow_pin_unlock_once 作废挂起绕过; lck_wake_should_lock() 作为唤醒门取代 lck_lock_required(1)(主菜单 2 处 + App 会话 2 处)。 - 测试:test_lock_screen 扩 51 ok——bypass 存在即消费/不存在不影响/消费后删除;清除免旧 PIN; 主动锁标志唤醒必锁/清除后回退;全回归 settings_brightness/notif_panel/notif_tf/vol_ramp_jack 无碍; 交叉 -Wall -Wextra 0 warning。meow_launcherd md5 bdf884756ef8a8353aa8e5dfb6e10a0a。 - SYSTEM_SETTINGS.md 同步锁屏行为段。
This commit is contained in:
1 parent
e948a0a44e
commit
c3abc3fee4
13 files changed
+409
-10
No files matched your search
@@ -134,6 +134,13 @@ int run_lock_screen(void)
|
||||
}
|
||||
time_t last_countdown = 0;
|
||||
|
||||
/* 面板一次性解锁恢复口:进入时消费(存在即删除+放行一次,不校验 PIN/不清 PIN/不重置失败计数) */
|
||||
if (lck_unlock_once_consume()) {
|
||||
lck_manual_lock_clear(); /* 进入系统即视为解除主动锁 */
|
||||
logmsg("lock: unlock-once bypass consumed at entry -> release");
|
||||
return 1;
|
||||
}
|
||||
|
||||
lk_draw(entered, status, lock_until); /* 首帧 */
|
||||
|
||||
int unlocked = 0;
|
||||
@@ -141,6 +148,14 @@ int run_lock_screen(void)
|
||||
time_t now = time(NULL);
|
||||
int redraw = 0;
|
||||
|
||||
/* 面板一次性解锁恢复口:锁屏页停留期(每次重试前/每轮)也消费 */
|
||||
if (lck_unlock_once_consume()) {
|
||||
lck_manual_lock_clear();
|
||||
logmsg("lock: unlock-once bypass consumed in-loop -> release");
|
||||
unlocked = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 锁定到期自动解禁(清计数+戳),仅重画状态行 */
|
||||
if (lock_until > 0 && now >= lock_until) {
|
||||
lck_lock_remaining();
|
||||
@@ -209,6 +224,7 @@ int run_lock_screen(void)
|
||||
if (entered == LCK_PIN_LEN) {
|
||||
if (lck_pin_check(digits)) {
|
||||
lck_pin_success();
|
||||
lck_manual_lock_clear(); /* 主动锁标志消解 */
|
||||
logmsg("lock: PIN OK -> unlock");
|
||||
unlocked = 1;
|
||||
goto done;
|
||||
@@ -246,13 +262,135 @@ done:
|
||||
return unlocked;
|
||||
}
|
||||
|
||||
/* 电源菜单「锁定」/ 唤醒共用的进入点。未配凭据 → no-op(无鉴别物,锁了也解不开)。
|
||||
* 返回与 run_lock_screen 同(1 已解锁 / 0 电源息屏 / 0 无凭据跳过)。 */
|
||||
/* 电源菜单「锁定」:**主动锁屏**(用户定案 2026-09-02 强化)。
|
||||
* 语义 = 立即熄屏 + 进入锁定 + 作废挂起的面板绕过标志:
|
||||
* ① rm /tmp/meow_pin_unlock_once(主动锁屏作废一次性绕过);
|
||||
* ② 写 /tmp/meow_pin_locked(主动锁标志 → 唤醒时无论 system.pin_lock_on_wake 是否开都必锁屏);
|
||||
* ③ meow_panel_off() 立即熄屏(唤醒时经主屏唤醒路径弹锁屏页)。
|
||||
* 不立即弹锁屏页(已熄屏);未配凭据 → no-op。返回 0(关菜单,run_menu 继续)。 */
|
||||
int meow_lock_screen_engage(void)
|
||||
{
|
||||
if (!lck_pin_configured()) {
|
||||
logmsg("lock: no system.pin/panel.pin configured -> skip lock (no-op)");
|
||||
logmsg("lock: no system.pin/panel.pin configured -> skip manual lock (no-op)");
|
||||
return 0;
|
||||
}
|
||||
return run_lock_screen();
|
||||
if (access(LCK_UNLOCK_ONCE_FILE, F_OK) == 0) {
|
||||
unlink(LCK_UNLOCK_ONCE_FILE);
|
||||
logmsg("lock: manual active-lock revoked pending unlock-once bypass");
|
||||
}
|
||||
lck_manual_lock_set();
|
||||
meow_panel_off(); /* 立即熄屏;唤醒时必走锁屏 */
|
||||
logmsg("lock: manual active-lock -> screen off + lock on wake");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---- 设置页「锁屏 PIN」数字输入模态(system 级 PIN 设置,用 SDK 按钮画数字键盘)----
|
||||
* 全屏遮罩:title + 4 圆点(●)+ 数字键盘(1-9 / C / 0 / 退格)。输入满 4 位即返回 1 并拷贝到 out
|
||||
* (不校验——调用方做双输确认/旧 PIN 校验);电源键=取消返回 0;音量键不动。 */
|
||||
int lck_input_pin_modal(const char *title, char *out, int outcap)
|
||||
{
|
||||
meow_screen_on = 1;
|
||||
fb_pan_buf0_force();
|
||||
meow_touch mt; mt_reset(&mt);
|
||||
int tfd = open(DEV_TOUCH, O_RDONLY | O_NONBLOCK);
|
||||
struct keypoll kp_power, kp_keys;
|
||||
kp_open(&kp_power, DEV_POWER);
|
||||
kp_open(&kp_keys, DEV_KEYS);
|
||||
|
||||
int entered = 0;
|
||||
char digits[LCK_PIN_LEN + 1] = {0};
|
||||
int result = 0;
|
||||
int dirty = 1; /* 首帧必画 */
|
||||
|
||||
for (;;) {
|
||||
/* 只在首帧/输入变化时整页重绘(消频闪:锁屏低频交互),后续轮次不动 LCDC */
|
||||
if (dirty) {
|
||||
const meow_ui_theme_t *th = s_ui_theme();
|
||||
fill_rect(0, 0, fb_xres, fb_yres, th->surface);
|
||||
lk_text(fb_xres / 2, 120, title, 24, th->on_surface);
|
||||
lk_draw_pin(entered, th);
|
||||
for (int r = 0; r < LK_ROWS; r++) {
|
||||
for (int c = 0; c < LK_COLS; c++) {
|
||||
int x, y, w, h; lk_key_rect(r, c, &x, &y, &w, &h);
|
||||
fill_round_rect(x, y, w, h, 12, th->surface_container);
|
||||
int key = lk_keys[r][c];
|
||||
if (key >= 0) {
|
||||
char d[2] = { (char)('0' + key), 0 };
|
||||
if (mfont_ready) {
|
||||
int fw = meow_font_width_text(d, 30);
|
||||
meow_font_drawtext((uint16_t *)fb, x + w / 2 - fw / 2,
|
||||
y + LK_ROW_H / 2 - meow_font_line_height(30) / 2,
|
||||
d, rgb565(th->on_surface), 30);
|
||||
} else {
|
||||
draw_text(x + w / 2 - 7, y + LK_ROW_H / 2 - 14, d, 2, th->on_surface);
|
||||
}
|
||||
} else if (key == LK_ACT_CLR) {
|
||||
const char *t2 = "C"; if (mfont_ready) t2 = "清空";
|
||||
lk_text(x + w / 2, y + LK_ROW_H / 2 - 9, t2, 22, th->on_surface);
|
||||
} else {
|
||||
const char *t2 = "DEL"; if (mfont_ready) t2 = "退格";
|
||||
lk_text(x + w / 2, y + LK_ROW_H / 2 - 9, t2, 22, th->on_surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
meow_dirty_full();
|
||||
fb_pan_buf0_force();
|
||||
meow_ui_flush();
|
||||
dirty = 0;
|
||||
}
|
||||
|
||||
if (kp_power.ok) {
|
||||
kp_poll(&kp_power, NULL, NULL);
|
||||
if (kp_is_down(&kp_power, KEY_POWER)) { result = 0; break; } /* 取消 */
|
||||
}
|
||||
kp_poll(&kp_keys, NULL, NULL);
|
||||
(void)kp_is_down(&kp_keys, KEY_VOLUMEDOWN);
|
||||
(void)kp_is_down(&kp_keys, KEY_VOLUMEUP);
|
||||
|
||||
if (tfd >= 0) {
|
||||
struct pollfd pfd = { tfd, POLLIN, 0 };
|
||||
if (poll(&pfd, 1, 0) > 0) {
|
||||
unsigned char ev[16];
|
||||
while (read(tfd, ev, sizeof ev) == (ssize_t)sizeof ev) {
|
||||
uint16_t type = *(uint16_t *)(ev + 8), code = *(uint16_t *)(ev + 10);
|
||||
int32_t val = *(int32_t *)(ev + 12);
|
||||
if (type == EV_ABS) {
|
||||
if (code == ABS_X || code == ABS_MT_POSITION_X) mt_abs(&mt, val, mt.last_y);
|
||||
else if (code == ABS_Y || code == ABS_MT_POSITION_Y) mt_abs(&mt, mt.last_x, val);
|
||||
} else if (type == EV_KEY && code == BTN_TOUCH) {
|
||||
if (val && !mt.down) { mt_down(&mt); }
|
||||
else if (!val && mt.down) {
|
||||
int dx, dy;
|
||||
if (mt_up(&mt, &dx, &dy)) {
|
||||
for (int r = 0; r < LK_ROWS; r++) {
|
||||
for (int c = 0; c < LK_COLS; c++) {
|
||||
int x, y, w, h; lk_key_rect(r, c, &x, &y, &w, &h);
|
||||
if (!mt_in(&mt, x, y, w, h)) continue;
|
||||
int key = lk_keys[r][c];
|
||||
if (key >= 0) {
|
||||
if (entered < LCK_PIN_LEN) { digits[entered++] = (char)('0' + key); digits[entered] = 0; }
|
||||
} else if (key == LK_ACT_CLR) { entered = 0; digits[0] = 0; }
|
||||
else if (key == LK_ACT_BS) { if (entered > 0) { entered--; digits[entered] = 0; } }
|
||||
dirty = 1;
|
||||
if (entered == LCK_PIN_LEN) {
|
||||
if (out && outcap > LCK_PIN_LEN) { snprintf(out, (size_t)outcap, "%s", digits); result = 1; }
|
||||
else result = 1;
|
||||
goto done2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
usleep(POLL_MS * 1000);
|
||||
}
|
||||
done2:
|
||||
if (tfd >= 0) close(tfd);
|
||||
kp_close(&kp_power);
|
||||
kp_close(&kp_keys);
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user