/* 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, "%s", meow_str_zh("lock.status_unset", "未设置")); return; } time_t rem = lck_lock_remaining(); if (rem > 0) snprintf(buf, len, meow_str_zh("lock.status_locked", "锁定中(%d:%02d)"), (int)(rem / 60), (int)(rem % 60)); else snprintf(buf, len, "%s", meow_str_zh("lock.status_set", "已设置")); } 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 = meow_str_zh("lock.title", "锁屏 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 = meow_str_zh("lock.status_row", "状态"); 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 = meow_str_zh("lock.act_set", "设置 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 = meow_str_zh("lock.act_modify", "修改 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 = meow_str_zh("lock.act_clear", "清除 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 = meow_str_zh("lock.wake_lock", "唤醒后锁屏"); 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(meow_str_zh("lock.enter_cur", "输入当前 PIN"), old, sizeof old)) return 0; if (!lck_pin_check(old)) { ls_modal(meow_str_zh("lock.act_modify", "修改 PIN"), meow_str_zh("lock.cur_wrong", "当前 PIN 错误")); return 1; } char a[LCK_PIN_LEN + 1], b[LCK_PIN_LEN + 1]; if (!lck_input_pin_modal(meow_str_zh("lock.set_new", "设置新 PIN"), a, sizeof a)) return 0; if (!lck_input_pin_modal(meow_str_zh("lock.confirm_new", "再次确认新 PIN"), b, sizeof b)) return 0; if (strcmp(a, b) != 0) { ls_modal(meow_str_zh("lock.act_modify", "修改 PIN"), meow_str_zh("lock.mismatch", "两次输入不一致")); return 1; } if (lck_pin_set(a) == MEOW_OK) ls_modal(meow_str_zh("lock.act_modify", "修改 PIN"), meow_str_zh("lock.modified", "已修改")); else ls_modal(meow_str_zh("lock.act_modify", "修改 PIN"), meow_str_zh("lock.set_failed", "设置失败")); return 1; } static int ls_do_set(void) { char a[LCK_PIN_LEN + 1], b[LCK_PIN_LEN + 1]; if (!lck_input_pin_modal(meow_str_zh("lock.enter_4", "设置 4 位 PIN"), a, sizeof a)) return 0; if (!lck_input_pin_modal(meow_str_zh("lock.confirm_input", "再次输入确认"), b, sizeof b)) return 0; if (strcmp(a, b) != 0) { ls_modal(meow_str_zh("lock.act_set", "设置 PIN"), meow_str_zh("lock.mismatch", "两次输入不一致")); return 1; } if (lck_pin_set(a) == MEOW_OK) ls_modal(meow_str_zh("lock.act_set", "设置 PIN"), meow_str_zh("lock.status_set", "已设置")); else ls_modal(meow_str_zh("lock.act_set", "设置 PIN"), meow_str_zh("lock.set_failed", "设置失败")); return 1; } static int ls_do_clear(void) { const char *items[2]; items[0] = meow_str_zh("power.confirm_yes", "是"); items[1] = meow_str_zh("power.confirm_no", "否"); int pick = s_dd_modal(meow_str_zh("lock.clear_confirm", "确定清除锁屏 PIN?"), items, 2, 1); /* 默认「否」(安全) */ if (pick != 0) return 1; if (lck_pin_clear() == MEOW_OK) ls_modal(meow_str_zh("lock.act_clear", "清除 PIN"), meow_str_zh("lock.cleared", "已清除")); else ls_modal(meow_str_zh("lock.act_clear", "清除 PIN"), meow_str_zh("lock.clear_failed", "清除失败(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, meow_str_zh("lock.locked_retry", "连续错误已锁定,剩余 %d:%02d 后重试"), rem / 60, rem % 60); ls_modal(meow_str_zh("lock.title", "锁屏 PIN"), buff); } else { ls_modal(meow_str_zh("lock.title", "锁屏 PIN"), line); } return 1; } return 0; } /* 运行「锁屏 PIN」独立子页面(阻塞到返回) */ int run_lock_settings_page(void) { sub_page_t p; memset(&p, 0, sizeof p); p.title = meow_str_zh("lock.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); }