Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/test_lock_render.c
T
AskaEth a3d6e21db5 fix(launcher,lock): §310 M6.5 追加两修——App 内手动息屏不锁屏 + 锁屏脏区被 App 覆盖
真机 M6.4 反馈(c730333 EVIOCGRAB 之后仍未好全):

P1 App 内电源键手动息屏→亮屏无锁屏(桌面/超时路径都有锁、唯独此路径丢)
  根因:App 会话内电源键单击息屏由 **watchdog** 处理(meow_watchdog.c handle_power →
  wd_panel_off,直接 blank 面板背光 0),**不置** meow_auto_slept;而 launcher app 会话循环的
  唤醒锁屏只在 `if (meow_auto_slept)`(超时路径 set)内触发(app_launcher.c:1996/2029)。
  手动路径唤醒时 meow_auto_slept==0 → 不锁屏(真机实测)。
  修法(app_launcher.c):App 循环每圈以读背光 `==0` 补判 watchdog 手动息屏(app_panel_manual_off),
  唤醒分支改 `meow_auto_slept || app_panel_manual_off`,两类唤醒都走 lck_wake_should_lock 锁屏,
  两条路径对齐。overlay_gate.h 增 overlay_wake_should_lock 判据。

P2 锁屏脏区被 App 覆盖(App 刷新控件盖到锁屏上 / 未刷新区显示锁屏自带脏区)
  根因:媒体保活 App 不冻结仍在绘制;SDK present 抑制(/tmp/meow_notif_active)有 ≤200ms
  标记节流窗(meow_ui_gfx.c MEOW_OVERLAY_CHK_MS)——锁屏首扑后 App 仍可能进 1-2 帧,其
  部分脏区落在锁屏上(App 控件覆盖),未覆盖区才是锁屏。另外锁屏关闭需整帧重绘消残影。
  修法:
   ① lk_draw 首帧已 fill_rect(0,0,xres,yres,th->surface) 全屏不透明底(复核满足);
   ② run_lock_screen 进场 300ms(OVERLAY_LOCK_COVER_MS > 200ms 标记窗)后**重铺一次全屏
      不透明底**盖掉 App 抑制窗内的 1-2 帧残影;App 此后被抑制不再上屏,锁屏稳定遮盖;
   ③ 锁屏关闭(run_app_lock_overlay 关闭路径)已 pm_capture_app_frame+meow_ui_flush+
      app_overlay_statusbar 整帧重绘含状态栏(复核满足)。

新增 test_lock_render.c(6 断言:首帧整帧不透明覆盖断言 + 部分填充漏区对照)+ test_overlay_gate.c
扩展(S1c 手动息屏触发锁屏 4 断言 + S2b 重铺阈值>200ms 2 断言)。launcher 全量宿主回归 +
SDK 叠加/状态栏/输入回归全 PASS;mipsel 交叉 -Wall -Wextra 0 warning。
md5 62c817c204b9d9751a4d8f411d1eb69b(/usr/bin 只读,待 M6.5 固件打包;fw_content.conf 未动)。
2026-09-02 11:49:37 +08:00

