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 struct Camera3Stream;
59 
60 /**
61  * Function pointer types with C calling convention to
62  * use for HAL callback functions.
63  */
64 extern "C" {
65     typedef void (callbacks_process_capture_result_t)(
66         const struct camera3_callback_ops *,
67         const camera3_capture_result_t *);
68 
69     typedef void (callbacks_notify_t)(
70         const struct camera3_callback_ops *,
71         const camera3_notify_msg_t *);
72 }
73 
74 struct CameraDeviceSession : public virtual RefBase, protected camera3_callback_ops  {
75 
76     CameraDeviceSession(camera3_device_t*,
77                         const camera_metadata_t* deviceInfo,
78                         const sp<ICameraDeviceCallback>&);
79     virtual ~CameraDeviceSession();
80     // Call by CameraDevice to dump active device states
81     void dumpState(const native_handle_t* fd);
82     // Caller must use this method to check if CameraDeviceSession ctor failed
isInitFailedCameraDeviceSession83     bool isInitFailed() { return mInitFail; }
84     // Used by CameraDevice to signal external camera disconnected
85     void disconnect();
86     bool isClosed();
87 
88     // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
89     // dealing with minor version revs and simultaneous implementation and interface inheritance
getInterfaceCameraDeviceSession90     virtual sp<ICameraDeviceSession> getInterface() {
91         return new TrampolineSessionInterface_3_2(this);
92     }
93 
94 protected:
95 
96     // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow
97 
98     Return<void> constructDefaultRequestSettings(
99             RequestTemplate type,
100             ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
101     Return<void> configureStreams(
102             const StreamConfiguration& requestedConfiguration,
103             ICameraDeviceSession::configureStreams_cb _hidl_cb);
104     Return<void> getCaptureRequestMetadataQueue(
105         ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb);
106     Return<void> getCaptureResultMetadataQueue(
107         ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb);
108     Return<void> processCaptureRequest(
109             const hidl_vec<CaptureRequest>& requests,
110             const hidl_vec<BufferCache>& cachesToRemove,
111             ICameraDeviceSession::processCaptureRequest_cb _hidl_cb);
112     Return<Status> flush();
113     Return<void> close();
114 
115     // Helper methods
116     Status constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata);
117 
118     bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration,
119             camera3_stream_configuration_t *stream_list /*out*/,
120             hidl_vec<camera3_stream_t*> *streams /*out*/);
121     void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration);
122 
123 protected:
124 
125     // protecting mClosed/mDisconnected/mInitFail
126     mutable Mutex mStateLock;
127     // device is closed either
128     //    - closed by user
129     //    - init failed
130     //    - camera disconnected
131     bool mClosed = false;
132 
133     // Set by CameraDevice (when external camera is disconnected)
134     bool mDisconnected = false;
135 
136     struct AETriggerCancelOverride {
137         bool applyAeLock;
138         uint8_t aeLock;
139         bool applyAePrecaptureTrigger;
140         uint8_t aePrecaptureTrigger;
141     };
142 
143     camera3_device_t* mDevice;
144     const uint32_t mDeviceVersion;
145     bool mIsAELockAvailable;
146     bool mDerivePostRawSensKey;
147     uint32_t mNumPartialResults;
148     // Stream ID -> Camera3Stream cache
149     std::map<int, Camera3Stream> mStreamMap;
150 
151     mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
152     // (streamID, frameNumber) -> inflight buffer cache
153     std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
154 
155     // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
156     std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
157     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
158     std::map<uint32_t, bool> mInflightRawBoostPresent;
159     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
160 
161     // buffers currently ciculating between HAL and camera service
162     // key: bufferId sent via HIDL interface
163     // value: imported buffer_handle_t
164     // Buffer will be imported during process_capture_request and will be freed
165     // when the its stream is deleted or camera device session is closed
166     typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
167     // Stream ID -> circulating buffers map
168     std::map<int, CirculatingBuffers> mCirculatingBuffers;
169 
170     static HandleImporter sHandleImporter;
171 
172     bool mInitFail;
173     bool mFirstRequest = false;
174 
175     common::V1_0::helper::CameraMetadata mDeviceInfo;
176 
177     using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
178     std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
179     using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
180     std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
181 
182     class ResultBatcher {
183     public:
184         ResultBatcher(const sp<ICameraDeviceCallback>& callback);
185         void setNumPartialResults(uint32_t n);
186         void setBatchedStreams(const std::vector<int>& streamsToBatch);
187         void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
188 
189         void registerBatch(uint32_t frameNumber, uint32_t batchSize);
190         void notify(NotifyMsg& msg);
191         void processCaptureResult(CaptureResult& result);
192 
193     protected:
194         struct InflightBatch {
195             // Protect access to entire struct. Acquire this lock before read/write any data or
196             // calling any methods. processCaptureResult and notify will compete for this lock
197             // HIDL IPCs might be issued while the lock is held
198             Mutex mLock;
199 
200             bool allDelivered() const;
201 
202             uint32_t mFirstFrame;
203             uint32_t mLastFrame;
204             uint32_t mBatchSize;
205 
206             bool mShutterDelivered = false;
207             std::vector<NotifyMsg> mShutterMsgs;
208 
209             struct BufferBatch {
BufferBatchCameraDeviceSession::InflightBatch::BufferBatch210                 BufferBatch(uint32_t batchSize) {
211                     mBuffers.reserve(batchSize);
212                 }
213                 bool mDelivered = false;
214                 // This currently assumes every batched request will output to the batched stream
215                 // and since HAL must always send buffers in order, no frameNumber tracking is
216                 // needed
217                 std::vector<StreamBuffer> mBuffers;
218             };
219             // Stream ID -> VideoBatch
220             std::unordered_map<int, BufferBatch> mBatchBufs;
221 
222             struct MetadataBatch {
223                 //                   (frameNumber, metadata)
224                 std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
225             };
226             // Partial result IDs that has been delivered to framework
227             uint32_t mNumPartialResults;
228             uint32_t mPartialResultProgress = 0;
229             // partialResult -> MetadataBatch
230             std::map<uint32_t, MetadataBatch> mResultMds;
231 
232             // Set to true when batch is removed from mInflightBatches
233             // processCaptureResult and notify must check this flag after acquiring mLock to make
234             // sure this batch isn't removed while waiting for mLock
235             bool mRemoved = false;
236         };
237 
238 
239         // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
240         // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
241         // It's possible that the InflightBatch is removed from mInflightBatches before the
242         // InflightBatch::mLock is acquired (most likely caused by an error notification), so
243         // caller must check InflightBatch::mRemoved flag after the lock is acquried.
244         // This method will hold ResultBatcher::mLock briefly
245         std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
246 
247         static const int NOT_BATCHED = -1;
248 
249         // move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
250         // handle
251         void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
252         void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
253 
254         void sendBatchMetadataLocked(
255                 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
256 
257         // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
258         // This method will hold ResultBatcher::mLock briefly
259         void checkAndRemoveFirstBatch();
260 
261         // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
262         // HIDL IPC methods will be called during these methods.
263         void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
264         // send buffers for all batched streams
265         void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
266         // send buffers for specified streams
267         void sendBatchBuffersLocked(
268                 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
269        // End of sendXXXX methods
270 
271         // helper methods
272         void freeReleaseFences(hidl_vec<CaptureResult>&);
273         void notifySingleMsg(NotifyMsg& msg);
274         void processOneCaptureResult(CaptureResult& result);
275         void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
276 
277         // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
278         // processCaptureRequest, processCaptureResult, notify will compete for this lock
279         // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
280         mutable Mutex mLock;
281         std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
282         uint32_t mNumPartialResults;
283         std::vector<int> mStreamsToBatch;
284         const sp<ICameraDeviceCallback> mCallback;
285         std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
286 
287         // Protect against invokeProcessCaptureResultCallback()
288         Mutex mProcessCaptureResultLock;
289 
290     } mResultBatcher;
291 
292     std::vector<int> mVideoStreamIds;
293 
294     bool initialize();
295 
296     Status initStatus() const;
297 
298     // Validate and import request's input buffer and acquire fence
299     Status importRequest(
300             const CaptureRequest& request,
301             hidl_vec<buffer_handle_t*>& allBufPtrs,
302             hidl_vec<int>& allFences);
303 
304     static void cleanupInflightFences(
305             hidl_vec<int>& allFences, size_t numFences);
306 
307     void cleanupBuffersLocked(int id);
308 
309     void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
310 
311     android_dataspace mapToLegacyDataspace(
312             android_dataspace dataSpace) const;
313 
314     bool handleAePrecaptureCancelRequestLocked(
315             const camera3_capture_request_t &halRequest,
316             android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
317             AETriggerCancelOverride *override /*out*/);
318 
319     void overrideResultForPrecaptureCancelLocked(
320             const AETriggerCancelOverride &aeTriggerCancelOverride,
321             ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
322 
323     Status processOneCaptureRequest(const CaptureRequest& request);
324     /**
325      * Static callback forwarding methods from HAL to instance
326      */
327     static callbacks_process_capture_result_t sProcessCaptureResult;
328     static callbacks_notify_t sNotify;
329 
330     status_t constructCaptureResult(CaptureResult& result,
331                                 const camera3_capture_result *hal_result);
332 
333     // Static helper method to copy/shrink capture result metadata sent by HAL
334     // Temporarily allocated metadata copy will be hold in mds
335     static void sShrinkCaptureResult(
336             camera3_capture_result* dst, const camera3_capture_result* src,
337             std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
338             std::vector<const camera_metadata_t*>* physCamMdArray,
339             bool handlePhysCam);
340     static bool sShouldShrink(const camera_metadata_t* md);
341     static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src);
342 
343 private:
344 
345     struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
TrampolineSessionInterface_3_2CameraDeviceSession::TrampolineSessionInterface_3_2346         TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
347                 mParent(parent) {}
348 
constructDefaultRequestSettingsCameraDeviceSession::TrampolineSessionInterface_3_2349         virtual Return<void> constructDefaultRequestSettings(
350                 V3_2::RequestTemplate type,
351                 V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
352             return mParent->constructDefaultRequestSettings(type, _hidl_cb);
353         }
354 
configureStreamsCameraDeviceSession::TrampolineSessionInterface_3_2355         virtual Return<void> configureStreams(
356                 const V3_2::StreamConfiguration& requestedConfiguration,
357                 V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
358             return mParent->configureStreams(requestedConfiguration, _hidl_cb);
359         }
360 
processCaptureRequestCameraDeviceSession::TrampolineSessionInterface_3_2361         virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
362                 const hidl_vec<V3_2::BufferCache>& cachesToRemove,
363                 V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
364             return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
365         }
366 
getCaptureRequestMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2367         virtual Return<void> getCaptureRequestMetadataQueue(
368                 V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
369             return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
370         }
371 
getCaptureResultMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2372         virtual Return<void> getCaptureResultMetadataQueue(
373                 V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
374             return mParent->getCaptureResultMetadataQueue(_hidl_cb);
375         }
376 
flushCameraDeviceSession::TrampolineSessionInterface_3_2377         virtual Return<Status> flush() override {
378             return mParent->flush();
379         }
380 
closeCameraDeviceSession::TrampolineSessionInterface_3_2381         virtual Return<void> close() override {
382             return mParent->close();
383         }
384 
385     private:
386         sp<CameraDeviceSession> mParent;
387     };
388 };
389 
390 }  // namespace implementation
391 }  // namespace V3_2
392 }  // namespace device
393 }  // namespace camera
394 }  // namespace hardware
395 }  // namespace android
396 
397 #endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
398