- meow_ui_theme.c: 为 MEOW_STYLE_MIUIX 实现整套 light/dark 配色(暖基面+小米橙 primary 0xF57200/0xFF8C4A+蓝 tertiary;圆角 20/卡片 28、间距 12、细描边 1),与 MD3 可感知差异 - display.background 随 style×mode 派生 MIUIx 色板(bg_surfaces 增 style 参;图片背景保持各 style 默认面) - meow_settings.c g_defs: ui.style 值域 'md3,miui'→'md3,miuix'(label Material You,MIUIx); apply_value SET_ENUM 对存量 'miui' 兼容映射为 miuix - settings_page s_commit: ui.style 分支 → meow_ui_set_style + paint_sb_right + meow_dirty_full 即时换肤 - font_theme s_ui_theme() 接 ui.style + MIUIx dark/light 表;main_menu 背景签名含 ui.style + 纯色底随 style 换族 - 宿主编译 -Wall -Wextra 0 warning;test_meow_ui_theme 四套 s×m 渲染全 PASS; test_meow_ui_widgets/test_sdk_fixes 全 PASS(MD3 行为一致) - 产物 md5: meow_ui.a a4231296 / launcher 9f97af1b(未部署走固件)/ hello e5527578 / files 993e41ca / ncm 6b9eeb0f(三 App 已 .new+mv 热更到卡, 设备 md5 已核一致) - 待后续: 状态栏图标集仍 MD3 一套(sb_icons.h 无 per-style 换集接口, MIUIx 仅换配色); App 进程 SDK 主题缓存 g_loaded 不随 settings 外部改写重读, 运行中 App 下次启动才换肤
24 KiB
MeowOS 系统设置子系统设计(阶段 B2a 后端 + B2b UI)
状态:设计稿(2026-08-28)。后端 B2a 前置到阶段 B 之前(B 的通告栏快捷按钮/亮度滑条/主题开关全是设置项,必须先有统一后端,B 直接消费、零返工);B2b 实体设置页 UI 在 B 之后;阶段 C(MeowPanel)调同一后端。 原则:一套设置后端,多端(实体 UI / Web 面板 / CLI)共用同一 API,单一数据源,不留旁路。
0. 目标与一句话
把 MeowOS 全部系统设置抽象成统一设置子系统(结构化存储 + C API + 变更通知);阶段 B2a 落地这套后端(meow_settings_* + settings.conf + listener,先于阶段 B);阶段 B 的通告栏控件直接消费它;阶段 B2b 用同一 API 建实体设置 UI;阶段 C 的 MeowPanel 设置页直接调同一后端(HTTP 转发 C API),实体与 web 镜像、改哪边都同步。
1. 设置项清单(覆盖 MeowOS 全部可配置项)
| 分组 | 设置键 | 类型 | 默认 | 说明 |
|---|---|---|---|---|
| 显示 | display.brightness |
int 0-255 | 101 | 当前亮度(clamp ≥display.brightness_min,防黑屏;设置页滑条 clamp 到 1-100,101 会闪屏) |
display.brightness_min |
int | 1 | 亮度安全下限(用户可调;M2.39 由 25 改 1,旧持久 25 视为残留默认自动迁移到 1,使亮度滑条可调到「极暗但可见」) | |
display.screen_off_mode |
enum | panel |
panel=面板下电+背光0+FBIOPBLANK / black=背光0全黑+双击亮屏 |
|
display.screen_off_timeout |
int 秒 | 30 | 息屏时长(0=常亮) | |
display.refresh_rate |
enum | 60 |
刷新率上限三档 60/30/15(默认 60,不逼 62Hz 瓶颈) |
|
display.refresh_always_max |
bool | false | 始终最大刷新率(=60 且不自动降档);关=允许自适应降档(60→30→15) | |
display.theme |
enum | dark |
dark/light(该顶级主题 style 下的明暗;manual 模式下 s_ui_theme 直读它;切明暗→同 style 浅/深背景自动切换,见 MEOW_APP_SDK §8.1) |
|
display.theme_mode |
enum | manual |
主题判定方式:manual(=读 display.theme)/auto(按深色时段)。B2b 新增 |
|
display.theme_dark_start |
int 分钟 0-1439 | 0 |
深色时段开始(如 19:00=1140);start==end 视为未配置 → auto 回退 manual。B2b 新增 |
|
display.theme_dark_end |
int 分钟 0-1439 | 0 |
深色时段结束(如 07:00=420);start>end=跨午夜。B2b 新增 |
|
display.background |
enum/图片 | black |
由「当前 style × 当前 mode」决定的背景底选项集(非独立全局维度;可选集+默认随 style/mode 一起变):MD3×dark=黑/深蓝/墨绿(默认黑)、MD3×light=白/浅蓝/浅绿(默认白)、MIUIx×dark/light各一套(草案)。每种配色定义深/浅两套 surface/bg,随 display.theme 切换(修复"背景仅对主页生效/仅深蓝/浅色不搭")。亦可为图片路径 MeowAPPs/backgrounds/xx.png(定案:图片 cover 居中裁剪,深浅作用于文字/角色色、背景图不随深浅换,叠加层固定跟明暗主题)。见 MEOW_APP_SDK §8.1 |
|
| 电源 | power.longpress_menu_ms |
int | 3000 | 长按电源弹电源菜单阈值 |
power.forceoff_ms |
int | 8000 | 长按电源强关阈值 | |
power.defeat_hotkey |
string | power_voldown |
切系统/切 MeowOS 热键组合 | |
| 开机 | boot.default |
enum | meow |
开机默认进入。权威文件 = 板载 /data/meow_boot_default(O_TRUNC 单值:0=MeowOS / 1=HiByOS);boot.default 每次保存同步写该文件(launcher meow_settings_save 同步;bootmenu set_boot_default_meow/launcher set_boot_default_hiby 同文件同语义);init 读入不触发、不反向覆盖。meow.conf 不再承担 boot_default [源:M2.61 同步修复][源:2026-08-30] |
boot.menu_enabled |
bool | true | 是否显示引导选单 | |
boot.timeout_ms |
int | 5000 | 选单超时(有输入暂停重计) | |
| 输入 | input.hotkey_seq |
string | volup,volup,volup |
应用列表热键序列 |
input.hotkey_window_ms |
int | 2500 | 组合/序列窗口 | |
input.touch_arm_delay_ms |
int | 700 | 触摸布防延迟(防幽灵) | |
input.swipe_invert |
bool | false | 设置页滑动方向(0=手指上滑→往下翻;1=反向) | |
| 字体/主题 | font.file |
path | MeowOS/fonts/default/regular/font.png |
字体图集(M2.6 指 <family>/<weight>/font.png,默认 default/regular;设置页「字体文件」行为 family→字重两级子菜单) |
display.multi_font |
int 0/1 | 0 | 多字体:1=按字符类别逐字符路由;0=单字体(只走 font.file,零额外内存/性能) |
|
font.class_cjk |
path | (空=跟全局) | 多字体:CJK 表意+扩展 所用字体(family 相对路径) | |
font.class_cjk_sym |
path | (空=跟全局) | 多字体:全角/中文标点 所用字体 | |
font.class_num |
path | (空=跟全局) | 多字体:0-9 所用字体 | |
font.class_latin |
path | (空=跟全局) | 多字体:A-Za-z 所用字体 | |
font.class_latin_sym |
path | (空=跟全局) | 多字体:半角标点 所用字体 | |
font.class_other |
path | (空=跟全局) | 多字体:其他字符 所用字体 | |
font.load_full |
int 0/1 | 0 | 加载大字库(M2.5x):1=强制全系统用大字库(gbk≈20k 档),覆盖 app 未声明/覆盖默认 font.file;0=默认小字库(common≈4k),仅 app 声明 fonts:"full" 才大字库 [源:用户 2026-08-30] |
|
font.size.title / font.size.body |
int | 28/20 | 标题/正文字号 | |
ui.style |
enum | md3 |
md3(默认,Material You)/miuix(MIUIx,M2.90 已实现:完整 light/dark 配色+控件形态参数,见 MEOW_APP_SDK §8.1.3)——顶级主题风格族(定义整套配色风格/控件形态/圆角/间距/描边),对应 SDK MEOW_STYLE_MD3/MEOW_STYLE_MIUIX(MEOW_APP_SDK §8.1)。g_defs 值域 "md3,miuix"(label "Material You,MIUIx");存量 "miui" 兼容映射为 miuix。状态栏图标集仍 MD3 一套(无 per-style 换集接口,MIUIx 仅换配色) |
|
| 通知 | notify.center_enabled |
bool | true | 下拉通知中心开关 |
notify.app_quota |
int | 16 | 每应用通知配额 | |
notify.categories |
int | 4 | 通知类型数上限(每 App,M2.53)[源:审计 2026-08-30] | |
notify.category_quota |
int | 4 | 每类型活动通知上限(4×4=16/App) | |
notify.media_quota |
int | 1 | 媒体通知单例(每 App 仅 1 条) | |
notify.dnd |
bool | false | 通知中心「勿扰」面板内开关(通知列表上方小 toggle;开=只显示 urgency>=2(HIGH/CRITICAL),关=全部;面板内读写 meow_settings_*,零旁路)[源:用户 2026-08-30] |
|
| 日志 | log.level |
enum | info |
error/warn/info/debug |
log.to_card |
bool | true | 写 TF 卡(无卡回退内存环) | |
| 音频 | audio.volume |
int 0-100 | 60 | 系统音量(MeowOS 直写 CS43198 DAC;读回为追踪值) |
audio.volume_max |
int 0-100 | 100 | MeowOS 内部音量上限(clamp;不与 HibyOS user.ini 上限同步——其带 CRC 有风险,已定案不做;用户可自设 MeowOS 上限) | |
audio.volume_step |
int 1-5 | 1 | 音量键跳步(默认 1%,可配 1-5,最大 5) | |
audio.output |
string | hw:0,0 |
MeowAPPs 音频输出设备 | |
| 网络 | network.wifi_enabled |
bool | true | WiFi 开关(写 wlan0;设置页开关经 wifi_up.sh/ip link set wlan0,ensure_wifi() 尊重此值——关=0 则不再自动连网) |
network.bluetooth_enabled |
bool | false | 蓝牙开关(写 hciconfig hci0 up/down;默认关=少耗电) |
|
| 系统 | system.hostname |
string | meowos |
主机名(RFC1035 首标签;bootmenu 的 S89meow_svcd 开机读它 sethostname,缺省 meowos;供自研 mDNS 应答器 meow_mdns 公布 <host>.local)[源:M2.54] |
字体尺寸标记(M2.5x,随「加载大字库」一起落地):字体/主题选择器每个字体选项标注库大小标记,如
MiSans Regular(common≈4k)/gbk≈20k/full,直观标注码位/体积量级,让用户知道所选字库大小(M2.6 含字重:<name> <Weight>(<marker>))。对应MeowOS/fonts/<family>/<weight>/font.json的charset(common|gbk|full)+glyph_count;档位枚举MEOW_FONT_TIER_COMMON(默认/≈4k)/GBK(大/≈20k)/FULL(全/可选);gen_font.py --charset common|gbk|full [--weight <name>]按档生成。定案见 MEOWOS_SPEC_REF §5.2「字体档位/大字库」与 §5.7.8 [源:用户 2026-08-30]。
新增设置项时:在清单加一行 + 存储 schema + API 常量/枚举 + 实体 UI 控件 + web 面板控件(四端同步)。
主题三键语义(2026-08-30 定案,实现权威见 MEOW_APP_SDK §8.1):
ui.style(MD3/MIUIx)=顶级主题风格族(定义整套配色/控件形态/圆角/描边);display.theme(dark/light)=该 style 下的明暗;display.background=由「当前 style × 当前 mode」决定的背景底选项集(非独立全局维度,可选集+默认随 style/mode 一起变)。三者关系:切明暗 → 同 style 浅/深背景自动切换(修复"浅色不搭");切 style → 整套配色+背景换族(修复"背景仅对主页生效/只有深色")——同时把display.background从"仅 launcher 主页/仅深色"改为"全局背景源"(状态栏/未声明背景 App/主页同步;App 显式声明背景则覆盖,App 声明优先)。meow_ui_theme旧字段bg/fg/accent/dim保留映射到 MD3 语义色(§5.8.4)。注:ui.style值域已由"md3,miui"对齐为"md3,miuix"(label "Material You,MIUIx",对应MEOW_STYLE_MIUIX);存量settings.conf/备份里的"miui"在meow_settings.c apply_value(SET_ENUM)里兼容映射为miuix。MIUIx 已实现(M2.90):meow_ui_theme.c为MEOW_STYLE_MIUIX提供整套 light/dark 配色+控件形态参数,display.background按 style×mode 派生 MIUIx 色板;状态栏图标集仍为 MD3 一套(无 per-style 换集接口)。
2. 统一存储(单一数据源)
- 主持久化位置:板载
/usr/data/meow/settings.conf(UBIFS)。settings.conf 是小文件(几十行、<10KB),持久在板载可跨换卡/掉卡保留配置,避免换音乐卡丢失设置。板载仅此小设置文件(日志/字库/媒体等大数据仍留 TF 卡,符合"板载不写大文件"纪律;KB 级设置除外)。 - 导入/导出(备份):
- 导出默认路径:TF 卡
MeowOS/backups/settings/setting.bak(自动建目录)。用户可在导出时改路径。 - 本地 TF 卡:导入 = 从该 .bak 文件读入覆盖(选择/确认 + 校验)。
- Web 面板(阶段 C):
GET /api/settings/export(下载 .conf)/POST /api/settings/import(上传覆盖)。 - 二者都调用同一
meow_settings_export(path)/import(path)。
- 导出默认路径:TF 卡
- 无卡/无板载时:内存缓存,启动加载;板载在则自动落盘。
- 格式:
key = value扁平文本(收敛旧 meow.conf),支持注释#。 - 处理:
settings_load()(启动读 + 变更即settings_save()落到 /data)、settings_save()(有变更/定时/掉电前)。避免频繁写(UBIFS 有磨损但 KB 级低频无碍)。 - 版本:文件头
# meow-settings 1。
3. C API 契约(后端,meow_settings.h)
/* 类型 schema:每个设置键注册“名称/类型/默认/取值域”,存取统一走表 */
typedef enum { SET_INT, SET_STR, SET_ENUM, SET_BOOL } meow_set_type;
int meow_settings_init(void); /* 加载存储,注册默认 */
int meow_settings_get_int(const char *key, int *out);
int meow_settings_get_str(const char *key, char *buf, int len);
int meow_settings_get_enum(const char *key, int *out); /* 按枚举名/索引 */
int meow_settings_get_bool(const char *key, int *out);
int meow_settings_set_int(const char *key, int v); /* clamp 到取值域 */
int meow_settings_set_str(const char *key, const char *v);
int meow_settings_set_enum(const char *key, int v);
int meow_settings_set_bool(const char *key, int v);
/* 变更通知:注册回调(实体 UI 重绘 / web 推送) */
typedef void (*meow_settings_listener)(const char *key);
int meow_settings_add_listener(meow_settings_listener cb);
int meow_settings_remove_listener(...);
/* 枚举辅助:名字<->索引,供 UI/web 显示中文标签 */
int meow_settings_enum_label(const char *key, int idx, char *buf, int len);
int meow_settings_enum_count(const char *key);
/* 列表:枚举当前全部键,供 web 面板 / 设置页生成控件 */
int meow_settings_list(int (*cb)(const char *key, meow_set_type t, void*), void *ctx);
/* 导入/导出(备份) */
int meow_settings_export(const char *path); /* 写一份 .conf 到 path */
int meow_settings_import(const char *path); /* 从 .conf 读入覆盖,校验 + 通知 */
- clamp/校验集中在 set:如
brightness自动 clamp ≥brightness_min(默认 1;M2.39 由 25 改 1);screen_off_timeout >= 0;枚举越界拒绝。 - 变更通知在 set 成功后对注册 listener 广播(key 字符串),实体 UI 据此重绘;web 端经 MeowPanel 长连接推送。
4. 阶段 B2b:实体系统设置页(Launcher 内,用 B2a 已就位后端)
- 入口:应用列表加一个系统设置卡片/图标(或列表项),点进设置页。
- UI:列表式(与应用列表同款渲染),分组:显示 / 电源 / 开机 / 输入 / 字体主题 / 通知 / 日志 / 音频。每项 = 标题 + 控件:
- 开关(bool):
display.theme深浅、notify.center_enabled… - 滑条(int):亮度(clamp ≥25)、音量、息屏时长时间
- 选择器(enum):息屏模式、开机默认、主题、日志级别——选择器用子菜单/对话框,选项中文标签来自
enum_label - 路径(str):字体、背景——文件浏览器选择(可先用内置几个预设,自定义文件选择后期);字体(M2.6 字重结构)用 family→字重两级子菜单:点「字体文件」/多字体类别行 → 一级列扫描到的 family(多字体行首项「跟随全局」)→ 二级列该 family 的可用字重(regular/bold/italic…),点字重即选中(写
font.file/font.class_*=<family>/<weight>/font.png卡根相对路径)
- 开关(bool):
- 所有控件只调
meow_settings_set_*/get_*,绝不直接改文件;改完settings_save(),UI 按 listener 重绘。保证与 web/CLI 一致。 - 权限/安全:本机信任,设置页不做鉴权。
5. 阶段 C 复用(MeowPanel 设置页)
- MeowPanel 后端新增
/api/settings:GET /api/settings→ 返回全部键值(调meow_settings_list+ get_*)POST /api/settings(body: key/value)→ 调meow_settings_set_*+ savePOST /api/settings/restore→ 恢复默认
- web 设置页与实体设置页同一套 key/控件定义(前端每 key 渲染对应控件),共用
meow_settings后端。改 web → 实体立即反映(listener/轮询);改实体 → web 下拉刷新。 - 设置 API 也暴露给 CLI/MCP(
meowcli settings get/set)供调试/自动化。
6. 与阶段 B / D 的衔接
- 阶段 B:搭
meow_settings后端 + 状态栏/通知中心期间,逐步把现有散落的配置(meow.conf 的 boot_default/hotkey/bg_color/字体路径)迁移进settings.conf卸载旧 meow.conf;状态栏/通知中心读设置(如通知中心开关、字体字号)走 API。 - 阶段 D(Activity/通知框架):通知配额/行为等设置进 settings;应用可通过 IPC 读改名(可选暴露只读
meow_settings_get_*)。
7. 实现里程碑
M1 存储+核心 API(get/set/save/load/listen/list/枚举)→ M2 实体设置页(分组列表+各类控件)→ M3 迁移旧 meow.conf + 状态栏/通知中心走 API → M4 web 设置页对接 → M5 加固(clamp/校验/掉电保存/测试)。
8. 风险/注意
- 板载存储不写:settings.conf 只落 TF 卡,未挂载用内存,挂载后落盘;掉电前 save。
- clamp 必须集中在 set(防亮度 0 / 非法枚举)。
- 迁移 meow.conf 时保持向后兼容(旧文件读入,写回新格式),避免把现有用户配置弄丢。
- 字体/背景路径若失效回退默认(不崩)。
附:系统状态重抓清单与策略(进 MeowOS 全量快照)
状态项(进 MeowOS 时全量抓,HibyOS 改过也同步):
- 电量(百分比/充电状态/电压/温度)、WiFi(开关/SSID/IP/信号/链路)、蓝牙(开关/连设备数)、音量(settings)、亮度(sysfs)、存储(/data 剩余/TF卡挂载容量)、性能(loadavg/meminfo)、温度(thermal_zone)、系统(模式/应用数/版本)、音频输出(后续)
性能策略:
- 进 MeowOS 一次性全量
meow_sys_snapshot()(阻塞可接受)。 - 主循环 10ms 热键轮询绝不读系统状态;单独 1s 轻刷仅时钟/电量/WiFi 信号。
- 性能/温度类用后台定时低频率(1-2s)读,仅 MeowPanel 用,别占 UI。
- 统一封装
meow_sys_state+meow_sys_refresh(),状态栏/设置/面板共用。
附 B:设备属性域(device attributes)——meow_sys 只读+可控子域
承接 §18.44 设备全属性只读枚举(任务要求「覆盖设备所有属性:4.4 平衡口插入、3.5 单端口插入、低增益/高增益输出、及所有自带属性」)。在
meow_sys_state(g_sys)上扩展struct meow_sys_devattr,状态栏/MeowPanel/设置页共用,只读属性与可控(kcontrol)分开标注。只设计接口,不改 launcher 实现(落地留框架批次)。
检测源(只读居多,可控项白名单):
| 域字段 | 类型 | 读取源 | 可写 | 说明/单位 |
|---|---|---|---|---|
out.port |
int 0-7 | amixer cget numid=9 |
写=切输出(白名单1-4) | 现读=0(空闲);1=lineout/2=headset(3.5)/3=balance(4.4)/4=Type-C SPDIF;0/5 危险勿写。line-out(1)=固定满幅电平,保守默认不响应音量键、不受 lock_vol 限制(无实机接功放可测,按最保守处理,见 §附B line-out) |
out.headset_present |
bool | /sys/class/switch/headset/state |
只读 | 3.5 插入(=1) |
out.balance_present |
bool | /sys/class/switch/balance/state |
只读 | 4.4 插入(=1) |
out.earpods_adc_sw |
bool | /sys/devices/platform/earpods_adc/earpods_adc/earpods_adc_sw |
只读 | 耳塞型判定 |
out.balance_lineout_en |
bool | amixer cget numid=8 |
写 | 平衡 Lineout 使能 |
vol.left/vol.right |
int 0-255 | amixer cget numid=1/2(读恒 0,dummy get) |
写(真写 DAC) | meow_vol_set 已用;get 仅跟踪值 |
out.vol_max_headset/out.vol_max_balance |
int % | config.json volume.lock_vol |
只读(玩家态) | 3.5=55 / 4.4=43 ——按输出口分级音量上限(实际「增益/响度等级」代理) |
out.vol_default_headset/out.vol_default_balance |
int % | volume.default_vol |
只读 | 20 / 15 |
out.vol_warn_headset/out.vol_warn_balance |
int % | volume.warn_vol |
只读 | 34 / 28 |
codec.soft_mute/mute_out/nos_en/dre_en/dop_en |
bool | numid=5/3/6/7/10 | 写 | 软静音/硬静音/关过采样/动态范围增强/DoP 编码(numid 8/10 put=存驱动标志,get=dummy) |
codec.digital_filter |
int 0-4 | numid=4 | 写 | 滤波模式 |
dac.sample_rate / dac.is_dsd |
int/bool | 无任何只读路径:/proc/asound 不存在、codec reg_val/write_reg_val 只写(--w-------,回读 EACCES)、current_samplerate 未导出、dmesg 已滚出 |
只读 | Unsupported(标记 MEOW_ERR_NOENT);需玩家态或改驱动导出 |
usb_dac.mode |
bool | /sys/class/udc/13500000.otg_new/is_a_peripheral+state + configfs usb_gadget/*/UDC |
只读 | 当前 is_a_peripheral=0,state=not attached → 非 DAC 模式;=1 当 is_a_peripheral=1+gadget pid=0x0004 |
usb_dac.vid/pid/dac_pid |
int | /usr/resource/config.json |
只读 | 0x32BB / 0x0101 / 0x0004 |
bt.powered |
bool | bluetoothctl show Powered(或 hciconfig UP/DOWN);勿用 rfkill/*/soft |
写(可控开/关) | 当前 no(rfkill soft=0/hard=0 但 HCI 未上电) |
bt.mac/bt.name/bt.codec |
str | /sys/class/bluetooth/hci0/{address,name} + 连接后 bluealsa |
只读 | codec 无连接不可读 |
batt.capacity/voltage/status |
int%/µV/enum | power_supply/battery/* |
只读 | 100% / 4342000µV / Discharging |
chg.online/current/temp |
bool/µA | fusb302-typec-source/online + mp2731-charger/* |
只读 | 0 / 0µA / 30.0℃(当前未充) |
ac.present |
bool | power_supply/ac/present |
只读 | 0 |
sys.temperature |
int | 无 thermal_zone | 只读 | 不可读(x1600 未暴露) |
关键结论:① 3.5/4.4 是独立输出口,由 Output Port Switch(numid=9) 路由、由 /sys/class/switch/headset|balance 判别插入(headset 走 ADC=1 通道、balance 走 GPIO=PC24;balancelo/lineout 开关未启用),有独立端口检测、无独立"平衡/单端"切换控件;② 硬件/驱动层无高/低增益接口——codec_set_gain 反汇编=strcmp、codec_set_pregain/lrbalance/dsd_compensate=jr ra 空操作、无 gain kcontrol、codec reg_val 只写不可回读;幅度即 Playback Volume(0-255)、动态仅 DRE_EN;真实的按输出口响度分级在玩家态 config.json(lock_vol 55/43、default_vol 20/15、warn_vol 34/28),可读;③ USB DAC 模式 = is_a_peripheral=1 + gadget(pid=0x0004)(当前 is_a_peripheral=0,state=not attached → 非 DAC 模式);④ CPU 温度、运行时采样率/DSD 无干净只读接口(采样率/DSD 因 /proc/asound 缺失+codec reg 只写+current_samplerate 未导出而 Unsupported;温度因无 thermal_zone 而不可读),均标记 MEOW_ERR_NOENT。
API / 暴露(meow_sys.h + 三端复用,同 meow_settings):meow_sys_devattr_refresh(&out)、meow_devattr_set(field,value)(白名单)、meow_devattr_enum_label(field,idx,buf,len);MeowPanel GET/POST /api/device;CLI meowcli device [set]。
安全:白名单写(out.port 1-4、vol、filter/nos/dre/dop/mute、bt.powered);禁写 0/5 端口;禁写 codec write_reg_val(保留为调试钩子);volume 读用跟踪值。
附 B:line-out 与 gain(2026-08-29 实机更新,无实测保守默认)
out.gain(高/低)= 播放器应用层数字增益,选ot_devices.json``VOLUMES.HW.Gains的 HDB/LDB(实机仅暴露高/低两档,MDB 未暴露;框架与曲线本有 HDB/MDB/LDB 三档)。选择值存user.ini(位置式 struct + 自定义完整性字0x0134fe6e,读不干净、写有完整性风险)→ MeowOS 只读标记Unsupported(MEOW_ERR_NOENT),不设可写;ot_devices.json增益曲线作只读信息展示(标注"工厂校准,非当前选择态")。增益(输出电平曲线) ≠ 音量上限(lock_vol),二者独立相乘叠加。out.port=1(line-out,3.5mm 同口):给功放/台式机的满幅固定电平。保守默认:MeowOS 切到 line-out 后不响应音量键、不套用 lock_vol 上限(out.vol_max_headset不作用于 line-out),UI 标注"固定电平输出";仅当用户在设置里显式开启"line-out 可调"时才放开。该行为未实测(无功放设备),待补:切 line-out 后音量键是否仍生效、音量滑杆是否影响输出、lock_vol 是否绕过——测后再松开约束。- 刷新触发:用户可能经 HibyOS 切增益档 / 切输出口,MeowOS 需在这两个事件后全量重抓
meow_sys_refresh()(与"每次进 MeowOS 抓一遍"同逻辑),勿只靠 1s 轻刷。