feat(system): 系统框架一期 — 专项服务(性能/电源)+IPC+电源CLI+电菜单改经服务(agent-155)

- meow_svc_power: 单一二进制(svcd空参IPC常驻 /usr/data/meow_power.sock + root CLI免鉴权), 12命令(shutdown/reboot强制=0/upgrade/set-default-hiby/reboot--hiby + set-default-meow/status/screen/dac(status仅)/battery/reboot-reason/upgrade-status); 动作同源sys_do_reboot/set_boot_default_hiby/mtd5=ota:kernel2; dac on/off无控制点不支持
- meow_svc_perf: IPC(/usr/data/meow_perf.sock MSG_PERF_*) + CLI, 聚合/proc/df/thermal/version/uname JSON(与MEOWPANEL_PROTOCOL对齐)
- power_menu.c 改经 meow_power_action(launcher先转储再IPC), 删sys_do_reboot/set_boot_default_hiby; 4动作+8s强关+confirm_reboot_player+3处长按强关全经服务; launcher内 sys_do_reboot/bootmode.sh/set_boot_default_hiby 0调用
- meow_ipc.h 仅加 MSG_PERF_QUERY/RESULT(0x50/51)+MSG_POWER_ACTION/STATUS(0x60/61)+POWER_*(12)+m_perf/power_t; 未动既有
- S89meow_svcd 预置 meow_svc_perf/power.conf(trigger=boot); 各独立socket
- IPC鉴权一期=SO_PEERCRED uid==0基础(完整os.meow.*二期); 通知转储=launcher先转储再IPC(二期补launcher→服务通道); 失败安全(服务不可达→按取消,不静默不直连)
- meow_svc_power=32d6be92/meow_svc_perf=7b0f3b64/launcher=d90f09e9/svcd=fb2d608b(未动)/meow_ui.a=92e61fb8(未改); 全0warning; 备份power_menu.c.pre-svc.bak回退
This commit is contained in:
MeowOS committed 2026-08-30 23:16:12 +08:00
1 parent 898bc176c9
commit 23727cf400
16 files changed
+1559 -41

No files matched your search

