Vendor extensions

CameraX provides an API for accessing effects—bokeh, HDR, and others—that have been implemented by phone manufacturers for specific phones. For a device to support vendor extensions, all of the following must be true:

  • The effect has library support from the device OEM.
  • The OEM library is installed on the current device.
  • The OEM library reports the device as supporting the extension.
  • The device has a version of the operating system that the library requires.

You can enable an extension preferentially: if the extension is both supported by and physically on the device, then it will be enabled; otherwise, it will degrade gracefully.

Vendors aren't required to provide an implementation for every effect and feature. Any capability without a vendor-provided implementation defaults to the CameraX implementation. The default implementation reports that the capability is unavailable and skips enabling it.

Extensions architecture

The following image shows the architecture for extensions with CameraX.

Figure 1. CameraX architecture for extensions

Extensions are separate from the Camera2 core of CameraX. In the diagram, the red arrows indicate the main data flow when users trigger an extension-based feature, such as HDR image capture.

Enable an effect for image capture and preview

Before using the extensions API, retrieve an ExtensionsManager instance using the ExtensionsManager#getInstance(Context) method. This will allow you to query the extension availability information. Then retrieve an extension enabled CameraSelector. The extension mode will be applied on the image capture and preview use cases when calling the bindToLifecycle() method with the CameraSelector extension enabled.

To implement the extension for the image capture and preview use cases, refer to the following code sample:

Kotlin

import androidx.camera.extensions.ExtensionMode
import androidx.camera.extensions.ExtensionsManager

fun onCreate() {
    // Create a camera provider
    val cameraProvider : ProcessCameraProvider = ... // Get the provider instance
    // Create an extensions manager
    val extensionsManager : ExtensionsManager = ... // Get the extensions manager instance

    // Select the camera
    val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

    // Query if extension is available.
    if (extensionsManager.isExtensionAvailable(
            cameraProvider,
            cameraSelector,
            ExtensionMode.BOKEH
        )
    ) {
        // Unbind all use cases before enabling different extension modes.
        cameraProvider.unbindAll()

        // Retrieve extension enabled camera selector
        val bokehCameraSelector = extensionsManager.getExtensionEnabledCameraSelector(
            cameraProvider,
            cameraSelector,
            ExtensionMode.BOKEH
        )

        // Bind image capture and preview use cases with the extension enabled camera selector.
        val imageCapture = ImageCapture.Builder().build()
        val preview = Preview.Builder().build()
        cameraProvider.bindToLifecycle(
            lifecycleOwner,
            bokehCameraSelector,
            imageCapture,
            preview
        )
    }
}

Java

import androidx.camera.extensions.ExtensionMode;
import androidx.camera.extensions.ExtensionsManager;

void onCreate() {
    // Create a camera provider
    ProcessCameraProvider cameraProvider = ...; // Get the provider instance
    // Create an extensions manager
    ExtensionsManager extensionsManager = ... // Get the extensions manager instance

    // Select the camera
    CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

    // Query if extension is available.
    if (extensionsManager
        .isExtensionAvailable(cameraProvider, cameraSelector, ExtensionMode.BOKEH)) {
        // Unbind all use cases before enabling different extension modes.
        cameraProvider.unbindAll();

        // Retrieve extension enabled camera selector
        CameraSelector bokehCameraSelector = extensionsManager
            .getExtensionEnabledCameraSelector(cameraProvider, cameraSelector, ExtensionMode.BOKEH);

        // Bind image capture and preview use cases with the extension enabled camera selector.
        ImageCapture imageCapture = new ImageCapture.Builder().build();
        Preview preview = new Preview.Builder().build();
        cameraProvider.bindToLifecycle(lifecycleOwner, bokehCameraSelector, imageCapture, preview);
    }
}

Disable the effect

To disable vendor extensions, unbind all use cases and rebind the image capture and preview use cases with a normal camera selector. For example, rebind to the back camera using CameraSelector.DEFAULT_BACK_CAMERA.

Additional resources

To learn more about CameraX, consult the following additional resources.

Codelab

  • Getting Started with CameraX
  • Code sample

  • Official CameraX sample app