主要卡在以下两个测试用例:

  1. android.display.cts.DisplayEventTest#testDisplayStateChangedEvent
  2. android.display.cts.VirtualDisplayTest#testSetSurface_powerGroupOff_doesNotTurnOnDisplay

这两个测试会调用类似 input keyevent KEYCODE_POWER 的命令来锁定屏幕。而锁定屏幕又会触发内核的休眠模式。查看 cat /sys/power/statemem_sleep

$ cat /sys/power/state
freeze mem disk
$ cat /sys/power/mem_sleep
s2idle [deep]

可以看到有三种低功耗状态:

  1. freeze:冻结,但还处于 D0
  2. mem:关闭除内存外的电源,进入 S3
  3. disk:将状态写入磁盘,进入 S4

mem 又分为两种:

  1. s2idle:一种新的休眠,比 deep 能更快唤醒
  2. deep:传统的 S3,会断开除内存外的电源,导致adb 断开;[ ] 表明这是默认值

一开始怀疑是因为 ACPI 表配置错误,导致屏幕关闭时应该进入 s2idle,但错误进入 deep 状态,导致测试用例无法继续执行唤醒屏幕操作。将 s2idle 设置为默认值:

$ echo s2idle > /sys/power/mem_sleep

再次运行 CtsDisplayTestCases 测试模块,仍然卡在上述测试用例中。直接在终端中模拟锁屏:

$ input keyevent KEYCODE_POWER

此时虽然不会进入 S3 状态,但 adb 仍然断开,串行终端仍然断联。

为了强制不让系统进入休眠状态,使用内核接口 wake_lock 加锁:

$ echo "my_app_lock" > /sys/power/wake_lock
$ cat /sys/power/wake_lock
my_app_lock

再次运行 CtsDisplayTestCases 测试模块,终于可以跑完整个模块。如果又返回去去掉锁,则会复现问题:

$ echo "my_app_lock" > /sys/power/wake_unlock
$ cat /sys/power/wake_lock

所以问题就是锁屏后立刻进入休眠状态导致测试无法继续。

但手动设置屏幕的电源并不会进入 S3 状态,所以是锁屏才会触发休眠???

### 关闭屏幕电源
$ cmd display power-off 0
### 复位屏幕电源
$ cmd display power-reset 0

AI 提示可以修改 frameworks/base/core/res/res/values/config.xml 中的配置项目:

<bool name="config_powerDecoupleAutoSuspendModeFromDisplay">true</bool>
<bool name="config_dreamsSupported">true</bool>
<bool name="config_dreamsEnabledByDefault">true</bool>

将锁屏和休眠解耦。但因为需要重新编译,没有尝试。

更多推荐