- 面板一次性解锁恢复口:/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 同步锁屏行为段。
162 lines
8.6 KiB
C
162 lines
8.6 KiB
C
/* 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;
|
||
}
|