Files
MeowOS-For-R3P2/patch_v2/meow_svc_power/svc_power_authtest.c
T
MeowOS f149e24f28 充电态权威源 mp2731-charger/status(修 battery/status 撒谎恒 Discharging)
真机实测:设备充电中但 battery/status 恒 Discharging;权威源为
mp2731-charger/status(Charging/Full),回退链 fusb302-typec-source/online==1
→ 旧逻辑 battery/status==Charging || ac/online==1。电量仍读 battery/capacity。

- meow_svc_power: battery/status 命令充电判定走权威链(MEOW_PS_DIR 可重定向供宿主自测);
  svc_power_authtest 补 6 用例(mp2731 Charging/Full/Discharging + 两级回退)全 PASS
- SDK meow_ui_sys: 状态栏充电态同权威链
- launcher util.c: 抽 batt_is_charging() 公共判定;meow_sys_light 1s 轻刷补充电态(插拔实时)
- bootmenu 无充电判定(仅读 capacity)/MeowPanel 透传 power 服务:均无需改
- 真机验证(充电窗口):新二进制 battery=88%(Charging),对照固件内旧版 88%(Discharging)
- hello/files/ncm 随 meow_ui.a(af6703f2) 重链已热更到卡(.new+mv,md5 对核一致)

md5: meow_svc_power 39ae3aa2 / meow_launcherd 2aa61780 / hello 2444c151 /
files 691db88b / ncm 89da63ed(仅重链,源码未动)
2026-09-01 03:25:01 +08:00

