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
35namespace android {
36namespace hardware {
37namespace camera {
38namespace device {
39namespace V3_2 {
40namespace implementation {
41
42using ::android::hardware::camera::device::V3_2::CaptureRequest;
43using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
44using ::android::hardware::camera::device::V3_2::StreamConfiguration;
45using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
46using ::android::hardware::camera::common::V1_0::Status;
47using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
48using ::android::hardware::kSynchronizedReadWrite;
49using ::android::hardware::MessageQueue;
50using ::android::hardware::MQDescriptorSync;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
53using ::android::hardware::hidl_vec;
54using ::android::hardware::hidl_string;
55using ::android::sp;
56using ::android::Mutex;
57
58struct Camera3Stream;
59
60/**
61 * Function pointer types with C calling convention to
62 * use for HAL callback functions.
63 */
64extern "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
74struct 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
83    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
90    virtual sp<ICameraDeviceSession> getInterface() {
91        return new TrampolineSessionInterface_3_2(this);
92    }
93
94protected:
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
123protected:
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 {
210                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
343private:
344
345    struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
346        TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
347                mParent(parent) {}
348
349        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
355        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
361        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
367        virtual Return<void> getCaptureRequestMetadataQueue(
368                V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
369            return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
370        }
371
372        virtual Return<void> getCaptureResultMetadataQueue(
373                V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
374            return mParent->getCaptureResultMetadataQueue(_hidl_cb);
375        }
376
377        virtual Return<Status> flush() override {
378            return mParent->flush();
379        }
380
381        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