Files
MeowOS 4bafdb5d69 fix(keys): 插孔消抖 + 音量 ramp 3s 上限 + 亮度写日志 — 耳机插拔 ADC 幽灵音量键修复
真机实证(meow_20260901_034946.log): 4.4 插入瞬间电气瞬态在 jz_adc_aux(event2)
产生 VOL_UP 幽灵按住, vol_ramp 24%→上限50 (225391 ramp 起→227213 爬满,
紧随 audiod jack changed). 修(限 meow_launcherd/+meow_watchdog/):
① launcher audio.c + watchdog 各自读 /sys/class/switch/{headset,balance}/state
  (节流缓存 1s/500ms, 热路径不每圈读文件), 变化后 800ms 内忽略音量键边沿
  (vol_ramp_begin 不起/在爬 ramp 中止/wd_vol_adj 单步忽略)
② ramp 总时长上限 VOL_RAMP_MAX_MS=3000 兜底防一次幽灵打满(正常长按 24→50 ~1.4s 不伤)
③ write_brightness(val,src) 全 10 调用点带源+逐写 logmsg, 亮度跳上限下次可定位
  (grep 全库: 写 backlight 仅 launcher/watchdog/svc_power/bootmenu, 无确定 255 路径)
宿主: 新 test_vol_ramp_jack 15/15 PASS(单击/长按回归+3s cap+消抖忽略/中止/恢复);
test_wd_fw 17/17 + test_settings_brightness + test_notif_tf PASS; MIPS -Wall -Wextra 0 warning
(顺带修 watchdog 既有 sys/poll.h→poll.h 重定向 warning).
watchdog 已热更设备 /usr/data(baa997ea); launcher 7be1d4eb 待固件. fw_content.conf 已更新.
遗留: SDK meow_ui_input.c 音量键路径需同款消抖(sdk/ 有主未动)
2026-09-01 04:28:10 +08:00

