Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3223742 authored by Shuzhen Wang's avatar Shuzhen Wang Committed by Android (Google) Code Review
Browse files

Merge "camera2: Add support for logical camera"

parents a036d599 23d2938f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -15577,6 +15577,7 @@ package android.hardware.camera2 {
    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableSessionKeys();
    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
    method public java.util.List<java.lang.String> getPhysicalCameraIds();
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15615,6 +15616,7 @@ package android.hardware.camera2 {
    field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_ROTATION;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_RADIAL_DISTORTION;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
@@ -15861,6 +15863,8 @@ package android.hardware.camera2 {
    field public static final int LENS_POSE_REFERENCE_PRIMARY_CAMERA = 0; // 0x0
    field public static final int LENS_STATE_MOVING = 1; // 0x1
    field public static final int LENS_STATE_STATIONARY = 0; // 0x0
    field public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE = 0; // 0x0
    field public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED = 1; // 0x1
    field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1
    field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
    field public static final int NOISE_REDUCTION_MODE_MINIMAL = 3; // 0x3
@@ -15870,6 +15874,7 @@ package android.hardware.camera2 {
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9; // 0x9
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11; // 0xb
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1
    field public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10; // 0xa
@@ -16208,6 +16213,7 @@ package android.hardware.camera2.params {
    method public int getSurfaceGroupId();
    method public java.util.List<android.view.Surface> getSurfaces();
    method public void removeSurface(android.view.Surface);
    method public void setPhysicalCameraId(java.lang.String);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
    field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff
+93 −0
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.PublicKey;
import android.hardware.camera2.impl.SyntheticKey;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.utils.ArrayUtils;
import android.hardware.camera2.utils.TypeReference;
import android.util.Rational;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@@ -407,6 +409,47 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
        return Collections.unmodifiableList(staticKeyList);
    }

    /**
     * Returns the list of physical camera ids that this logical {@link CameraDevice} is
     * made up of.
     *
     * <p>A camera device is a logical camera if it has
     * REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA capability. If the camera device
     * doesn't have the capability, the return value will be an empty list. </p>
     *
     * <p>The list returned is not modifiable, so any attempts to modify it will throw
     * a {@code UnsupportedOperationException}.</p>
     *
     * <p>Each physical camera id is only listed once in the list. The order of the keys
     * is undefined.</p>
     *
     * @return List of physical camera ids for this logical camera device.
     */
    @NonNull
    public List<String> getPhysicalCameraIds() {
        int[] availableCapabilities = get(REQUEST_AVAILABLE_CAPABILITIES);
        if (availableCapabilities == null) {
            throw new AssertionError("android.request.availableCapabilities must be non-null "
                        + "in the characteristics");
        }

        if (!ArrayUtils.contains(availableCapabilities,
                REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA)) {
            return Collections.emptyList();
        }
        byte[] physicalCamIds = get(LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);

        String physicalCamIdString = null;
        try {
            physicalCamIdString = new String(physicalCamIds, "UTF-8");
        } catch (java.io.UnsupportedEncodingException e) {
            throw new AssertionError("android.logicalCam.physicalIds must be UTF-8 string");
        }
        String[] physicalCameraIdList = physicalCamIdString.split("\0");

        return Collections.unmodifiableList(Arrays.asList(physicalCameraIdList));
    }

    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
     * The key entries below this point are generated from metadata
     * definitions in /system/media/camera/docs. Do not modify by hand or
@@ -1579,6 +1622,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
     *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT}</li>
     *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO CONSTRAINED_HIGH_SPEED_VIDEO}</li>
     *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING MOTION_TRACKING}</li>
     *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA LOGICAL_MULTI_CAMERA}</li>
     * </ul></p>
     * <p>This key is available on all devices.</p>
     *
@@ -1594,6 +1638,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
     * @see #REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT
     * @see #REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
     * @see #REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING
     * @see #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
     */
    @PublicKey
    public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
