# SurfaceRequest

Artifact: [androidx.camera:camera-core](https://developer.android.com/jetpack/androidx/releases/camera) [View Source](https://cs.android.com/search?q=file:androidx/camera/core/SurfaceRequest.java+class:androidx.camera.core.SurfaceRequest) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

*** ** * ** ***


```
public final class SurfaceRequest
```

<br />

*** ** * ** ***

A completable, single-use request of a `https://developer.android.com/reference/android/view/Surface.html`.

Contains requirements for surface characteristics along with methods for completing the request and listening for request cancellation.

Acts as a bridge between the surface provider and the surface requester. The diagram below describes how it works:

1. The surface provider gives a reference to surface requester for providing `https://developer.android.com/reference/android/view/Surface.html` (e.g. `https://developer.android.com/reference/androidx/camera/core/Preview#setSurfaceProvider(androidx.camera.core.Preview.SurfaceProvider)`).
2. The surface requester uses the reference to send a `SurfaceRequest` to get a `https://developer.android.com/reference/android/view/Surface.html` (e.g. `https://developer.android.com/reference/androidx/camera/core/Preview.SurfaceProvider#onSurfaceRequested(androidx.camera.core.SurfaceRequest)`).
3. The surface provider can use `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` to provide a `https://developer.android.com/reference/android/view/Surface.html` or inform the surface requester no `https://developer.android.com/reference/android/view/Surface.html` will be provided with `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#willNotProvideSurface()`. If a `https://developer.android.com/reference/android/view/Surface.html` is provided, the connection between surface provider and surface requester is established.
4. If the connection is established, the surface requester can get the `https://developer.android.com/reference/android/view/Surface.html` through `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#getDeferrableSurface()` and start to send frame data.
5. If for some reason the provided `https://developer.android.com/reference/android/view/Surface.html` is no longer valid (e.g. when the SurfaceView destroys its surface due to page being slid out in ViewPager2), the surface provider can use `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#invalidate()` method to inform the surface requester and the established connection will be closed.
6. The surface requester will re-send a new `SurfaceRequest` to establish a new connection.

![](https://developer.android.com/static/images/reference/androidx/camera/camera-core/surface_request_work_flow.svg)

## Summary

| ### Nested types |
|---|
| `@https://www.javadoc.io/doc/com.google.auto.value/auto-value/latest/com/google/auto/value/AutoValue.html public abstract class https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` Result of providing a surface to a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest` via `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)`. |
| `@https://www.javadoc.io/doc/com.google.auto.value/auto-value/latest/com/google/auto/value/AutoValue.html public abstract class https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfo` Transformation associated the preview output. |
| `public interface https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfoListener` Listener that receives updates of the `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfo` associated with the `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest`. |

| ### Public methods |
|---|---|
| `void` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#addRequestCancellationListener(java.util.concurrent.Executor,java.lang.Runnable)( @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/util/concurrent/Executor.html executor, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/lang/Runnable.html listener )` Adds a listener to be informed when the camera cancels the surface request. |
| `void` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#clearTransformationInfoListener()()` Clears the `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfoListener` set via `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#setTransformationInfoListener(java.util.concurrent.Executor,androidx.camera.core.SurfaceRequest.TransformationInfoListener)`. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/camera/core/DynamicRange` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#getDynamicRange()()` Returns the dynamic range expected to be used with the requested surface. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/util/Size.html` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#getResolution()()` Returns the resolution of the requested `https://developer.android.com/reference/android/view/Surface.html`. |
| `boolean` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#invalidate()()` Invalidates the previously provided `https://developer.android.com/reference/android/view/Surface.html` to provide a new `https://developer.android.com/reference/android/view/Surface.html`. |
| `void` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)( @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/view/Surface.html surface, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/util/concurrent/Executor.html executor, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/core/util/Consumer<https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result> resultListener )` Completes the request for a `https://developer.android.com/reference/android/view/Surface.html` if it has not already been completed or cancelled. |
| `void` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#setTransformationInfoListener(java.util.concurrent.Executor,androidx.camera.core.SurfaceRequest.TransformationInfoListener)( @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/util/concurrent/Executor.html executor, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfoListener listener )` Sets a listener to receive updates on transformation info. |
| `boolean` | `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#willNotProvideSurface()()` Signals that the request will never be fulfilled. |

## Public methods

### addRequestCancellationListener

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

