For devices running Android 14-QPR1 or higher, Android supports using the
device as a USB webcam. Android devices supporting this feature are advertise
as a UVC device, which lets a wide range of USB hosts with different
operating systems (for example, Linux, macOS, Windows, and ChromeOS) use the
device's camera as a webcam. The DeviceAsWebcam
service
supports this feature to use the device as a webcam.
DeviceAsWebcam service
The DeviceAsWebcam
service in AOSP includes a preview activity
(DeviceAsWebcamPreview.java
) that lets users frame the scene. The preview
activity lets the user do the following:
Preview how the webcam feed will look on the host machine before streaming starts.
Customize the webcam feed sent to the host in the following ways:
- Selecting the camera to stream, front or back.
- Selecting the zoom level using a slider or buttons.
- Tapping a particular region of the preview to focus or remove the focus on a region.
The preview activity works with general accessibility features on Android such as TalkBack, Switch Access, and Voice Access.
Figure 1. Webcam feed being streamed to a host with preview controlling the feed.
Architecture
The architecture to support using a device as a webcam is illustrated in
Figure 2. The following describes the interaction flow of the DeviceAsWebcam
service with the rest of the Android framework:
- The user selects the USB webcam option in the Settings app.
- The Settings app sends a binder call to
system_server
through theUsbManager
class informing it thatFUNCTION_UVC
is selected. - The system server does the following:
- Informs the USB gadget HAL to retrieve the UVC gadget function through a
setUsbFunctions
HAL interface call. - Informs the USB gadget HAL to configure the UVC gadget driver using ConfigFs.
- Informs the USB gadget HAL to retrieve the UVC gadget function through a
- Upon receiving a callback from the gadget HAL,
system_server
sends a broadcast to the framework to be picked up by theDeviceAsWebcam
service. - The USB gadget driver starts the webcam stream upon receiving configuration
commands from the host through V4L2 nodes at
/dev/video*
.
Figure 2. DeviceAsWebcam architecture.
Implementation
This section describes how to support using an Android device as a webcam.
Kernel support
For Android 14 or higher, the Generic Kernel Image (GKI) enables the UVC gadget driver by default (see details in AOSP patch).
Support UVC in Gadget HAL
Starting with Android 14, the UVC function is included in the
GadgetFunction.aidl
HAL interface. For the Gadget HAL, the UVC
gadget is mounted to ConfigFS in the same way as other ConfigFS functions such
as MTP or ADB.
To implement the Gadget HAL, make modifications to mount the UVC function to ConfigFS. The following is an example snippet of a Gadget HAL implementation supporting the UVC function:
UsbGadget::setCurrentUsbFunctions(long functions) {
...
// Existing functions
if ((functions & GadgetFunction::MTP) != 0) {
...
linkFunction("ffs.mtp"); // Mount to ConfigFS
...
}
...
// UVC function follows the same pattern!
if ((functions & GadgetFunction::UVC) != 0) {
...
linkFunction("uvc.0"); // Mount to ConfigFS
...
}
...
}
When the device is acting as a webcam, ensure the USB gadget HAL is advertising the proper VID/PID combinations.
Because all UVC logic is in either vendor init or in the DeviceAsWebcam
service, no UVC specific logic, other than symlinking the UVC function to
ConfigFS, is required in the Gadget HAL.
For further guidance on implementation, see the following sample code in AOSP:
Set up ConfigFS with UVC configurations
To inform the UVC gadget driver which formats, sizes, and frame rates are supported by the Android webcam, set up ConfigFS with UVC configurations. For more information, see the upstream Linux documentation on the ConfigFS UVC gadget ABI.
The following is an example of how vendor init can set up the UVC gadget driver (code snippet in AOSP):
# uvc function
mkdir /configfs_path/functions/uvc.0
write /configfs_path/functions/uvc.0/function_name "Android Webcam"
write /configfs_path/functions/uvc.0/streaming_maxpacket 3072
# setup control params
mkdir /configfs_path/functions/uvc.0/control/header/h
symlink /configfs_path/functions/uvc.0/control/header/h \
/configfs_path/functions/uvc.0/control/class/fs/h
symlink /configfs_path/functions/uvc.0/control/header/h \
/configfs_path/functions/uvc.0/control/class/ss/h
# advertise 1080p resolution for webcam encoded as mjpeg
mkdir /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/wHeight 1080
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/wWidth 1920
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxVideoFrameBufferSize 4147200
# advertise 30 fps support for 1080p.
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwDefaultFrameInterval 333333
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwFrameInterval "333333"
# setup streaming params
mkdir /configfs_path/functions/uvc.0/streaming/header/h
symlink /configfs_path/functions/uvc.0/streaming/mjpeg/m \
/configfs_path/functions/uvc.0/streaming/header/h/m
symlink /configfs_path/functions/uvc.0/streaming/header/h \
/configfs_path/functions/uvc.0/streaming/class/fs/h
symlink /configfs_path/functions/uvc.0/streaming/header/h \
/configfs_path/functions/uvc.0/streaming/class/hs/h
symlink /configfs_path/functions/uvc.0/streaming/header/h \
/config/usb_gadget/g1/functions/uvc.0/streaming/class/ss/h
# ...
This snippet sets up the UVC gadget driver to advertise a 1080p MJPEG stream at 30 fps. These capabilities are communicated to the USB host when it queries supported resolutions and frame rates.
The following are general guidelines for selecting the configurations the webcam advertises:
- The two stream formats supported by the
DeviceAsWebcam
service are MJPEG and uncompressed YUYV. - USB 2.0 supports 480 Mbps (60 MBps) transfer of data. This
means that at 30 fps, each frame must have a maximum size of 2 MB;
and at 60 fps, a maximum size of 1 MB.
- Uncompressed streams (YUYV): At 30 fps, the maximum supported frame size is 720p because YUYV is 2 bytes per pixel.
- Compressed MJPEG streams: Assuming a 1:10 compression ratio from YUV, USB 2.0 can support 4K (1.18 MB per frame).
- Primary front and back camera devices must support all the frame sizes that are advertised. This is because the user can switch between camera IDs using the preview UI. For MJPEG streams, we recommend vendors advertise 480p (640 x 480), 720p (1280 x 820) and 1080p (1920 x 1080) frame sizes because these are sizes commonly used by host apps.
- Primary front and back camera devices must support all frame rates that are advertised. We strongly recommend vendors support 30 fps.
For an example of adding webcam stream configurations (ConfigFS), see AOSP sample patch.
Enable webcam in the build
To enable the DeviceAsWebcam
service, you must set the ro.usb.uvc.enabled
system property to true
in the device.mk
file.
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
When this system property is enabled, a Webcam option appears in the Settings app under USB preferences as shown in Figure 3. When the option is selected, the Android device appears as a USB webcam to the host device.
Figure 3. USB preferences in Settings app.
You can also set the device to the USB webcam function through ADB using this command:
adb shell svc usb setFunctions uvc
Consider power and thermal concerns
Webcam operations means that a device's camera might be on for multiple hours a day, so we recommend taking measures to ensure that the power consumption and thermal of the device remains under certain limits. The following are recommended solutions to keep power consumption under limits:
- For better power performance from the camera HAL, enable
STREAM_USE_CASE_VIDEO_CALL
in theDeviceAsWebcam
service. If power is a concern even with
STREAM_USE_CASE_VIDEO_CALL
enabled, theDeviceAsWebcam
service provides an option to further decrease power consumption by using physical streams. You can use runtime resource overlays (RROs) to specify which physical camera to use. Physical streams significantly drop the video quality and lead to a confusing UX, so use this solution only as a last resort. OptimizingSTREAM_USE_CASE_VIDEO_CALL
is the preferred solution to power concerns. For more information on RROs supported by theDeviceAsWebcam
service, see readme.md.The following is an example of an RRO set up to use physical camera ID 3 instead of logical camera ID 0. For an example in AOSP, see DeviceAsWebcamRaven.
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
Verification
To test your implementation of the DeviceAsWebcam
service on your device, use
the following tests:
- CTS verifier test webcam: Test that formats, sizes, and frame rates are supported by the device.
- Manual tests: Test that the webcam feature works with a variety of host apps on a variety of host operating systems.
Known issues
The following are known issues for the DeviceAsWebcam
service:
The UVC gadget driver's stream sometimes flickers and shows what looks like corrupted frames. This issue has been fixed and merged upstream and in GKI.
Android devices in webcam mode don't work with USB 3.0+ cables on macOS hosts because of a bug with Apple's UVC driver.