@@ -3169,6 +3214,54 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
    public static final Key<Boolean> DEPTH_DEPTH_IS_EXCLUSIVE =
            new Key<Boolean>("android.depth.depthIsExclusive", boolean.class);

    /**
     * <p>String containing the ids of the underlying physical cameras.</p>
     * <p>For a logical camera, this is concatenation of all underlying physical camera ids.
     * The null terminator for physical camera id must be preserved so that the whole string
     * can be tokenized using '\0' to generate list of physical camera ids.</p>
     * <p>For example, if the physical camera ids of the logical camera are "2" and "3", the
     * value of this tag will be ['2', '\0', '3', '\0'].</p>
     * <p>The number of physical camera ids must be no less than 2.</p>
     * <p><b>Units</b>: UTF-8 null-terminated string</p>
     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
     * <p><b>Limited capability</b> -
     * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
     *
     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
     * @hide
     */
    public static final Key<byte[]> LOGICAL_MULTI_CAMERA_PHYSICAL_IDS =
            new Key<byte[]>("android.logicalMultiCamera.physicalIds", byte[].class);

    /**
     * <p>The accuracy of frame timestamp synchronization between physical cameras</p>
     * <p>The accuracy of the frame timestamp synchronization determines the physical cameras'
     * ability to start exposure at the same time. If the sensorSyncType is CALIBRATED,
     * the physical camera sensors usually run in master-slave mode so that their shutter
     * time is synchronized. For APPROXIMATE sensorSyncType, the camera sensors usually run in
     * master-master mode, and there could be offset between their start of exposure.</p>
     * <p>In both cases, all images generated for a particular capture request still carry the same
     * timestamps, so that they can be used to look up the matching frame number and
     * onCaptureStarted callback.</p>
     * <p><b>Possible values:</b>
     * <ul>
     *   <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE APPROXIMATE}</li>
     *   <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED CALIBRATED}</li>
     * </ul></p>
     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
     * <p><b>Limited capability</b> -
     * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
     *
     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
     * @see #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE
     * @see #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED
     */
    @PublicKey
    public static final Key<Integer> LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE =
            new Key<Integer>("android.logicalMultiCamera.sensorSyncType", int.class);

    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
     * End generated code
     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+67 −0
