fix(launcher,lock): §310 M6.7 锁屏页自睡——空闲超时自动灭屏(294 遗留补)
背景:锁屏页(run_lock_screen)此前常亮不灭屏——用户停在锁屏页不操作,屏幕一直亮着耗电。
M6.6 上机后用户反馈,补 294 遗留项「锁屏页未做空闲超时自动息屏」。
实现(/usr/bin 只读,待 M6.7 固件打包,fw_content.conf 未动):
- run_lock_screen 循环加空闲跟踪(last_act)+ 自睡状态(asleep):
① 阈值 = overlay_lock_idle_off_sec(screen_off_timeout) = min(系统 screen_off_timeout, 30s)。
系统未设/设 0(常亮)/超 30 → 锁屏页封顶 30s(锁屏页不应常亮耗电);系统设更短 → 尊重更短。
② 活跃态空闲超阈值 → meow_panel_off()(与息屏路径一致:panel 模式 FBIOBLANK 4 挂起 goodix /
black 模式仅背光 0)+ asleep=1 —— 锁态保持,仍留在锁屏循环(=「锁屏页自己也会睡」)。
③ asleep 后电源键按下边沿 或 触摸活动 → meow_panel_on() + lk_draw 重画锁屏页(本循环唤醒链
回锁),输入活动(任意按键 change / 触摸)都重置 last_act。
④ 音量键本页不动,仅计入输入活动重置计时;自睡期面板已关,不重绘(唤醒时统一重画)。
- EVIOCGRAB 与灭屏交互(核对结论):灭屏期 grab **保持**(tfd 不关)。panel 模式 FBIOBLANK 4
挂起 goodix → 灭屏期无触摸事件,唤醒只走电源键;black 模式触摸仍活动且被抓取者(launcher)独占
→ 唤醒第一下触摸进锁屏(不穿透 App、不被吞——被锁屏作为活动消费,可能命中 PIN 键)。唤醒后
FBIOBLANK 0 + grab 仍在,全程无穿透。
- App 前台叠加锁屏(run_app_lock_overlay)期间 App 的 /tmp/meow_notif_active 标记在整个自睡/
唤醒周期保持(仅锁屏退出才 unlink),故媒体保活 App 自睡期仍被 present 抑制,不覆盖锁屏。
overlay_gate.h 增 overlay_lock_idle_off_sec / overlay_lock_should_sleep / overlay_lock_wake_now
(纯决策,可单测)。test_overlay_gate.c 扩展 S4(12 断言:阈值 tradeoff / 超时灭屏 / 唤醒回锁屏 /
屏幕关不重睡)。launcher 全量宿主回归 + SDK 叠加/状态栏/输入回归全 PASS;mipsel 交叉 -Wall -Wextra
0 warning。md5 42b6633afde37035585fc36b074a73c6(待 M6.7 固件打包,不部署)。
This commit is contained in:
1 parent
cf8b0da3bd
commit
986e3814bc
4 files changed
+97
-13
No files matched your search
@@ -164,6 +164,15 @@ int run_lock_screen(void)
|
||||
int unlocked = 0;
|
||||
unsigned long long entry_ms = now_ms();
|
||||
int covered_once = 0; /* §310 问题2-②:标记节流窗后重铺一次全屏底,盖掉 App 残帧 */
|
||||
/* §310 M6.7 锁屏页自睡(294 遗留):锁屏页不应常亮耗电。
|
||||
* 阈值 = min(系统 screen_off_timeout, 30s):系统未设/设 0(常亮)/超 30 → 锁屏页封顶 30s,
|
||||
* 系统设更短则尊重更短。超阈值 → meow_panel_off()(与息屏路径一致)+ asleep=1(锁态保持,
|
||||
* 仍留在锁屏循环);asleep 后电源键按下边沿/触摸活动 → meow_panel_on() + 重画锁屏页回锁。 */
|
||||
int lk_off_sec = overlay_lock_idle_off_sec(screen_off_timeout);
|
||||
unsigned long long lk_off_ms = (unsigned long long)lk_off_sec * 1000;
|
||||
unsigned long long last_act = now_ms();
|
||||
int asleep = 0;
|
||||
int prev_pwr_down = 0;
|
||||
for (;;) {
|
||||
time_t now = time(NULL);
|
||||
int redraw = 0;
|
||||
@@ -179,7 +188,7 @@ int run_lock_screen(void)
|
||||
/* §310 问题2-②:媒体保活 App 不冻结、SDK present 抑制有 ≤200ms 标记节流窗——锁屏首扑后
|
||||
* App 仍可能再进 1-2 帧(部分脏区盖到锁屏上)。等标记窗过后(≥300ms)重铺一次全屏不透明底
|
||||
* 盖掉 App 残帧;App 此后被抑制不再上屏,锁屏稳定遮盖(真机「App 控件盖到锁屏上」)。 */
|
||||
if (!covered_once && now_ms() - entry_ms >= OVERLAY_LOCK_COVER_MS) {
|
||||
if (!covered_once && !asleep && now_ms() - entry_ms >= OVERLAY_LOCK_COVER_MS) {
|
||||
covered_once = 1;
|
||||
logmsg("lock: re-cover full opaque after marker window (app stave suppressed)");
|
||||
lk_draw(entered, status, lock_until);
|
||||
@@ -212,23 +221,58 @@ int run_lock_screen(void)
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
/* 电源键=息屏(允许再睡);音量键本页不动 */
|
||||
if (kp_power.ok) {
|
||||
kp_poll(&kp_power, NULL, NULL);
|
||||
if (kp_is_down(&kp_power, KEY_POWER)) {
|
||||
logmsg("lock: power key -> screen off (stay locked)");
|
||||
meow_panel_off();
|
||||
break; /* return 0 */
|
||||
/* 电源键/音量键轮询 + 输入活动检测(重置自睡计时) + 自睡/唤醒切换。
|
||||
* 活跃态:电源键按下 → 息屏并退出锁屏(回 App/主屏,下次唤醒再锁)——沿用原语义;
|
||||
* 空闲超 lk_off_ms → 自睡(asleep=1,锁态保持,仍在本循环)。
|
||||
* asleep:电源键按下边沿 / 触摸活动 → meow_panel_on + 重画锁屏页(本循环唤醒链回锁)。
|
||||
* 音量键本页不动(仅视为输入活动,重置计时)。 */
|
||||
{
|
||||
int chg = 0;
|
||||
if (kp_power.ok) chg |= kp_poll(&kp_power, NULL, NULL);
|
||||
chg |= kp_poll(&kp_keys, NULL, NULL);
|
||||
if (chg) last_act = now_ms(); /* 任意按键活动重置自睡计时 */
|
||||
int pwr_down = kp_is_down(&kp_power, KEY_POWER);
|
||||
int pwr_edge = pwr_down && !prev_pwr_down; /* 按下边沿 */
|
||||
prev_pwr_down = pwr_down;
|
||||
|
||||
if (asleep) {
|
||||
int touch_ready = (tfd >= 0);
|
||||
if (touch_ready) {
|
||||
struct pollfd tp = { tfd, POLLIN, 0 };
|
||||
if (poll(&tp, 1, 0) <= 0) touch_ready = 0;
|
||||
}
|
||||
if (pwr_edge || touch_ready) {
|
||||
logmsg("lock: wake from self-sleep (power=%d touch=%d)", pwr_edge, touch_ready);
|
||||
meow_panel_on();
|
||||
asleep = 0;
|
||||
last_act = now_ms();
|
||||
lk_draw(entered, status, lock_until); /* 重画锁屏页回锁 */
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* 电源键=息屏(允许再睡;下次唤醒按 lck_wake_should_lock 再锁) */
|
||||
if (pwr_down) {
|
||||
logmsg("lock: power key -> screen off (stay locked)");
|
||||
meow_panel_off();
|
||||
break; /* return 0 */
|
||||
}
|
||||
/* 空闲超时 → 自睡(锁态保持,仍在锁屏循环,唤醒回锁屏页) */
|
||||
if (meow_screen_on && now_ms() - last_act >= lk_off_ms) {
|
||||
logmsg("lock: idle %ds -> self screen off (stay locked)", lk_off_sec);
|
||||
meow_panel_off();
|
||||
asleep = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
kp_poll(&kp_keys, NULL, NULL);
|
||||
(void)kp_is_down(&kp_keys, KEY_VOLUMEDOWN);
|
||||
(void)kp_is_down(&kp_keys, KEY_VOLUMEUP);
|
||||
|
||||
/* 触摸:只认键盘 tap(滑动手势忽略:不左缘返回、不通知中心下拉) */
|
||||
if (tfd >= 0) {
|
||||
/* 触摸:只认键盘 tap(滑动手势忽略:不左缘返回、不通知中心下拉);触摸即输入活动,重置自睡计时 */
|
||||
if (tfd >= 0 && !asleep) {
|
||||
struct pollfd pfd = { tfd, POLLIN, 0 };
|
||||
if (poll(&pfd, 1, 0) > 0) {
|
||||
last_act = now_ms(); /* §310 M6.7:任意触摸重置自睡计时 */
|
||||
unsigned char ev[16];
|
||||
while (read(tfd, ev, sizeof ev) == (ssize_t)sizeof ev) {
|
||||
uint16_t type = *(uint16_t *)(ev + 8), code = *(uint16_t *)(ev + 10);
|
||||
@@ -290,8 +334,8 @@ int run_lock_screen(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* 整页重绘(锁屏低频交互,简单整页即可) */
|
||||
if (redraw) lk_draw(entered, status, lock_until);
|
||||
/* 整页重绘(锁屏低频交互,简单整页即可);自睡(面板已关)期间不重绘(唤醒时统一重画) */
|
||||
if (redraw && !asleep) lk_draw(entered, status, lock_until);
|
||||
usleep(POLL_MS * 1000);
|
||||
}
|
||||
done:
|
||||
|
||||
Binary file not shown.
@@ -67,4 +67,27 @@ static inline int overlay_wake_should_lock(int auto_slept, int manual_panel_off)
|
||||
return (auto_slept || manual_panel_off) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* 锁屏页自睡阈值(秒,§310 M6.7,294 遗留):min(系统 screen_off_timeout, 30s)。
|
||||
* 系统未设/设 0(常亮)/超 30 → 锁屏页封顶 30s(锁屏页不应常亮耗电);系统设更短 → 尊重更短。
|
||||
* 返回正数秒。lock_screen_ui.c 的 run_lock_screen 空闲超时用它(单测同源断言)。 */
|
||||
static inline int overlay_lock_idle_off_sec(int screen_off_timeout)
|
||||
{
|
||||
return (screen_off_timeout > 0 && screen_off_timeout < 30)
|
||||
? screen_off_timeout : 30;
|
||||
}
|
||||
|
||||
/* 锁屏页是否应自睡(§310 M6.7):屏幕亮(meow_screen_on)且在本循环 && 空闲(now-last_act) ≥ 阈值。
|
||||
* 返回 1=超时灭屏(锁态保持)。 */
|
||||
static inline int overlay_lock_should_sleep(int screen_on, unsigned long long idle_ms,
|
||||
unsigned long long off_ms)
|
||||
{
|
||||
return (screen_on && idle_ms >= off_ms) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* 锁屏自睡后应否唤醒回锁屏页:电源键按下边沿 或 触摸活动。返回 1=唤醒(meow_panel_on+重画锁屏)。 */
|
||||
static inline int overlay_lock_wake_now(int pwr_edge, int touch_ready)
|
||||
{
|
||||
return (pwr_edge || touch_ready) ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif /* MEOW_OVERLAY_GATE_H */
|
||||
@@ -15,6 +15,9 @@
|
||||
* (watchdog blank → manual_panel_off)两类唤醒都须走 lock 语义。
|
||||
* S2b 锁屏重铺盖 App 残帧 → OVERLAY_LOCK_COVER_MS:锁屏进场后重铺全屏不透明底的阈值必须
|
||||
* > SDK present 抑制标记节流窗(200ms),盖住 App 抑制窗内的残帧。
|
||||
* S4 锁屏页自睡(294 遗留) → overlay_lock_idle_off_sec():阈值 = min(系统 screen_off_timeout, 30s)
|
||||
* (0/超30→30,尊重更短);overlay_lock_should_sleep()/overlay_lock_wake_now()
|
||||
* 判定超时灭屏(锁态保持)与唤醒回锁屏。
|
||||
*
|
||||
* 编译运行(在 patch_v2/meow_launcherd 下,无其它依赖):
|
||||
* gcc -Wall -Wextra -o test_overlay_gate test_overlay_gate.c && ./test_overlay_gate
|
||||
@@ -63,6 +66,20 @@ int main(void)
|
||||
CHECK(overlay_wake_should_lock(0, 1) == 1, "S1c manual power sleep (manual) -> lock (was missing)");
|
||||
CHECK(overlay_wake_should_lock(1, 1) == 1, "S1c both -> lock");
|
||||
|
||||
/* ---- S4 锁屏页自睡(294 遗留):阈值 min(系统,30s),超时灭屏锁态保持,唤醒回锁屏 ---- */
|
||||
CHECK(overlay_lock_idle_off_sec(0) == 30, "S4 system 0 (never) -> lock caps 30s");
|
||||
CHECK(overlay_lock_idle_off_sec(-1) == 30, "S4 system absent -> lock caps 30s");
|
||||
CHECK(overlay_lock_idle_off_sec(30) == 30, "S4 system 30 -> 30");
|
||||
CHECK(overlay_lock_idle_off_sec(60) == 30, "S4 system 60 -> 30 (cap, shorter)");
|
||||
CHECK(overlay_lock_idle_off_sec(10) == 10, "S4 system 10 -> 10 (respect shorter)");
|
||||
CHECK(overlay_lock_idle_off_sec(1) == 1, "S4 system 1 -> 1 (respect shorter)");
|
||||
CHECK(overlay_lock_should_sleep(1, 30000, 30000) == 1, "S4 idle>=off & screen on -> self sleep");
|
||||
CHECK(overlay_lock_should_sleep(1, 29999, 30000) == 0, "S4 idle<off -> not yet");
|
||||
CHECK(overlay_lock_should_sleep(0, 99999, 30000) == 0, "S4 screen off -> no re-sleep");
|
||||
CHECK(overlay_lock_wake_now(1, 0) == 1, "S4 power edge -> wake to lock");
|
||||
CHECK(overlay_lock_wake_now(0, 1) == 1, "S4 touch -> wake to lock");
|
||||
CHECK(overlay_lock_wake_now(0, 0) == 0, "S4 no wake input -> stay asleep");
|
||||
|
||||
/* ---- S3 App 死亡触发主屏重绘:崩溃必须走统一退出路径 ---- */
|
||||
CHECK(lock_overlay_app_died_exit(1) == 1, "S3 app died -> unified exit path (redraw home)");
|
||||
CHECK(lock_overlay_app_died_exit(0) == 0, "S3 app alive -> normal restore");
|
||||
|
||||
Reference in new issue
Block a user