4. dumpsys工具使用
做Camera HAL层调试,有个工具你绕不开——dumpsys。我个人习惯,遇到问题第一件事就是先抓一份dumpsys log看看。为什么?因为它能告诉你系统当前对Camera的理解是什么,而不是你以为的什么。
说白了,dumpsys就是Android系统的一个“快照”。你执行dumpsys media.camera,系统会把CameraService内部的状态一股脑倒出来。这些信息对定位问题太关键了。
4.1 基础命令与输出结构
先看最基础的用法:
adb shell dumpsys media.camera
这条命令会输出所有Camera相关的信息。输出内容大致分三块:
- Camera特性列表——设备支持什么,不支持什么
- Stream配置——当前数据流怎么走的
- Session状态——Camera会话活着还是死了
嗯,这里要注意:输出内容可能很长。我建议你先把结果重定向到文件里慢慢看:
adb shell dumpsys media.camera > camera_dump.txt
4.2 获取Camera特性列表
Camera特性列表,说白了就是你的摄像头能干什么、不能干什么。比如支持多少分辨率、有没有闪光灯、能不能做HDR。
执行命令后,你会看到类似这样的输出:
Camera 0 (back) characteristics:
android.info.supportedHardwareLevel: FULL
android.sensor.info.pixelArraySize: 4032x3024
android.flash.info.available: true
android.control.aeAvailableModes: [OFF, ON, AUTO]
android.scaler.availableStreamConfigurations:
[WIDTH, HEIGHT, FORMAT, INPUT/OUTPUT]
1920x1080, YUV_420_888, OUTPUT
1280x720, YUV_420_888, OUTPUT
640x480, YUV_420_888, OUTPUT
...
我在项目中遇到过好几次,明明硬件支持4K,但上层就是拿不到。一查dumpsys,发现是HAL层上报的stream configuration里根本没写4K分辨率。这种问题,不看dumpsys根本想不到。
supportedHardwareLevel:LEGACY、LIMITED、FULL、LEVEL_3。级别越高,功能越全。availableStreamConfigurations:所有支持的输出格式和分辨率。aeAvailableModes:自动曝光模式,没有AUTO的话连基本拍照都成问题。
4.3 查看Stream配置
Stream配置,就是当前Camera数据流的“管道”是怎么搭的。你想想看,上层要一个预览流,底层要一个拍照流,中间怎么协调?dumpsys能把这些管道清清楚楚列出来。
输出示例:
Active Camera Streams:
Stream 0: 1920x1080, FORMAT_YUV_420_888, direction: OUTPUT
Stream 1: 640x480, FORMAT_JPEG, direction: OUTPUT
Stream 2: 1280x720, FORMAT_RAW10, direction: OUTPUT
Camera 0 Session 0:
State: ACTIVE
Repeating request enabled: true
Current request ID: 47
Last frame number: 1023
这里有个坑,我曾经踩过:上层开了三个stream,但HAL层只支持两个并发。结果就是第三个stream一直拿不到数据,预览卡成PPT。dumpsys里一看,stream配置确实有三个,但session状态一直在报错。嗯,这种问题,光看logcat很难定位,dumpsys直接告诉你真相。
INPUT方向的流,说明这个Camera支持输入(比如用于视频编码)。很多设备不支持,别被文档忽悠了。
4.4 分析Session状态
Session状态,就是Camera会话当前是死是活。一个正常的Session应该是ACTIVE状态。如果看到ERROR或者CLOSED,那问题就大了。
常见状态:
| 状态 | 含义 | 常见原因 |
|---|---|---|
| ACTIVE | 会话正常运行 | 正常 |
| CONFIGURING | 正在配置流 | 刚打开Camera或切换配置 |
| ERROR | 会话出错 | HAL崩溃、资源不足、配置冲突 |
| CLOSED | 会话已关闭 | 应用释放了Camera |
为什么会看到ERROR?我遇到过最典型的情况:HAL层在配置stream时,发现某个分辨率不支持,直接返回错误。但上层应用没处理好这个错误,导致session一直卡在ERROR状态。dumpsys里一看,session状态是ERROR,再往下翻,能看到具体的错误码。
- 先看session状态是不是ACTIVE。不是的话,问题大概率出在配置阶段。
- 再看repeating request是否开启。没开启的话,预览流不会持续输出。
- 最后看current request ID和last frame number。如果frame number一直不变,说明数据流卡住了。
4.5 实战:用dumpsys定位预览黑屏问题
我记得有一次,客户反馈预览黑屏。我第一反应就是抓dumpsys。结果一看:
Camera 0 Session 0:
State: ACTIVE
Repeating request enabled: true
Current request ID: 0
Last frame number: 0
session是ACTIVE,repeating request也开了,但request ID和frame number都是0。这说明上层发了请求,但HAL层根本没处理。再往下看stream配置:
Stream 0: 1920x1080, FORMAT_YUV_420_888, direction: OUTPUT
Buffer count: 4
Current buffer: null
Current buffer是null!这意味着HAL层没有把buffer填好。问题就出在HAL层的buffer管理上。后来查出来是HAL里一个指针没初始化,导致buffer一直没提交。
你看,一个dumpsys命令,直接定位到问题根因。这就是为什么我总说,dumpsys是Camera调试的第一把刀。
- dumpsys media.camera 能拿到Camera的全量状态信息
- 特性列表告诉你硬件能力,stream配置告诉你数据流,session状态告诉你会话健康度
- 遇到问题,先抓dumpsys,再分析,别盲目改代码
好了,dumpsys的基本用法就这些。记住,它不是你唯一的工具,但是你最常用的工具。下次遇到Camera问题,别急着改代码,先跑一遍dumpsys看看。