Files
MeowOS-SDK/sdk/test_notify_post.c
T
MeowOS f44e3bc6d0 Add 'sdk/' from commit '2e7561d74f75de05dd7fb362f203f600afb451d7'
git-subtree-dir: sdk
git-subtree-mainline: 17a972d46f
git-subtree-split: 2e7561d74f
2026-09-01 21:08:40 +08:00

169 lines
7.4 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_notify_post.c — 宿主交叉验证:SDK send 的 IPC 帧 → launcher 真·中央存储。
*
* 把 SDK 的 meow_notify_ipc.c(映射+传输)与 launcher 的 meow_notif.c(真·中央存储,
* meow_notif_post/dismiss)接到一起,stub 掉 meow_settings 后端;服务端复刻
* meow_launcherd.c:6427-6440 的 m_notify_t→meow_notif_t 映射 + MSG_NOTIFY_ACK 应答。
*
* 验证:SDK meow_notify_ipc_send() 产出的帧被 meow_notif_post() 真实落库并回分配 nid>0;
* 随后 meow_notify_ipc_dismiss() 经 meow_notif_dismiss() 撤下(count 归 0)。
*
* 编译(宿主 gcc):
* gcc -o test_notify_post test_notify_post.c meow_notify_ipc.c \
* ../meow_launcherd/meow_notif.c -I. -I../meow_launcherd -lpthread
*/
#include "meow_notify_ipc.h"
#include "meow_ui.h"
#include "meow_ipc.h"
#include "meow_notif.h" /* launcher 真·中央存储 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pthread.h>
/* ---- stub:settings 后端(键缺省 → meow_notif.c 用默认配额) ---- */
int meow_settings_get_int(const char *key, int *out) { (void)key; (void)out; return MEOW_ERR_NOENT; }
/* ---- 复刻 launcher 的 m_notify_t → meow_notif_t 映射(meow_launcherd.c:6427-6440) ----
* 注:与 launcher 同款 snprintf(dest 较 src 小会有 format-truncation 提示),launcher 自身
* 以其编译 flags 构建无警告;此处仅为宿主测试,用 pragma 压掉以免 -Werror 干扰。 */
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
static void launcher_map(const m_notify_t *mn, meow_notif_t *n)
{
memset(n, 0, sizeof *n);
n->id = mn->replaces_id; /* 0=>新建;>0=>替换(不存在则新建) */
snprintf(n->app_id, sizeof n->app_id, "%s", mn->app_id);
snprintf(n->category, sizeof n->category, "%s", mn->category);
snprintf(n->summary, sizeof n->summary, "%s", mn->summary);
snprintf(n->body, sizeof n->body, "%s", mn->body);
snprintf(n->app_icon, sizeof n->app_icon, "%s", mn->app_icon);
snprintf(n->target_activity, sizeof n->target_activity, "%s", mn->target_activity);
n->expire_timeout = mn->expire_timeout;
n->progress = mn->progress;
n->urgency = mn->urgency; /* 0-3;旧调用=0 → LOW(静默) */
n->ongoing = mn->ongoing;
n->media = mn->media;
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
static int g_listen_fd = -1;
static int g_stop = 0;
static uint32_t g_posted_nid = 0;
static meow_notif_t g_stored; /* 回读 launcher 存储的最近一条通知(store_cb) */
static int g_store_called = 0;
static int store_cb(const meow_notif_t *n, void *ctx)
{
(void)ctx;
if (n) { g_stored = *n; g_store_called = 1; }
return 1; /* 只取第一条 */
}
static void reply_ack(int c, uint16_t type, uint32_t req_id, uint32_t status)
{
m_ack_t a; memset(&a, 0, sizeof a); a.code = MEOW_OK; a.status = status;
uint8_t rhdr[MEOW_IPC_HDR_LEN];
uint32_t mag = MEOW_IPC_MAGIC; uint16_t ver = MEOW_IPC_VERSION, t = type; uint32_t rl = sizeof a;
memcpy(rhdr+0,&mag,4); memcpy(rhdr+4,&ver,2); memcpy(rhdr+6,&t,2); memcpy(rhdr+8,&req_id,4); memcpy(rhdr+12,&rl,4);
size_t o = 0; while (o < sizeof rhdr) { ssize_t w = write(c, rhdr+o, sizeof rhdr-o); if (w<=0) break; o += (size_t)w; }
o = 0; while (o < rl) { ssize_t w = write(c, (uint8_t*)&a+o, rl-o); if (w<=0) break; o += (size_t)w; }
}
static void *server(void *arg)
{
(void)arg;
meow_notif_init();
while (!g_stop) {
int c = accept(g_listen_fd, NULL, NULL);
if (c < 0) { if (errno == EAGAIN && g_stop) break; if (errno == EBADF) break; usleep(1000); continue; }
uint8_t hdr[MEOW_IPC_HDR_LEN]; size_t o = 0;
while (o < sizeof hdr) { ssize_t r = read(c, hdr+o, sizeof hdr-o); if (r<=0) break; o += (size_t)r; }
if (o < sizeof hdr) { close(c); continue; }
uint32_t type, len, req_id; memcpy(&type, hdr+6, 2); memcpy(&req_id, hdr+8, 4); memcpy(&len, hdr+12, 4);
if (len > MEOW_IPC_MAX) { close(c); continue; }
uint8_t pay[MEOW_IPC_MAX]; o = 0;
while (o < len) { ssize_t r = read(c, pay+o, len-o); if (r<=0) break; o += (size_t)r; }
if (type == MSG_NOTIFY && len >= sizeof(m_notify_t)) {
m_notify_t mn; memcpy(&mn, pay, sizeof mn);
meow_notif_t n; launcher_map(&mn, &n);
uint32_t nid = 0;
int rc = meow_notif_post(&n, &nid);
if (rc == NOTIF_OK) g_posted_nid = nid;
reply_ack(c, MSG_NOTIFY_ACK, req_id, (rc == NOTIF_OK) ? nid : (uint32_t)rc);
fprintf(stderr, "[post-srv] post rc=%d nid=%u cat=%s\n", rc, nid, mn.category);
} else if (type == MSG_NOTIFY_DISMISS && len >= 4) {
uint32_t id; memcpy(&id, pay, 4);
int rc = meow_notif_dismiss(id);
reply_ack(c, MSG_ACK, req_id, 0);
fprintf(stderr, "[post-srv] dismiss id=%u rc=%d\n", id, rc);
}
close(c);
}
return NULL;
}
static int make_listen(char *path, size_t n)
{
snprintf(path, n, "/tmp/meow_notify_post_%d.sock", (int)getpid());
unlink(path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un a; memset(&a, 0, sizeof a); a.sun_family = AF_UNIX;
strncpy(a.sun_path, path, sizeof a.sun_path - 1);
if (bind(fd, (struct sockaddr*)&a, sizeof a) < 0 || listen(fd, 4) < 0) { close(fd); return -1; }
fcntl(fd, F_SETFL, O_NONBLOCK);
g_listen_fd = fd;
return 0;
}
static int failures = 0;
static void check(const char *name, int cond) { printf("%s %s\n", cond ? "PASS" : "FAIL", name); if (!cond) failures++; }
int main(void)
{
setenv("MEOW_LOG_APP", "intgapp", 1);
char sock[108];
if (make_listen(sock, sizeof sock) != 0) { fprintf(stderr, "cannot listen\n"); return 2; }
setenv("MEOW_IPC_SOCK", sock, 1);
pthread_t th; pthread_create(&th, NULL, server, NULL);
/* SDK send → launcher 真存储。media + ONGOING 走全部映射分支。 */
meow_notify nt; memset(&nt, 0, sizeof nt);
nt.cat = MEOW_NOTIFY_CAT_MEDIA; nt.urgency = MEOW_NOTIFY_URG_HIGH;
nt.title = "正在播放"; nt.timeout_ms = -1; nt.progress = 40;
nt.icon = "os.meow.hello/icon.png";
uint32_t nid = meow_notify_ipc_send(&nt, 0);
check("send 经 launcher 真存储回 nid>0", nid != 0);
check("send 拿到 launcher 分配的 nid(与 post 一致)", g_posted_nid == nid);
check("launcher 存储 count(media app)=1", meow_notif_count("intgapp") == 1);
/* 回读 launcher 存储,验证 urgency/icon/progress 全链路落库 */
g_store_called = 0; memset(&g_stored, 0, sizeof g_stored);
meow_notif_list(NULL, store_cb, NULL);
check("post 存储 urgency=HIGH(2)", g_store_called && g_stored.urgency == MEOW_NOTIFY_URG_HIGH);
check("post 存储 icon→app_icon", g_stored.app_icon[0] && !strcmp(g_stored.app_icon, "os.meow.hello/icon.png"));
check("post 存储 progress=40", g_stored.progress == 40);
/* SDK dismiss → launcher 撤下 */
meow_notify_ipc_dismiss(nid);
check("dismiss 后 launcher 存储 count=0", meow_notif_count("intgapp") == 0);
g_stop = 1; close(g_listen_fd);
pthread_join(th, NULL);
meow_notif_shutdown();
printf("\n%s (%d failure%s)\n", failures ? "RESULT: FAIL" : "RESULT: PASS", failures, failures == 1 ? "" : "s");
return failures ? 1 : 0;
}