Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/test_lock_screen.c
T
AskaEth c3abc3fee4 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 同步锁屏行为段。
2026-09-02 00:57:17 +08:00

162 lines
8.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* test_lock_screen.c — M6.x 宿主测试:锁屏 4 位 PIN(lock_screen.c 纯逻辑 + 真实 meow_settings 后端)。
*
* 直接 #include "meow_settings.c" + "lock_screen.c" 于同一 TU(同 test_notif_tf.c 手法),以「真实
* settings.conf」验证:设置/校验/错5锁定持久化(重启不清)/唤醒路径触发/panel.pin 迁移。
* 与面板面板访问级 PIN 同格式(`salt:sha256(salt||pin)`),sha256 算法与 meowpanel 逐字一致。
*
* 运行:gcc -D_GNU_SOURCE -DMEOW_SETTINGS_FILE=\"/tmp/meow_lock_test/settings.conf\" \
* -o test_lock_screen test_lock_screen.c mydir? —— 实际在 launcher 目录:
* gcc -D_GNU_SOURCE -DMEOW_SETTINGS_FILE=\"/tmp/meow_lock_test/settings.conf\" \
* -I. -o test_lock_screen test_lock_screen.c && ./test_lock_screen
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
/* 覆盖存储路径到临时目录(需父目录存在;test 内 mkdir) */
#include "meow_settings.c"
#include "lock_screen.c"
static int g_fail = 0;
#define CHECK(cond, msg) do { \
if (!(cond)) { fprintf(stderr, "FAIL: %s (%s:%d)\n", msg, __FILE__, __LINE__); g_fail++; } \
else fprintf(stderr, "ok: %s\n", msg); \
} while (0)
int main(void)
{
const char *conf = MEOW_SETTINGS_FILE;
mkdir("/tmp/meow_lock_test", 0755);
unlink(conf);
unlink("/data/meow_boot_default"); /* 尽力清掉 save 的 boot.default 同步残留(非 root 会失败,无碍) */
/* ---- 初始化(空文件:默认值激活)---- */
CHECK(meow_settings_init() == MEOW_OK, "init (empty conf)");
CHECK(lck_pin_configured() == 0, "no pin configured initially");
CHECK(lck_lock_required(1) == 0, "wake-required=0 when no pin");
/* ---- 设置/校验(lck_pin_set 落盘 + 校验正确/错误)---- */
CHECK(lck_pin_set("1234") == MEOW_OK, "set pin 1234");
CHECK(lck_pin_configured() == 1, "configured after set");
CHECK(lck_lock_required(1) == 1, "wake-required=1 (pin set, wake=1 default)");
CHECK(lck_pin_check("1234") == 1, "check correct pin");
CHECK(lck_pin_check("0000") == 0, "check wrong pin");
CHECK(lck_pin_valid("1234") == 1, "valid 4-digit");
CHECK(lck_pin_valid("12") == 0, "invalid len 2");
CHECK(lck_pin_valid("12a4") == 0, "invalid non-digit");
CHECK(lck_pin_valid("") == 0, "invalid empty");
CHECK(lck_pin_set("12") == MEOW_ERR_INVAL, "reject set non-4-digit");
/* ---- 唤醒路径触发 / 开关 ---- */
CHECK(lck_lock_required(0) == 1, "manual lock(allow_disable=0) always required");
meow_settings_set_int("system.pin_lock_on_wake", 0);
meow_settings_save();
CHECK(lck_lock_required(1) == 0, "wake-required=0 after wake=0");
CHECK(lck_lock_required(0) == 1, "manual still required after wake=0");
meow_settings_set_int("system.pin_lock_on_wake", 1);
meow_settings_save();
CHECK(lck_lock_required(1) == 1, "wake-required=1 after wake=1");
/* 开机不锁是结构性(boot 路径不调 lck_lock_required)——此处断言决策函数正确即隔离该项 */
/* ---- 唤醒门=主动锁标志:唤醒锁关 + 主动锁标志 → 仍必锁屏(电源菜单「锁定」语义)---- */
unlink("/tmp/meow_pin_locked");
meow_settings_set_int("system.pin_lock_on_wake", 0);
meow_settings_save();
CHECK(lck_wake_should_lock() == 0, "wake_should_lock=0 (wake=0, no manual marker)");
CHECK(lck_manual_lock_set() == MEOW_OK, "manual_lock_set ok");
CHECK(lck_wake_should_lock() == 1, "wake_should_lock=1 (manual marker, wake=0)");
lck_manual_lock_clear();
CHECK(lck_wake_should_lock() == 0, "wake_should_lock=0 after manual marker cleared");
meow_settings_set_int("system.pin_lock_on_wake", 1);
meow_settings_save();
CHECK(lck_wake_should_lock() == 1, "wake_should_lock=1 (wake=1)");
/* ---- 面板一次性解锁恢复口(bypass 标志)---- */
CHECK(lck_unlock_once_consume() == 0, "unlock_once_consume=0 when flag absent");
{
int fd = open("/tmp/meow_pin_unlock_once", O_WRONLY | O_CREAT | O_TRUNC, 0644);
CHECK(fd >= 0, "create unlock_once flag");
if (fd >= 0) { write(fd, "1", 1); close(fd); }
}
CHECK(lck_unlock_once_consume() == 1, "unlock_once_consume=1 when flag present");
CHECK(access("/tmp/meow_pin_unlock_once", F_OK) != 0, "bypass flag consumed (deleted)");
CHECK(lck_unlock_once_consume() == 0, "unlock_once_consume=0 after consumed");
/* ---- 错 5 次锁定(持久化,重启不清)---- */
CHECK(lck_lock_remaining() == 0, "not locked before fails");
int r1 = lck_pin_fail(); /* 1 */
int r2 = lck_pin_fail(); /* 2 */
int r3 = lck_pin_fail(); /* 3 */
int r4 = lck_pin_fail(); /* 4 */
CHECK(r1 == 0 && r2 == 0 && r3 == 0 && r4 == 0, "first 4 fails not locked");
int r5 = lck_pin_fail(); /* 5 -> lock */
CHECK(r5 > 280 && r5 <= 300, "5th fail locks ~300s");
time_t rem1 = lck_lock_remaining();
CHECK(rem1 > 280 && rem1 <= 300, "lock_remaining reflects lockout");
/* 模拟 launcher 重启(重读 settings.conf)→ 锁定戳持久,不因重启清零 */
meow_settings_shutdown();
CHECK(meow_settings_init() == MEOW_OK, "re-init after shutdown (simulated reboot)");
time_t re = lck_lock_remaining();
CHECK(re > 280 && re <= 300, "lock persists after reboot (persisted)");
/* 锁定期间:正确 PIN 仍被识别(但 UI 层禁 input;此处验证逻辑不因锁定改变凭据) */
CHECK(lck_pin_check("1234") == 1, "correct pin still recognized during lockout");
/* 锁定到期:把截止戳拨到过去 → remaining 自动清 + 清零(进程内解禁) */
meow_settings_set_int("system.pin_lock_until", (int)time(NULL) - 1);
meow_settings_save();
CHECK(lck_lock_remaining() == 0, "expired lock auto-clears");
int fails_now; meow_settings_get_int("system.pin_fails", &fails_now);
CHECK(fails_now == 0, "fail counter cleared after expiry");
/* ---- panel.pin 迁移:system.pin 未设 + panel.pin 已设 → 接受 panel.pin;首成功并入 system.pin ---- */
/* 造一个合法 panel.pin(复用本库的哈希:先 set 得 hash 值,清 system.pin 转写 panel.pin) */
lck_pin_set("5678");
char pphash[MEOW_SET_MAX_LEN];
CHECK(meow_settings_get_str("system.pin", pphash, sizeof pphash) == MEOW_OK, "get system.pin hash");
meow_settings_set_str("system.pin", ""); /* 模拟 system.pin 未设 */
meow_settings_set_str("panel.pin", pphash); /* 面板已设 panel.pin(同 hash 格式) */
meow_settings_save();
CHECK(lck_pin_configured() == 1, "configured via panel.pin only");
CHECK(lck_lock_required(1) == 1, "wake-required via panel.pin");
CHECK(lck_pin_check("5678") == 1, "accept panel.pin when system.pin absent");
CHECK(lck_pin_check("1234") == 0, "reject wrong pin during migration");
/* 首次成功 → 并入 system.pin */
lck_pin_success();
char sp2[MEOW_SET_MAX_LEN];
CHECK(meow_settings_get_str("system.pin", sp2, sizeof sp2) == MEOW_OK && sp2[0], "system.pin set after migrate");
CHECK(strcmp(sp2, pphash) == 0, "system.pin == panel.pin after migrate");
CHECK(lck_pin_check("5678") == 1, "still accept after migrate (via system.pin)");
/* ---- 清除免旧 PIN(设置页清除语义:物理持机即授权,无旧密码要求)---- */
/* 先设一个 PIN,然后**不验旧 PIN** 直接 lck_pin_clear()(清除 API 本身无旧 PIN 前置)。
* 先清 panel.pin(迁移残留),确保「已设」只由 system.pin 贡献。 */
meow_settings_set_str("panel.pin", "");
meow_settings_save();
CHECK(lck_pin_set("2468") == MEOW_OK, "set pin 2468 for clear");
CHECK(lck_pin_configured() == 1, "configured before clear");
CHECK(lck_pin_clear() == MEOW_OK, "clear WITHOUT old PIN succeeds");
CHECK(lck_pin_configured() == 0, "not configured after clear (no old PIN path)");
/* ---- 清除(兜底解锁):lck_pin_clear 后不再要求锁 ---- */
/* lck_pin_clear 只清 system.pin;panel.pin 仍存(迁移源),先清掉再断言全部未配 */
meow_settings_set_str("panel.pin", "");
meow_settings_save();
CHECK(lck_pin_clear() == MEOW_OK, "pin clear (final)");
CHECK(lck_pin_configured() == 0, "not configured after clear");
CHECK(lck_lock_required(1) == 0, "wake-required=0 after clear");
/* 清理临时标志文件(幂等) */
unlink("/tmp/meow_pin_unlock_once");
unlink("/tmp/meow_pin_locked");
unlink(conf);
printf("\n%s\n", g_fail ? "SOME TESTS FAILED" : "ALL PASS");
return g_fail ? 1 : 0;
}