```
public void addRequestCancellationListener(
    @NonNull Executor executor,
    @NonNull Runnable listener
)
```

Adds a listener to be informed when the camera cancels the surface request.

A surface request may be cancelled by the camera if the surface is no longer required. Examples of why cancellation may occur include (1) a `https://developer.android.com/reference/androidx/camera/core/UseCase` being unbound from the camera, (2) surface requirements, such as `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#getResolution()`, changing due to newly bound use cases, or (3) the camera requiring a new `https://developer.android.com/reference/android/view/Surface.html` object on lower API levels to work around compatibility issues.

When a request is cancelled, the `https://developer.android.com/reference/java/lang/Runnable.html` provided here will be invoked on the `https://developer.android.com/reference/java/util/concurrent/Executor.html` they are added with, and can be used as a signal to stop any work that may be in progress to fulfill the surface request.

Once a surface request has been cancelled by the camera, `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#willNotProvideSurface()` will have no effect and will return `false`. Attempting to complete the request via `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` will also have no effect, and any `resultListener` passed to `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` will be invoked with a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` containing `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result#RESULT_REQUEST_CANCELLED()`.

Note that due to the asynchronous nature of this listener, it is not guaranteed that the listener will be called before an attempt to complete the request with `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` or `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#willNotProvideSurface()`, so the return values of these methods can always be checked if your workflow for producing a surface expects them to complete successfully.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/util/concurrent/Executor.html executor` | The executor used to notify the listener. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/lang/Runnable.html listener` | The listener which will be run upon request cancellation. |

### clearTransformationInfoListener

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

```
public void clearTransformationInfoListener()
```

Clears the `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfoListener` set via `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#setTransformationInfoListener(java.util.concurrent.Executor,androidx.camera.core.SurfaceRequest.TransformationInfoListener)`.

### getDynamicRange