Original line number Diff line number Diff line
@@ -845,6 +845,53 @@ public abstract class CameraMetadata<TKey> {
     */
    public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10;

    /**
     * <p>The camera device is a logical camera backed by two or more physical cameras that are
     * also exposed to the application.</p>
     * <p>This capability requires the camera device to support the following:</p>
     * <ul>
     * <li>This camera device must list the following static metadata entries in {@link android.hardware.camera2.CameraCharacteristics }:<ul>
     * <li>android.logicalMultiCamera.physicalIds</li>
     * <li>{@link CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE android.logicalMultiCamera.sensorSyncType}</li>
     * </ul>
     * </li>
     * <li>The underlying physical cameras' static metadata must list the following entries,
     *   so that the application can correlate pixels from the physical streams:<ul>
     * <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference}</li>
     * <li>{@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}</li>
     * <li>{@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}</li>
     * <li>{@link CameraCharacteristics#LENS_INTRINSIC_CALIBRATION android.lens.intrinsicCalibration}</li>
     * <li>{@link CameraCharacteristics#LENS_RADIAL_DISTORTION android.lens.radialDistortion}</li>
     * </ul>
     * </li>
     * <li>The logical camera device must be LIMITED or higher device.</li>
     * </ul>
     * <p>Both the logical camera device and its underlying physical devices support the
     * mandatory stream combinations required for their device levels.</p>
     * <p>Additionally, for each guaranteed stream combination, the logical camera supports:</p>
     * <ul>
     * <li>Replacing one logical {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}
     *   or raw stream with two physical streams of the same size and format, each from a
     *   separate physical camera, given that the size and format are supported by both
     *   physical cameras.</li>
     * <li>Adding two raw streams, each from one physical camera, if the logical camera doesn't
     *   advertise RAW capability, but the underlying physical cameras do. This is usually
     *   the case when the physical cameras have different sensor sizes.</li>
     * </ul>
     * <p>Using physical streams in place of a logical stream of the same size and format will
     * not slow down the frame rate of the capture, as long as the minimum frame duration
     * of the physical and logical streams are the same.</p>
     *
     * @see CameraCharacteristics#LENS_INTRINSIC_CALIBRATION
     * @see CameraCharacteristics#LENS_POSE_REFERENCE
     * @see CameraCharacteristics#LENS_POSE_ROTATION
     * @see CameraCharacteristics#LENS_POSE_TRANSLATION
     * @see CameraCharacteristics#LENS_RADIAL_DISTORTION
     * @see CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
     */
    public static final int REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11;

    //
    // Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE
    //
@@ -1191,6 +1238,26 @@ public abstract class CameraMetadata<TKey> {
     */
    public static final int SYNC_MAX_LATENCY_UNKNOWN = -1;

    //
    // Enumeration values for CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
    //

    /**
     * <p>A software mechanism is used to synchronize between the physical cameras. As a result,
     * the timestamp of an image from a physical stream is only an approximation of the
     * image sensor start-of-exposure time.</p>
     * @see CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
     */
    public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE = 0;

    /**
     * <p>The camera device supports frame timestamp synchronization at the hardware level,
     * and the timestamp of a physical stream image accurately reflects its
     * start-of-exposure time.</p>
     * @see CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
     */
    public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED = 1;

    //
    // Enumeration values for CaptureRequest#COLOR_CORRECTION_MODE
    //
+19 −7
Original line number Diff line number Diff line
@@ -18,13 +18,14 @@ package android.hardware.camera2.impl;

import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;

import android.hardware.ICameraService;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.TotalCaptureResult;
@@ -34,7 +35,6 @@ import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.utils.SurfaceUtils;
import android.hardware.ICameraService;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -49,16 +49,14 @@ import android.view.Surface;

import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate
@@ -956,7 +954,8 @@ public class CameraDeviceImpl extends CameraDevice
        // callback is valid
        handler = checkHandler(handler, callback);

        // Make sure that there all requests have at least 1 surface; all surfaces are non-null
        // Make sure that there all requests have at least 1 surface; all surfaces are non-null;
        // the surface isn't a physical stream surface for reprocessing request
        for (CaptureRequest request : requestList) {
            if (request.getTargets().isEmpty()) {
                throw new IllegalArgumentException(
@@ -967,9 +966,22 @@ public class CameraDeviceImpl extends CameraDevice
                if (surface == null) {
                    throw new IllegalArgumentException("Null Surface targets are not allowed");
                }

                if (!request.isReprocess()) {
                    continue;
                }
                for (int i = 0; i < mConfiguredOutputs.size(); i++) {
                    OutputConfiguration configuration = mConfiguredOutputs.valueAt(i);
                    if (configuration.isForPhysicalCamera()
                            && configuration.getSurfaces().contains(surface)) {
                        throw new IllegalArgumentException(
                                "Reprocess request on physical stream is not allowed");
                    }
                }
            }

        }

        synchronized(mInterfaceLock) {
            checkIfCameraClosedOrInError();
            if (repeating) {
+57 −9
Original line number Diff line number Diff line
@@ -31,13 +31,12 @@ import android.util.Log;
import android.util.Size;
import android.view.Surface;

import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;

import static com.android.internal.util.Preconditions.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * A class for describing camera output, which contains a {@link Surface} and its specific
 * configuration for creating capture session.
@@ -266,6 +265,7 @@ public final class OutputConfiguration implements Parcelable {
        mConfiguredGenerationId = surface.getGenerationId();
        mIsDeferredConfig = false;
        mIsShared = false;
        mPhysicalCameraId = null;
    }

    /**
@@ -319,6 +319,7 @@ public final class OutputConfiguration implements Parcelable {
        mConfiguredGenerationId = 0;
        mIsDeferredConfig = true;
        mIsShared = false;
        mPhysicalCameraId = null;
    }

    /**
@@ -348,8 +349,9 @@ public final class OutputConfiguration implements Parcelable {
     * </ol>
     *
     * <p>To enable surface sharing, this function must be called before {@link
     * CameraDevice#createCaptureSessionByOutputConfigurations}. Calling this function after {@link
     * CameraDevice#createCaptureSessionByOutputConfigurations} has no effect.</p>
     * CameraDevice#createCaptureSessionByOutputConfigurations} or {@link
     * CameraDevice#createReprocessableCaptureSessionByConfigurations}. Calling this function after
     * {@link CameraDevice#createCaptureSessionByOutputConfigurations} has no effect.</p>
     *
     * <p>Up to {@link #getMaxSharedSurfaceCount} surfaces can be shared for an OutputConfiguration.
     * The supported surfaces for sharing must be of type SurfaceTexture, SurfaceView,
@@ -359,6 +361,44 @@ public final class OutputConfiguration implements Parcelable {
        mIsShared = true;
    }

    /**
     * Set the id of the physical camera for this OutputConfiguration
     *
     * <p>In the case one logical camera is made up of multiple physical cameras, it could be
     * desirable for the camera application to request streams from individual physical cameras.
     * This call achieves it by mapping the OutputConfiguration to the physical camera id.</p>
     *
     * <p>The valid physical camera id can be queried by {@link
     * android.hardware.camera2.CameraCharacteristics#getPhysicalCameraIds}.
     * </p>
     *
     * <p>Passing in a null physicalCameraId means that the OutputConfiguration is for a logical
     * stream.</p>
     *
     * <p>This function must be called before {@link
     * CameraDevice#createCaptureSessionByOutputConfigurations} or {@link
     * CameraDevice#createReprocessableCaptureSessionByConfigurations}. Calling this function
     * after {@link CameraDevice#createCaptureSessionByOutputConfigurations} or {@link
     * CameraDevice#createReprocessableCaptureSessionByConfigurations} has no effect.</p>
     *
     * <p>The surface belonging to a physical camera OutputConfiguration must not be used as input
     * or output of a reprocessing request. </p>
     */
    public void setPhysicalCameraId(@Nullable String physicalCameraId) {
        mPhysicalCameraId = physicalCameraId;
    }

    /**
     * Check if this configuration is for a physical camera.
     *
     * <p>This returns true if the output configuration was for a physical camera making up a
     * logical multi camera via {@link OutputConfiguration#setPhysicalCameraId}.</p>
     * @hide
     */
    public boolean isForPhysicalCamera() {
        return (mPhysicalCameraId != null);
    }

    /**
     * Check if this configuration has deferred configuration.
     *
@@ -487,6 +527,7 @@ public final class OutputConfiguration implements Parcelable {
        this.mConfiguredGenerationId = other.mConfiguredGenerationId;
        this.mIsDeferredConfig = other.mIsDeferredConfig;
        this.mIsShared = other.mIsShared;
        this.mPhysicalCameraId = other.mPhysicalCameraId;
    }

    /**
@@ -502,6 +543,7 @@ public final class OutputConfiguration implements Parcelable {
        boolean isShared = source.readInt() == 1;
        ArrayList<Surface> surfaces = new ArrayList<Surface>();
        source.readTypedList(surfaces, Surface.CREATOR);
        String physicalCameraId = source.readString();

        checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");

@@ -524,6 +566,7 @@ public final class OutputConfiguration implements Parcelable {
                    StreamConfigurationMap.imageFormatToDataspace(ImageFormat.PRIVATE);
            mConfiguredGenerationId = 0;
        }
        mPhysicalCameraId = physicalCameraId;
    }

    /**
@@ -622,6 +665,7 @@ public final class OutputConfiguration implements Parcelable {
        dest.writeInt(mIsDeferredConfig ? 1 : 0);
        dest.writeInt(mIsShared ? 1 : 0);
        dest.writeTypedList(mSurfaces);
        dest.writeString(mPhysicalCameraId);
    }

    /**
@@ -675,13 +719,15 @@ public final class OutputConfiguration implements Parcelable {
        if (mIsDeferredConfig) {
            return HashCodeHelpers.hashCode(
                    mRotation, mConfiguredSize.hashCode(), mConfiguredFormat, mConfiguredDataspace,
                    mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0);
                    mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0,
                    mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
        }

        return HashCodeHelpers.hashCode(
                mRotation, mSurfaces.hashCode(), mConfiguredGenerationId,
                mConfiguredSize.hashCode(), mConfiguredFormat,
                mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0);
                mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0,
                mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
    }

    private static final String TAG = "OutputConfiguration";
@@ -701,4 +747,6 @@ public final class OutputConfiguration implements Parcelable {
    private final boolean mIsDeferredConfig;
    // Flag indicating if this config has shared surfaces
    private boolean mIsShared;
    // The physical camera id that this output configuration is for.
    private String mPhysicalCameraId;
}