1 /*
2  * Copyright (C) 2016 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 
17 #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
18 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
19 
20 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
21 #include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
22 #include <fmq/MessageQueue.h>
23 #include <hidl/MQDescriptor.h>
24 #include <hidl/Status.h>
25 #include <include/convert.h>
26 #include <deque>
27 #include <map>
28 #include <unordered_map>
29 #include "CameraMetadata.h"
30 #include "HandleImporter.h"
31 #include "hardware/camera3.h"
32 #include "hardware/camera_common.h"
33 #include "utils/Mutex.h"
34 
35 namespace android {
36 namespace hardware {
37 namespace camera {
38 namespace device {
39 namespace V3_2 {
40 namespace implementation {
41 
42 using ::android::hardware::camera::device::V3_2::CaptureRequest;
43 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
44 using ::android::hardware::camera::device::V3_2::StreamConfiguration;
45 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
46 using ::android::hardware::camera::common::V1_0::Status;
47 using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
48 using ::android::hardware::kSynchronizedReadWrite;
49 using ::android::hardware::MessageQueue;
50 using ::android::hardware::MQDescriptorSync;
51 using ::android::hardware::Return;
52 using ::android::hardware::Void;
53 using ::android::hardware::hidl_vec;
54 using ::android::hardware::hidl_string;
55 using ::android::sp;
56 using ::android::Mutex;
57 
58 /**
59  * Function pointer types with C calling convention to
60  * use for HAL callback functions.
61  */
62 extern "C" {
63     typedef void (callbacks_process_capture_result_t)(
64         const struct camera3_callback_ops *,
65         const camera3_capture_result_t *);
66 
67     typedef void (callbacks_notify_t)(
68         const struct camera3_callback_ops *,
69         const camera3_notify_msg_t *);
70 }
71 
72 struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops  {
73 
74     CameraDeviceSession(camera3_device_t*,
75                         const camera_metadata_t* deviceInfo,
76                         const sp<ICameraDeviceCallback>&);
77     ~CameraDeviceSession();
78     // Call by CameraDevice to dump active device states
79     void dumpState(const native_handle_t* fd);
80     // Caller must use this method to check if CameraDeviceSession ctor failed
isInitFailedCameraDeviceSession81     bool isInitFailed() { return mInitFail; }
82     // Used by CameraDevice to signal external camera disconnected
83     void disconnect();
84     bool isClosed();
85 
86     // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
87     Return<void> constructDefaultRequestSettings(
88             RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
89     Return<void> configureStreams(
90             const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
91     Return<void> getCaptureRequestMetadataQueue(
92         getCaptureRequestMetadataQueue_cb _hidl_cb) override;
93     Return<void> getCaptureResultMetadataQueue(
94         getCaptureResultMetadataQueue_cb _hidl_cb) override;
95     Return<void> processCaptureRequest(
96             const hidl_vec<CaptureRequest>& requests,
97             const hidl_vec<BufferCache>& cachesToRemove,
98             processCaptureRequest_cb _hidl_cb) override;
99     Return<Status> flush() override;
100     Return<void> close() override;
101 
102 private:
103     // protecting mClosed/mDisconnected/mInitFail
104     mutable Mutex mStateLock;
105     // device is closed either
106     //    - closed by user
107     //    - init failed
108     //    - camera disconnected
109     bool mClosed = false;
110 
111     // Set by CameraDevice (when external camera is disconnected)
112     bool mDisconnected = false;
113 
114     struct AETriggerCancelOverride {
115         bool applyAeLock;
116         uint8_t aeLock;
117         bool applyAePrecaptureTrigger;
118         uint8_t aePrecaptureTrigger;
119     };
120 
121     camera3_device_t* mDevice;
122     uint32_t mDeviceVersion;
123     bool mIsAELockAvailable;
124     bool mDerivePostRawSensKey;
125     uint32_t mNumPartialResults;
126     // Stream ID -> Camera3Stream cache
127     std::map<int, Camera3Stream> mStreamMap;
128 
129     mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
130     // (streamID, frameNumber) -> inflight buffer cache
131     std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
132 
133     // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
134     std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
135     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
136     std::map<uint32_t, bool> mInflightRawBoostPresent;
137     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
138 
139     // buffers currently ciculating between HAL and camera service
140     // key: bufferId sent via HIDL interface
141     // value: imported buffer_handle_t
142     // Buffer will be imported during process_capture_request and will be freed
143     // when the its stream is deleted or camera device session is closed
144     typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
145     // Stream ID -> circulating buffers map
146     std::map<int, CirculatingBuffers> mCirculatingBuffers;
147 
148     static HandleImporter sHandleImporter;
149 
150     bool mInitFail;
151 
152     common::V1_0::helper::CameraMetadata mDeviceInfo;
153 
154     using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
155     std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
156     using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
157     std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
158 
159     class ResultBatcher {
160     public:
161         ResultBatcher(const sp<ICameraDeviceCallback>& callback);
162         void setNumPartialResults(uint32_t n);
163         void setBatchedStreams(const std::vector<int>& streamsToBatch);
164         void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
165 
166         void registerBatch(const hidl_vec<CaptureRequest>& requests);
167         void notify(NotifyMsg& msg);
168         void processCaptureResult(CaptureResult& result);
169 
170     private:
171         struct InflightBatch {
172             // Protect access to entire struct. Acquire this lock before read/write any data or
173             // calling any methods. processCaptureResult and notify will compete for this lock
174             // HIDL IPCs might be issued while the lock is held
175             Mutex mLock;
176 
177             bool allDelivered() const;
178 
179             uint32_t mFirstFrame;
180             uint32_t mLastFrame;
181             uint32_t mBatchSize;
182 
183             bool mShutterDelivered = false;
184             std::vector<NotifyMsg> mShutterMsgs;
185 
186             struct BufferBatch {
BufferBatchCameraDeviceSession::InflightBatch::BufferBatch187                 BufferBatch(uint32_t batchSize) {
188                     mBuffers.reserve(batchSize);
189                 }
190                 bool mDelivered = false;
191                 // This currently assumes every batched request will output to the batched stream
192                 // and since HAL must always send buffers in order, no frameNumber tracking is
193                 // needed
194                 std::vector<StreamBuffer> mBuffers;
195             };
196             // Stream ID -> VideoBatch
197             std::unordered_map<int, BufferBatch> mBatchBufs;
198 
199             struct MetadataBatch {
200                 //                   (frameNumber, metadata)
201                 std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
202             };
203             // Partial result IDs that has been delivered to framework
204             uint32_t mNumPartialResults;
205             uint32_t mPartialResultProgress = 0;
206             // partialResult -> MetadataBatch
207             std::map<uint32_t, MetadataBatch> mResultMds;
208 
209             // Set to true when batch is removed from mInflightBatches
210             // processCaptureResult and notify must check this flag after acquiring mLock to make
211             // sure this batch isn't removed while waiting for mLock
212             bool mRemoved = false;
213         };
214 
215         static const int NOT_BATCHED = -1;
216 
217         // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
218         // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
219         // It's possible that the InflightBatch is removed from mInflightBatches before the
220         // InflightBatch::mLock is acquired (most likely caused by an error notification), so
221         // caller must check InflightBatch::mRemoved flag after the lock is acquried.
222         // This method will hold ResultBatcher::mLock briefly
223         std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
224 
225         // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
226         // This method will hold ResultBatcher::mLock briefly
227         void checkAndRemoveFirstBatch();
228 
229         // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
230         // HIDL IPC methods will be called during these methods.
231         void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
232         // send buffers for all batched streams
233         void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
234         // send buffers for specified streams
235         void sendBatchBuffersLocked(
236                 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
237         void sendBatchMetadataLocked(
238                 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
239         // End of sendXXXX methods
240 
241         // helper methods
242         void freeReleaseFences(hidl_vec<CaptureResult>&);
243         void notifySingleMsg(NotifyMsg& msg);
244         void processOneCaptureResult(CaptureResult& result);
245         void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
246 
247         // move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
248         // handle
249         void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
250         void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
251 
252         // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
253         // processCaptureRequest, processCaptureResult, notify will compete for this lock
254         // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
255         mutable Mutex mLock;
256         std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
257         uint32_t mNumPartialResults;
258         std::vector<int> mStreamsToBatch;
259         const sp<ICameraDeviceCallback> mCallback;
260         std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
261 
262         // Protect against invokeProcessCaptureResultCallback()
263         Mutex mProcessCaptureResultLock;
264 
265     } mResultBatcher;
266 
267     std::vector<int> mVideoStreamIds;
268 
269     bool initialize();
270 
271     Status initStatus() const;
272 
273     // Validate and import request's input buffer and acquire fence
274     Status importRequest(
275             const CaptureRequest& request,
276             hidl_vec<buffer_handle_t*>& allBufPtrs,
277             hidl_vec<int>& allFences);
278 
279     static void cleanupInflightFences(
280             hidl_vec<int>& allFences, size_t numFences);
281 
282     void cleanupBuffersLocked(int id);
283 
284     void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
285 
286     android_dataspace mapToLegacyDataspace(
287             android_dataspace dataSpace) const;
288 
289     bool handleAePrecaptureCancelRequestLocked(
290             const camera3_capture_request_t &halRequest,
291             android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
292             AETriggerCancelOverride *override /*out*/);
293 
294     void overrideResultForPrecaptureCancelLocked(
295             const AETriggerCancelOverride &aeTriggerCancelOverride,
296             ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
297 
298     Status processOneCaptureRequest(const CaptureRequest& request);
299     /**
300      * Static callback forwarding methods from HAL to instance
301      */
302     static callbacks_process_capture_result_t sProcessCaptureResult;
303     static callbacks_notify_t sNotify;
304 };
305 
306 }  // namespace implementation
307 }  // namespace V3_2
308 }  // namespace device
309 }  // namespace camera
310 }  // namespace hardware
311 }  // namespace android
312 
313 #endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
314