Added in [1.3.0](https://developer.android.com/jetpack/androidx/releases/camera#1.3.0)

```
public @NonNull DynamicRange getDynamicRange()
```

Returns the dynamic range expected to be used with the requested surface.

The dynamic range may have implications for which surface type is returned. Special care should be taken to ensure the provided surface can support the requested dynamic range. For example, if the returned dynamic range has `https://developer.android.com/reference/androidx/camera/core/DynamicRange#getBitDepth()` equal to `https://developer.android.com/reference/androidx/camera/core/DynamicRange#BIT_DEPTH_10_BIT()`, then the surface provided to `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` should use an `https://developer.android.com/reference/android/graphics/ImageFormat.html` that can support ten bits of dynamic range, such as `https://developer.android.com/reference/android/graphics/ImageFormat.html#PRIVATE` or `https://developer.android.com/reference/android/graphics/ImageFormat.html#YCBCR_P010`.

The dynamic range returned here will always be fully specified. That is, it will never have an `https://developer.android.com/reference/androidx/camera/core/DynamicRange#getEncoding()` of `https://developer.android.com/reference/androidx/camera/core/DynamicRange#ENCODING_UNSPECIFIED()` or `https://developer.android.com/reference/androidx/camera/core/DynamicRange#ENCODING_HDR_UNSPECIFIED()` and will never have `https://developer.android.com/reference/androidx/camera/core/DynamicRange#getBitDepth()` of `https://developer.android.com/reference/androidx/camera/core/DynamicRange#BIT_DEPTH_UNSPECIFIED()`.

### getResolution

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

```
public @NonNull Size getResolution()
```

Returns the resolution of the requested `https://developer.android.com/reference/android/view/Surface.html`.

The surface which fulfills this request must have the resolution specified here in order to fulfill the resource requirements of the camera. Fulfillment of the request with a surface of a different resolution may cause the `resultListener` passed to `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` to be invoked with a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` containing `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result#RESULT_INVALID_SURFACE()`.

| Returns |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/util/Size.html` | The guaranteed supported resolution. |

| See also |
|---|---|
| `https://developer.android.com/reference/android/graphics/SurfaceTexture.html#setDefaultBufferSize(int, int)` |   |

### invalidate

Added in [1.3.0](https://developer.android.com/jetpack/androidx/releases/camera#1.3.0)

```
public boolean invalidate()
```

Invalidates the previously provided `https://developer.android.com/reference/android/view/Surface.html` to provide a new `https://developer.android.com/reference/android/view/Surface.html`.

Call this method to inform the surface requester that the previously provided `https://developer.android.com/reference/android/view/Surface.html` is no longer valid (e.g. when the SurfaceView destroys its surface due to page being slid out in ViewPager2) and should re-send a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest` to obtain a new `https://developer.android.com/reference/android/view/Surface.html`.

Calling this method will cause the camera to be reconfigured. The app should call this method when the surface provider is ready to provide a new `https://developer.android.com/reference/android/view/Surface.html`. (e.g. a SurfaceView's surface is created when its window is visible.)

If the provided `https://developer.android.com/reference/android/view/Surface.html` was already invalidated, invoking this method will return `false`, and will have no effect. The surface requester will not be notified again, so there will not be another `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest`.

Calling this method without `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` (regardless of whether @link #willNotProvideSurface()} has been called) will still trigger the surface requester to re-send a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest`.

Since calling this method also means that the `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest` will not be fulfilled, if the `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest` has not responded, it will respond as if calling `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#willNotProvideSurface()`.

| Returns |
|---|---|
| `boolean` | true if the provided `https://developer.android.com/reference/android/view/Surface.html` is invalidated or false if it was already invalidated. |

### provideSurface

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

```
public void provideSurface(
    @NonNull Surface surface,
    @NonNull Executor executor,
    @NonNull Consumer<SurfaceRequest.Result> resultListener
)
```

Completes the request for a `https://developer.android.com/reference/android/view/Surface.html` if it has not already been completed or cancelled.

Once the camera no longer needs the provided surface, the `resultListener` will be invoked with a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` containing `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result#RESULT_SURFACE_USED_SUCCESSFULLY()`. At this point it is safe to release the surface and any underlying resources. Releasing the surface before receiving this signal may cause undesired behavior on lower API levels.

If the request is cancelled by the camera before successfully attaching the provided surface to the camera, then the `resultListener` will be invoked with a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` containing `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result#RESULT_REQUEST_CANCELLED()`. In addition, any cancellation listeners provided to `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#addRequestCancellationListener(java.util.concurrent.Executor,java.lang.Runnable)` will be invoked.

If the request was previously completed via `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#willNotProvideSurface()`, then `resultListener` will be invoked with a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` containing `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result#RESULT_WILL_NOT_PROVIDE_SURFACE()`.

Upon returning from this method, the surface request is guaranteed to be complete. However, only the `resultListener` provided to the first invocation of this method should be used to track when the provided `https://developer.android.com/reference/android/view/Surface.html` is no longer in use by the camera, as subsequent invocations will always invoke the `resultListener` with a `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result` containing `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result#RESULT_SURFACE_ALREADY_PROVIDED()`.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/view/Surface.html surface` | The surface which will complete the request. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/util/concurrent/Executor.html executor` | Executor used to execute the `resultListener`. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/core/util/Consumer<https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.Result> resultListener` | Listener used to track how the surface is used by the camera in response to being provided by this method. |

### setTransformationInfoListener

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

```
public void setTransformationInfoListener(
    @NonNull Executor executor,
    @NonNull SurfaceRequest.TransformationInfoListener listener
)
```

Sets a listener to receive updates on transformation info.

Sets a listener to receive the transformation info associated with this `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest` when it changes or becomes available. The listener is called immediately if transformation info is available at the time of setting.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/util/concurrent/Executor.html executor` | The executor used to notify the listener. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfoListener listener` | the listener which will be called when transformation info changes. |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfoListener` |   |
| `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest.TransformationInfo` |   |

### willNotProvideSurface

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/camera#1.0.0)

```
public boolean willNotProvideSurface()
```

Signals that the request will never be fulfilled.

This may be called in the case where the application may be shutting down and a surface will never be produced to fulfill the request.

This should always be called as soon as it is known that the request will not be fulfilled. Failure to complete the SurfaceRequest via `willNotProvideSurface()` or `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` may cause long delays in shutting down the camera.

Upon returning from this method, the request is guaranteed to be complete, regardless of the return value. If the request was previously successfully completed by `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)`, invoking this method will return `false`, and will have no effect on how the surface is used by the camera.

| Returns |
|---|---|
| `boolean` | `true` if this call to `willNotProvideSurface()` successfully completes the request, i.e., the request has not already been completed via `https://developer.android.com/reference/androidx/camera/core/SurfaceRequest#provideSurface(android.view.Surface,java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result>)` or by a previous call to `willNotProvideSurface()` and has not already been cancelled by the camera. |