<br />

**Note:** This page refers to the[Camera2](https://developer.android.com/reference/android/hardware/camera2/package-summary)package. Unless your app requires specific, low-level features from Camera2, we recommend using[CameraX](https://developer.android.com/camerax). Both CameraX and Camera2 support Android 5.0 (API level 21) and higher.

<br />

Cameras and camera previews aren't always in the same orientation on Android devices.

A camera is in a fixed position on a device, regardless of whether the device is a phone, tablet, or computer. When the device orientation changes, the camera orientation changes.

As a result, camera apps generally assume a fixed relationship between the orientation of the device and the aspect ratio of the camera preview. When a phone is in portrait orientation, the camera preview is assumed to be taller than it is wide. When the phone (and camera) are rotated to landscape, the camera preview is expected to be wider than it is tall.

But these assumptions are challenged by new form factors, such as[foldable devices](https://developer.android.com/develop/ui/compose/layouts/adaptive/foldables/learn-about-foldables), and display modes such as[multi‑window](https://developer.android.com/develop/ui/compose/layouts/adaptive/support-multi-window-mode)and[multi‑display](https://developer.android.com/develop/ui/compose/layouts/adaptive/support-multi-window-mode#multi-display_support). Foldable devices change display size and aspect ratio without changing orientation. Multi‑window mode constrains camera apps to a portion of the screen, scaling the camera preview regardless of device orientation. Multi‑display mode enables the use of secondary displays which might not be in the same orientation as the primary display.

## Camera orientation

The[Android Compatibility Definition](https://source.android.com/compatibility/cdd)specifies that a camera image sensor "MUST be oriented so that the long dimension of the camera aligns with the screen's long dimension. That is, when the device is held in the landscape orientation, cameras MUST capture images in the landscape orientation. This applies regardless of the device's natural orientation; that is, it applies to landscape‑primary devices as well as portrait‑primary devices."

The camera to screen arrangement maximizes the display area of the camera viewfinder in a camera app. Also, image sensors typically output their data in landscape aspect ratios, 4:3 being the most common.
![Phone and camera sensor both in portrait orientation.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_preview_portrait_front_facing.png)**Figure 1.**Typical relationship of phone and camera sensor orientation.

The camera sensor's natural orientation is landscape. In figure 1, the sensor of the front-facing camera (the camera pointing in the same direction as the display) is rotated 270 degrees relative to the phone to comply with the Android Compatibility Definition.

To expose the sensor rotation to apps, the[camera2](https://developer.android.com/reference/android/hardware/camera2/package-summary)API includes a[`SENSOR_ORIENTATION`](https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#SENSOR_ORIENTATION)constant. For most phones and tablets, the device reports a sensor orientation of 270 degrees for front-facing cameras and 90 degrees (point of view from the back of the device) for back-facing cameras, which aligns the long edge of the sensor with the long edge of the device. Laptop cameras generally report a sensor orientation of 0 or 180 degrees.
| **Note:** Natural (or native) orientation is the typical orientation of a device or sensor---portrait for phones, landscape for tablets and laptops, landscape for camera image sensors.

Because camera image sensors output their data (an image buffer) in the sensor's natural orientation (landscape), the image buffer must be rotated the number of degrees specified by`SENSOR_ORIENTATION`for the camera preview to appear upright in the device's natural orientation. For front-facing cameras, the rotation is counterclockwise; for back-facing cameras, clockwise.

For example, for the front-facing camera in figure 1, the image buffer produced by the camera sensor looks like this:
![Camera sensor rotated to landscape orientation with image sideways, top left.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_portrait_rotated_90.png)

The image must be rotated 270 degrees counterclockwise so that the preview's orientation matches the device orientation:
![Camera sensor in portrait orientation with image upright.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_portrait_without_coordinates.png)

A back-facing camera would produce an image buffer with the same orientation as the buffer above, but`SENSOR_ORIENTATION`is 90 degrees. As a result, the buffer is rotated 90 degrees clockwise.

## Device rotation

Device rotation is the number of degrees a device is rotated from its natural orientation. For example, a phone in landscape orientation has a device rotation of 90 or 270 degrees, depending on the direction of rotation.

A camera sensor image buffer must be rotated the same number of degrees as the device rotation (in addition to the degrees of sensor orientation) for the camera preview to appear upright.

## Orientation calculation

Proper orientation of the camera preview takes into consideration sensor orientation and device rotation.

The overall rotation of the sensor image buffer can be computed using the following formula:  

    rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

where`sign`is`1`for front-facing cameras,`-1`for back-facing cameras.

For front-facing cameras, the image buffer is rotated counterclockwise (from the natural orientation of the sensor). For back-facing cameras, the sensor image buffer is rotated clockwise.

The expression`deviceOrientationDegrees * sign + 360`converts device rotation from counterclockwise to clockwise for back-facing cameras (for example, converting 270 degrees counterclockwise to 90 degrees clockwise). The modulo operation scales the result to less than 360 degrees (for example, scaling 540 degrees of rotation to 180).

Different APIs report device rotation differently:

- [`Display#getRotation()`](https://developer.android.com/reference/android/view/Display#getRotation())provides the counterclockwise rotation of the device (from the user's point of view). This value plugs into the formula above as is.
- [`OrientationEventListener#onOrientationChanged()`](https://developer.android.com/reference/android/view/OrientationEventListener#onOrientationChanged(int))returns the clockwise rotation of the device (from the user's point of view). Negate the value for use in the formula above.

### Front-facing cameras

![Camera preview and sensor both in landscape orientation, sensor is right side up.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_preview_landscape_counterclockwise_front_facing.png)**Figure 2.**Camera preview and sensor with phone turned 90 degrees to landscape orientation.

Here's the image buffer produced by the camera sensor in figure 2:
![Camera sensor in landscape orientation with image upright.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape.png)

The buffer has to be rotated 270 degrees counterclockwise to adjust for sensor orientation (see[Camera orientation](https://developer.android.com/media/camera/camera2/camera-preview#camera-orientation)above):
![Camera sensor rotated to portait orientation with image sideways, top right.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_rotated_270.png)

Then the buffer is rotated an additional 90 degrees counterclockwise to account for device rotation, resulting in the correct orientation of the camera preview in figure 2:
![Camera sensor rotated to landscape orientation with image upright.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_without_coordinates.png)

Here's the camera turned to the right to landscape orientation:
![Camera preview and sensor both in landscape orientation, but sensor is upside down.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_preview_landscape_clockwise_front_facing.png)**Figure 3.**Camera preview and sensor with phone turned 270 degrees (or -90 degrees) to landscape orientation.

Here's the image buffer:
![Camera sensor rotated to landscape orientation with image upside down.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_clockwise.png)

The buffer must be rotated 270 degrees counterclockwise to adjust for sensor orientation:
![Camera sensor rated to portrait orientation with image sideways, top left.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_clockwise_rotated_270.png)

Then the buffer is rotated another 270 degrees counterclockwise to account for the device rotation:
![Camera sensor rotated to landscape orientation with image upright.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_without_coordinates.png)

### Back-facing cameras

Back-facing cameras typically have a sensor orientation of 90 degrees (as viewed from the back of the device). When orienting the camera preview, the sensor image buffer is rotated clockwise by the amount of sensor rotation (rather than counterclockwise like front-facing cameras), and then the image buffer is rotated counterclockwise by the amount of device rotation.
![Camera preview and sensor both in landscape orientation, but sensor is upside down.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_preview_landscape_clockwise_back_facing.png)**Figure 4.**Phone with back-facing camera in landscape orientation (turned 270 or -90 degrees).

Here's the image buffer from the camera sensor in figure 4:
![Camera sensor rotated to landscape orientation with image upside down.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_clockwise.png)

The buffer must be rotated 90 degrees clockwise to adjust for sensor orientation:
![Camera sensor rated to portrait orientation with image sideways, top left.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_clockwise_rotated_270.png)

Then the buffer is rotated 270 degrees counterclockwise to account for device rotation:
![Camera sensor rotated to landscape orientation with image upright.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/camera_sensor_landscape_without_coordinates.png)

## Aspect ratio

Display aspect ratio changes when the device orientation changes but also when foldables fold and unfold, when windows are resized in multi-window environments, and when apps open on secondary displays.

The camera sensor image buffer must be oriented and scaled to match the orientation and aspect ratio of the viewfinder UI element as the UI dynamically changes orientation---with or without the device changing orientation.

On new form factors or in multi-window or multi-display environments, if your app assumes that the camera preview has the same orientation as the device (portrait or landscape) your preview might be oriented incorrectly, scaled incorrectly, or both.
![Unfolded foldable device with portrait camera preview turned sideways.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/foldable_with_rotation_problem.png)**Figure 5.**Foldable device transitions from portrait to landscape aspect ratio but camera sensor remains in portrait orientation.

In figure 5, the application mistakenly assumed the device was rotated 90 degrees counterclockwise; and so, the app rotated the preview the same amount.
![Unfolded foldable device with camera preview upright but squashed because of incorrect scaling.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/foldable_with_scaling_problem.png)**Figure 6.**Foldable device transitions from portrait to landscape aspect ratio but camera sensor remains in portrait orientation.

In figure 6, the app didn't adjust the aspect ratio of the image buffer to enable it to properly scale to fit the new dimensions of the camera preview UI element.

Fixed-orientation camera apps typically experience problems on foldables and other large screen devices such as laptops:
![Camera preview on laptop is upright but app UI is sideways.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/laptop_camera_preview_fixed-orientation_app.png)**Figure 7.**Fixed-orientation portrait app on laptop computer.

In figure 7, the UI of the camera app is sideways because the app's orientation is restricted to portrait only. The viewfinder image is oriented correctly relative to the camera sensor.

## Inset portrait mode

Camera apps that do not support multi-window mode ([`resizeableActivity="false"`](https://developer.android.com/guide/topics/manifest/application-element#resizeableActivity)) and restrict their orientation ([`screenOrientation="portrait"`](https://developer.android.com/guide/topics/manifest/activity-element#screen)or[`screenOrientation="landscape"`](https://developer.android.com/guide/topics/manifest/activity-element#screen)) can be placed in inset portrait mode on large screen devices to properly orient the camera preview.

Inset portrait mode letterboxes (insets) portrait‑only apps in portrait orientation even though the display aspect ratio is landscape. Landscape‑only apps are letterboxed in landscape orientation even though the display aspect ratio is portrait. The camera image is rotated to align with the app UI, cropped to match the aspect ratio of the camera preview, and then scaled to fill the preview.

Inset portrait mode is triggered when the aspect ratio of the camera image sensor and the aspect ratio of the application's primary activity do not match.
![Camera preview and app UI in proper portrait orientation on laptop. Wide preview image is scaled and cropped to fit portrait orientation.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/laptop_inset_portrait_mode.png)**Figure 8.**Fixed-orientation portrait app in inset portrait mode on laptop.

In figure 8, the portrait-only camera app has been rotated to display the UI upright on the laptop display. The app is letterboxed because of the difference in aspect ratio between the portrait app and the landscape display. The camera preview image has been rotated to compensate for the app's UI rotation (due to inset portrait mode), and the image has been cropped and scaled to fit the portrait orientation, reducing the field of view.

### Rotate, crop, scale

Inset portrait mode is invoked for a portrait-only camera app on a display that has a landscape aspect ratio:
![Camera preview on laptop is upright but app UI is sideways.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/laptop_inset_portrait_mode_fixed-orientation_app.png)**Figure 9.**Fixed-orientation portrait app on laptop.

The app is letterboxed in portrait orientation:
![App rotated to portrait orientation and letterboxed. Image is sideways, top to the right.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/laptop_inset_portrait_mode_rotate_ui.png)

The camera image is rotated 90 degrees to adjust for the reorientation of the app:
![Sensor image rotated 90 degrees to make it upright.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/laptop_inset_portrait_mode_rotate_sensor_image.png)

The image is cropped to the aspect ratio of the camera preview, then scaled to fill the preview (field of view is reduced):
![Cropped camera image scaled to fill camera preview.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/laptop_inset_portrait_mode_crop_and_scale.png)

On foldable devices, the orientation of the camera sensor can be portrait while the aspect ratio of the display is landscape:
![Camera preview and app UI turned sideways of wide, unfolded display.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/unfolded_phone_camera_preview_fixed-orientation_app.png)**Figure 10.**Unfolded device with portrait-only camera app and different aspect ratios of camera sensor and display.

Because the camera preview is rotated to adjust for the sensor orientation, the image is properly oriented in the viewfinder, but the portrait-only app is sideways.

Inset portrait mode only needs to letterbox the app in portrait orientation to properly orient the app and camera preview:
![Letterboxed app in portait orientation with camera preview upright on foldable device.](https://developer.android.com/static/images/training/camera/camera2/camera-preview/unfolded_phone_inset_portrait_mode.png)

### API

As of Android 12 (API level 31) apps can also explicitly control inset portrait mode by means of the[`SCALER_ROTATE_AND_CROP`](https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#SCALER_ROTATE_AND_CROP)property of the[`CaptureRequest`](https://developer.android.com/reference/android/hardware/camera2/CaptureRequest)class.

The default value is[`SCALER_ROTATE_AND_CROP_AUTO`](https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#SCALER_ROTATE_AND_CROP_AUTO), which enables the system to invoke inset portrait mode.[`SCALER_ROTATE_AND_CROP_90`](https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#SCALER_ROTATE_AND_CROP_90)is the behavior of inset portrait mode as described above.

Not all devices support all`SCALER_ROTATE_AND_CROP`values. To obtain a list of supported values, reference[`CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES`](https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES).
| **Note:** Only devices with a camera hardware abstraction layer ([HAL](https://source.android.com/devices/camera/camera3)) that supports the`SCALER_ROTATE_AND_CROP`API can enable inset portrait mode.

## CameraX

| **Note:** Jetpack CameraX provides backward compatibility to Android 5.0 (API level 21).

The[Jetpack CameraX](https://developer.android.com/training/camerax)library makes creating a camera viewfinder that accommodates sensor orientation and device rotation a simple task.

The[`PreviewView`](https://developer.android.com/reference/androidx/camera/view/PreviewView)layout element creates a camera preview, automatically adjusting for sensor orientation, device rotation, and scaling.`PreviewView`maintains the aspect ratio of the camera image by applying the[`FILL_CENTER`](https://developer.android.com/reference/androidx/camera/view/PreviewView.ScaleType#FILL_CENTER)scale type, which centers the image but might crop it to match the dimensions of the`PreviewView`. To letterbox the camera image, set the scale type to[`FIT_CENTER`](https://developer.android.com/reference/androidx/camera/view/PreviewView.ScaleType#FIT_CENTER).

To learn the basics of creating a camera preview with`PreviewView`, see[Implement a preview](https://developer.android.com/training/camerax/preview).

For a complete sample implementation, see the[`CameraXBasic`](https://github.com/android/camera-samples/tree/master/CameraXBasic)repository on GitHub.

## CameraViewfinder

| **Note:** The`CameraViewfinder`library is backward compatible with Android 5.0 (API level 21).

Similar to the[Preview](https://developer.android.com/training/camerax/preview)use case, the[CameraViewfinder](https://developer.android.com/reference/androidx/camera/viewfinder/package-summary)library provides a set of tools to simplify the creation of a camera preview. It does not depend on CameraX Core, so you can seamlessly integrate it into your existing Camera2 codebase.

Instead of using the[`Surface`](https://developer.android.com/reference/android/view/Surface)directly, you can use the[`CameraViewfinder`](https://developer.android.com/reference/androidx/camera/viewfinder/CameraViewfinder)widget to display the camera feed for Camera2.

`CameraViewfinder`internally uses either a`TextureView`or`SurfaceView`to display the camera feed, and applies the required transformations on them to correctly display the viewfinder. This involves correcting their aspect ratio, scale, and rotation.

To request the surface from the`CameraViewfinder`object, you need to create a[`ViewfinderSurfaceRequest`](https://developer.android.com/reference/androidx/camera/viewfinder/ViewfinderSurfaceRequest).

This request contains requirements for the surface resolution and camera device information from[`CameraCharacteristics`](https://developer.android.com/reference/kotlin/android/hardware/camera2/CameraCharacteristics).

Calling[`requestSurfaceAsync()`](https://developer.android.com/reference/androidx/camera/viewfinder/CameraViewfinder#requestSurfaceAsync(androidx.camera.viewfinder.ViewfinderSurfaceRequest))sends the request to the surface provider, which is either a`TextureView`or`SurfaceView`and gets a`ListenableFuture`of`Surface`.

Calling[`markSurfaceSafeToRelease()`](https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/ViewfinderSurfaceRequest#markSurfaceSafeToRelease())notifies the surface provider that the surface is not needed and related resources can be released.  

### Kotlin

```kotlin
fun startCamera(){
    val previewResolution = Size(width, height)
    val viewfinderSurfaceRequest =
        ViewfinderSurfaceRequest(previewResolution, characteristics)
    val surfaceListenableFuture =
        cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)

    Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
        override fun onSuccess(surface: Surface) {
            /* create a CaptureSession using this surface as usual */
        }
        override fun onFailure(t: Throwable) { /* something went wrong */}
    }, ContextCompat.getMainExecutor(context))
}
```

### Java

```java
    void startCamera(){
        Size previewResolution = new Size(width, height);
        ViewfinderSurfaceRequest viewfinderSurfaceRequest =
                new ViewfinderSurfaceRequest(previewResolution, characteristics);
        ListenableFuture<Surface> surfaceListenableFuture =
                cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest);

        Futures.addCallback(surfaceListenableFuture, new FutureCallback<Surface>() {
            @Override
            public void onSuccess(Surface result) {
                /* create a CaptureSession using this surface as usual */
            }
            @Override public void onFailure(Throwable t) { /* something went wrong */}
        },  ContextCompat.getMainExecutor(context));
    }
```

## SurfaceView

[`SurfaceView`](https://developer.android.com/reference/android/view/SurfaceView)is a straightforward approach to creating a camera preview if the preview doesn't require processing and isn't animated.

`SurfaceView`automatically rotates the camera sensor image buffer to match the display orientation, accounting for both sensor orientation and device rotation. However, the image buffer is scaled to fit the`SurfaceView`dimensions without any consideration of aspect ratio.

You must ensure that the aspect ratio of the image buffer matches the aspect ratio of the`SurfaceView`, which you can accomplish by scaling the contents of the`SurfaceView`in the component's[`onMeasure()`](https://developer.android.com/reference/android/view/SurfaceView#onMeasure(int,%20int))method:

(The`computeRelativeRotation()`source code is in[Relative rotation](https://developer.android.com/media/camera/camera2/camera-preview#relative-rotation)below.)  

### Kotlin

```kotlin
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val width = MeasureSpec.getSize(widthMeasureSpec)
    val height = MeasureSpec.getSize(heightMeasureSpec)

    val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees)

    if (previewWidth > 0f && previewHeight > 0f) {
        /* Scale factor required to scale the preview to its original size on the x-axis. */
        val scaleX =
            if (relativeRotation % 180 == 0) {
                width.toFloat() / previewWidth
            } else {
                width.toFloat() / previewHeight
            }
        /* Scale factor required to scale the preview to its original size on the y-axis. */
        val scaleY =
            if (relativeRotation % 180 == 0) {
                height.toFloat() / previewHeight
            } else {
                height.toFloat() / previewWidth
            }

        /* Scale factor required to fit the preview to the SurfaceView size. */
        val finalScale = min(scaleX, scaleY)

        setScaleX(1 / scaleX * finalScale)
        setScaleY(1 / scaleY * finalScale)
    }
    setMeasuredDimension(width, height)
}
```

### Java

```java
@Override
void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    int relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees);

    if (previewWidth > 0f && previewHeight > 0f) {

        /* Scale factor required to scale the preview to its original size on the x-axis. */
        float scaleX = (relativeRotation % 180 == 0)
                       ? (float) width / previewWidth
                       : (float) width / previewHeight;

        /* Scale factor required to scale the preview to its original size on the y-axis. */
        float scaleY = (relativeRotation % 180 == 0)
                       ? (float) height / previewHeight
                       : (float) height / previewWidth;

        /* Scale factor required to fit the preview to the SurfaceView size. */
        float finalScale = Math.min(scaleX, scaleY);

        setScaleX(1 / scaleX * finalScale);
        setScaleY(1 / scaleY * finalScale);
    }
    setMeasuredDimension(width, height);
}
```

For more details on implementing`SurfaceView`as a camera preview, see[Camera orientations](https://chromeos.dev/en/android/camera-orientation#surfaceview).

## TextureView

[`TextureView`](https://developer.android.com/reference/android/view/TextureView)is less performant than`SurfaceView`---and more work---but`TextureView`gives you maximum control of the camera preview.

`TextureView`rotates the sensor image buffer based on sensor orientation but does not handle device rotation or preview scaling.

Scaling and rotation can be encoded in a[Matrix](https://developer.android.com/reference/android/graphics/Matrix)transformation. To learn how to correctly scale and rotate a`TextureView`, see[Support resizable surfaces in your camera app](https://developer.android.com/codelabs/android-camera2-preview)

## Relative rotation

The camera sensor's relative rotation is the amount of rotation required to align the camera sensor output with the device orientation.

Relative rotation is used by components such as`SurfaceView`and`TextureView`to determine x and y scaling factors for the preview image. It is also used to specify the rotation of the sensor image buffer.

The[`CameraCharacteristics`](https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics)and[`Surface`](https://developer.android.com/reference/android/view/Surface)classes enable calculation of the camera sensor's relative rotation:  

### Kotlin

```kotlin
/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public fun computeRelativeRotation(
    characteristics: CameraCharacteristics,
    surfaceRotationDegrees: Int
): Int {
    val sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!!

    // Reverse device orientation for back-facing cameras.
    val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT
    ) 1 else -1

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360
}
```

### Java

```java
/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public int computeRelativeRotation(
    CameraCharacteristics characteristics,
    int surfaceRotationDegrees
){
    Integer sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

    // Reverse device orientation for back-facing cameras.
    int sign = characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT ? 1 : -1;

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360;
}
```

## Window metrics

Screen size should not be used to determine the dimensions of the camera viewfinder; the camera app might be running in a portion of the screen, either in multi-window mode on mobile devices or free-from mode on ChromeOS.

[`WindowManager#getCurrentWindowMetrics()`](https://developer.android.com/reference/android/view/WindowManager#getCurrentWindowMetrics())(added in API level 30) returns the size of the application window rather than the size of the screen. The Jetpack WindowManager library methods[`WindowMetricsCalculator#computeCurrentWindowMetrics()`](https://developer.android.com/reference/androidx/window/layout/WindowMetricsCalculator#computeCurrentWindowMetrics(android.app.Activity))and[`WindowInfoTracker#currentWindowMetrics()`](https://developer.android.com/reference/kotlin/androidx/window/layout/WindowInfoTracker)provide similar support with backward compatibility to API level 14.
| **Note:** [`Display`](https://developer.android.com/reference/android/view/Display)methods[`getRealSize()`](https://developer.android.com/reference/android/view/Display#getRealSize(android.graphics.Point))and[`getRealMetrics()`](https://developer.android.com/reference/android/view/Display#getRealMetrics(android.util.DisplayMetrics))are deprecated as of API level 31. The methods do not support multi-window mode or free-form mode. To get the display density, use[`Configuration#densityDpi`](https://developer.android.com/reference/android/content/res/Configuration#densityDpi)instead of`getRealMetrics()`.

## 180 degree rotation

A 180 degree rotation of a device (for example, from natural orientation to natural orientation upside down) does not trigger the[`onConfigurationChanged()`](https://developer.android.com/reference/android/app/Activity#onConfigurationChanged(android.content.res.Configuration))callback. As a result, the camera preview might be upside down.

To detect a 180 degree rotation, implement a[`DisplayListener`](https://developer.android.com/reference/android/hardware/display/DisplayManager.DisplayListener)and check the device rotation with a call to[`Display#getRotation()`](https://developer.android.com/reference/android/view/Display#getRotation())in the[`onDisplayChanged()`](https://developer.android.com/reference/android/hardware/display/DisplayManager.DisplayListener#onDisplayChanged(int))callback.

## Exclusive resources

Prior to Android 10, only the topmost visible activity in a multi-window environment was in the`RESUMED`state. This was confusing for users because the system provided no indication of which activity was resumed.

Android 10 (API level 29) introduced multi-resume where all visible activities are in the`RESUMED`state. Visible activities can still enter the`PAUSED`state if, for example, a transparent activity is on top of the activity or the activity is not focusable, such as in picture-in-picture mode (see[Picture-in-picture support](https://developer.android.com/guide/topics/ui/picture-in-picture)).

An application using the camera, microphone, or any exclusive or singleton resource on API level 29 or higher must support multi-resume. For example, if three resumed activities want to use the camera, only one is able to access this exclusive resource. Each activity must implement an[`onDisconnected()`](https://developer.android.com/reference/android/hardware/camera2/CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice))callback to stay aware of preemptive access to the camera by a higher priority activity.
| **Note:** Setting[`resizeableActivity="false"`](https://developer.android.com/guide/topics/manifest/activity-element#resizeableActivity)doesn't guarantee access to exclusive resources because another activity or an application running on a secondary display might have higher priority. Also, as of Android 12 (API level 31),`resizeableActivity="false"`does not prevent an activity from entering multi-window mode in which other activities might take precedence for exclusive resources.

For more information, see[Multi-resume](https://source.android.com/devices/tech/display/multi_display/multi-resume).

## Additional resources

- For a Camera2 sample, see the[Camera2Basic app](https://github.com/android/camera-samples/tree/master/Camera2Basic)on GitHub.
- To learn about the CameraX preview use case, see CameraX[Implement a preview](https://developer.android.com/training/camerax/preview).
- For a CameraX camera preview sample implementation, see the[CameraXBasic](https://github.com/android/camera-samples/tree/master/CameraXBasic)repository on GitHub.
- For information about camera preview on ChromeOS, see[Camera orientations](https://chromeos.dev/en/android/camera-orientation).
- For information about developing for foldable devices, see[Learn about foldables](https://developer.android.com/develop/ui/compose/layouts/adaptive/foldables/learn-about-foldables).