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     void postProcessConfigurationFailureLocked(const StreamConfiguration& requestedConfiguration);
124 
125 protected:
126 
127     // protecting mClosed/mDisconnected/mInitFail
128     mutable Mutex mStateLock;
129     // device is closed either
130     //    - closed by user
131     //    - init failed
132     //    - camera disconnected
133     bool mClosed = false;
134 
135     // Set by CameraDevice (when external camera is disconnected)
136     bool mDisconnected = false;
137 
138     struct AETriggerCancelOverride {
139         bool applyAeLock;
140         uint8_t aeLock;
141         bool applyAePrecaptureTrigger;
142         uint8_t aePrecaptureTrigger;
143     };
144 
145     camera3_device_t* mDevice;
146     const uint32_t mDeviceVersion;
147     const bool mFreeBufEarly;
148     bool mIsAELockAvailable;
149     bool mDerivePostRawSensKey;
150     uint32_t mNumPartialResults;
151     // Stream ID -> Camera3Stream cache
152     std::map<int, Camera3Stream> mStreamMap;
153 
154     mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
155     // (streamID, frameNumber) -> inflight buffer cache
156     std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
157 
158     // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
159     std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
160     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
161     std::map<uint32_t, bool> mInflightRawBoostPresent;
162     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
163 
164     static const uint64_t BUFFER_ID_NO_BUFFER = 0;
165     // buffers currently ciculating between HAL and camera service
166     // key: bufferId sent via HIDL interface
167     // value: imported buffer_handle_t
168     // Buffer will be imported during process_capture_request and will be freed
169     // when the its stream is deleted or camera device session is closed
170     typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
171     // Stream ID -> circulating buffers map
172     std::map<int, CirculatingBuffers> mCirculatingBuffers;
173 
174     static HandleImporter sHandleImporter;
175     static buffer_handle_t sEmptyBuffer;
176 
177     bool mInitFail;
178     bool mFirstRequest = false;
179 
180     common::V1_0::helper::CameraMetadata mDeviceInfo;
181 
182     using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
183     std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
184     using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
185     std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
186 
187     class ResultBatcher {
188     public:
189         ResultBatcher(const sp<ICameraDeviceCallback>& callback);
190         void setNumPartialResults(uint32_t n);
191         void setBatchedStreams(const std::vector<int>& streamsToBatch);
192         void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
193 
194         void registerBatch(uint32_t frameNumber, uint32_t batchSize);
195         void notify(NotifyMsg& msg);
196         void processCaptureResult(CaptureResult& result);
197 
198     protected:
199         struct InflightBatch {
200             // Protect access to entire struct. Acquire this lock before read/write any data or
201             // calling any methods. processCaptureResult and notify will compete for this lock
202             // HIDL IPCs might be issued while the lock is held
203             Mutex mLock;
204 
205             bool allDelivered() const;
206 
207             uint32_t mFirstFrame;
208             uint32_t mLastFrame;
209             uint32_t mBatchSize;
210 
211             bool mShutterDelivered = false;
212             std::vector<NotifyMsg> mShutterMsgs;
213 
214             struct BufferBatch {
BufferBatchCameraDeviceSession::InflightBatch::BufferBatch215                 BufferBatch(uint32_t batchSize) {
216                     mBuffers.reserve(batchSize);
217                 }
218                 bool mDelivered = false;
219                 // This currently assumes every batched request will output to the batched stream
220                 // and since HAL must always send buffers in order, no frameNumber tracking is
221                 // needed
222                 std::vector<StreamBuffer> mBuffers;
223             };
224             // Stream ID -> VideoBatch
225             std::unordered_map<int, BufferBatch> mBatchBufs;
226 
227             struct MetadataBatch {
228                 //                   (frameNumber, metadata)
229                 std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
230             };
231             // Partial result IDs that has been delivered to framework
232             uint32_t mNumPartialResults;
233             uint32_t mPartialResultProgress = 0;
234             // partialResult -> MetadataBatch
235             std::map<uint32_t, MetadataBatch> mResultMds;
236 
237             // Set to true when batch is removed from mInflightBatches
238             // processCaptureResult and notify must check this flag after acquiring mLock to make
239             // sure this batch isn't removed while waiting for mLock
240             bool mRemoved = false;
241         };
242 
243 
244         // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
245         // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
246         // It's possible that the InflightBatch is removed from mInflightBatches before the
247         // InflightBatch::mLock is acquired (most likely caused by an error notification), so
248         // caller must check InflightBatch::mRemoved flag after the lock is acquried.
249         // This method will hold ResultBatcher::mLock briefly
250         std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
251 
252         static const int NOT_BATCHED = -1;
253 
254         // move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
255         // handle
256         void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
257         void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
258 
259         void sendBatchMetadataLocked(
260                 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
261 
262         // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
263         // This method will hold ResultBatcher::mLock briefly
264         void checkAndRemoveFirstBatch();
265 
266         // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
267         // HIDL IPC methods will be called during these methods.
268         void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
269         // send buffers for all batched streams
270         void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
271         // send buffers for specified streams
272         void sendBatchBuffersLocked(
273                 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
274        // End of sendXXXX methods
275 
276         // helper methods
277         void freeReleaseFences(hidl_vec<CaptureResult>&);
278         void notifySingleMsg(NotifyMsg& msg);
279         void processOneCaptureResult(CaptureResult& result);
280         void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
281 
282         // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
283         // processCaptureRequest, processCaptureResult, notify will compete for this lock
284         // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
285         mutable Mutex mLock;
286         std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
287         uint32_t mNumPartialResults;
288         std::vector<int> mStreamsToBatch;
289         const sp<ICameraDeviceCallback> mCallback;
290         std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
291 
292         // Protect against invokeProcessCaptureResultCallback()
293         Mutex mProcessCaptureResultLock;
294 
295     } mResultBatcher;
296 
297     std::vector<int> mVideoStreamIds;
298 
299     bool initialize();
300 
301     static bool shouldFreeBufEarly();
302 
303     Status initStatus() const;
304 
305     // Validate and import request's input buffer and acquire fence
306     virtual Status importRequest(
307             const CaptureRequest& request,
308             hidl_vec<buffer_handle_t*>& allBufPtrs,
309             hidl_vec<int>& allFences);
310 
311     Status importRequestImpl(
312             const CaptureRequest& request,
313             hidl_vec<buffer_handle_t*>& allBufPtrs,
314             hidl_vec<int>& allFences,
315             // Optional argument for ICameraDeviceSession@3.5 impl
316             bool allowEmptyBuf = false);
317 
318     Status importBuffer(int32_t streamId,
319             uint64_t bufId, buffer_handle_t buf,
320             /*out*/buffer_handle_t** outBufPtr,
321             bool allowEmptyBuf);
322 
323     static void cleanupInflightFences(
324             hidl_vec<int>& allFences, size_t numFences);
325 
326     void cleanupBuffersLocked(int id);
327 
328     void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
329 
330     android_dataspace mapToLegacyDataspace(
331             android_dataspace dataSpace) const;
332 
333     bool handleAePrecaptureCancelRequestLocked(
334             const camera3_capture_request_t &halRequest,
335             android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
336             AETriggerCancelOverride *override /*out*/);
337 
338     void overrideResultForPrecaptureCancelLocked(
339             const AETriggerCancelOverride &aeTriggerCancelOverride,
340             ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
341 
342     Status processOneCaptureRequest(const CaptureRequest& request);
343     /**
344      * Static callback forwarding methods from HAL to instance
345      */
346     static callbacks_process_capture_result_t sProcessCaptureResult;
347     static callbacks_notify_t sNotify;
348 
349     // By default camera service uses frameNumber/streamId pair to retrieve the buffer that
350     // was sent to HAL. Override this implementation if HAL is using buffers from buffer management
351     // APIs to send output buffer.
352     virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId);
353 
354     status_t constructCaptureResult(CaptureResult& result,
355                                 const camera3_capture_result *hal_result);
356 
357     // Static helper method to copy/shrink capture result metadata sent by HAL
358     // Temporarily allocated metadata copy will be hold in mds
359     static void sShrinkCaptureResult(
360             camera3_capture_result* dst, const camera3_capture_result* src,
361             std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
362             std::vector<const camera_metadata_t*>* physCamMdArray,
363             bool handlePhysCam);
364     static bool sShouldShrink(const camera_metadata_t* md);
365     static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src);
366 
367 private:
368 
369     struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
TrampolineSessionInterface_3_2CameraDeviceSession::TrampolineSessionInterface_3_2370         TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
371                 mParent(parent) {}
372 
constructDefaultRequestSettingsCameraDeviceSession::TrampolineSessionInterface_3_2373         virtual Return<void> constructDefaultRequestSettings(
374                 V3_2::RequestTemplate type,
375                 V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
376             return mParent->constructDefaultRequestSettings(type, _hidl_cb);
377         }
378 
configureStreamsCameraDeviceSession::TrampolineSessionInterface_3_2379         virtual Return<void> configureStreams(
380                 const V3_2::StreamConfiguration& requestedConfiguration,
381                 V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
382             return mParent->configureStreams(requestedConfiguration, _hidl_cb);
383         }
384 
processCaptureRequestCameraDeviceSession::TrampolineSessionInterface_3_2385         virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
386                 const hidl_vec<V3_2::BufferCache>& cachesToRemove,
387                 V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
388             return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
389         }
390 
getCaptureRequestMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2391         virtual Return<void> getCaptureRequestMetadataQueue(
392                 V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
393             return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
394         }
395 
getCaptureResultMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2396         virtual Return<void> getCaptureResultMetadataQueue(
397                 V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
398             return mParent->getCaptureResultMetadataQueue(_hidl_cb);
399         }
400 
flushCameraDeviceSession::TrampolineSessionInterface_3_2401         virtual Return<Status> flush() override {
402             return mParent->flush();
403         }
404 
closeCameraDeviceSession::TrampolineSessionInterface_3_2405         virtual Return<void> close() override {
406             return mParent->close();
407         }
408 
409     private:
410         sp<CameraDeviceSession> mParent;
411     };
412 };
413 
414 }  // namespace implementation
415 }  // namespace V3_2
416 }  // namespace device
417 }  // namespace camera
418 }  // namespace hardware
419 }  // namespace android
420 
421 #endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
422