1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.hardware.camera2;
17 
18 import android.annotation.IntDef;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 
25 /**
26  * A report of failed capture for a single image capture from the image sensor.
27  *
28  * <p>CaptureFailures are produced by a {@link CameraDevice} if processing a
29  * {@link CaptureRequest} fails, either partially or fully. Use {@link #getReason}
30  * to determine the specific nature of the failed capture.</p>
31  *
32  * <p>Receiving a CaptureFailure means that the metadata associated with that frame number
33  * has been dropped -- no {@link CaptureResult} with the same frame number will be
34  * produced.</p>
35  */
36 public class CaptureFailure {
37     /**
38      * The {@link CaptureResult} has been dropped this frame only due to an error
39      * in the framework.
40      *
41      * @see #getReason()
42      */
43     public static final int REASON_ERROR = 0;
44 
45     /**
46      * The capture has failed due to a {@link CameraCaptureSession#abortCaptures} call from the
47      * application.
48      *
49      * @see #getReason()
50      */
51     public static final int REASON_FLUSHED = 1;
52 
53      /** @hide */
54      @Retention(RetentionPolicy.SOURCE)
55      @IntDef(prefix = {"REASON_"}, value =
56          {REASON_ERROR,
57           REASON_FLUSHED })
58      public @interface FailureReason {};
59 
60     private final CaptureRequest mRequest;
61     private final int mReason;
62     private final boolean mWasImageCaptured;
63     private final int mSequenceId;
64     private final long mFrameNumber;
65     private final String mErrorPhysicalCameraId;
66 
67     /**
68      * @hide
69      */
CaptureFailure(CaptureRequest request, int reason, boolean wasImageCaptured, int sequenceId, long frameNumber, String errorPhysicalCameraId)70     public CaptureFailure(CaptureRequest request, int reason,
71             boolean wasImageCaptured, int sequenceId, long frameNumber,
72             String errorPhysicalCameraId) {
73         mRequest = request;
74         mReason = reason;
75         mWasImageCaptured = wasImageCaptured;
76         mSequenceId = sequenceId;
77         mFrameNumber = frameNumber;
78         mErrorPhysicalCameraId = errorPhysicalCameraId;
79     }
80 
81     /**
82      * Get the request associated with this failed capture.
83      *
84      * <p>Whenever a request is unsuccessfully captured, with
85      * {@link CameraCaptureSession.CaptureCallback#onCaptureFailed},
86      * the {@code failed capture}'s {@code getRequest()} will return that {@code request}.
87      * </p>
88      *
89      * <p>In particular,
90      * <code><pre>cameraDevice.capture(someRequest, new CaptureCallback() {
91      *     {@literal @}Override
92      *     void onCaptureFailed(CaptureRequest myRequest, CaptureFailure myFailure) {
93      *         assert(myFailure.getRequest.equals(myRequest) == true);
94      *     }
95      * };
96      * </code></pre>
97      * </p>
98      *
99      * @return The request associated with this failed capture. Never {@code null}.
100      */
101     @NonNull
getRequest()102     public CaptureRequest getRequest() {
103         return mRequest;
104     }
105 
106     /**
107      * Get the frame number associated with this failed capture.
108      *
109      * <p>Whenever a request has been processed, regardless of failed capture or success,
110      * it gets a unique frame number assigned to its future result/failed capture.</p>
111      *
112      * <p>This value monotonically increments, starting with 0,
113      * for every new result or failure; and the scope is the lifetime of the
114      * {@link CameraDevice}.</p>
115      *
116      * @return long frame number
117      */
getFrameNumber()118     public long getFrameNumber() {
119         return mFrameNumber;
120     }
121 
122     /**
123      * Determine why the request was dropped, whether due to an error or to a user
124      * action.
125      *
126      * @return int The reason code.
127      *
128      * @see #REASON_ERROR
129      * @see #REASON_FLUSHED
130      */
131     @FailureReason
getReason()132     public int getReason() {
133         return mReason;
134     }
135 
136     /**
137      * Determine if the image was captured from the camera.
138      *
139      * <p>If the image was not captured, no image buffers will be available.
140      * If the image was captured, then image buffers may be available.</p>
141      *
142      * @return boolean True if the image was captured, false otherwise.
143      */
wasImageCaptured()144     public boolean wasImageCaptured() {
145         return mWasImageCaptured;
146     }
147 
148     /**
149      * The sequence ID for this failed capture that was returned by the
150      * {@link CameraCaptureSession#capture} family of functions.
151      *
152      * <p>The sequence ID is a unique monotonically increasing value starting from 0,
153      * incremented every time a new group of requests is submitted to the CameraDevice.</p>
154      *
155      * @return int The ID for the sequence of requests that this capture failure is the result of
156      *
157      * @see CameraCaptureSession.CaptureCallback#onCaptureSequenceCompleted
158      */
getSequenceId()159     public int getSequenceId() {
160         return mSequenceId;
161     }
162 
163     /**
164      * The physical camera device ID in case the capture failure comes from a {@link CaptureRequest}
165      * with configured physical camera streams for a logical camera.
166      *
167      * @return String The physical camera device ID of the respective failing output.
168      *         {@code null} in case the capture request has no associated physical camera device.
169      * @see CaptureRequest.Builder#setPhysicalCameraKey
170      * @see android.hardware.camera2.params.OutputConfiguration#setPhysicalCameraId
171      */
getPhysicalCameraId()172     public @Nullable String getPhysicalCameraId() {
173         return mErrorPhysicalCameraId;
174     }
175 }
176