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 */
16package android.hardware.camera2;
17
18import android.annotation.NonNull;
19import android.annotation.IntDef;
20
21import java.lang.annotation.Retention;
22import java.lang.annotation.RetentionPolicy;
23
24/**
25 * A report of failed capture for a single image capture from the image sensor.
26 *
27 * <p>CaptureFailures are produced by a {@link CameraDevice} if processing a
28 * {@link CaptureRequest} fails, either partially or fully. Use {@link #getReason}
29 * to determine the specific nature of the failed capture.</p>
30 *
31 * <p>Receiving a CaptureFailure means that the metadata associated with that frame number
32 * has been dropped -- no {@link CaptureResult} with the same frame number will be
33 * produced.</p>
34 */
35public class CaptureFailure {
36    /**
37     * The {@link CaptureResult} has been dropped this frame only due to an error
38     * in the framework.
39     *
40     * @see #getReason()
41     */
42    public static final int REASON_ERROR = 0;
43
44    /**
45     * The capture has failed due to a {@link CameraCaptureSession#abortCaptures} call from the
46     * application.
47     *
48     * @see #getReason()
49     */
50    public static final int REASON_FLUSHED = 1;
51
52     /** @hide */
53     @Retention(RetentionPolicy.SOURCE)
54     @IntDef(prefix = {"REASON_"}, value =
55         {REASON_ERROR,
56          REASON_FLUSHED })
57     public @interface FailureReason {};
58
59    private final CaptureRequest mRequest;
60    private final int mReason;
61    private final boolean mDropped;
62    private final int mSequenceId;
63    private final long mFrameNumber;
64
65    /**
66     * @hide
67     */
68    public CaptureFailure(CaptureRequest request, int reason,
69            boolean dropped, int sequenceId, long frameNumber) {
70        mRequest = request;
71        mReason = reason;
72        mDropped = dropped;
73        mSequenceId = sequenceId;
74        mFrameNumber = frameNumber;
75    }
76
77    /**
78     * Get the request associated with this failed capture.
79     *
80     * <p>Whenever a request is unsuccessfully captured, with
81     * {@link CameraCaptureSession.CaptureCallback#onCaptureFailed},
82     * the {@code failed capture}'s {@code getRequest()} will return that {@code request}.
83     * </p>
84     *
85     * <p>In particular,
86     * <code><pre>cameraDevice.capture(someRequest, new CaptureCallback() {
87     *     {@literal @}Override
88     *     void onCaptureFailed(CaptureRequest myRequest, CaptureFailure myFailure) {
89     *         assert(myFailure.getRequest.equals(myRequest) == true);
90     *     }
91     * };
92     * </code></pre>
93     * </p>
94     *
95     * @return The request associated with this failed capture. Never {@code null}.
96     */
97    @NonNull
98    public CaptureRequest getRequest() {
99        return mRequest;
100    }
101
102    /**
103     * Get the frame number associated with this failed capture.
104     *
105     * <p>Whenever a request has been processed, regardless of failed capture or success,
106     * it gets a unique frame number assigned to its future result/failed capture.</p>
107     *
108     * <p>This value monotonically increments, starting with 0,
109     * for every new result or failure; and the scope is the lifetime of the
110     * {@link CameraDevice}.</p>
111     *
112     * @return long frame number
113     */
114    public long getFrameNumber() {
115        return mFrameNumber;
116    }
117
118    /**
119     * Determine why the request was dropped, whether due to an error or to a user
120     * action.
121     *
122     * @return int The reason code.
123     *
124     * @see #REASON_ERROR
125     * @see #REASON_FLUSHED
126     */
127    @FailureReason
128    public int getReason() {
129        return mReason;
130    }
131
132    /**
133     * Determine if the image was captured from the camera.
134     *
135     * <p>If the image was not captured, no image buffers will be available.
136     * If the image was captured, then image buffers may be available.</p>
137     *
138     * @return boolean True if the image was captured, false otherwise.
139     */
140    public boolean wasImageCaptured() {
141        return !mDropped;
142    }
143
144    /**
145     * The sequence ID for this failed capture that was returned by the
146     * {@link CameraCaptureSession#capture} family of functions.
147     *
148     * <p>The sequence ID is a unique monotonically increasing value starting from 0,
149     * incremented every time a new group of requests is submitted to the CameraDevice.</p>
150     *
151     * @return int The ID for the sequence of requests that this capture failure is the result of
152     *
153     * @see CameraDevice.CaptureCallback#onCaptureSequenceCompleted
154     */
155    public int getSequenceId() {
156        return mSequenceId;
157    }
158}
159