The second Android 11 Developer Preview is now available, test it out and share your feedback.

Preview.PreviewSurfaceProvider

public static interface Preview.PreviewSurfaceProvider

androidx.camera.core.Preview.PreviewSurfaceProvider


A interface implemented by the application to provide a Surface for Preview.

This interface is implemented by the application to provide a Surface. This will be called by CameraX when it needs a Surface for Preview. It also signals when the Surface is no longer in use by CameraX.

Summary

Public methods

abstract ListenableFuture<Surface> provideSurface(Size resolution, ListenableFuture<Void> surfaceReleaseFuture)

Provides preview output Surface with the given resolution.

Public methods

provideSurface

public abstract ListenableFuture<Surface> provideSurface (Size resolution, 
                ListenableFuture<Void> surfaceReleaseFuture)

Provides preview output Surface with the given resolution.

This is called when Preview needs a valid Surface. e.g. when the Preview is bound to lifecycle. The Surface should either be backed by a SurfaceTexture or a SurfaceHolder.

If the Surface is backed by a SurfaceTexture, both the Surface and the ListenableFuture need to be recreated each time this is invoked. The implementer is also responsible to hold a reference to the SurfaceTexture since the weak reference from Surface does not prevent it from being garbage collected.

If the Surface is backed by a SurfaceView, the PixelFormat should always be the default PixelFormat.OPAQUE.

The application will need to crop and rotate the Surface to fit the UI.

The resolution that is requested by CameraX will be the sensor resolution, based on the capabilities of the camera Preview is attached to. The approximate resolution used for the sensor can be controlled via Preview.Builder.setTargetResolution(Size)}. However, the final resolution that is used might need to be cropped in order to fit the view.

Undefined behavior may occur if the Surface does not have the requested resolution or is released before surfaceReleaseFuture completes. So care must be taken when to using a SurfaceView or a TextureView to handle rotation to display orientation, since they automatically resize and release the Surface. Example:

 class MyPreviewSurfaceProvider implements PreviewSurfaceProvider {
     SurfaceTexture mSurfaceTexture;

     @Override
     public ListenableFuture<Surface> provideSurface(
         @NonNull Size resolution,
         @NonNull ListenableFuture<Void>
         surfaceReleaseFuture) {
         // Create the ListenableFuture for the Surface
         mSurfaceTexture = new SurfaceTexture(0);
         mSurfaceTexture.detachFromGLContext();
         ListenableFuture surfaceFuture = CallbackToFutureAdapter.getFuture(
             completer -> completer.set(new Surface(mSurfaceTexture));

         Futures.addCallback(surfaceReleaseFuture,
             new FutureCallback<Void>() {
             @Override
             public void onSuccess(Void result) {
                 // mSurfaceTexture is no longer used by the camera so it is safe to
                 // release
                 mSurfaceTexture.release();
             }

             @Override
             public void onFailure(Throwable t) {
                 // Should never fail
             }
         }, Executors.newSingleThreadExecutor());

         return surfaceFuture;
     }
 }
 

Parameters
resolution Size: the resolution required by CameraX, which is in image sensor coordinate system.

surfaceReleaseFuture ListenableFuture: it's safe to release the returned Surface return by the method, after this ListenableFuture finishes.

Returns
ListenableFuture<Surface> A ListenableFuture that contains the implementer created Surface.