/* wd_power.h — watchdog 电源键判定(纯函数,宿主可单测,无设备/无文件系统依赖)。 * * 语义与 launcher 主屏(main_menu.c)统一: * 单击(松开时 held < power.longpress_menu_ms) → 息屏/亮屏切换; * 长按 held ≥ power.longpress_menu_ms → 写菜单请求(watchdog 让位 launcher); * 长按 held ≥ power.forceoff_ms 且菜单未被接管 → 强制关机兜底。 * 旧实现把 PWR_TOGGLE_MS 与 PWR_MENU_MS 都硬编码成 2000,导致「长按但不出菜单」的区间 * 不存在,且 App 内 2s / launcher 主屏 3s 不一致;现在两者都读 settings(缺省 3000/8000)。 * * 阈值清洗: * - 非正数 → 默认 3000 / 8000(settings 允许 0,但 0ms 阈值会让每次按下立刻出菜单,无意义); * - forceoff ≤ longpress → 抬到 longpress+1000,避免「强关先于菜单」的自相矛盾配置。 */ #ifndef WD_POWER_H #define WD_POWER_H #define WD_PWR_LONGPRESS_DEFAULT_MS 3000 #define WD_PWR_FORCEOFF_DEFAULT_MS 8000 static inline void wd_pwr_resolve_thresholds(int cfg_longpress, int cfg_forceoff, unsigned long long *longpress_ms, unsigned long long *forceoff_ms) { unsigned long long lp = (cfg_longpress > 0) ? (unsigned long long)cfg_longpress : WD_PWR_LONGPRESS_DEFAULT_MS; unsigned long long fo = (cfg_forceoff > 0) ? (unsigned long long)cfg_forceoff : WD_PWR_FORCEOFF_DEFAULT_MS; if (fo <= lp) fo = lp + 1000; *longpress_ms = lp; *forceoff_ms = fo; } /* 松开边沿的动作。bright>0=屏亮 → 息屏;否则亮屏。 * woke(按下时屏已黑,本次只唤醒)/ menu_notified(已请求菜单)→ 不再 toggle。 */ typedef enum { WD_PWR_REL_NONE = 0, WD_PWR_REL_TOGGLE_OFF, WD_PWR_REL_TOGGLE_ON } wd_pwr_release_act; static inline wd_pwr_release_act wd_pwr_release_action(int woke, int menu_notified, unsigned long long held_ms, unsigned long long longpress_ms, int bright) { if (woke || menu_notified) return WD_PWR_REL_NONE; if (held_ms >= longpress_ms) return WD_PWR_REL_NONE; /* 长按已由 tick 处理 */ return (bright > 0) ? WD_PWR_REL_TOGGLE_OFF : WD_PWR_REL_TOGGLE_ON; } /* 轮询 tick(按住中)的动作。menu_active=launcher 已接管 → 全让位。 * 强关不要求 menu_notified:launcher 未接管菜单时 8s 兜底仍须生效。 */ typedef enum { WD_PWR_TICK_NONE = 0, WD_PWR_TICK_MENU, WD_PWR_TICK_FORCEOFF } wd_pwr_tick_act; static inline wd_pwr_tick_act wd_pwr_tick_action(int menu_active, int down, int menu_notified, int force_done, unsigned long long held_ms, unsigned long long longpress_ms, unsigned long long forceoff_ms) { if (menu_active || !down) return WD_PWR_TICK_NONE; if (held_ms >= forceoff_ms && !force_done) return WD_PWR_TICK_FORCEOFF; if (held_ms >= longpress_ms && !menu_notified) return WD_PWR_TICK_MENU; return WD_PWR_TICK_NONE; } #endif /* WD_POWER_H */