179 lines
8.9 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.
/* svc_power_authtest.c — meow_svc_power II 期 IPC 鉴权逻辑 宿主自测(本程序非生产代码)。
*
* 通过 #include 生产源文件(meow_svc_power.c,用 #define main 改名避免入口冲突),在同一 TU 内直接
* 访问其 FILE-STATIC 函数 classify_exe / is_system_action / is_sys_identity / is_read_level,
* 验证鉴别/分级策略的决策表。
* 覆盖「真机需特权路径 /proc/pid/exe 判定」之外的所有纯逻辑分支;真实 pid→exe 解析留真机验证。
*
* 用途:dev docs 复现级宿主自测;不进入固件/不部署。用法:
* cc -Wall -Wextra -I../meow_launcherd svc_power_authtest.c -o svc_power_authtest && ./svc_power_authtest
*/
#define main meow_svc_power_prod_main_unused
#define MEOW_PS_DIR "/tmp/meow_ps_authtest" /* 充电态判定宿主自测:重定向 sysfs 根 */
#include "meow_svc_power.c"
#undef main
#undef MEOW_PS_DIR
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
static int g_fail = 0;
#define CHECK(cond) do { if (!(cond)) { printf(" FAIL: %s (line %d)\n", #cond, __LINE__); g_fail++; } \
else { printf(" ok : %s\n", #cond); } } while (0)
int main(void)
{
caller_t c;
printf("== classify_exe ==\n");
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowAPPs/os.meow.tst/meow", &c);
CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "os.meow.tst") == 0);
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowAPPs/com.example.tool/meow", &c);
CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "com.example.tool") == 0);
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowAPPs/os.meow.tst/sub/meow", &c);
CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "os.meow.tst") == 0); /* 取首段目录 */
memset(&c, 0, sizeof c);
classify_exe("/usr/bin/meow_launcherd", &c);
CHECK(c.kind == CALL_SYS && strcmp(c.pkg, "os.meow.launcher") == 0);
memset(&c, 0, sizeof c);
classify_exe("/usr/bin/meow_svc_power", &c);
CHECK(c.kind == CALL_SYS); /* /usr/bin/meow_* 前缀批准 */
/* 2B 精确绑定:仅精确命中登记路径(meowpanel.conf 的 exec)才予 os.meow.panel。
* 旧启发式(路径含 /MeowPanel/ 或 meowpanel 子串)会被过宽放行,今已收紧为精确路径登记。 */
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowOS/opt/MeowPanel/meowpanel", &c);
CHECK(c.kind == CALL_SYS && strcmp(c.pkg, "os.meow.panel") == 0);
/* 反例:路径含 /MeowPanel/ 或 meowpanel 子串但并非精确登记路径 → 不再放行(CALL_OTHER) */
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowOS/opt/MeowPanel/backend/meowpanel", &c);
CHECK(c.kind == CALL_OTHER);
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowOS/opt/MeowPanel/evil", &c);
CHECK(c.kind == CALL_OTHER);
memset(&c, 0, sizeof c);
classify_exe("/usr/bin/meowpanel_fake", &c);
CHECK(c.kind == CALL_OTHER); /* 含 "meowpanel" 但非 /usr/bin/meow_* 精确前缀、非登记路径 */
memset(&c, 0, sizeof c);
classify_exe("/usr/data/meow/settings_tool", &c);
CHECK(c.kind == CALL_SYS); /* /usr/data/meow/ 批准 */
memset(&c, 0, sizeof c);
classify_exe("/usr/bin/bash", &c);
CHECK(c.kind == CALL_OTHER);
memset(&c, 0, sizeof c);
classify_exe("/bin/sh", &c);
CHECK(c.kind == CALL_OTHER);
memset(&c, 0, sizeof c);
classify_exe("/usr/data/mnt/sd_0/MeowAPPs/justadirty/k", &c);
CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "justadirty") == 0); /* 第三方包(非 os.meow.*) */
CHECK(is_sys_identity(&c) == 0); /* 非系统身份 → 系统动作被拒 */
printf("== is_sys_identity ==\n");
c.kind = CALL_PKG; snprintf(c.pkg, sizeof c.pkg, "%s", "os.meow.tst");
CHECK(is_sys_identity(&c) == 1);
c.kind = CALL_PKG; snprintf(c.pkg, sizeof c.pkg, "%s", "com.example.tool");
CHECK(is_sys_identity(&c) == 0);
c.kind = CALL_SYS; snprintf(c.pkg, sizeof c.pkg, "%s", "os.meow.launcher");
CHECK(is_sys_identity(&c) == 1);
c.kind = CALL_OTHER; c.pkg[0] = 0;
CHECK(is_sys_identity(&c) == 0);
printf("== is_system_action ==\n");
CHECK(is_system_action(POWER_SHUTDOWN) == 1);
CHECK(is_system_action(POWER_REBOOT) == 1);
CHECK(is_system_action(POWER_UPGRADE) == 1);
CHECK(is_system_action(POWER_BACK_HIBY) == 1);
CHECK(is_system_action(POWER_SET_DEFAULT_MEOW) == 1);
CHECK(is_system_action(POWER_SET_DEFAULT_HIBY) == 1);
CHECK(is_system_action(POWER_STATUS) == 0);
CHECK(is_system_action(POWER_BATTERY) == 0);
CHECK(is_system_action(POWER_REBOOT_REASON) == 0);
CHECK(is_system_action(POWER_UPGRADE_STATUS) == 0);
CHECK(is_system_action(POWER_SCREEN) == 0);
CHECK(is_system_action(POWER_DAC) == 0);
printf("== is_read_level ==\n");
m_power_action_t a;
memset(&a, 0, sizeof a);
/* 读级(只读无副作用)→ 1:放宽到任意调用者 */
a.cmd = POWER_STATUS; CHECK(is_read_level(&a) == 1);
a.cmd = POWER_BATTERY; CHECK(is_read_level(&a) == 1);
a.cmd = POWER_REBOOT_REASON; CHECK(is_read_level(&a) == 1);
a.cmd = POWER_UPGRADE_STATUS; CHECK(is_read_level(&a) == 1);
/* DAC status(flag=2) 为读级;on/off(flag=0/1) 为动作级 */
a.cmd = POWER_DAC; a.flag = 2; CHECK(is_read_level(&a) == 1); /* dac status */
a.cmd = POWER_DAC; a.flag = 0; CHECK(is_read_level(&a) == 0); /* dac off */
a.cmd = POWER_DAC; a.flag = 1; CHECK(is_read_level(&a) == 0); /* dac on */
/* 动作级(有副作用/系统级)→ 0:走现有鉴权 */
a.cmd = POWER_SCREEN; a.flag = 0; CHECK(is_read_level(&a) == 0); /* screen off/on */
a.cmd = POWER_SCREEN; a.flag = 2; CHECK(is_read_level(&a) == 0); /* screen timeout 写 settings */
a.cmd = POWER_SHUTDOWN; CHECK(is_read_level(&a) == 0);
a.cmd = POWER_REBOOT; CHECK(is_read_level(&a) == 0);
a.cmd = POWER_UPGRADE; CHECK(is_read_level(&a) == 0);
a.cmd = POWER_BACK_HIBY; CHECK(is_read_level(&a) == 0);
a.cmd = POWER_SET_DEFAULT_MEOW; CHECK(is_read_level(&a) == 0);
a.cmd = POWER_SET_DEFAULT_HIBY; CHECK(is_read_level(&a) == 0);
/* == 充电态权威源(真机实测 2026-09-01:battery/status 恒 Discharging 撒谎)==
* 在 /tmp 造 power_supply 假节点(MEOW_PS_DIR 已重定向),覆盖判定优先级:
* mp2731-charger/status(权威)→ fusb302-typec-source/online → battery/status|ac/online。 */
printf("== charging_status_str (authoritative mp2731) ==\n");
mkdir("/tmp/meow_ps_authtest", 0755);
mkdir("/tmp/meow_ps_authtest/battery", 0755);
mkdir("/tmp/meow_ps_authtest/mp2731-charger", 0755);
mkdir("/tmp/meow_ps_authtest/fusb302-typec-source", 0755);
mkdir("/tmp/meow_ps_authtest/ac", 0755);
write_file_str("/tmp/meow_ps_authtest/battery/capacity", "72", 0644);
write_file_str("/tmp/meow_ps_authtest/battery/voltage_now", "4150000", 0644);
write_file_str("/tmp/meow_ps_authtest/battery/status", "Discharging", 0644); /* 撒谎节点 */
write_file_str("/tmp/meow_ps_authtest/ac/online", "0", 0644);
char out[64];
/* T1: mp2731=Charging(battery 撒谎 Discharging)→ 充电中 */
write_file_str("/tmp/meow_ps_authtest/mp2731-charger/status", "Charging", 0644);
battery_fill(out, sizeof out);
CHECK(strstr(out, "(Charging)") != NULL);
/* T2: mp2731=Full → 满电 */
write_file_str("/tmp/meow_ps_authtest/mp2731-charger/status", "Full", 0644);
battery_fill(out, sizeof out);
CHECK(strstr(out, "(Full)") != NULL);
/* T3: mp2731=Discharging 且拔线 → 非充电(权威源的放电可信) */
write_file_str("/tmp/meow_ps_authtest/mp2731-charger/status", "Discharging", 0644);
write_file_str("/tmp/meow_ps_authtest/fusb302-typec-source/online", "0", 0644);
battery_fill(out, sizeof out);
CHECK(strstr(out, "(Discharging)") != NULL);
/* T4: mp2731 节点不可读 → 回退 fusb302 online==1 → 充电 */
unlink("/tmp/meow_ps_authtest/mp2731-charger/status");
write_file_str("/tmp/meow_ps_authtest/fusb302-typec-source/online", "1", 0644);
battery_fill(out, sizeof out);
CHECK(strstr(out, "(Charging)") != NULL);
/* T5: 全不可读 → 回退旧逻辑 ac/online==1 → Charging */
unlink("/tmp/meow_ps_authtest/fusb302-typec-source/online");
write_file_str("/tmp/meow_ps_authtest/ac/online", "1", 0644);
battery_fill(out, sizeof out);
CHECK(strstr(out, "(Charging)") != NULL);
/* T6: 全不可读且 ac/online=0、battery=Discharging → Discharging */
write_file_str("/tmp/meow_ps_authtest/ac/online", "0", 0644);
battery_fill(out, sizeof out);
CHECK(strstr(out, "(Discharging)") != NULL);
if (g_fail) { printf("\nAUTH TEST: %d FAIL\n", g_fail); return 1; }
printf("\nAUTH TEST: ALL PASS\n");
return 0;
}