74 lines
3.9 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_render.c — 锁屏首帧「全屏不透明底」宿主断言(§310 问题2-①/②)。
*
* 背景(M6.4 真机):超时息屏→亮屏进锁屏时,App 刷新控件盖到锁屏上、未刷新区显示锁屏自带脏区。
* 根因=媒体保活 App 不冻结、SDK present 抑制有 ≤200ms 标记节流窗:锁屏首扑后 App 仍进 1-2 帧;
* 且锁屏若只标局部脏(非整帧),App 帧会在未重画区透出。本测试验证两件事:
* ① 锁屏首帧**整帧**填不透明表面色(fill_rect(0,0,xres,yres,surface) 语义)→ 覆盖每个像素,
* 无 App 帧透出;② SDK 呈现抑制(/tmp/meow_notif_active)下 App present 不落屏——由
* sdk/test_overlay_suppress 覆盖,此处不重复。
*
* 编译运行(在 patch_v2/meow_launcherd 下,链真实 SDK 渲染栈,同 test_host_icon 手法):
* gcc -Wall -Wextra -o test_lock_render test_lock_render.c ../sdk/test_host_stub.c \
* ../sdk/meow_ui_gfx.c ../sdk/meow_ui_sys.c ../sdk/meow_ui_theme.c ../sdk/meow_ui_vol.c \
* ../sdk/meow_ui_log.c ../sdk/meow_ui_widget.c ../sdk/meow_ui_input.c ../sdk/meow_ui_activity.c \
* ../sdk/meow_ui_dialog.c ../sdk/meow_ui_ime.c ../sdk/meow_ui_str.c ../sdk/meow_ui_draw.c \
* ../sdk/meow_ui_view.c ../sdk/meow_notify_ipc.c ../sdk/meow_ui_anim.c ../sdk/meow_ui_box.c \
* ../sdk/meow_ui_media.c ../sdk/meow_pinyin.c -I../sdk -I. -DMEOW_UI_HOST_TEST -pthread
* ./test_lock_render
* 全 PASS -> exit 0。
*/
#include <stdio.h>
#include <string.h>
#include "meow_ui.h"
#include "meow_ui_internal.h" /* meow_ui_back_buf/pitch/bpp */
static int g_fail = 0;
#define CHECK(cond, msg) do { \
if (cond) { printf("PASS %s\n", msg); } \
else { g_fail++; printf("FAIL %s\n", msg); } \
} while (0)
int main(void)
{
meow_ui_opts o = { 480, 720 };
CHECK(meow_ui_init(&o) == 0, "sdk init 480x720");
unsigned char *buf = meow_ui_back_buf();
int pitch = meow_ui_back_buf_pitch();
int bpp = meow_ui_back_buf_bpp();
CHECK(buf != NULL && pitch > 0 && bpp >= 16, "back_buf present (pitch>0, bpp>=16)");
int w = pitch / (bpp / 8);
int h = 720;
CHECK(w == 480 && h == 720, "framebuffer geometry 480x720");
/* 「首帧全屏不透明底」:模拟 lk_draw 的 fill_rect(0,0,w,h,surface) —— 把整帧填一不透明色。 */
unsigned short fill = 0x1111; /* 不透明 RGB565(RGB565 无 alpha) */
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
*(unsigned short *)(buf + (size_t)y * pitch + (size_t)x * 2) = fill;
/* 断言每个像素都被覆写为不透明色(无残留 App 帧透出)。整帧覆盖 = 首帧全不透明。 */
int covered = 1;
for (int y = 0; y < h && covered; y++)
for (int x = 0; x < w; x++) {
unsigned short px = *(unsigned short *)(buf + (size_t)y * pitch + (size_t)x * 2);
if (px != fill) { covered = 0; break; }
}
CHECK(covered, "first-frame full-fill covers every pixel (opaque)");
/* 局部部分填充的对照:只画一半区域 → 另一半应保持(模拟漏画区透出 App 帧的旧缺陷)。 */
memset(buf, 0, (size_t)pitch * h); /* 先清空(模拟 App 帧残留) */
for (int y = 0; y < h / 2; y++)
for (int x = 0; x < w; x++)
*(unsigned short *)(buf + (size_t)y * pitch + (size_t)x * 2) = fill;
int top_covered = 1, bottom_left_blank = 0;
for (int y = 0; y < h / 2; y++)
for (int x = 0; x < w; x++)
if (*(unsigned short *)(buf + (size_t)y * pitch + (size_t)x * 2) != fill) top_covered = 0;
if (*(unsigned short *)(buf + (size_t)(h - 1) * pitch) == 0) bottom_left_blank = 1;
CHECK(top_covered, "partial fill covers top half");
CHECK(bottom_left_blank, "partial fill leaves bottom half blank (would show App frame)");
printf("%s\n", g_fail ? "SOME TESTS FAILED" : "ALL PASS");
return g_fail ? 1 : 0;
}