+1 -1
View File
@@ -555,7 +555,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
* M2.37:阈值接 power.forceoff_ms(默认 8000),强关保持 > 弹菜单上限。 */
if (t - pwr_hold_at >= power_forceoff_ms && !pwr_menu_state) {
if (sim_no_exec) { logmsg("pm: [sim-no-exec] POWER HOLD %dms -> would force poweroff", power_forceoff_ms); }
else { logmsg("pm: POWER HOLD %dms -> force poweroff", power_forceoff_ms); sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF); }
else { logmsg("pm: POWER HOLD %dms -> force poweroff", power_forceoff_ms); meow_power_action(POWER_SHUTDOWN); }
m_prev_pwr = pwr; continue;
} else if (t - pwr_hold_at >= power_longpress_menu_ms && !pwr_menu_state) {
pwr_menu_state = 1;
+56
View File
@@ -52,6 +52,10 @@ enum {
MSG_ACT_BACK = 0x0034, /* ↑ 上报回到根/无 activity(清 keep_awake,M2.17) */
MSG_NAV = 0x0040, /* ↑ 上报导航/请求退出 */
MSG_SHOW_ACTIVITY= 0x0041, /* ↓ 令前端应用显示某屏 */
MSG_PERF_QUERY = 0x0050, /* ↑ 性能/系统聚合查询(专项服务 meow_svc_perf) */
MSG_PERF_RESULT = 0x0051, /* ↓ 聚合 JSON(perf/system 子集) */
MSG_POWER_ACTION = 0x0060, /* ↑ 电源/系统动作信号(专项服务 meow_svc_power) */
MSG_POWER_STATUS = 0x0061, /* ↓ 动作受理/结果 + 状态文本 */
MSG_SYS = 0x00F0 /* ↓ 系统事件(守护关闭/服务死亡/播放器状态) */
};
@@ -165,4 +169,56 @@ typedef struct m_notify_progress {
int32_t progress; /* 0-100;<0=清除进度条 */
} m_notify_progress_t; /* 8 B */
/* ================= 专项服务 IPC(SYSTEM_FRAMEWORK_SERVICES §2.2/§2.3)= */
/* ---- MSG_PERF_QUERY 子集位(0=全部)---- */
#define PERF_SUBSET_PERF (1u << 0) /* cpu/mem/uptime/temp/storage/tfcard */
#define PERF_SUBSET_SYSTEM (1u << 1) /* system(version/hostname/kernel/arch) */
/* MSG_PERF_QUERY ↑:性能/系统聚合查询(服务端 meow_svc_perf) */
typedef struct m_perf_query {
uint32_t subset; /* 0=全部;PERF_SUBSET_* 组合 */
} m_perf_query_t; /* 4 B */
/* MSG_PERF_RESULT ↓:聚合 JSON(payload 为 NUL 结尾 JSON 文本) */
typedef struct m_perf_result {
uint32_t code; /* MEOW_OK / MEOW_ERR_* */
uint32_t subset; /* 回显请求 subset */
uint16_t json_len; /* json 有效字节(不含 NUL) */
uint16_t pad;
char json[MEOW_IPC_MAX - 12]; /* 聚合 JSON(.data 形状,§2.2) */
} m_perf_result_t;
/* ---- POWER_* 动作枚举(m_power_action_t.cmd;与 CLI §2.4 同源)---- */
enum {
POWER_SHUTDOWN = 0, /* 关机 */
POWER_REBOOT = 1, /* 重启回 MeowOS(强制写 boot_default=0) */
POWER_UPGRADE = 2, /* 写 mtd5=ota:kernel2 进升级模式 */
POWER_BACK_HIBY = 3, /* 写 boot_default=1 + reboot(回 HiBy) */
POWER_SET_DEFAULT_MEOW = 4, /* 只写 boot_default=0,不重启 */
POWER_SET_DEFAULT_HIBY = 5, /* 只写 boot_default=1,不重启 */
POWER_STATUS = 6, /* 综合状态查询 */
POWER_BATTERY = 7, /* 电池查询 */
POWER_REBOOT_REASON = 8, /* 上次重启原因 */
POWER_UPGRADE_STATUS = 9, /* 升级标志(mtd5=ota:kernel2?) */
POWER_SCREEN = 10, /* 屏幕电源:flag 0=off/1=on/2=timeout(秒取 arg) */
POWER_DAC = 11 /* DAC:flag 0=off/1=on/2=status */
};
/* MSG_POWER_ACTION ↑:电源/系统动作信号(服务端 meow_svc_power) */
typedef struct m_power_action {
uint32_t cmd; /* POWER_* 枚举 */
uint32_t flag; /* 随 cmd;POWER_SCREEN/DAC 用 */
char arg[32]; /* 可选文本参数(如 screen timeout 秒数字符串) */
} m_power_action_t; /* 40 B */
/* MSG_POWER_STATUS ↓:动作受理/结果 + 状态文本(CLI/IPC 展示) */
typedef struct m_power_status {
uint32_t code; /* MEOW_OK / MEOW_ERR_PERM / MEOW_ERR_INVAL / MEOW_ERR_NODEV */
uint32_t cmd; /* 回显 cmd */
uint16_t msg_len; /* msg 有效字节(不含 NUL) */
uint16_t pad;
char msg[96]; /* 结果/状态文本 */
} m_power_status_t;
#endif /* MEOW_IPC_H */
@@ -624,7 +624,9 @@ void settings_volume_adj(int delta);
int settings_volume_get(void);
int show_power_menu(void);
int stop_player(void);
void sys_do_reboot(int cmd);
/* 电源管理服务 IPC(SYSTEM_FRAMEWORK_SERVICES §3.2:launcher 电源动作经 meow_svc_power 执行) */
int pm_power_ipc(uint32_t cmd, uint32_t flag, const char *arg, char *res, int reslen);
int meow_power_action(uint32_t cmd);
void ui_draw(int x, int y, const char *s, uint32_t color, int size);
int ui_width(const char *s, int size);
void unblank_panel(void);
Binary file not shown.
+1 -1
View File
@@ -930,7 +930,7 @@ void run_notif_center(struct app *apps, int napps, int *want_launch,
if (pwr && pwr_hold_at) {
if (now - pwr_hold_at >= power_forceoff_ms && !pwr_menu_state) {
if (sim_no_exec) logmsg("notif-center pm: [sim-no-exec] hold %dms -> would forceoff", power_forceoff_ms);
else { logmsg("notif-center pm: hold %dms -> force poweroff", power_forceoff_ms); sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF); }
else { logmsg("notif-center pm: hold %dms -> force poweroff", power_forceoff_ms); meow_power_action(POWER_SHUTDOWN); }
} else if (now - pwr_hold_at >= power_longpress_menu_ms && !pwr_menu_state) {
pwr_menu_state = 1;
logmsg("notif-center pm: hold %dms -> power menu", power_longpress_menu_ms);
+129 -36
View File
@@ -70,25 +70,102 @@ static void draw_pm_button(int i, int selected)
}
}
void sys_do_reboot(int cmd)
/* ---- 电源管理服务 IPC 客户端(SYSTEM_FRAMEWORK_SERVICES §3.2:launcher 经服务触发电源动作)----
* launcher 不再直连 reboot(2)syscall/写 mtd5/写 boot 默认 —— 统一经 meow_svc_power 的
* `/usr/data/meow_power.sock`(`MEOW_IPC_POWER_SOCK` 可覆盖)发 MSG_POWER_ACTION。 */
#define PW_SOCK_DEFAULT "/usr/data/meow_power.sock"
static int pw_write_all(int fd, const uint8_t *b, size_t n)
{
/* M2a:正常电源事件(关机/重启)触发清除板载通知数据之前,先转储所有未上卡通知
* (NOTIFICATION_SYSTEM.md §8)。meow_notif_before_poweroff 幂等安全(未 init 直接返回)。 */
meow_notif_before_poweroff();
sync(); /* 先落盘,避免数据丢失 */
logmsg("sys_do_reboot cmd=0x%x", cmd);
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, NULL);
logmsg("sys_do_reboot returned: %s", strerror(errno)); /* 正常不会返回 */
for (;;) usleep(1000); /* 防御:永不返回 */
size_t off = 0;
while (off < n) { ssize_t w = write(fd, b + off, n - off); if (w <= 0) return -1; off += (size_t)w; }
return 0;
}
static int pw_read_all(int fd, uint8_t *b, size_t n)
{
size_t off = 0;
while (off < n) { ssize_t r = read(fd, b + off, n - off); if (r <= 0) return -1; off += (size_t)r; }
return 0;
}
/* 发一帧并等应答(读超时 1.5s,服务不可达/无响应不至于卡死菜单)。 */
static int pw_xchg(int fd, uint16_t type, uint32_t req, const void *pl, uint32_t len,
uint8_t *rbuf, uint32_t rcap, uint16_t *rtype)
{
uint8_t hdr[MEOW_IPC_HDR_LEN];
uint32_t magic = MEOW_IPC_MAGIC, rlen = len;
uint16_t ver = MEOW_IPC_VERSION, t = type;
memcpy(hdr + 0, &magic, 4); memcpy(hdr + 4, &ver, 2); memcpy(hdr + 6, &t, 2);
memcpy(hdr + 8, &req, 4); memcpy(hdr + 12, &rlen, 4);
if (pw_write_all(fd, hdr, sizeof hdr) < 0) return -1;
if (len && pl && pw_write_all(fd, pl, len) < 0) return -1;
struct pollfd pf = { fd, POLLIN, 0 };
int pr = poll(&pf, 1, 1500);
if (pr <= 0) return -1;
uint8_t rhdr[MEOW_IPC_HDR_LEN];
if (pw_read_all(fd, rhdr, sizeof rhdr) < 0) return -1;
uint32_t rmagic, rlen2; uint16_t rver, rt;
memcpy(&rmagic, rhdr, 4); memcpy(&rver, rhdr + 4, 2); memcpy(&rt, rhdr + 6, 2);
memcpy(&rlen2, rhdr + 12, 4);
if (rmagic != MEOW_IPC_MAGIC || rver != MEOW_IPC_VERSION) return -1;
if (rlen2 > rcap) rlen2 = rcap;
if (rlen2 && pw_read_all(fd, rbuf, rlen2) < 0) return -1;
if (rtype) *rtype = rt;
return 0;
}
/* 回HibyOS:写板载 /data/meow_boot_default=1(开机默认权威标记,O_TRUNC 单值、不写 TF 卡),
* 再 reboot 回选单并默认 HibyOS。meow.conf 不再写/承载 boot_default(bootmenu 以板载标记为准)。 */
static void set_boot_default_hiby(void)
/* 经电源服务执行动作。返回 MEOW_OK 或错误码;res/reslen 可收状态文本。 */
int pm_power_ipc(uint32_t cmd, uint32_t flag, const char *arg, char *res, int reslen)
{
int fd = open("/data/meow_boot_default", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd >= 0) { write(fd, "1\n", 2); close(fd); logmsg("pm: /data/meow_boot_default=1"); }
const char *sock = getenv("MEOW_IPC_POWER_SOCK");
if (!sock || !sock[0]) sock = PW_SOCK_DEFAULT;
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) return MEOW_ERR_IO;
struct sockaddr_un a;
memset(&a, 0, sizeof a);
a.sun_family = AF_UNIX;
strncpy(a.sun_path, sock, sizeof a.sun_path - 1);
if (connect(fd, (struct sockaddr *)&a, sizeof a) < 0) { close(fd); return MEOW_ERR_IO; }
m_hello_t h;
memset(&h, 0, sizeof h);
snprintf(h.app_id, sizeof h.app_id, "%s", "os.meow.launcher");
h.version = 1;
uint8_t rbuf[256]; uint16_t rtype = 0;
if (pw_xchg(fd, MSG_HELLO, 0x100, &h, sizeof h, rbuf, sizeof rbuf, &rtype) < 0 || rtype != MSG_ACK) {
close(fd); return MEOW_ERR_IO;
}
m_ack_t ak;
memcpy(&ak, rbuf, sizeof ak);
if (ak.code != MEOW_OK) { close(fd); return (int)ak.code; }
m_power_action_t pa;
memset(&pa, 0, sizeof pa);
pa.cmd = cmd;
pa.flag = flag;
if (arg) snprintf(pa.arg, sizeof pa.arg, "%s", arg);
if (pw_xchg(fd, MSG_POWER_ACTION, 0x101, &pa, sizeof pa, rbuf, sizeof rbuf, &rtype) < 0 || rtype != MSG_POWER_STATUS) {
close(fd); return MEOW_ERR_IO;
}
m_power_status_t st;
memcpy(&st, rbuf, sizeof st);
close(fd);
if (res && reslen > 0) {
uint16_t ml = st.msg_len;
if (ml >= (uint16_t)reslen) ml = (uint16_t)(reslen - 1);
memcpy(res, st.msg, ml);
res[ml] = 0;
}
return (int)st.code;
}
/* launcher 侧统一电源动作入口:先转储未上卡通知(进程本地,见 §3.2 定案),再经服务 IPC 执行。
* 返回 MEOW_OK=已受理(服务将执行,通常随即 reboot/poweroff);非 OK=服务不可达/拒绝,调用方应
* 稳妥处理(如菜单按「取消」返回,绝不误报动作成功导致 launcher 退出卡死)。 */
int meow_power_action(uint32_t cmd)
{
meow_notif_before_poweroff(); /* 幂等安全(未 init 直接返回) */
int rc = pm_power_ipc(cmd, 0, NULL, NULL, 0);
if (rc != MEOW_OK)
logmsg("meow_power_action cmd=%u FAILED rc=%d (power service unavailable?)", cmd, rc);
return rc;
}
@@ -225,8 +302,12 @@ int show_power_menu(void)
/* 8s 强关(绕过):仅当电源持续按住、且用户全程未与菜单互动才触发 —— 放在触摸/按键处理
* 之后,避免「用户已点选按钮」的同一轮被强关抢先(M2.10 Bug)。 */
if (pwr && !pm_interacted && now_ms() - pm_t0 >= 5000) {
if (sim_no_exec) { logmsg("pm: [sim-no-exec] POWER HOLD 8s -> would force poweroff"); }
else { logmsg("pm: POWER HOLD 8s -> force poweroff"); sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF); }
if (sim_no_exec) { logmsg("pm: [sim-no-exec] POWER HOLD 8s -> would force poweroff"); return 1; }
logmsg("pm: POWER HOLD 8s -> force poweroff");
if (meow_power_action(POWER_SHUTDOWN) != MEOW_OK) {
logmsg("pm: power service unavailable, abort force-off (menu closed, no action)");
return 0;
}
return 1;
}
@@ -247,35 +328,44 @@ int show_power_menu(void)
}
if (tfd >= 0) close(tfd);
/* M2.11 B:电源键在菜单 = 按当前项确认。act 与 syscall 类型逐项核对:
* act==4(取消) -> 只关菜单,绝不关机(return 0,永不到 reboot);
* act==0(关机) -> 才 poweroff;act==1(重启)/act==2(回HibyOS)/act==3(升级模式) -> 才 reboot。
* 只有 act 为 0/1/2/3 才可能执行 sys_do_reboot;power 键本身绝不触发关机。 */
/* M2.11 B:电源键在菜单 = 按当前项确认。act 与电源动作逐项核对:
* act==4(取消) -> 只关菜单,绝不关机(return 0,永不到电源动作);
* act==0(关机)/act==1(重启)/act==2(回HibyOS)/act==3(升级模式) -> 才经服务 IPC 执行电源动作。
* 只有 act 为 0/1/2/3 才可能发电源动作;power 键本身绝不触发关机。 */
logmsg("pm: act=%d -> %s", act,
act == 0 ? "关机" : act == 1 ? "重启" : act == 2 ? "回HibyOS" : act == 3 ? "升级模式" : "取消");
if (act == 4) { logmsg("pm: cancel (close menu only)"); return 0; }
/* 动作统一经电源管理服务 IPC(meow_svc_power);launcher 不再直连 poweroff/reboot(2)/写 mtd5/
* 写 boot 默认——关机/重启/升级/回HiBy 的动作原语都在服务内实现(§3.2 单一动作链路)。 */
/* 公共服务:执行动作;服务不可达 → 按「取消」返回(launcher 存活,绝不误报已动作卡死)。
* meow_power_action 内部已先 meow_notif_before_poweroff()(转储未上卡通知)。 */
if (act == 0) {
logmsg("pm: POWER OFF");
if (!sim_no_exec) {
/* 先显关机 logo(cmd_jpeg_display 是独立二进制,能正常显图),再直连 poweroff */
system("PATH=/bin:/sbin:/usr/bin:/usr/sbin cmd_jpeg_display /etc/shutdown_logo.jpeg >/dev/null 2>&1");
sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF);
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would poweroff"); return 1; }
if (meow_power_action(POWER_SHUTDOWN) != MEOW_OK) {
logmsg("pm: power service unavailable, abort (menu closed, no action)");
return 0;
}
} else if (act == 1) {
logmsg("pm: REBOOT");
if (!sim_no_exec) sys_do_reboot(LINUX_REBOOT_CMD_RESTART);
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would reboot"); return 1; }
if (meow_power_action(POWER_REBOOT) != MEOW_OK) {
logmsg("pm: power service unavailable, abort (menu closed, no action)");
return 0;
}
} else if (act == 2) {
logmsg("pm: RETURN TO HIBYOS");
set_boot_default_hiby();
if (!sim_no_exec) sys_do_reboot(LINUX_REBOOT_CMD_RESTART);
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would reboot to hiby"); return 1; }
if (meow_power_action(POWER_BACK_HIBY) != MEOW_OK) {
logmsg("pm: power service unavailable, abort (menu closed, no action)");
return 0;
}
} else if (act == 3) {
/* M2.29 升级模式:写 mtd5=ota:kernel2(bootmode.sh Recovery = flash_erase + nandwrite)
* 再 reboot —— uboot 读 mtd5=ota:kernel2 引导 kernel2(升级模式,自动刷 TF 卡
* r3proii.upt,双进度条,跑完重启进新固件)。已验证此链路可靠。 */
logmsg("pm: ENTER UPGRADE");
if (!sim_no_exec) {
system("PATH=/bin:/sbin:/usr/bin:/usr/sbin /usr/bin/bootmode.sh Recovery >/dev/null 2>&1");
sys_do_reboot(LINUX_REBOOT_CMD_RESTART);
if (sim_no_exec) { logmsg("pm: [sim-no-exec] would enter upgrade"); return 1; }
if (meow_power_action(POWER_UPGRADE) != MEOW_OK) {
logmsg("pm: power service unavailable, abort (menu closed, no action)");
return 0;
}
}
return 1;
@@ -396,8 +486,11 @@ int confirm_reboot_player(void)
if (tfd >= 0) close(tfd);
if (act == 0) {
logmsg("reboot-to-player: YES -> default HibyOS + reboot");
set_boot_default_hiby();
if (!sim_no_exec) sys_do_reboot(LINUX_REBOOT_CMD_RESTART);
if (sim_no_exec) { logmsg("reboot-to-player: [sim-no-exec] would reboot to hiby"); return 1; }
if (meow_power_action(POWER_BACK_HIBY) != MEOW_OK) {
logmsg("reboot-to-player: power service unavailable, abort (stay in MeowOS)");
return 0;
}
return 1;
}
logmsg("reboot-to-player: cancel");
+1 -1
View File
@@ -1045,7 +1045,7 @@ void run_settings_page(void)
* 时触发;开过菜单则交给菜单内确认/取消,杜绝「开菜单->取消->仍按住->强关」残留。 */
if (now - pwr_hold_at >= power_forceoff_ms && !pwr_menu_state) {
if (sim_no_exec) { logmsg("settings pm: [sim-no-exec] POWER HOLD %dms -> would force poweroff", power_forceoff_ms); }
else { logmsg("settings pm: POWER HOLD %dms -> force poweroff", power_forceoff_ms); sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF); }
else { logmsg("settings pm: POWER HOLD %dms -> force poweroff", power_forceoff_ms); meow_power_action(POWER_SHUTDOWN); }
/* 关机一般不复返;若 reboot 失败返回仍按按住处理(m_prev 由下方统一复写) */
} else if (now - pwr_hold_at >= power_longpress_menu_ms && !pwr_menu_state) {
pwr_menu_state = 1;