通知模型补全(agent-107: SDK icon+update_progress / IPC urgency+MSG_NOTIFY_PROGRESS / 存储 urgency+icon回退+progress / CSV加3列) + 全屏收合视觉+滑条(agent-108)
This commit is contained in:
1 parent
b3e57d4b55
commit
e8fa373a2f
18 files changed
+410
-56
No files matched your search
@@ -58,6 +58,7 @@ static int g_cat_quota = MEOW_NOTIF_CAT_QUOTA_DEF;
|
||||
static int g_media_quota = MEOW_NOTIF_MEDIA_QUOTA_DEF;
|
||||
|
||||
static meow_notif_dump_cb g_dump_cb = NULL;
|
||||
static meow_notif_icon_cb g_icon_cb = NULL;
|
||||
static int g_inited = 0;
|
||||
|
||||
/* ---- 日志(自包含,不依赖 launcher 的 logmsg;前缀 "notif:")---- */
|
||||
@@ -94,14 +95,27 @@ static void n_strncpy(char *dst, const char *src, size_t len)
|
||||
dst[len - 1] = 0;
|
||||
}
|
||||
|
||||
/* app_icon 回退(用户定案):post 的 app_icon 为空时,经 g_icon_cb(app_id) 填该 app 默认图标;
|
||||
* 无回调/回调未填 → 保持空(通知中心 UI 再回退)。每条可独立图标(非空即用)。 */
|
||||
static void notif_resolve_icon(meow_notif_t *s)
|
||||
{
|
||||
if (!g_icon_cb) return;
|
||||
if (s->app_icon[0]) return;
|
||||
char tmp[MEOW_NOTIF_ICON_MAX];
|
||||
if (g_icon_cb(s->app_id, tmp, sizeof tmp) > 0 && tmp[0])
|
||||
n_strncpy(s->app_icon, tmp, sizeof s->app_icon);
|
||||
}
|
||||
|
||||
/* ================= TF 卡转储(通知#6 / M2c,NOTIFICATION_SYSTEM.md §5/§8)=================
|
||||
* 每条通知一行 CSV 追加到 <卡根>/MeowOS/notifications/notifications.log,并按日志总大小
|
||||
* 滚动截断(保留最新 10MB)。系统文件统一放 <卡根>/MeowOS/ 下(TF_CARD_LAYOUT.md)。 */
|
||||
* 滚动截断(保留最新 10MB)。系统文件统一放 <卡根>/MeowOS/ 下(TF_CARD_LAYOUT.md)。
|
||||
* 字段见 tf_line():timestamp,id,app_id,app_icon,category,urgency,progress,title,body,
|
||||
* target_activity,ongoing,media,dismissed(CSV 转义/去换行)。 */
|
||||
#define MEOW_NOTIF_TF_DIR "/usr/data/mnt/sd_0/MeowOS/notifications"
|
||||
#define MEOW_NOTIF_TF_LOG MEOW_NOTIF_TF_DIR "/notifications.log"
|
||||
#define MEOW_NOTIF_LOG_MAX_BYTES ((size_t)10 * 1024 * 1024) /* §8:保留最新 10MB */
|
||||
|
||||
/* 单行 CSV 上限:app_id(32)/category(24)/summary(64)/body(96)/target_activity(48)
|
||||
/* 单行 CSV 上限:app_id(32)/category(24)/summary(64)/body(96)/app_icon(48)/target_activity(48)
|
||||
* 全引号转义后仍远小于此。 */
|
||||
#define MEOW_NOTIF_CSV_LINE_MAX 1024
|
||||
|
||||
@@ -155,26 +169,31 @@ static void csv_field(char *dst, size_t dstsz, const char *src)
|
||||
}
|
||||
|
||||
/* 生成一行 CSV:
|
||||
* timestamp,id,app_id,category,urgency,title,body,target_activity,ongoing,media,dismissed
|
||||
* title<-summary;urgency:meow_notif 结构无该字段(保持既有 API),列值留空 ""。
|
||||
* 返回写入长度(不含 NUL)。 */
|
||||
* timestamp,id,app_id,app_icon,category,urgency,progress,title,body,target_activity,ongoing,media,dismissed
|
||||
* title<-summary;app_icon<-SDK icon(空→储存时已按 app_id 回退 app 图标);urgency 0-3(缺省 NORMAL);
|
||||
* progress 写当前值(-1=无进度)。返回写入长度(不含 NUL)。 */
|
||||
static size_t tf_line(const meow_notif_t *n, char *buf, size_t bufsz)
|
||||
{
|
||||
char a_app [2 + 2 * MEOW_NOTIF_APP_ID_MAX + 2];
|
||||
char a_cat [2 + 2 * MEOW_NOTIF_CAT_MAX + 2];
|
||||
char a_sum [2 + 2 * MEOW_NOTIF_SUMMARY_MAX + 2];
|
||||
char a_body[2 + 2 * MEOW_NOTIF_BODY_MAX + 2];
|
||||
char a_icon[2 + 2 * MEOW_NOTIF_ICON_MAX + 2];
|
||||
char a_tgt [2 + 2 * MEOW_NOTIF_ACTIVITY_MAX + 2];
|
||||
csv_field(a_app, sizeof a_app, n->app_id);
|
||||
csv_field(a_cat, sizeof a_cat, n->category);
|
||||
csv_field(a_sum, sizeof a_sum, n->summary);
|
||||
csv_field(a_body, sizeof a_body, n->body);
|
||||
csv_field(a_icon, sizeof a_icon, n->app_icon);
|
||||
csv_field(a_tgt, sizeof a_tgt, n->target_activity);
|
||||
int r = snprintf(buf, bufsz,
|
||||
"%llu,%u,%s,%s,\"\",%s,%s,%s,%u,%u,%u\n",
|
||||
"%llu,%u,%s,%s,%s,%u,%d,%s,%s,%s,%u,%u,%u\n",
|
||||
(unsigned long long)n->created_ms,
|
||||
(unsigned)n->id,
|
||||
a_app, a_cat, a_sum, a_body, a_tgt,
|
||||
a_app, a_icon, a_cat,
|
||||
(unsigned)n->urgency,
|
||||
(int)n->progress,
|
||||
a_sum, a_body, a_tgt,
|
||||
n->ongoing ? 1u : 0u,
|
||||
n->media ? 1u : 0u,
|
||||
n->dismissed ? 1u : 0u);
|
||||
@@ -477,8 +496,10 @@ int meow_notif_post(const meow_notif_t *n, uint32_t *out_id)
|
||||
n_strncpy(s->target_activity, n->target_activity, sizeof s->target_activity);
|
||||
s->expire_timeout = n->expire_timeout;
|
||||
s->progress = n->progress;
|
||||
s->urgency = n->urgency;
|
||||
s->ongoing = n->ongoing;
|
||||
s->media = n->media;
|
||||
notif_resolve_icon(s); /* 空 app_icon → app 图标回退 */
|
||||
if (out_id) *out_id = s->id;
|
||||
notif_log("post: UPDATE id=%u app=%s cat=%s", s->id, s->app_id, s->category);
|
||||
return NOTIF_OK;
|
||||
@@ -533,10 +554,12 @@ int meow_notif_post(const meow_notif_t *n, uint32_t *out_id)
|
||||
n_strncpy(s->target_activity, n->target_activity, sizeof s->target_activity);
|
||||
s->expire_timeout = n->expire_timeout;
|
||||
s->progress = n->progress;
|
||||
s->urgency = n->urgency;
|
||||
s->ongoing = n->ongoing;
|
||||
s->media = media ? 1 : 0;
|
||||
s->created_ms = wall_ms();
|
||||
s->dump_at_ms = mono_ms() + MEOW_NOTIF_TTL_MS; /* §8:创建 10s 转储 */
|
||||
notif_resolve_icon(s); /* 空 app_icon → app 图标回退 */
|
||||
s->active = 1;
|
||||
if (out_id) *out_id = s->id;
|
||||
notif_log("post: NEW id=%u app=%s cat=%s media=%d ongoing=%d", s->id, s->app_id,
|
||||
@@ -558,6 +581,26 @@ int meow_notif_dismiss(uint32_t id)
|
||||
return NOTIF_OK;
|
||||
}
|
||||
|
||||
/* ---- 实时更新进度:仅改内存活跃槽;progress>=100 视为「结束」→ 立即归档(里程碑落盘)---- */
|
||||
int meow_notif_update_progress(uint32_t id, int progress)
|
||||
{
|
||||
if (!g_inited) return NOTIF_ERR_NOTINIT;
|
||||
int p = (progress < -1) ? -1 : (progress > 100 ? 100 : progress); /* 钳位 [-1,100] */
|
||||
int idx = slot_by_id(id);
|
||||
if (idx < 0) return NOTIF_ERR_NOENT;
|
||||
meow_notif_t *s = &g_slots[idx];
|
||||
s->progress = p; /* 实时:只改内存活跃槽,不落盘 */
|
||||
if (p >= 100) { /* 结束(100%):里程碑落盘 + 释放非 ONGOING */
|
||||
int was_ongoing = s->ongoing;
|
||||
archive_one(s); /* 此刻快照(progress=100 写入 dump) */
|
||||
if (!was_ongoing) slot_release(idx);
|
||||
else notif_log("progress: id=%u reached 100%%, archived (kept for UI)", id);
|
||||
} else {
|
||||
notif_log("progress: id=%u p=%d (memory only)", id, p);
|
||||
}
|
||||
return NOTIF_OK;
|
||||
}
|
||||
|
||||
/* ---- count ---- */
|
||||
int meow_notif_count(const char *app_id)
|
||||
{
|
||||
@@ -641,6 +684,12 @@ void meow_notif_set_dump_cb(meow_notif_dump_cb cb)
|
||||
g_dump_cb = cb; /* NULL=恢复默认(无回调,仅日志;M2c 接 TF) */
|
||||
}
|
||||
|
||||
/* ---- 设置图标回退回调 ---- */
|
||||
void meow_notif_set_icon_cb(meow_notif_icon_cb cb)
|
||||
{
|
||||
g_icon_cb = cb; /* NULL=禁用(空 app_icon 保持空,通知中心 UI 再回退) */
|
||||
}
|
||||
|
||||
/* ---- MSG_NOTIFY_LIST 序列化(守护→App 下发清单;M5 通知中心/重同步用)----
|
||||
* 负载: [u16 count] + count 条 定长 meow_notif 记录(records 以 app_id/category/
|
||||
* summary/body/app_icon/target_activity 为主,精简 payload,适配 MEOW_IPC_CARGO)。 */
|
||||
@@ -690,8 +739,8 @@ void meow_notif_dump(const char *log_prefix)
|
||||
for (int i = 0; i < MEOW_NOTIF_MAX_SLOTS; i++) {
|
||||
meow_notif_t *s = &g_slots[i];
|
||||
if (!s->active) continue;
|
||||
notif_log("%s slot%02d id=%u app=%s cat=%s sum=%s ong=%d media=%d dumped=%d",
|
||||
notif_log("%s slot%02d id=%u app=%s cat=%s sum=%s ong=%d media=%d urg=%u dumped=%d",
|
||||
lp, i, s->id, s->app_id, s->category, s->summary,
|
||||
s->ongoing, s->media, s->dumped);
|
||||
s->ongoing, s->media, s->urgency, s->dumped);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user