Project: /_project.yaml Book: /_book.yaml # External USB Cameras The Android platform supports the use of plug-and-play USB cameras (i.e. webcams) using the standard [Android Camera2 API](https://developer.android.com/reference/android/hardware/camera2/package-summary.html){: .external} and the camera [HIDL](/reference/hidl/android/hardware/camera/provider/2.4/ICameraProvider){: .external} interface. Webcams generally support [USB video class (UVC)](https://en.wikipedia.org/wiki/USB_video_device_class){: .external} drivers and on Linux the standard [Video4Linux (V4L)](https://en.wikipedia.org/wiki/Video4Linux){: .external} driver is used to control UVC cameras. With support for webcams, devices can be used in lightweight use cases such as video chatting and photo kiosks. This feature does not serve as a replacement for typical internal camera HALs on Android phones and is not designed to support performance-intensive, complex tasks involving high-resolution and high-speed streaming, AR, and manual ISP/sensor/lens control. The new USB camera HAL process is part of the external camera provider that listens to USB device availability and enumerates external camera devices accordingly. The process has permissions and an SE policy similar to the built-in camera HAL process. Third party webcam applications that communicate directly with USB devices require the same camera permissions to access UVC devices as with any regular camera application. ## Examples and sources For more information on how to implement USB cameras, see an external camera provider reference implementation at [`ExternalCameraProvider`](https://android.googlesource.com/platform/hardware/interfaces/+/master/camera/provider/2.4/default/CameraProvider.cpp){: .external}. The external camera device and session implementations are included in [`ExternalCameraDevice`](https://android.googlesource.com/platform/hardware/interfaces/+/master/camera/device/3.4/default/ExternalCameraDevice.cpp){: .external} and [`ExternalCameraDeviceSession`](https://android.googlesource.com/platform/hardware/interfaces/+/master/camera/device/3.4/default/ExternalCameraDeviceSession.cpp){: .external}. The Java client API includes a new [`EXTERNAL`](https://developer.android.com/reference/android/hardware/camera2/CameraMetadata?authuser=3#INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL){: .external} hardware level. ## Implementation The implementation must support the [`android.hardware.usb.host`](https://developer.android.com/guide/topics/connectivity/usb/host){: .external} system feature. Kernel support for UVC devices must also be enabled. You can enable this by adding the following to the respective kernel `deconfig` files. ``` +CONFIG_USB_VIDEO_CLASS=y +CONFIG_MEDIA_USB_SUPPORT=y ``` Note: Make sure you also have this [patch](https://patchwork.kernel.org/patch/6874491/){: .external} for uvcvideo. To enable the external camera provider in the respective device build, which adds the necessary SELinux permissions, external camera configuration, and external camera provider dependency, complete the following steps: + Add external camera config file and external camera library to `device.mk` ``` +PRODUCT_PACKAGES += android.hardware.camera.provider@2.4-impl +PRODUCT_PACKAGES += android.hardware.camera.provider@2.4-external-service +PRODUCT_COPY_FILES += \ +device/manufacturerX/productY/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml ``` + Add external camera provider name to device Treble HAL manifest ``` android.hardware.camera.provider passthrough 2.4 ICameraProvider legacy/0 + external/0 ``` + (Optional) If the device runs in Treble passthrough mode, update `sepolicy` so `cameraserver` can access UVC camera ``` +# for external camera +allow cameraserver device:dir r_dir_perms; +allow cameraserver video_device:dir r_dir_perms; +allow cameraserver video_device:chr_file rw_file_perms; ``` Here is an example of `external_camera_config.xml` (copyright lines omitted) ``` 0 1 ``` ## Customization You can enhance the Android camera either through general customization options or device-specific optimizations. ### General customizations You can customize the external camera provider by modifying the `external_camera_config.xml` file. Specifically, clients can customize the following parameters: + Excluding video nodes of internal camera(s) + Supported image size and frame rate upper bound + Number of inflight buffers (jank vs memory tradeoff) In addition to these parameters, you can add your own parameters or develop your own configurations. ### Device-specific optimizations You can also improve performance by adding device-specific optimizations. #### Buffer copy/scaling and JPEG decode/encode Generic implementations use CPU (libyuv/libjpeg) but you can replace this with device-specific optimizations. #### HAL output format Generic implementations use the following output formats: + YUV_420_888 for video IMPLEMENTATION_DEFINED buffers. + YV12 for all other IMPLEMENTATION_DEFINED buffers. To improve performance, you can replace output formats with device-specific efficient formats. You can also support additional formats in a customized implementation ## Validation Devices with external camera support must pass [camera CTS](/compatibility/cts/camera-hal#cts_tests). The external USB webcam must remain plugged in the specific device during the entire test run, otherwise some test cases will fail. Note: `media_profiles` entries are not available for external USB webcams, so [camcorder profiles](https://developer.android.com/reference/android/media/CamcorderProfile){: .external} are absent.