通知模型补全(agent-107: SDK icon+update_progress / IPC urgency+MSG_NOTIFY_PROGRESS / 存储 urgency+icon回退+progress / CSV加3列) + 全屏收合视觉+滑条(agent-108)

This commit is contained in:
MeowOS Dev committed 2026-08-30 13:02:17 +08:00
1 parent b3e57d4b55
commit e8fa373a2f
18 files changed
+410 -56

No files matched your search

+42 -3
View File
@@ -6,13 +6,15 @@
* meow_ipc.h(同源一份、杜绝两端漂移):
* - 帧头 16B:magic=0x4D4F5701 / version=1 / type / req_id / len(全小端 LE,mipsel 原生);
* - MSG_NOTIFY(0x0020) ↑ 负载 = m_notify_t;MSG_NOTIFY_ACK(0x0021) ↓ 负载 = m_ack_t(status=nid);
* - MSG_NOTIFY_DISMISS(0x0022) ↑ 负载 = uint32 nid。
* - MSG_NOTIFY_DISMISS(0x0022) ↑ 负载 = uint32 nid;
* - MSG_NOTIFY_PROGRESS(0x0024) ↑ 负载 = m_notify_progress_t(nid+progress,实时进度仅内存)。
*
* 设计要点:
* - 只做「一次性 connect + send + read ACK」,不维护连接/订阅循环(与 meow_ipc.c 客户端同型);
* - 映射层(SDK 枚举 ↔ IPC 字段)集中在本文件:分类枚举 CAT_* ↔ 字符串
* "general"/"message"/"email"/"event"/"progress"/"media";timeout_ms → expire_timeout:
* >0 该毫秒、0=不自动过期、-1(ONGOING)=0xFFFFFFFF(并置 ongoing=1);媒体类型置 media=1;
* SDK `icon` → app_icon(空则 launcher 按 app_id 回退 app 图标);urgency 0-3 直通(越界钳位 NORMAL);
* - 优雅降级:无 socket(connect 失败)/写失败/ACK 超时(SO_RCVTIMEO)/非 ACK 应答 →
* 返回 0(调用方 meow_ui_notify.c 保留本地 id 兜底),绝不崩;
* - 线程安全:app_id 经 pthread_once 缓存;socket 路径每次调用读 env MEOW_IPC_SOCK 覆盖
@@ -82,8 +84,8 @@ static uint32_t timeout_to_expire(int timeout_ms)
return (uint32_t)timeout_ms; /* 0(NEVER)/ >0(毫秒) */
}
/* 构建 IPC 负载 m_notify_t(app_icon/actions/hints v1 留空,M2b D-Bus 桥再填)。
* 仅在持有调用者互斥之外、发送前调用(纯 CPU 拷贝,不阻塞)。 */
/* 构建 IPC 负载 m_notify_t(app_icon<->SDK icon;urgency 0-3;actions/hints v1 留空,
* M2b D-Bus 桥再填)。仅在持有调用者互斥之外、发送前调用(纯 CPU 拷贝,不阻塞)。 */
static void build_m_notify(const meow_notify *n, uint32_t replaces_id, m_notify_t *mn)
{
memset(mn, 0, sizeof *mn);
@@ -91,6 +93,7 @@ static void build_m_notify(const meow_notify *n, uint32_t replaces_id, m_notify_
snprintf(mn->category, sizeof mn->category, "%s", cat_to_str(n->cat));
snprintf(mn->summary, sizeof mn->summary, "%s", n->title ? n->title : "");
snprintf(mn->body, sizeof mn->body, "%s", n->body ? n->body : "");
snprintf(mn->app_icon, sizeof mn->app_icon, "%s", n->icon ? n->icon : "");
snprintf(mn->target_activity, sizeof mn->target_activity, "%s",
n->target_activity ? n->target_activity : "");
mn->replaces_id = replaces_id; /* 0=新建;>0=更新(不存在则落为新建,见 launcher) */
@@ -98,6 +101,9 @@ static void build_m_notify(const meow_notify *n, uint32_t replaces_id, m_notify_
mn->progress = (n->progress < -1) ? -1 : (n->progress > 100 ? 100 : n->progress);
mn->media = (n->cat == MEOW_NOTIFY_CAT_MEDIA) ? 1 : 0;
mn->ongoing = (n->timeout_ms == MEOW_NOTIFY_TIMEOUT_ONGOING) ? 1 : 0;
/* urgency:越界钳位到 NORMAL(缺省);0-3 直通(launcher 侧再回退缺省) */
mn->urgency = ((int)n->urgency >= 0 && (int)n->urgency < (int)MEOW_NOTIFY_URG_COUNT)
? (uint8_t)n->urgency : (uint8_t)MEOW_NOTIFY_URG_NORMAL;
}
/* ============================================================ */
@@ -241,3 +247,36 @@ void meow_notify_ipc_dismiss(uint32_t nid)
}
close(fd);
}
void meow_notify_ipc_update_progress(uint32_t nid, int progress)
{
int fd;
if (nid == 0) return;
m_notify_progress_t p;
memset(&p, 0, sizeof p);
p.nid = nid;
p.progress = (progress < -1) ? -1 : (progress > 100 ? 100 : progress);
fd = conn_path(ipc_sock_path());
if (fd < 0) return; /* 无 socket:静默 */
set_ack_timeout(fd);
if (!send_frame(fd, MSG_NOTIFY_PROGRESS, 0x4E4F5450u /* "NOTP" */, &p, (uint32_t)sizeof p)) {
close(fd); /* 写失败:静默 */
return;
}
/* 读回应答(launcher 对 PROGRESS 回 MSG_ACK,best-effort;读回确保 launcher 已处理完) */
uint8_t rhdr[MEOW_IPC_HDR_LEN];
if (read_all(fd, rhdr, sizeof rhdr)) {
uint32_t rmagic, rlen;
uint16_t rver, rtype;
memcpy(&rmagic, rhdr + 0, 4);
memcpy(&rver, rhdr + 4, 2);
memcpy(&rtype, rhdr + 6, 2);
memcpy(&rlen, rhdr + 12, 4);
if (rmagic == MEOW_IPC_MAGIC && rver == MEOW_IPC_VERSION &&
rtype == MSG_ACK && rlen >= sizeof(m_ack_t)) {
uint8_t pay[sizeof(m_ack_t)];
(void)read_all(fd, pay, sizeof(m_ack_t)); /* 读到即确认;内容不关心 */
}
}
close(fd);
}