content: /*
   * Copyright (C) 2013 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package android.hardware.camera2;
  
  import android.annotation.IntDef;
  import android.annotation.NonNull;
  import android.annotation.Nullable;
  
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  
  /**
   * A report of failed capture for a single image capture from the image sensor.
   *
   * <p>CaptureFailures are produced by a {@link CameraDevice} if processing a
   * {@link CaptureRequest} fails, either partially or fully. Use {@link #getReason}
   * to determine the specific nature of the failed capture.</p>
   *
   * <p>Receiving a CaptureFailure means that the metadata associated with that frame number
   * has been dropped -- no {@link CaptureResult} with the same frame number will be
   * produced.</p>
   */
  public class CaptureFailure {
      /**
       * The {@link CaptureResult} has been dropped this frame only due to an error
       * in the framework.
       *
       * @see #getReason()
       */
      public static final int REASON_ERROR = 0;
  
      /**
       * The capture has failed due to a {@link CameraCaptureSession#abortCaptures} call from the
       * application.
       *
       * @see #getReason()
       */
      public static final int REASON_FLUSHED = 1;
  
       /** @hide */
       @Retention(RetentionPolicy.SOURCE)
       @IntDef(prefix = {"REASON_"}, value =
           {REASON_ERROR,
            REASON_FLUSHED })
       public @interface FailureReason {};
  
      private final CaptureRequest mRequest;
      private final int mReason;
      private final boolean mDropped;
      private final int mSequenceId;
      private final long mFrameNumber;
      private final String mErrorPhysicalCameraId;
  
      /**
       * @hide
       */
      public CaptureFailure(CaptureRequest request, int reason,
              boolean dropped, int sequenceId, long frameNumber, String errorPhysicalCameraId) {
          mRequest = request;
          mReason = reason;
          mDropped = dropped;
          mSequenceId = sequenceId;
          mFrameNumber = frameNumber;
          mErrorPhysicalCameraId = errorPhysicalCameraId;
      }
  
      /**
       * Get the request associated with this failed capture.
       *
       * <p>Whenever a request is unsuccessfully captured, with
       * {@link CameraCaptureSession.CaptureCallback#onCaptureFailed},
       * the {@code failed capture}'s {@code getRequest()} will return that {@code request}.
       * </p>
       *
       * <p>In particular,
       * <code><pre>cameraDevice.capture(someRequest, new CaptureCallback() {
       *     {@literal @}Override
       *     void onCaptureFailed(CaptureRequest myRequest, CaptureFailure myFailure) {
       *         assert(myFailure.getRequest.equals(myRequest) == true);
       *     }
       * };
       * </code></pre>
       * </p>
       *
       * @return The request associated with this failed capture. Never {@code null}.
       */
      @NonNull
      public CaptureRequest getRequest() {
          return mRequest;
      }
  
      /**
       * Get the frame number associated with this failed capture.
       *
       * <p>Whenever a request has been processed, regardless of failed capture or success,
       * it gets a unique frame number assigned to its future result/failed capture.</p>
       *
       * <p>This value monotonically increments, starting with 0,
       * for every new result or failure; and the scope is the lifetime of the
       * {@link CameraDevice}.</p>
       *
       * @return long frame number
       */
      public long getFrameNumber() {
          return mFrameNumber;
      }
  
      /**
       * Determine why the request was dropped, whether due to an error or to a user
       * action.
       *
       * @return int The reason code.
       *
       * @see #REASON_ERROR
       * @see #REASON_FLUSHED
       */
      @FailureReason
      public int getReason() {
          return mReason;
      }
  
      /**
       * Determine if the image was captured from the camera.
       *
       * <p>If the image was not captured, no image buffers will be available.
       * If the image was captured, then image buffers may be available.</p>
       *
       * @return boolean True if the image was captured, false otherwise.
       */
      public boolean wasImageCaptured() {
          return !mDropped;
      }
  
      /**
       * The sequence ID for this failed capture that was returned by the
       * {@link CameraCaptureSession#capture} family of functions.
       *
       * <p>The sequence ID is a unique monotonically increasing value starting from 0,
       * incremented every time a new group of requests is submitted to the CameraDevice.</p>
       *
       * @return int The ID for the sequence of requests that this capture failure is the result of
       *
       * @see CameraCaptureSession.CaptureCallback#onCaptureSequenceCompleted
       */
      public int getSequenceId() {
          return mSequenceId;
      }
  
      /**
       * The physical camera device ID in case the capture failure comes from a {@link CaptureRequest}
       * with configured physical camera streams for a logical camera.
       *
       * @return String The physical camera device ID of the respective failing output.
       *         {@code null} in case the capture request has no associated physical camera device.
       * @see CaptureRequest.Builder#setPhysicalCameraKey
       * @see android.hardware.camera2.params.OutputConfiguration#setPhysicalCameraId
       */
      public @Nullable String getPhysicalCameraId() {
          return mErrorPhysicalCameraId;
      }
  }
  