149 lines
6.5 KiB
C
Raw Permalink 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.
/* backlight.c — MeowOS launcher 拆分模块(LAUNCHER_SPLIT_PLAN 拆分)。*/
/* 本文件由拆分工具从 meow_launcherd.c 按职责搬移;逻辑与原文 0-diff(仅 static 可见性按跨模块需求调整)。*/
#include "meow_launcher_internal.h"
/* ---- MeowOS 面板自持(M2.6:播放器已死,MeowOS 拥有面板/背光,无拔河)----
* 电源键按时长三分:单击(短按松开)= 息屏/亮屏;3s=电源菜单;8s=强制关机。
* 息屏 = 亮度0 + FBIOBLANK(4)(面板下电,同时挂起 goodix 触摸,无误触);
* 亮屏 = FBIOBLANK(0) + 恢复亮度。 */
int meow_screen_on = 1;
int meow_saved_brightness = 60;
int meow_auto_slept = 0; /* M2.17:当前是否「超时自动息屏」置位(手动电源息屏不置位) */
/* brightness save/restore (defined below, used by run_menu) */
int saved_brightness = -1;
/* M2.86:亮度「待补应用」挂起标志。launcher 被 sysui 在 S70 早拉起,早于 /usr/data(UBIFS) 就绪,
* settings_load 读到的是纯默认值(display.brightness=101→clamp 100);此时 apply_user_brightness
* 若照写 100 即「开机遇 100 满亮」。修:设置未真正读到盘上时挂起,待 run_menu 轮询 settings_load
* 成功(meow_settings_loaded()==1)后补应用真实用户亮度。 */
int meow_brightness_pending = 0;
/* M2.53:MeowOS 主屏接管时把亮度强制压回用户设置值(display.brightness,经
* meow_settings_brightness_clamped() —— 下限 brightness_min 默认 1、上限 100),
* 覆盖 HibyOS 播放器写入 sysfs 的背光下限(16/25)。仅应在「MeowOS 真正接管画面」
* (播放器已死、主屏常驻,即 run_menu 的 had_player==0)时调用;播放器会话期间的
* 覆盖菜单(had_player==1)不去抢亮度——尊重播放器背光(§红线)。
* M2.86:设置未读到(meow_settings_loaded()==0,S70 早启动 /usr/data 未就绪)时不盲目写 100 ——
* 挂起 meow_brightness_pending,待设置就绪后由 settings_load()(run_menu 每 2s 重试)补应用。 */
void apply_user_brightness(void)
{
if (!meow_settings_loaded()) {
if (!meow_brightness_pending)
logmsg("apply user brightness: settings unloaded, defer (not forcing 100)");
meow_brightness_pending = 1;
return;
}
int v = meow_settings_brightness_clamped();
if (v <= 0) v = 60; /* 防御:clamp 后不可能 ≤0,仅兜底 */
write_brightness(v, "apply_user_brightness");
g_sys.brightness = v;
meow_brightness_pending = 0;
logmsg("apply user brightness (MeowOS takeover) -> %d", v);
}
/* ---- backlight save/restore ---- */
int read_brightness(void)
{
int fd = open(BACKLIGHT, O_RDONLY);
if (fd < 0) return -1;
char buf[16];
int n = read(fd, buf, sizeof buf - 1);
close(fd);
if (n <= 0) return -1;
buf[n] = 0;
return atoi(buf);
}
static void write_file(const char *path, const char *val)
{
int fd = open(path, O_WRONLY);
if (fd < 0) return;
int l = strlen(val);
if (write(fd, val, l) < 0)
logmsg("write %s <- %s: %s", path, val, strerror(errno));
close(fd);
}
void write_brightness(int val, const char *src)
{
/* 亮度幽灵排查(2026-09-01:用户报告插耳机瞬间亮度自己跳到 raw 上限,写者未知):
* 每次写背光都留值+调用源线索,下次「亮度自己跳」可直接定位写者。 */
char buf[8];
int l = snprintf(buf, sizeof buf, "%d\n", val);
int fd = open(BACKLIGHT, O_WRONLY);
if (fd < 0) { logmsg("backlight <- %d (src=%s) open fail: %s", val, src, strerror(errno)); return; }
if (write(fd, buf, l) < 0) logmsg("backlight <- %d (src=%s): %s", val, src, strerror(errno));
else logmsg("backlight <- %d (src=%s)", val, src);
close(fd);
}
/* Bring the panel up for the menu, but ONLY when it is actually dark:
* brightness 0 (the player's own screen-off/standby writes brightness 0
* then FBIOBLANK(4); on this device bl_power stays 0, so brightness==0 is
* the reliable indicator — keep the bl_power check as a belt-and-suspenders
* for other states). A normal brightness is left completely untouched so
* the menu never yanks the brightness up (Bug A).
*
* CRITICAL (2026-08-28 hotfix): we NEVER touch FBIOBLANK here — the panel
* blank state belongs to the player's display state machine. fb_open()
* already unblanks for the menu (the menu must be visible); forcibly
* unblanking while the player thinks the screen is blanked leaves the
* player's state machine inconsistent (it stops drawing, UI freezes —
* this is the Bug B keeper deadlock, do not reintroduce). */
void ensure_backlight(void)
{
int cur = read_brightness();
int blp = read_file_int(BACKLIGHT_POWER);
if (cur > 0 && blp <= 0) {
logmsg("backlight: screen on (%d), leave untouched", cur);
return;
}
int target = (saved_brightness > 0) ? saved_brightness : 60;
logmsg("backlight off (cur=%d bl_power=%d) -> %d", cur, blp, target);
if (cur <= 0) write_brightness(target, "ensure_backlight");
if (blp > 0) write_file(BACKLIGHT_POWER, "0\n");
}
/* Restore the backlight after the player resumes (app exit / SIGTERM).
* Minimal duty after the 2026-08-28 hotfix:
* - if the menu opened while the player had blanked the panel (screen
* timeout), re-blank it (brightness 0 + FBIOBLANK(4)) so the physical
* panel matches the player's display state machine — no frozen frame,
* and the player still owns the blank state;
* - otherwise only write brightness back when it reads 0, and never
* unblank (unblanking behind the player's back wedges its display state
* machine — see ensure_backlight). A normal brightness is left
* completely untouched (Bug A: no forced brightness raise). */
void restore_backlight(void)
{
if (menu_opened_blank) {
logmsg("restore: panel was blanked at menu open, re-blank (0 + FBIOBLANK 4)");
write_brightness(0, "restore_backlight(re-blank)");
int fbfd = open(FB_DEV, O_RDWR);
if (fbfd >= 0) { ioctl(fbfd, FBIOBLANK, 4); close(fbfd); }
menu_opened_blank = 0;
return;
}
int cur = read_brightness();
int blp = read_file_int(BACKLIGHT_POWER);
if (cur <= 0 || blp > 0) {
int target = (saved_brightness > 0) ? saved_brightness : 60;
logmsg("restore backlight (cur=%d bl_power=%d) -> %d (saved=%d)",
cur, blp, target, saved_brightness);
if (cur <= 0) write_brightness(target, "restore_backlight");
if (blp > 0) write_file(BACKLIGHT_POWER, "0\n");
}
}