- 面板一次性解锁恢复口:/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 同步锁屏行为段。
146 lines
5.6 KiB
C
146 lines
5.6 KiB
C
/* lock_settings.c — MeowOS 系统设置「锁屏 PIN」独立子页面(subpage.c 脚手架,用户定案 2026-09-02)。
|
||
*
|
||
* 页面(sub_page_t 驱动,同 wifi_page/bt_page):
|
||
* - 状态行(SUB_ROW):未设置 / 已设置 / 锁定中(剩余 mm:ss)
|
||
* - [未设] 设置 PIN:4 位数字双输入确认(lck_input_pin_modal,SDK 数字键)
|
||
* - [已设] 修改 PIN:需旧 PIN 一次校验 + 新 PIN 双输入确认
|
||
* - [已设] 清除 PIN:**无需旧密码**(物理持机即授权,仅 s_dd_modal 二次确认)→ lck_pin_clear
|
||
* - 唤醒后锁屏(system.pin_lock_on_wake)开关行
|
||
* 全程走 lock_screen.c 纯逻辑 + meow_settings 后端(无旁路)。
|
||
*/
|
||
#include "meow_launcher_internal.h"
|
||
|
||
#define LS_ACT_STATUS 0
|
||
#define LS_ACT_SET 1
|
||
#define LS_ACT_MODIFY 2
|
||
#define LS_ACT_CLEAR 3
|
||
#define LS_ACT_WAKE 4
|
||
|
||
static char g_ls_status[48]; /* 状态行摘要(rows 填,paint 后不再变) */
|
||
|
||
static void ls_status_text(char *buf, int len)
|
||
{
|
||
if (!lck_pin_configured()) { snprintf(buf, len, "未设置"); return; }
|
||
time_t rem = lck_lock_remaining();
|
||
if (rem > 0) snprintf(buf, len, "锁定中(%d:%02d)", (int)(rem / 60), (int)(rem % 60));
|
||
else snprintf(buf, len, "已设置");
|
||
}
|
||
|
||
static int ls_rows(void *ctx, sub_row_t *rbuf, int max)
|
||
{
|
||
(void)ctx;
|
||
int n = 0;
|
||
if (n < max) { rbuf[n].kind = SUB_HDR; rbuf[n].label = "锁屏 PIN"; rbuf[n].sub = NULL; rbuf[n].on = 0; rbuf[n].act = 0; n++; }
|
||
ls_status_text(g_ls_status, sizeof g_ls_status);
|
||
if (n < max) { rbuf[n].kind = SUB_ROW; rbuf[n].label = "状态"; rbuf[n].sub = g_ls_status; rbuf[n].on = 0; rbuf[n].act = LS_ACT_STATUS; n++; }
|
||
int configured = lck_pin_configured();
|
||
if (!configured) {
|
||
if (n < max) { rbuf[n].kind = SUB_ACT; rbuf[n].label = "设置 PIN"; rbuf[n].sub = NULL; rbuf[n].on = 0; rbuf[n].act = LS_ACT_SET; n++; }
|
||
} else {
|
||
if (n < max) { rbuf[n].kind = SUB_ACT; rbuf[n].label = "修改 PIN"; rbuf[n].sub = NULL; rbuf[n].on = 0; rbuf[n].act = LS_ACT_MODIFY; n++; }
|
||
if (n < max) { rbuf[n].kind = SUB_ACT; rbuf[n].label = "清除 PIN"; rbuf[n].sub = NULL; rbuf[n].on = 0; rbuf[n].act = LS_ACT_CLEAR; n++; }
|
||
}
|
||
if (n < max) {
|
||
int wake = 1;
|
||
if (meow_settings_get_int("system.pin_lock_on_wake", &wake) != 0) wake = 1;
|
||
rbuf[n].kind = SUB_SW; rbuf[n].label = "唤醒后锁屏"; rbuf[n].sub = NULL;
|
||
rbuf[n].on = wake; rbuf[n].act = LS_ACT_WAKE; n++;
|
||
}
|
||
return n;
|
||
}
|
||
|
||
static void ls_modal(const char *title, const char *line)
|
||
{
|
||
const char *it[1]; it[0] = line;
|
||
s_dd_modal(title, it, 1, -1);
|
||
}
|
||
|
||
static int ls_do_modify(void)
|
||
{
|
||
char old[LCK_PIN_LEN + 1];
|
||
if (!lck_input_pin_modal("输入当前 PIN", old, sizeof old)) return 0;
|
||
if (!lck_pin_check(old)) { ls_modal("修改 PIN", "当前 PIN 错误"); return 1; }
|
||
char a[LCK_PIN_LEN + 1], b[LCK_PIN_LEN + 1];
|
||
if (!lck_input_pin_modal("设置新 PIN", a, sizeof a)) return 0;
|
||
if (!lck_input_pin_modal("再次确认新 PIN", b, sizeof b)) return 0;
|
||
if (strcmp(a, b) != 0) { ls_modal("修改 PIN", "两次输入不一致"); return 1; }
|
||
if (lck_pin_set(a) == MEOW_OK) ls_modal("修改 PIN", "已修改");
|
||
else ls_modal("修改 PIN", "设置失败");
|
||
return 1;
|
||
}
|
||
|
||
static int ls_do_set(void)
|
||
{
|
||
char a[LCK_PIN_LEN + 1], b[LCK_PIN_LEN + 1];
|
||
if (!lck_input_pin_modal("设置 4 位 PIN", a, sizeof a)) return 0;
|
||
if (!lck_input_pin_modal("再次输入确认", b, sizeof b)) return 0;
|
||
if (strcmp(a, b) != 0) { ls_modal("设置 PIN", "两次输入不一致"); return 1; }
|
||
if (lck_pin_set(a) == MEOW_OK) ls_modal("设置 PIN", "已设置");
|
||
else ls_modal("设置 PIN", "设置失败");
|
||
return 1;
|
||
}
|
||
|
||
static int ls_do_clear(void)
|
||
{
|
||
const char *items[2]; items[0] = "是"; items[1] = "否";
|
||
int pick = s_dd_modal("确定清除锁屏 PIN?", items, 2, 1); /* 默认「否」(安全) */
|
||
if (pick != 0) return 1;
|
||
if (lck_pin_clear() == MEOW_OK) ls_modal("清除 PIN", "已清除");
|
||
else ls_modal("清除 PIN", "清除失败(settings 不可写)");
|
||
return 1;
|
||
}
|
||
|
||
static int ls_act(void *ctx, int idx, int act)
|
||
{
|
||
(void)ctx; (void)idx;
|
||
switch (act) {
|
||
case LS_ACT_SET: return ls_do_set();
|
||
case LS_ACT_MODIFY: return ls_do_modify();
|
||
case LS_ACT_CLEAR: return ls_do_clear();
|
||
case LS_ACT_WAKE: {
|
||
int v = 1;
|
||
if (meow_settings_get_int("system.pin_lock_on_wake", &v) != 0) v = 1;
|
||
meow_settings_set_int("system.pin_lock_on_wake", v ? 0 : 1);
|
||
meow_settings_save();
|
||
logmsg("lock_settings: wake-lock toggle -> %d", v ? 0 : 1);
|
||
return 1; /* 重绘 + 重填行(开关态) */
|
||
}
|
||
default: return 0;
|
||
}
|
||
}
|
||
|
||
static int ls_detail(void *ctx, int idx, int act)
|
||
{
|
||
(void)ctx; (void)idx;
|
||
if (act == LS_ACT_STATUS) {
|
||
char line[80];
|
||
ls_status_text(line, sizeof line);
|
||
int rem = (int)lck_lock_remaining();
|
||
if (lck_pin_configured() && rem > 0) {
|
||
char buff[96];
|
||
snprintf(buff, sizeof buff, "连续错误已锁定,剩余 %d:%02d 后重试", rem / 60, rem % 60);
|
||
ls_modal("锁屏 PIN", buff);
|
||
} else {
|
||
ls_modal("锁屏 PIN", line);
|
||
}
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/* 运行「锁屏 PIN」独立子页面(阻塞到返回) */
|
||
int run_lock_settings_page(void)
|
||
{
|
||
sub_page_t p;
|
||
memset(&p, 0, sizeof p);
|
||
p.title = "锁屏 PIN";
|
||
p.top_sw = NULL;
|
||
p.top_sw_set = NULL;
|
||
p.rows = ls_rows;
|
||
p.act = ls_act;
|
||
p.detail = ls_detail;
|
||
p.live = 0;
|
||
p.ctx = NULL;
|
||
return meow_subpage_run(&p);
|
||
}
|