feat: M6.10–M6.19 批量收编 + M6.19 推卡验收

- M7 launcher 重写 5 期(虚拟化宫格/meow_theme 单一权威/横幅动画/自定义 PIN 键盘)
- OOM 通用化(cachegov 上收 SDK)、自动切歌根治、meowpanel jv_free 泄漏修复、Hello 滚动卡顿修复
- ncm 歌词 UI / 媒体通知封面 / 封面分辨率 640
- 5 bug 修复:ncm 后台化 UI 叠层+点击穿透、再进 ncm 桌面叠层、播放页新旧 UI 叠层抢刷脏区(meow_ui_gfx 恢复边沿整帧重画)、PIN 亮屏亮度跳(keys.c meow_panel_on 按 settings_brightness_clamped 恢复)、通知中心封面显歌单封面(cover.c save_cover_raw 加 is_song + 命中块守卫)
- 四 App 统一重链新 meow_ui.a 51caee4a;M6.19=0.8.19 固件 2d2331f2 推卡自刷验收全绿
This commit is contained in:
AskaEth committed 2026-09-03 12:16:01 +08:00
1 parent c2ee7626a4
commit 3d70a3dd2c
176 files changed
+15507 -597

No files matched your search

+223
View File
@@ -0,0 +1,223 @@
/* test_lock_widgets.c — M7.1b 锁屏 UI 控件化宿主验证。
*
* 复现 lock_screen_ui.c 所建锁屏键盘控件集(12 键 meow_widget_custom + meow_widget 命中 +
* 按压态 MEOW_WS_PRESSED→primary 26% α),验证:
* P1 键盘渲染:12 键各画成 surfaceContainer 圆角钮(非背景像素);
* P2 键盘命中:meow_widget_hit 在每键中心命中;键值映射(digit/清空/退格)正确;间隙不命中;
* P3 主题四态(MD3/MIUIx × 明暗)键盘渲染非背景;
* P4 按压态:meow_widget_set_state(MEOW_WS_PRESSED) → 该键像素变化(primary 26% α 叠加);
* P5 键值 round-trip:lk_key_value_at 在键中心/间隙分别返回正确键值与 LK_DOWN_NONE。
*
* 布局几何/键序与 lock_screen_ui.c 镜像(LK_X0..LK_COLS/LK_ROWS/lk_keys),控件创建方式与
* lk_widgets_build 同(owner=哨兵 0x51,meow_widget_custom_create,render 读 meow_widget_rect 几何)。
*
* 编译(在 patch_v2/meow_launcherd 下):
* gcc -Wall -Wextra -o test_lock_widgets test_lock_widgets.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_pinyin.c \
* ../sdk/meow_ui_draw.c ../sdk/meow_ui_view.c ../sdk/meow_ui_box.c ../sdk/meow_ui_anim.c \
* ../sdk/meow_ui_scroll.c ../sdk/meow_ui_img.c ../sdk/meow_ui_media.c \
* ../sdk/meow_notify_ipc.c ../sdk/stb_image.c -I../sdk -I. -DMEOW_UI_HOST_TEST -pthread -lm
* 运行:./test_lock_widgets
*/
#include "meow_ui.h"
#include "meow_ui_internal.h" /* meow_ui_back_buf / meow_widget_rect / meow_gfx_fill_round[_alpha] */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int g_fail = 0;
#define CHECK(cond, ...) do { \
if (cond) { printf(" PASS: " __VA_ARGS__); printf("\n"); } \
else { printf(" FAIL: " __VA_ARGS__); printf("\n"); g_fail++; } } while (0)
/* ---- 与 lock_screen_ui.c 同源几何(镜像) ---- */
#define LK_X0 32
#define LK_COLW 130
#define LK_COLG 8
#define LK_Y0 320
#define LK_ROW_H 82
#define LK_ROWG 10
#define LK_ROWS 4
#define LK_COLS 3
#define LK_ACT_CLR (-2)
#define LK_ACT_BS (-1)
#define LK_SENTINEL 0x51 /* 锁屏控件 owner 哨兵(镜像 lock_screen_ui.c) */
#define LK_DOWN_NONE (-10)
static const int lk_keys[LK_ROWS][LK_COLS] = {
{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { LK_ACT_CLR, 0, LK_ACT_BS },
};
#define XRES 480
#define YRES 720
static meow_widget *lk_w[LK_ROWS][LK_COLS];
static void lk_rect(int row, int col, int rc[4])
{
rc[0] = LK_X0 + col * (LK_COLW + LK_COLG);
rc[1] = LK_Y0 + row * (LK_ROW_H + LK_ROWG);
rc[2] = LK_COLW;
rc[3] = LK_ROW_H;
}
static void lk_center(int row, int col, int *cx, int *cy)
{
int rc[4]; lk_rect(row, col, rc);
*cx = rc[0] + rc[2] / 2;
*cy = rc[1] + rc[3] / 2;
}
/* ---- 键渲染(镜像 lock_screen_ui.c lk_key_render 的视觉语义)---- */
static void key_render(meow_widget *w, const meow_theme *th, void *ctx)
{
(void)ctx;
int rc[4]; meow_widget_rect(w, rc);
int rad = (th->radius > 0) ? th->radius : 10;
meow_gfx_fill_round(rc[0], rc[1], rc[2], rc[3], rad, th->surfaceContainer);
if (meow_widget_state(w) & MEOW_WS_PRESSED)
meow_gfx_fill_round_alpha(rc[0], rc[1], rc[2], rc[3], rad, th->primary, 66);
meow_ui_text_center(rc[0] + rc[2] / 2,
rc[1] + rc[3] / 2 - meow_ui_text_height(22) / 2,
"1", 22, th->onSurface);
}
static void mk_widgets(void)
{
meow_ui_activity_push(LK_SENTINEL);
for (int r = 0; r < LK_ROWS; r++)
for (int c = 0; c < LK_COLS; c++) {
int rc[4]; lk_rect(r, c, rc);
lk_w[r][c] = meow_widget_custom_create(rc[0], rc[1], rc[2], rc[3],
key_render, NULL,
(void *)(intptr_t)lk_keys[r][c]);
}
meow_ui_activity_pop();
}
/* 坐标 -> 键值(镜像 lock_screen_ui.c lk_key_value_at)。 */
static int key_value_at(int x, int y)
{
for (int r = 0; r < LK_ROWS; r++)
for (int c = 0; c < LK_COLS; c++)
if (lk_w[r][c] && meow_widget_hit(lk_w[r][c], x, y))
return lk_keys[r][c];
return LK_DOWN_NONE;
}
static void draw_all(void)
{
const meow_theme *th = meow_theme_get();
meow_ui_fill_rect(0, 0, XRES, YRES, th->surface);
for (int r = 0; r < LK_ROWS; r++)
for (int c = 0; c < LK_COLS; c++)
if (lk_w[r][c]) meow_widget_draw(lk_w[r][c]);
}
static unsigned short px565(int x, int y)
{
unsigned char *bb = meow_ui_back_buf();
int pitch = meow_ui_back_buf_pitch(), bpp = meow_ui_back_buf_bpp();
if (!bb || x < 0 || y < 0 || x >= XRES || y >= YRES) return 0;
if (bpp == 16) return *(unsigned short *)(bb + (size_t)y * pitch + (size_t)x * 2);
return (unsigned short)(*(unsigned int *)(bb + (size_t)y * pitch + (size_t)x * 4) >> 16);
}
static unsigned short bg565(uint32_t bg)
{
return (unsigned short)(((bg >> 8) & 0xF800) | ((bg >> 5) & 0x07E0) | ((bg >> 3) & 0x001F));
}
int main(void)
{
setbuf(stdout, NULL);
setenv("MEOW_UI_DUMP", "/tmp/lock_widgets.ppm", 1);
meow_ui_opts o = { XRES, YRES };
if (meow_ui_init(&o) != 0) { printf("init failed\n"); return 1; }
mk_widgets();
meow_ui_activity_push(LK_SENTINEL); /* 命中闸门打开(owner==active) */
/* ============ P1 键盘渲染(12 键各画成非背景钮) ============ */
printf("P1 keypad render (12 keys non-bg)\n");
const meow_theme *th = meow_theme_get();
draw_all();
int all_nonbg = 1;
for (int r = 0; r < LK_ROWS && all_nonbg; r++)
for (int c = 0; c < LK_COLS && all_nonbg; c++) {
int cx, cy; lk_center(r, c, &cx, &cy);
if (px565(cx, cy) == bg565(th->surface)) all_nonbg = 0;
}
CHECK(all_nonbg, "each of 12 keys draws non-surface at center");
/* ============ P2 命中(meow_widget_hit + 键值映射) ============ */
printf("P2 keypad hit via meow_widget_hit\n");
int hit_ok = 1, val_ok = 1;
for (int r = 0; r < LK_ROWS; r++)
for (int c = 0; c < LK_COLS; c++) {
int cx, cy; lk_center(r, c, &cx, &cy);
if (!meow_widget_hit(lk_w[r][c], cx, cy)) hit_ok = 0;
if (key_value_at(cx, cy) != lk_keys[r][c]) val_ok = 0;
}
CHECK(hit_ok, "meow_widget_hit hits every key center");
CHECK(val_ok, "key_value_at maps every key center to its digit/clear/backspace value");
/* 间隙(两列之间)不命中 */
int gap_x = LK_X0 + LK_COLW + LK_COLG / 2; /* 列0 与列1 之间的间隙中心 */
int gap_y = LK_Y0 + LK_ROW_H / 2;
CHECK(meow_widget_hit(lk_w[0][0], gap_x, gap_y) == 0, "gap between columns not hit");
CHECK(key_value_at(gap_x, gap_y) == LK_DOWN_NONE, "gap not mapped to any key");
/* ============ P3 主题四态(MD3/MIUIx × 明暗)键盘渲染非背景 ============ */
printf("P3 theme 4-state keypad render\n");
const int styles[2] = { MEOW_STYLE_MD3, MEOW_STYLE_MIUIX };
const int modes[2] = { MEOW_THEME_LIGHT, MEOW_THEME_DARK };
char nm[96];
for (int si = 0; si < 2; si++) {
for (int mi = 0; mi < 2; mi++) {
meow_ui_set_style(styles[si]);
meow_theme_set_mode((meow_theme_mode)modes[mi]);
th = meow_theme_get();
draw_all();
/* 用一个键区的多像素带判定非背景(文字+底) */
int rc[4]; lk_rect(1, 0, rc);
int nonbg = 0;
for (int dy = 0; dy < rc[3] && !nonbg; dy++)
for (int dx = 0; dx < rc[2] && !nonbg; dx++)
if (px565(rc[0] + dx, rc[1] + dy) != bg565(th->surface)) nonbg = 1;
snprintf(nm, sizeof nm, "style=%s mode=%s keypad renders non-surface",
styles[si] ? "MIUIx" : "MD3", modes[mi] ? "dark" : "light");
CHECK(nonbg, "%s", nm);
}
}
meow_ui_set_style(MEOW_STYLE_MD3);
meow_theme_set_mode(MEOW_THEME_DARK);
/* ============ P4 按压态(MEOW_WS_PRESSED → primary 26% α 像素变化) ============ */
printf("P4 pressed state -> primary 26%% alpha overlay\n");
th = meow_theme_get();
draw_all();
int cx, cy; lk_center(2, 1, &cx, &cy); /* 键 (2,1) = 数字 8 */
unsigned short p0 = px565(cx, cy);
meow_widget_set_state(lk_w[2][1], MEOW_WS_PRESSED, 1);
draw_all();
unsigned short p1 = px565(cx, cy);
meow_widget_set_state(lk_w[2][1], MEOW_WS_PRESSED, 0);
CHECK(p1 != p0, "pressed key center pixel changes (primary 26%% overlay)");
draw_all();
unsigned short p2 = px565(cx, cy);
CHECK(p2 == p0, "release restores original pixel");
/* ============ P5 键值 round-trip(清空/退格/间隙) ============ */
printf("P5 key-value round-trip (clear/backspace/gap)\n");
int ccx, ccy, bcx, bcy, zcx, zcy;
lk_center(3, 0, &ccx, &ccy); /* 清空 */
lk_center(3, 1, &zcx, &zcy); /* 0 */
lk_center(3, 2, &bcx, &bcy); /* 退格 */
CHECK(key_value_at(ccx, ccy) == LK_ACT_CLR, "bottom-left center == CLEAR (-2)");
CHECK(key_value_at(zcx, zcy) == 0, "bottom-mid center == 0");
CHECK(key_value_at(bcx, bcy) == LK_ACT_BS, "bottom-right center == BACKSPACE (-1)");
meow_ui_activity_pop();
meow_ui_shutdown();
printf(g_fail ? "\nRESULT: %d FAIL(S)\n" : "\nRESULT: ALL PASS\n", g_fail);
return g_fail;
}