为什么你插上 USB 摄像头,Android 原生 ROM 却假装没看见?

1. 故事开场:一个「插了却看不见」的 BUG

插上 UVC 摄像头 → dmesg 里出现 /dev/video2  
Camera2 打开 id="2" → crash:CAMERA_DISCONNECTED  

问题:内核都识别了,为何 Camera2 就是找不到?
答案:原生 ROM 默认把 EXTERNAL 开关关掉了 —— 它根本没把 UVC 设备注册到 CameraService。


2. 两条路线对比:内置相机 vs USB 摄像头

维度内置相机USB 摄像头(UVC)
物理接口MIPI CSI-2USB 2.0/3.0
内核驱动camera sensor driveruvcvideo
HAL 枚举编译时固定声明需动态注册
默认实例back/0 front/1默认无 external/2
3A/HDR/防抖完整 pipeline
功耗可控未知 + 500 mA 供电
安全模型用户可见可「偷窥」
原生 ROM必开默认关

3. 主流程:一次「预览」到底走了多少层?

左:内置相机(永远开启)
右:USB 相机(被编译开关屏蔽)

App CameraManager CameraService HAL Kernel 内置相机(默认开启) openCamera("0") connect("0") open(back/0) /dev/video0 buffer ok onOpened USB 相机(原生 ROM 关) openCamera("2") connect("2") external/2? 404 NOT FOUND CAMERA_DISCONNECTED App CameraManager CameraService HAL Kernel

4. 架构图:到底「关」在了哪一层?

%% 架构层级图
graph TD
    A[App] -->|Camera2/CameraX| B(CameraService)
    B --> |HIDL/AIDL| C[CameraProvider@2.6]
    C -->|legacy/0| D[CameraModule (内置)]
    C -->|external/0| E[ExternalCameraProvider]
    E -.->|libuvc| F[uvcvideo /dev/video2]
    D -->|ioctl| G[sensor /dev/video0]

    style E fill:#f9f,stroke:#333
    style F fill:#f9f,stroke:#333
    click E "https://source.android.com/docs/core/camera/external-camera" _blank

关键
ExternalCameraProviderAOSP 源码里默认不编进 system.img
手机厂 device.mk 里没加,导致 Provider 不注册 → CameraService 看不到任何 EXTERNAL 实例


5. 源码级证据:开关在哪里?

文件作用默认状态
device/google/xxx/device.mk是否把 external-service 编进镜像注释掉
external_camera_config.xml声明支持分辨率/帧率不存在
manifest.xml注册 <instance>external/0</instance>
SELinux policy hal_camera_provider_external.te允许 Provider 运行未导入

只要 1 个编译变量就能打开:

# 在 device.mk 里解开即可
PRODUCT_PACKAGES += android.hardware.camera.provider@2.6-external-service
PRODUCT_COPY_FILES += $(LOCAL_PATH)/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml

6. 打开之后的效果

adb shell dumpsys media.camera | grep EXTERNAL
  Device 2 maps to "external/0"

getCameraIdList() 返回 [0, 1, 2]FEATURE_CAMERA_EXTERNAL=trueCamera2 无需任何改动即可预览


7. 结语:技术不是做不到,只是产品不需要

  • 原生 AOSP 把 EXTERNAL 做成「编译时可选」→ 手机厂为了功耗、安全、CTS 成本 一律不选
  • 于是 99% 零售机 内核可见 / framework 不可见,才会出现「插了 USB 摄像头却报 CAMERA_DISCONNECTED」的诡异现象。
  • 真想玩,就 自己编译 AOSP 把那两行 makefile 解开,或者 直接绕过 Camera2 用 UVCCamera —— 这才是民间正道。

8. 一张图带走全部知识点

在这里插入图片描述

复制→渲染→收藏,下次再有人问你“为什么 openCamera("2") 崩了”,直接把这篇甩给他。

参考文章

外接 USB 摄像头
在这里插入图片描述


以我之思,借AI之力

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值