fix(watchdog+launcher+sdk): M40 电源键 time64 ABI + 锁屏/叠加残留链
- sdk/meow_time32: 抽出可独立链接的 o32 time32 取时/睡眠设施(不依赖 meow_ui.a, watchdog 等独立静态组件可直接链;可选 -DMEOW_TIME32_LIBC_OVERRIDES 接管 libc 入口) - watchdog: now_ms/usleep 改走 time32(修复 held 变天文数字→每次单击都弹菜单); 阈值读 power.longpress_menu_ms/forceoff_ms(缺省 3000/8000),删除 PWR_TOGGLE_MS==PWR_MENU_MS;新增 wd_power.h 纯判定 + 宿主行为矩阵测试 - launcher: App 前台电源菜单补齐 §10.5(notif 全抑制 + 帧恢复 + SIGCONT 排空 + 标记翻回前台);show_power_menu 恢复进入前背景帧(关闭后不再停留菜单画面); 重绘挪到首轮按键采样之后;activity 标记排空窗 + 会话入口清理 + manual_off 去闩锁 - lock_screen: 电源改按下边沿 + 进场 300ms 才熄屏;电源熄屏退出也恢复底层帧; launcher 在 SIGCONT 前写 /tmp/meow_app_repaint,SDK present 消费并 dirty_full - power_menu: 菜单内强关接 power.forceoff_ms(按 longpress 抵扣),日志不再谎称 8s - 重编 meow_ui.a 并重链 meow_launcherd/ncm/files/hello/reader(picbrowser 无源码) - fw_content.conf: 同步 launcherd/watchdog 新 md5;顺带修正 M35 遗留的 nyai 失效钉值 Host: test_wd_fw 66/66、test_overlay_gate 40/40、test_meow_time64/time/repaint PASS。 真机未验证(设备关机);未刷机、未写设备。
This commit is contained in:
1 parent
b1acc9096b
commit
63b278e13e
28 files changed
+977
-217
No files matched your search
@@ -1432,6 +1432,15 @@ static void notif_active_set(const char *owner)
|
||||
}
|
||||
}
|
||||
|
||||
/* M40 F5/P5-P6:请求 App 在恢复前台后整帧重画一次(SDK present 层消费)。
|
||||
* launcher 侧恢复的「底层帧」只能是快照;锁屏/菜单期间 App 若被冻结,它自己的 back_buf
|
||||
* 仍是旧内容,只按脏区上屏会留下 PIN/菜单残影。写这个文件让 App dirty_full 一次。 */
|
||||
static void meow_app_repaint_request(void)
|
||||
{
|
||||
int fd = open(MEOW_APP_REPAINT_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd >= 0) { (void)write(fd, "1", 1); close(fd); }
|
||||
}
|
||||
|
||||
/* §10.5:App 前台顶部下滑 → 展开「由 launcher 渲染」的通知中心叠加会话。
|
||||
* 复用电源菜单对 App 的冻结模板(show_power_menu 的 SIGSTOP/读回/叠加/接管/恢复):
|
||||
* ① SIGSTOP App → ② 写 /tmp/meow_notif_active(+ /tmp/meow_power_menu_active 让 watchdog 让位)
|
||||
@@ -1570,6 +1579,9 @@ static int run_app_lock_overlay(struct app *a, pid_t pid)
|
||||
|
||||
pm_capture_app_frame();
|
||||
meow_ui_flush();
|
||||
/* M40 F5/P5-P6:先写整帧重画请求,再 SIGCONT/放行——App 恢复后的第一次 present 会
|
||||
* 消费它并 dirty_full(),用自身完整帧盖掉 launcher 快照恢复可能留下的任何残影。 */
|
||||
meow_app_repaint_request();
|
||||
if (!keep_running) {
|
||||
/* §310 输入穿透定案(overlay_gate.h):App 被 SIGSTOP 冻结过 → 在 /tmp/meow_notif_active
|
||||
* 仍未更新时**先 SIGCONT**,让 SDK 输入线程排空冻结期缓冲的 evdev 事件副本 + 对齐
|
||||
@@ -1577,10 +1589,10 @@ static int run_app_lock_overlay(struct app *a, pid_t pid)
|
||||
* 防解锁瞬间把积累的触摸回放成 App 内点击(锁屏穿透→「启动奇怪界面」→ 状态栏消失的触发源)。 */
|
||||
kill(pid, SIGCONT);
|
||||
usleep(OVERLAY_DRAIN_WINDOW_MS * 1000);
|
||||
logmsg("lock-overlay: closed (lr=%d) -> SIGCONT app, drain %dms, then mark fg",
|
||||
logmsg("lock-overlay: closed (lr=%d) -> SIGCONT app, drain %dms, repaint req, then mark fg",
|
||||
lr, OVERLAY_DRAIN_WINDOW_MS);
|
||||
} else {
|
||||
logmsg("lock-overlay: closed (lr=%d) -> app never stopped (media keep-alive), no SIGCONT", lr);
|
||||
logmsg("lock-overlay: closed (lr=%d) -> app never stopped (media keep-alive), no SIGCONT, repaint req", lr);
|
||||
}
|
||||
/* 标记翻回前台归属(a->id):本 App 解除自抑恢复前台;后台常驻 App(如 ncm)随之继续自抑
|
||||
* (不叠帧 / 不穿输入——修复「锁屏解锁后 ncm 歌单帧叠加在 Hello 上 + 交互双响应」)。 */
|
||||
@@ -1595,6 +1607,72 @@ static int run_app_lock_overlay(struct app *a, pid_t pid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* M40 F2/P2:App 前台「电源菜单」会话——补齐 §10.5 协议。
|
||||
* 旧实现(M2.24)只有 SIGSTOP → show_power_menu → SIGCONT:
|
||||
* - 没有 notif_active 抑制标记(后台常驻 App 可能在这期间上屏/穿输入);
|
||||
* - 没有帧快照/恢复(菜单把「压暗 App 帧 + 菜单卡」present 后,关闭时 launcher 又
|
||||
* pm_capture_app_frame() 把**菜单帧**拍回 back_buf 再上屏 → 屏幕仍是菜单画面,
|
||||
* 用户看到「按了没反应」,而 App 只按脏区重绘、永远不会重画整屏(P2 主因);
|
||||
* - 没有 SIGCONT→300ms 排空→标记翻回前台 的输入隔离(冻结期触摸回放)。
|
||||
* show_power_menu() 现在会在所有退出路径恢复进入前的背景帧(power_menu.c),所以这里
|
||||
* 的 pm_capture_app_frame() 读到的是 App 帧而不是菜单帧。
|
||||
* 返回:0=取消(继续 App);1=已执行动作(调用方退出循环);2=App 在菜单期死亡。 */
|
||||
static int run_app_power_menu(struct app *a, pid_t pid)
|
||||
{
|
||||
int keep_running = meow_media_app_playing(a->id);
|
||||
if (keep_running) {
|
||||
logmsg("power-menu: open (app=%s pid=%d) PLAYING -> no SIGSTOP (SDK present suppressed)",
|
||||
a->name, pid);
|
||||
} else {
|
||||
logmsg("power-menu: open (app=%s pid=%d) SIGSTOP", a->name, pid);
|
||||
if (kill(pid, SIGSTOP) < 0) {
|
||||
logmsg("power-menu: SIGSTOP %d fail: %s", pid, strerror(errno));
|
||||
} else {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
if (proc_is_stopped(pid)) break;
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 叠加期全抑制:菜单盖在前台 App + 后台常驻 App 上;同时写 POWMENU_ACTIVE 让 watchdog
|
||||
* 对电源长按/强关让位(与通知中心/锁屏同款双标记)。 */
|
||||
notif_active_set("");
|
||||
int pfd = open(POWMENU_ACTIVE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (pfd >= 0) { write(pfd, "1", 1); close(pfd); }
|
||||
|
||||
meow_sys_light();
|
||||
meow_theme_reload();
|
||||
pm_capture_app_frame(); /* 背景 = App 帧(fb0 buffer0) */
|
||||
|
||||
int pm_ret = show_power_menu();
|
||||
|
||||
if (proc_is_zombie(pid)) {
|
||||
/* App 在菜单期死亡:不 SIGCONT、不把菜单帧当 App 帧恢复;交回 waitpid 统一回收。 */
|
||||
notif_active_set("");
|
||||
unlink(POWMENU_ACTIVE);
|
||||
logmsg("power-menu: app pid %d died during menu -> unified exit path", pid);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* 恢复 App 帧(show_power_menu 已还原进入前背景;再拍一次兜底覆盖任何非标准退出路径),
|
||||
* 然后按 §10.5:先请求整帧重画 → SIGCONT → 排空窗 → 标记翻回前台归属。 */
|
||||
pm_capture_app_frame();
|
||||
meow_ui_flush();
|
||||
meow_app_repaint_request();
|
||||
if (!keep_running) {
|
||||
kill(pid, SIGCONT);
|
||||
usleep(OVERLAY_DRAIN_WINDOW_MS * 1000);
|
||||
logmsg("power-menu: closed (ret=%d) -> SIGCONT app, drain %dms, repaint req, then mark fg",
|
||||
pm_ret, OVERLAY_DRAIN_WINDOW_MS);
|
||||
} else {
|
||||
logmsg("power-menu: closed (ret=%d) -> app never stopped (media keep-alive), no SIGCONT, repaint req",
|
||||
pm_ret);
|
||||
}
|
||||
notif_active_set(a ? a->id : "");
|
||||
unlink(POWMENU_ACTIVE);
|
||||
return pm_ret;
|
||||
}
|
||||
|
||||
/* launch_app_chain:launch_app / launch_activity 的共享核心。
|
||||
* chain 非空 → 向子进程注入 MEOW_ACTIVITY/MEOW_CHAIN 并初始化 nav_stack(M3);空/NULL → 裸启动。 */
|
||||
static int launch_app_chain(struct app *a, const char *chain)
|
||||
@@ -1963,6 +2041,11 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
* 修法:本循环以「背光==0 且非超时」补判手动息屏,唤醒时按 meow_auto_slept||manual 一并触发
|
||||
* lck_wake_should_lock 锁屏,两条路径对齐。 */
|
||||
int app_panel_manual_off = 0;
|
||||
/* M40 F3/P3:叠加层/电源菜单返回后的排空窗。watchdog 在电源菜单期间让位,菜单关闭后
|
||||
* 被 SIGCONT 的 App 会把冻结期缓存的触摸重放成 /tmp/meow_app_activity;若把它当用户
|
||||
* 触摸,会立刻「亮屏 + 弹锁屏」(P3 的 ACTIVITY 唤醒路径)。窗口内的标记只消费不唤醒。 */
|
||||
unsigned long long overlay_return_ms = now_ms();
|
||||
int overlay_return_valid = 0;
|
||||
/* M2.11 D:应用二进制/资源若在卡上,卡被拔可能 SIGBUS 崩。启动前记录,运行期监测卡移除。
|
||||
* (拷贝到内存/板载 staging 的方案先不做,仅记录 APPS.md 规范。) */
|
||||
int app_on_card = (strncmp(a->exec, MEOWAPPS, strlen(MEOWAPPS)) == 0);
|
||||
@@ -1986,9 +2069,12 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
g_sb_mode_last = -1; /* 强制首帧同步(进入新 App 会话清零,避免沿用上一 App 的缓存态) */
|
||||
unlink(MEOW_SBAR_MODE_FILE); /* 清可能残留的上一 App 顶条模式(崩溃/被杀未清),防新 App 误收合 */
|
||||
if (!a->fullscreen) app_overlay_statusbar();
|
||||
/* M2.24:清上一次会话可能残留的电源菜单标记,只认本次新 watchdog 生成的请求。 */
|
||||
/* M2.24:清上一次会话可能残留的电源菜单标记,只认本次新 watchdog 生成的请求。
|
||||
* M40 F3:同时清 /tmp/meow_app_activity——上一会话(或启动手势)遗留的标记不能在本会话
|
||||
* 首圈被当成「用户触摸」而触发息屏计时重置/唤醒+锁屏。 */
|
||||
unlink(POWMENU_MARKER);
|
||||
unlink(POWMENU_ACTIVE);
|
||||
unlink(MEOW_APP_ACTIVITY_FILE);
|
||||
/* §10.5:进入 App 前台会话。置位让 ipc_dispatch 的 MSG_NOTIF_OPEN 可入队(否则回 ERR);
|
||||
* 清残留 pending(防上一会话未消费的 OPEN 被本会话误展开)。 */
|
||||
g_app_session_active = 1;
|
||||
@@ -2057,6 +2143,8 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
m_notif_open_t nopen;
|
||||
if (meow_notif_open_take(&nopen)) {
|
||||
int nr = run_app_notif_overlay(a, pid);
|
||||
overlay_return_ms = now_ms(); /* M40 F3:排空窗起点(activity 标记忽略窗) */
|
||||
overlay_return_valid = 1;
|
||||
/* 输入基线重播(与电源菜单同款):面板期间按键可能已变化,重播防误判 key_edge */
|
||||
kp_poll(&kp_power, NULL, NULL);
|
||||
kp_poll(&kp_keys, NULL, NULL);
|
||||
@@ -2109,9 +2197,23 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
* M6.5 §310 问题1:watchdog 电源键手动息屏(背光 0、不置 meow_auto_slept)→ 唤醒时按
|
||||
* app_panel_manual_off 一并锁屏,与超时路径(meow_auto_slept)对齐。 */
|
||||
{
|
||||
/* 背光==0 => 面板已关(超时路径已置 auto_slept;手动路径靠此补判)。
|
||||
* read_brightness() 失败返回 -1(≠0),不误置位。 */
|
||||
if (read_brightness() == 0) app_panel_manual_off = 1;
|
||||
/* M40 F3:去掉单向闩锁。旧实现只在 watchdog 手动息屏时置 1、只有本循环唤醒分支清 1;
|
||||
* watchdog 之后把屏点亮(pwr_woke)闩锁仍是 1 → 任何 activity 标记都会再次
|
||||
* 「亮屏+锁屏」(P3 放大器)。改为每圈按真实背光复位:
|
||||
* - 背光==0 → 置 1(手动/超时熄屏都算);
|
||||
* - 背光>0 且**没有任何键按住** → 复位 0(屏已被 watchdog 点亮,不再残留闩锁);
|
||||
* - 背光>0 但电源键仍按住(本次唤醒按压)→ 保留一拍,让下面的 key-wake 分支仍能
|
||||
* 按 lck_wake_should_lock 弹锁屏(不牺牲「手动息屏后电源唤醒要锁屏」语义)。
|
||||
* read_brightness() 失败返回 -1(≠0),不误置/误清。 */
|
||||
int bri_now = read_brightness();
|
||||
if (bri_now == 0) {
|
||||
app_panel_manual_off = 1;
|
||||
} else if (bri_now > 0) {
|
||||
int any_key_down = 0;
|
||||
for (int w = 0; w < KEYBUF_WORDS; w++)
|
||||
if (kp_power.cur[w] || kp_keys.cur[w]) { any_key_down = 1; break; }
|
||||
if (!any_key_down) app_panel_manual_off = 0;
|
||||
}
|
||||
int key_edge = 0;
|
||||
for (int w = 0; w < KEYBUF_WORDS; w++)
|
||||
if (kp_power.cur[w] != save_pow[w] || kp_keys.cur[w] != save_keys[w]) { key_edge = 1; break; }
|
||||
@@ -2141,6 +2243,8 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
* (launcher 不崩、run_menu 重绘主屏),同 run_app_notif_overlay 的 died 分支。 */
|
||||
if (lck_wake_should_lock()) {
|
||||
int lr2 = run_app_lock_overlay(a, pid);
|
||||
overlay_return_ms = now_ms(); /* M40 F3:排空窗起点 */
|
||||
overlay_return_valid = 1;
|
||||
if (lr2 != 0) {
|
||||
reap_wait(pid, &status);
|
||||
ams_status_valid = 1;
|
||||
@@ -2161,11 +2265,15 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
}
|
||||
}
|
||||
/* M2.71-bug5:App 前台触摸/交互(launcher 看不到应用内触摸,SDK 写标记)→ 重置自动息屏
|
||||
* 计时;若已自动息屏,按 key-wake 同款路径唤醒(面板上电 + 落 buffer0)。 */
|
||||
* 计时;若已自动息屏,按 key-wake 同款路径唤醒(面板上电 + 落 buffer0)。
|
||||
* M40 F3:叠加层/电源菜单刚返回的排空窗内,该标记是 App 被 SIGCONT 后重放的冻结期
|
||||
* 输入,只消费不唤醒(否则「亮屏 + 弹 PIN」,P3)。 */
|
||||
if (access(MEOW_APP_ACTIVITY_FILE, F_OK) == 0) {
|
||||
unlink(MEOW_APP_ACTIVITY_FILE);
|
||||
app_last_input = now_ms();
|
||||
if (meow_auto_slept || app_panel_manual_off) {
|
||||
if (overlay_activity_drain_active(overlay_return_valid, overlay_return_ms, now_ms())) {
|
||||
logmsg("activity marker consumed in overlay drain window -> no wake");
|
||||
} else if (meow_auto_slept || app_panel_manual_off) {
|
||||
logmsg("screen-off (app): touch wake (auto=%d manual=%d)",
|
||||
meow_auto_slept, app_panel_manual_off);
|
||||
meow_panel_on();
|
||||
@@ -2176,6 +2284,8 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
* §310:叠加期 App 崩溃 → 回收僵尸走统一退出路径(launcher 不崩、run_menu 重绘主屏)。 */
|
||||
if (lck_wake_should_lock()) {
|
||||
int lr2 = run_app_lock_overlay(a, pid);
|
||||
overlay_return_ms = now_ms(); /* M40 F3:排空窗起点 */
|
||||
overlay_return_valid = 1;
|
||||
if (lr2 != 0) {
|
||||
reap_wait(pid, &status);
|
||||
ams_status_valid = 1;
|
||||
@@ -2216,20 +2326,16 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
app_prev_vold = vold;
|
||||
if (app_seq_hits > 0 && now_ms() - app_seq_last > (unsigned)seq_gap_ms * 2)
|
||||
app_seq_hits = 0;
|
||||
/* M2.24 全面按键接管:watchdog 检测到电源长按≥3s 写 /tmp/meow_power_menu → 此处消费:
|
||||
* SIGSTOP 应用冻结 → 写 powmenu_active 让 watchdog 让位 → 统一电源菜单(launcher 一处绘制,
|
||||
* 复用 show_power_menu,含触摸/音量导航/电源确认/8s 强关/pm_interacted 保护)→ 菜单关 →
|
||||
* 清 active → SIGCONT 应用续跑。 */
|
||||
/* M2.24/M40 全面按键接管:watchdog 检测到电源长按≥power.longpress_menu_ms 写
|
||||
* /tmp/meow_power_menu → 此处消费。M40 F2 起走 run_app_power_menu() 的完整 §10.5
|
||||
* 协议(SIGSTOP + 全抑制标记 + 帧恢复 + SIGCONT→排空→标记翻回前台 + 整帧重画请求),
|
||||
* 不再只 SIGSTOP/show_power_menu/SIGCONT(旧实现关闭后屏幕仍是菜单帧 = P2 主因)。 */
|
||||
if (access(POWMENU_MARKER, F_OK) == 0) {
|
||||
unlink(POWMENU_MARKER);
|
||||
logmsg("watchdog: power menu request (app %s) -> SIGSTOP + menu", a->name);
|
||||
kill(pid, SIGSTOP);
|
||||
int mfd = open(POWMENU_ACTIVE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (mfd >= 0) { write(mfd, "1", 1); close(mfd); }
|
||||
int pm_ret = show_power_menu();
|
||||
unlink(POWMENU_ACTIVE);
|
||||
kill(pid, SIGCONT);
|
||||
logmsg("watchdog: power menu closed (ret=%d) -> SIGCONT app", pm_ret);
|
||||
logmsg("watchdog: power menu request (app %s) -> overlay session", a->name);
|
||||
int pm_ret = run_app_power_menu(a, pid);
|
||||
overlay_return_ms = now_ms(); /* M40 F3:排空窗起点(activity 标记忽略窗) */
|
||||
overlay_return_valid = 1;
|
||||
/* M2.25:菜单期间按键可能已变化,重播 save_pow/save_keys 防误判 key_edge
|
||||
* (避免菜单关闭瞬间误触发「键唤醒」或刷新自动息屏计时)。 */
|
||||
kp_poll(&kp_power, NULL, NULL);
|
||||
@@ -2237,6 +2343,11 @@ static int launch_app_chain(struct app *a, const char *chain)
|
||||
memcpy(save_pow, kp_power.cur, sizeof save_pow);
|
||||
memcpy(save_keys, kp_keys.cur, sizeof save_keys);
|
||||
app_last_input = now_ms(); /* M2.17:菜单交互即输入,重置应用会话自动息屏计时 */
|
||||
if (pm_ret == 2) { /* App 在菜单期死亡:回收僵尸走统一退出路径 */
|
||||
reap_wait(pid, &status);
|
||||
ams_status_valid = 1;
|
||||
break;
|
||||
}
|
||||
if (pm_ret != 0) break; /* 关机/重启/回HibyOS:系统通常已 reboot,防御性退出 */
|
||||
}
|
||||
/* 「同一个状态栏」闭环:常驻顶条叠加(agent-146 全屏收合接入)。
|
||||
|
||||
@@ -315,11 +315,12 @@ int run_lock_screen(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* M7.1 解锁恢复:锁屏是整帧不透明覆盖(lk_draw fill_rect 全屏),退出后底层界面不会自动重绘
|
||||
* —— 只有 App 自绘的控件区域刷新,未刷新区残留锁屏 PIN 最后一帧(解锁后整屏脏区根因)。此处
|
||||
* 在锁屏首扑前把底层帧(SDK back_buf = 进入前的 App 帧/主界面帧)快照下来;解锁(unlocked=1)
|
||||
* 时整帧回写 back_buf + present,强制底层界面完整重绘(app_launcher.c 的 lock-overlay 关闭路径
|
||||
* 随后 pm_capture_app_frame 读 fb0 即得到正确 App 帧,不再读到锁帧)。 */
|
||||
/* M7.1/M40 F5 解锁/熄屏恢复:锁屏是整帧不透明覆盖(lk_draw fill_rect 全屏),退出后底层界面
|
||||
* 不会自动重绘 —— 只有 App 自绘的控件区域刷新,未刷新区残留锁屏 PIN 最后一帧。
|
||||
* 此处把锁屏首扑前的底层帧(SDK back_buf = 进入前的 App 帧/主界面帧)快照下来;
|
||||
* **任何退出路径**(解锁 unlocked=1 或电源键熄屏 unlocked=0)都整帧回写 back_buf + present,
|
||||
* 保证 app_launcher.c 的 lock-overlay 关闭路径随后 pm_capture_app_frame 读 fb0 得到的是
|
||||
* 正确 App 帧,而不是 PIN 帧(后者会被下一次锁屏当成底层帧 → P5 残影链)。 */
|
||||
unsigned char *lk_bg_snap = NULL;
|
||||
size_t lk_bg_len = 0;
|
||||
if (back_buf_ok && fb && fb_line > 0 && fb_yres > 0) {
|
||||
@@ -400,7 +401,7 @@ int run_lock_screen(void)
|
||||
}
|
||||
|
||||
/* 电源键/音量键轮询 + 输入活动检测(重置自睡计时) + 自睡/唤醒切换。
|
||||
* 活跃态:电源键按下 → 息屏并退出锁屏(回 App/主屏,下次唤醒再锁)——沿用原语义;
|
||||
* 活跃态:电源键**按下边沿**(进场 ≥300ms)→ 息屏并退出锁屏(回 App/主屏,下次唤醒再锁);
|
||||
* 空闲超 lk_off_ms → 自睡(asleep=1,锁态保持,仍在本循环)。
|
||||
* asleep:电源键按下边沿 / 触摸活动 → meow_panel_on + 重画锁屏页(本循环唤醒链回锁)。
|
||||
* 音量键本页不动(仅视为输入活动,重置计时)。 */
|
||||
@@ -429,9 +430,14 @@ int run_lock_screen(void)
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* 电源键=息屏(允许再睡;下次唤醒按 lck_wake_should_lock 再锁) */
|
||||
if (pwr_down) {
|
||||
logmsg("lock: power key -> screen off (stay locked)");
|
||||
/* 电源键=息屏(允许再睡;下次唤醒按 lck_wake_should_lock 再锁)。
|
||||
* M40 F4/P4:必须用**按下边沿**且进场 ≥300ms 才生效。旧实现用电平
|
||||
* (pwr_down):打开电源菜单的那次长按在 PIN 页出现时仍按着,页面被同一次
|
||||
* 按住立刻熄灭(用户症状「手动锁屏不熄屏而是进 PIN,此时点电源才熄屏」)。
|
||||
* 边沿判定在 overlay_gate.h(宿主单测同源)。 */
|
||||
if (overlay_lock_power_off_now(pwr_edge, now_ms() - entry_ms)) {
|
||||
logmsg("lock: power key edge (%llums after entry) -> screen off (stay locked)",
|
||||
now_ms() - entry_ms);
|
||||
meow_panel_off();
|
||||
break; /* return 0 */
|
||||
}
|
||||
@@ -569,13 +575,17 @@ int run_lock_screen(void)
|
||||
done:
|
||||
meow_ui_activity_pop(); /* M7.1b:锁屏控件 owner 闸门关闭(与进场 push 对称) */
|
||||
g_lk_down_key = LK_DOWN_NONE;
|
||||
/* M7.1 解锁恢复:把锁屏首扑前快照的底层帧整帧回写 back_buf + present,强制底层 App/主界面
|
||||
* 完整重绘(消除「解锁后整屏 = PIN 最后一帧,仅 App 控件自绘区刷新」的脏区残留)。 */
|
||||
if (unlocked && lk_bg_snap && back_buf_ok && fb && lk_bg_len > 0) {
|
||||
/* M7.1/M40 F5:把锁屏首扑前快照的底层帧整帧回写 back_buf + present。
|
||||
* M40 起**不再限定 unlocked**:电源键熄屏退出(lr=0)也必须恢复,否则 fb0 会停留在
|
||||
* PIN 最后一帧;launcher 的 lock-overlay 关闭路径紧接着 pm_capture_app_frame() 会把
|
||||
* 这帧 PIN 抄进 back_buf 并上屏,下一次锁屏再把它当「底层帧」快照 —— P5 残影链的起点。
|
||||
* 屏黑时 present 无害(面板已下电),解锁时则同时消除「整屏 = PIN」的脏区残留。
|
||||
* 「解锁后 App 整帧重画」由 launcher 写 /tmp/meow_app_repaint(SDK present 消费)完成。 */
|
||||
if (lk_bg_snap && back_buf_ok && fb && lk_bg_len > 0) {
|
||||
memcpy(fb, lk_bg_snap, lk_bg_len);
|
||||
meow_dirty_full();
|
||||
meow_ui_flush();
|
||||
logmsg("lock: unlock -> restore underlying frame (full repaint)");
|
||||
logmsg("lock: exit (unlocked=%d) -> restore underlying frame (full repaint)", unlocked);
|
||||
}
|
||||
if (lk_bg_snap) { free(lk_bg_snap); lk_bg_snap = NULL; lk_bg_len = 0; }
|
||||
if (tfd >= 0) {
|
||||
|
||||
@@ -268,6 +268,9 @@ static inline const char *meow_str_zh(const char *id, const char *zh)
|
||||
#define MEOW_SBAR_MODE_FILE "/tmp/meowapp_sbar"
|
||||
/* M2.71-bug5:App 前台触摸/交互 → SDK 写该标记;launcher 前台 app 循环消费(unlink + 重置息屏计时) */
|
||||
#define MEOW_APP_ACTIVITY_FILE "/tmp/meow_app_activity"
|
||||
/* M40 F5/P5-P6:解锁/菜单关闭后强制 App 整帧重画的请求文件。launcher 在 SIGCONT 前写,
|
||||
* SDK present 层(sdk/meow_ui_repaint.c)看到就 dirty_full() 一次并删除。 */
|
||||
#define MEOW_APP_REPAINT_FILE "/tmp/meow_app_repaint"
|
||||
|
||||
/* ---- 共享结构体/枚举(来自 meow_launcherd.c,拆分后统一放置)---- */
|
||||
struct kd_state { int raw, stable, down; int longpressed; unsigned long long since, down_at; };
|
||||
|
||||
Binary file not shown.
@@ -91,4 +91,26 @@ static inline int overlay_lock_wake_now(int pwr_edge, int touch_ready)
|
||||
return (pwr_edge || touch_ready) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* M40 F4/P4:锁屏页「电源按下=息屏退出」必须在**按下边沿**生效,且进场后 ≥300ms 才允许。
|
||||
* 旧实现用电平(kp_is_down)且无防抖:打开电源菜单的那次按压在 PIN 页出现时仍按着,
|
||||
* PIN 页会被同一次按住立刻熄灭(用户症状「手动锁屏不熄屏而是进 PIN,此时点电源才熄屏」)。
|
||||
* 300ms 也避开 launcher 进入锁屏页时的按键基线窗口。 */
|
||||
#define OVERLAY_LOCK_POWER_GRACE_MS 300
|
||||
|
||||
static inline int overlay_lock_power_off_now(int pwr_down_edge, unsigned long long since_entry_ms)
|
||||
{
|
||||
return (pwr_down_edge && since_entry_ms >= OVERLAY_LOCK_POWER_GRACE_MS) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* M40 F3/P3:叠加层/电源菜单返回后的排空窗内,`/tmp/meow_app_activity` 是 App 被 SIGCONT
|
||||
* 后重放的冻结期输入(不是用户新触摸),必须消费掉但不得触发「亮屏+锁屏」。
|
||||
* 返回 1=仍在排空窗(忽略 activity 标记)。 */
|
||||
static inline int overlay_activity_drain_active(int have_return_mark,
|
||||
unsigned long long since_return_ms,
|
||||
unsigned long long now_ms)
|
||||
{
|
||||
if (!have_return_mark) return 0;
|
||||
return (now_ms - since_return_ms < OVERLAY_DRAIN_WINDOW_MS) ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif /* MEOW_OVERLAY_GATE_H */
|
||||
@@ -355,22 +355,59 @@ int meow_power_action(uint32_t cmd)
|
||||
}
|
||||
|
||||
|
||||
/* M40 F2/P2:关闭菜单时恢复进入前的背景帧并 present。
|
||||
* dim_screen() 就地压暗 back_buf;若不恢复,app_launcher 关闭会话时的 pm_capture_app_frame()
|
||||
* 会把「压暗 App 帧 + 菜单卡」当成 App 帧拍回并上屏 → 菜单关闭后屏幕仍是菜单画面,
|
||||
* 用户看到「再次单击没反应」(P2 主因)。所有退出路径(取消/锁定/关机/强关)统一恢复。 */
|
||||
static void pm_restore_bg(unsigned char *snap, size_t len)
|
||||
{
|
||||
if (!snap || !len || !back_buf_ok || !fb) return;
|
||||
memcpy(fb, snap, len);
|
||||
meow_dirty_full();
|
||||
meow_ui_flush();
|
||||
}
|
||||
|
||||
/* 电源菜单(M2.6):2×2 网格,dirty 绘制消频闪;输入修复:
|
||||
* - 触摸按下捕获坐标、抬起命中按钮即确认(同 run_menu MT 防抖);
|
||||
* - 音量上/下导航;播放=确认;电源新按(松开长按后)=确认当前钮(非取消);
|
||||
* - 取消=选「取消」钮;8s 持续按住=强制关机(绕过)。
|
||||
* - 取消=选「取消」钮;按住 power.forceoff_ms(缺省 8s,从按下起算)=强制关机(绕过)。
|
||||
* 返回 1=采取动作,0=取消。 */
|
||||
int show_power_menu(void)
|
||||
{
|
||||
int fbfd = open(FB_DEV, O_RDWR);
|
||||
if (fbfd >= 0) { ioctl(fbfd, FBIOBLANK, 0); close(fbfd); } /* 亮起面板 */
|
||||
pm_capture_app_frame(); /* A-0:菜单背景 = app 当前帧(fb0 buffer0),再压暗绘制其上 */
|
||||
meow_screen_on = 1; /* 菜单打开即视为亮屏 */
|
||||
|
||||
/* M40 F2:先开输入设备并采样第一轮基线。旧顺序把这一步放在 pm_capture/dim/建卡之后
|
||||
* (真机实测菜单请求→keypoll ready 相隔 75ms),一次完整的按下+抬起若落在这段阻塞绘制里
|
||||
* 就永远看不到边沿(EVIOCGKEY 是电平采样,不回溯事件队列)。重活挪到采样之后。 */
|
||||
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 prev_vold = 0, prev_volu = 0, prev_pwr = 0;
|
||||
kp_poll(&kp_power, NULL, NULL); kp_poll(&kp_keys, NULL, NULL);
|
||||
prev_pwr = kp_is_down(&kp_power, KEY_POWER) ? 1 : 0;
|
||||
prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN) ? 1 : 0;
|
||||
prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP) ? 1 : 0;
|
||||
|
||||
/* 背景帧:先把 app 当前帧读回 back_buf,快照后再压暗绘制 */
|
||||
pm_capture_app_frame(); /* A-0:菜单背景 = app 当前帧(fb0 buffer0) */
|
||||
unsigned char *pm_bg_snap = NULL;
|
||||
size_t pm_bg_len = 0;
|
||||
if (back_buf_ok && fb && fb_line > 0 && fb_yres > 0) {
|
||||
pm_bg_len = (size_t)fb_line * (size_t)fb_yres;
|
||||
pm_bg_snap = malloc(pm_bg_len);
|
||||
if (pm_bg_snap) memcpy(pm_bg_snap, fb, pm_bg_len);
|
||||
else { pm_bg_len = 0; logmsg("pm: bg snapshot malloc fail (len=%zu)", pm_bg_len); }
|
||||
}
|
||||
dim_screen();
|
||||
/* M2.8 Bug 3-residual:若电源菜单是在「息屏」态打开(按住 3s),此处 FBIOBLANK(0)
|
||||
* 刚上电,LCDC 扫描地址可能非 buffer0;强制 re-pan 让压暗的应用列表 + 菜单落在被显示的
|
||||
* 缓冲,否则菜单画在非显示缓冲上不可见。 */
|
||||
fb_pan_buf0_force();
|
||||
meow_screen_on = 1; /* 菜单打开即视为亮屏 */
|
||||
|
||||
/* M2.11 B:默认光标 = 「取消」(安全项,index 4)。用户打开菜单后未导航就按电源/播放,
|
||||
* 只会取消关菜单,绝不因「按电源键」本身关机/重启。要真关机必须先导航到「关机」再确认。 */
|
||||
@@ -383,29 +420,25 @@ int show_power_menu(void)
|
||||
pm_draw_card(); /* 卡片 + 标题 POWER MENU + 底部提示(SDK 主题色,i18n 文案) */
|
||||
meow_dirty_full(); /* M2.16:把压暗列表+卡片+标题+(下方圆钮)作为一整帧呈现 */
|
||||
|
||||
/* 触摸状态(按下→抬起):统一 meow_touch 接口(goodix 时序免疫,原点由首个有效 ABS 锁) */
|
||||
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 prev_vold = 0, prev_volu = 0, prev_pwr = 0;
|
||||
kp_poll(&kp_power, NULL, NULL); kp_poll(&kp_keys, NULL, NULL);
|
||||
prev_pwr = kp_is_down(&kp_power, KEY_POWER) ? 1 : 0;
|
||||
prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN) ? 1 : 0;
|
||||
prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP) ? 1 : 0;
|
||||
|
||||
int act = -1;
|
||||
int pm_rc = 0;
|
||||
unsigned long long pm_t0 = now_ms();
|
||||
/* 强关阈值:power.forceoff_ms 是**从按下起算**的总时长;菜单在 longpress 阈值处打开,
|
||||
* 因此菜单内剩余等待 = forceoff - longpress(缺省 8000-3000=5000ms,与原硬编码值一致,
|
||||
* 但不再忽略 settings)。配置异常(剩余<1s)时退回完整 forceoff。 */
|
||||
unsigned long long pm_forceoff_after_ms = 5000;
|
||||
if (power_forceoff_ms > power_longpress_menu_ms &&
|
||||
power_forceoff_ms - power_longpress_menu_ms >= 1000)
|
||||
pm_forceoff_after_ms = (unsigned long long)(power_forceoff_ms - power_longpress_menu_ms);
|
||||
else if (power_forceoff_ms > 0)
|
||||
pm_forceoff_after_ms = (unsigned long long)power_forceoff_ms;
|
||||
unsigned long long pm_last_interact = pm_t0; /* M2.33:菜单空闲自动关闭基准(任何互动刷新) */
|
||||
int pm_init = 0, last_sel = -1;
|
||||
/* M2.10 Bug:电源菜单 8s 强关(按住电源≥8s=绕过强关)会覆盖用户的菜单操作 —— 用户按住
|
||||
* 电源打开菜单后(尤其仍按着电源)点选「回到HibyOS/重启」等按钮,8s 一到先触发强关 → 关机
|
||||
/* M2.10 Bug:电源菜单强关(按住电源到 forceoff)会覆盖用户的菜单操作 —— 用户按住
|
||||
* 电源打开菜单后(尤其仍按着电源)点选「回到HibyOS/重启」等按钮,强关一到先触发 → 关机
|
||||
* 而非执行所选动作。修法:一旦用户与菜单互动(音量导航/触摸/播放/电源确认),置 pm_interacted=1
|
||||
* 取消 8s 强关,让所选动作(如「回到HibyOS」→ reboot RESTART)生效。仅当全程未互动才保留「按住
|
||||
* 8s=强关」。*/
|
||||
* 取消强关,让所选动作(如「回到HibyOS」→ reboot RESTART)生效。仅当全程未互动才保留「按住
|
||||
* 到 forceoff=强关」。*/
|
||||
int pm_interacted = 0;
|
||||
int pm_press_idx = -1; /* M7.0b:当前按下钮(按压态走 SDK 状态机位) */
|
||||
for (;;) {
|
||||
@@ -488,17 +521,25 @@ int show_power_menu(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* 8s 强关(绕过):仅当电源持续按住、且用户全程未与菜单互动才触发 —— 放在触摸/按键处理
|
||||
* 之后,避免「用户已点选按钮」的同一轮被强关抢先(M2.10 Bug)。 */
|
||||
if (pwr && !pm_interacted && now_ms() - pm_t0 >= 5000) {
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] POWER HOLD 8s -> would force poweroff"); meow_ui_activity_pop(); return 1; }
|
||||
logmsg("pm: POWER HOLD 8s -> force poweroff");
|
||||
/* 强关(绕过):仅当电源持续按住、且用户全程未与菜单互动才触发 —— 放在触摸/按键处理
|
||||
* 之后,避免「用户已点选按钮」的同一轮被强关抢先(M2.10 Bug)。
|
||||
* M40:阈值接 power.forceoff_ms(从按下起算的剩余时长),不再硬编码 5000/日志谎称 8s。 */
|
||||
if (pwr && !pm_interacted && now_ms() - pm_t0 >= pm_forceoff_after_ms) {
|
||||
if (sim_no_exec) {
|
||||
logmsg("pm: [sim-no-exec] POWER HOLD %dms (menu-open + %llums) -> would force poweroff",
|
||||
power_forceoff_ms, pm_forceoff_after_ms);
|
||||
pm_rc = 1;
|
||||
goto out;
|
||||
}
|
||||
logmsg("pm: POWER HOLD %dms (menu-open + %llums) -> force poweroff",
|
||||
power_forceoff_ms, pm_forceoff_after_ms);
|
||||
if (meow_power_action(POWER_SHUTDOWN) != MEOW_OK) {
|
||||
logmsg("pm: power service unavailable, abort force-off (menu closed, no action)");
|
||||
meow_ui_activity_pop(); return 0;
|
||||
pm_rc = 0;
|
||||
goto out;
|
||||
}
|
||||
meow_ui_activity_pop();
|
||||
return 1;
|
||||
pm_rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* M2.33 菜单空闲超时自动关闭:菜单受 MeowOS screen_off_timeout 管理(系统界面不豁免)。
|
||||
@@ -516,57 +557,64 @@ int show_power_menu(void)
|
||||
if (act >= 0) break;
|
||||
usleep(POLL_MS * 1000);
|
||||
}
|
||||
if (tfd >= 0) close(tfd);
|
||||
meow_ui_activity_pop(); /* M7.0b:退出电源菜单,回主 activity(控件 owner 仍钉哨兵,复用) */
|
||||
|
||||
/* M2.11 B:电源键在菜单 = 按当前项确认。act 与电源动作逐项核对:
|
||||
* act==PM_NUM-1(取消) -> 只关菜单,绝不关机(return 0,永不到电源动作);
|
||||
* act==PM_NUM-1(取消) -> 只关菜单,绝不关机(rc=0,永不到电源动作);
|
||||
* act==4(锁定) -> 手动锁(meow_lock_screen_engage,未配 PIN 则 no-op),关菜单;
|
||||
* act==0(关机)/act==1(重启)/act==2(回HibyOS)/act==3(升级模式) -> 才经服务 IPC 执行电源动作。
|
||||
* 只有 act 为 0/1/2/3 才可能发电源动作;power 键本身绝不触发关机。 */
|
||||
logmsg("pm: act=%d -> %s", act,
|
||||
act == 0 ? "关机" : act == 1 ? "重启" : act == 2 ? "回HibyOS" : act == 3 ? "升级模式"
|
||||
: act == 4 ? "锁定" : "取消");
|
||||
if (act == PM_NUM - 1) { logmsg("pm: cancel (close menu only)"); return 0; }
|
||||
if (act == PM_NUM - 1) { logmsg("pm: cancel (close menu only)"); pm_rc = 0; goto out; }
|
||||
if (act == 4) {
|
||||
logmsg("pm: LOCK SCREEN");
|
||||
meow_lock_screen_engage();
|
||||
return 0; /* 关菜单;run_menu 继续(锁屏页已阻塞到解锁或电源息屏) */
|
||||
pm_rc = 0; /* 关菜单;run_menu 继续(锁屏页已阻塞到解锁或电源息屏) */
|
||||
goto out;
|
||||
}
|
||||
/* 动作统一经电源管理服务 IPC(meow_svc_power);launcher 不再直连 poweroff/reboot(2)/写 mtd5/
|
||||
* 写 boot 默认——关机/重启/升级/回HiBy 的动作原语都在服务内实现(§3.2 单一动作链路)。 */
|
||||
/* 公共服务:执行动作;服务不可达 → 按「取消」返回(launcher 存活,绝不误报已动作卡死)。
|
||||
* meow_power_action 内部已先 meow_notif_before_poweroff()(转储未上卡通知)。 */
|
||||
pm_rc = 1;
|
||||
if (act == 0) {
|
||||
logmsg("pm: POWER OFF");
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would poweroff"); return 1; }
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would poweroff"); goto out; }
|
||||
if (meow_power_action(POWER_SHUTDOWN) != MEOW_OK) {
|
||||
logmsg("pm: power service unavailable, abort (menu closed, no action)");
|
||||
return 0;
|
||||
pm_rc = 0;
|
||||
}
|
||||
} else if (act == 1) {
|
||||
logmsg("pm: REBOOT");
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would reboot"); return 1; }
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would reboot"); goto out; }
|
||||
if (meow_power_action(POWER_REBOOT) != MEOW_OK) {
|
||||
logmsg("pm: power service unavailable, abort (menu closed, no action)");
|
||||
return 0;
|
||||
pm_rc = 0;
|
||||
}
|
||||
} else if (act == 2) {
|
||||
logmsg("pm: RETURN TO HIBYOS");
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would reboot to hiby"); return 1; }
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would reboot to hiby"); goto out; }
|
||||
if (meow_power_action(POWER_BACK_HIBY) != MEOW_OK) {
|
||||
logmsg("pm: power service unavailable, abort (menu closed, no action)");
|
||||
return 0;
|
||||
pm_rc = 0;
|
||||
}
|
||||
} else if (act == 3) {
|
||||
logmsg("pm: ENTER UPGRADE");
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would enter upgrade"); return 1; }
|
||||
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would enter upgrade"); goto out; }
|
||||
if (meow_power_action(POWER_UPGRADE) != MEOW_OK) {
|
||||
logmsg("pm: power service unavailable, abort (menu closed, no action)");
|
||||
return 0;
|
||||
pm_rc = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
out:
|
||||
if (tfd >= 0) close(tfd);
|
||||
meow_ui_activity_pop(); /* M7.0b:退出电源菜单,回主 activity(控件 owner 仍钉哨兵,复用) */
|
||||
/* M40 F2:恢复进入前的背景帧(否则 app_launcher 会把菜单帧当 App 帧上屏 = P2)。
|
||||
* 放在动作执行之后:锁屏动作已 meow_panel_off(),此时恢复只写 fb0(面板黑),
|
||||
* 下次唤醒 / App 整帧重画时得到的是正确底层帧而不是 PIN/菜单帧。 */
|
||||
pm_restore_bg(pm_bg_snap, pm_bg_len);
|
||||
if (pm_bg_snap) free(pm_bg_snap);
|
||||
return pm_rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
* S4 锁屏页自睡(294 遗留) → overlay_lock_idle_off_sec():阈值 = min(系统 screen_off_timeout, 30s)
|
||||
* (0/超30→30,尊重更短);overlay_lock_should_sleep()/overlay_lock_wake_now()
|
||||
* 判定超时灭屏(锁态保持)与唤醒回锁屏。
|
||||
* M40 F3/F4 → overlay_activity_drain_active():叠加/菜单返回后的排空窗内忽略
|
||||
* activity 标记(防冻结期输入重放成「亮屏+锁屏」);
|
||||
* overlay_lock_power_off_now():锁屏电源必须按下边沿 + 进场≥300ms。
|
||||
*
|
||||
* 编译运行(在 patch_v2/meow_launcherd 下,无其它依赖):
|
||||
* gcc -Wall -Wextra -o test_overlay_gate test_overlay_gate.c && ./test_overlay_gate
|
||||
@@ -80,6 +83,19 @@ int main(void)
|
||||
CHECK(overlay_lock_wake_now(0, 1) == 1, "S4 touch -> wake to lock");
|
||||
CHECK(overlay_lock_wake_now(0, 0) == 0, "S4 no wake input -> stay asleep");
|
||||
|
||||
/* ---- M40 F4/P4:锁屏页电源「按下边沿 + 进场 ≥300ms」才熄屏 ----
|
||||
* 电平判定会让「打开菜单的那次长按」在 PIN 页出现时立刻把页面熄灭(用户症状)。 */
|
||||
CHECK(OVERLAY_LOCK_POWER_GRACE_MS == 300, "F4 lock power grace = 300ms");
|
||||
CHECK(overlay_lock_power_off_now(1, 299) == 0, "F4 press edge inside 300ms grace -> no off");
|
||||
CHECK(overlay_lock_power_off_now(1, 300) == 1, "F4 press edge at 300ms -> off");
|
||||
CHECK(overlay_lock_power_off_now(0, 5000) == 0, "F4 held level (no edge) -> never re-fires");
|
||||
CHECK(overlay_lock_power_off_now(1, 5000) == 1, "F4 new press edge after grace -> off");
|
||||
|
||||
/* ---- M40 F3/P3:叠加层/菜单返回后的 activity 标记排空窗 ---- */
|
||||
CHECK(overlay_activity_drain_active(0, 0, 999999) == 0, "F3 no overlay return mark -> activity honored");
|
||||
CHECK(overlay_activity_drain_active(1, 1000, 1299) == 1, "F3 marker inside 300ms drain -> ignored");
|
||||
CHECK(overlay_activity_drain_active(1, 1000, 1300) == 0, "F3 marker after drain -> honored");
|
||||
|
||||
/* ---- S3 App 死亡触发主屏重绘:崩溃必须走统一退出路径 ---- */
|
||||
CHECK(lock_overlay_app_died_exit(1) == 1, "S3 app died -> unified exit path (redraw home)");
|
||||
CHECK(lock_overlay_app_died_exit(0) == 0, "S3 app alive -> normal restore");
|
||||
|
||||
Reference in new issue
Block a user