1 /*
2  * Copyright (C) 2020 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_6_EXTCAMERAOFFLINESESSION_H
18 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_6_EXTCAMERAOFFLINESESSION_H
19 
20 #include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
21 #include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
22 #include <android/hardware/camera/device/3.6/ICameraOfflineSession.h>
23 #include <android/hardware/camera/common/1.0/types.h>
24 #include <fmq/MessageQueue.h>
25 #include <hidl/MQDescriptor.h>
26 #include <deque>
27 #include <../../3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h>
28 #include <../../3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h>
29 #include <HandleImporter.h>
30 #include <Exif.h>
31 #include <android-base/unique_fd.h>
32 
33 namespace android {
34 namespace hardware {
35 namespace camera {
36 namespace device {
37 namespace V3_6 {
38 namespace implementation {
39 
40 using ::android::hardware::camera::device::V3_2::BufferCache;
41 using ::android::hardware::camera::device::V3_5::BufferRequest;
42 using ::android::hardware::camera::device::V3_5::BufferRequestStatus;
43 using ::android::hardware::camera::device::V3_2::BufferStatus;
44 using ::android::hardware::camera::device::V3_2::CameraMetadata;
45 using ::android::hardware::camera::device::V3_2::CaptureRequest;
46 using ::android::hardware::camera::device::V3_2::CaptureResult;
47 using ::android::hardware::camera::device::V3_2::ErrorCode;
48 using ::android::hardware::camera::device::V3_5::ICameraDeviceCallback;
49 using ::android::hardware::camera::device::V3_2::MsgType;
50 using ::android::hardware::camera::device::V3_2::NotifyMsg;
51 using ::android::hardware::camera::device::V3_2::RequestTemplate;
52 using ::android::hardware::camera::device::V3_2::Stream;
53 using ::android::hardware::camera::device::V3_5::StreamConfiguration;
54 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
55 using ::android::hardware::camera::device::V3_2::StreamRotation;
56 using ::android::hardware::camera::device::V3_2::StreamType;
57 using ::android::hardware::camera::device::V3_2::DataspaceFlags;
58 using ::android::hardware::camera::device::V3_2::CameraBlob;
59 using ::android::hardware::camera::device::V3_2::CameraBlobId;
60 using ::android::hardware::camera::device::V3_4::HalStreamConfiguration;
61 using ::android::hardware::camera::device::V3_6::ICameraOfflineSession;
62 using ::android::hardware::camera::common::V1_0::Status;
63 using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
64 using ::android::hardware::camera::common::V1_0::helper::ExifUtils;
65 using ::android::hardware::camera::external::common::ExternalCameraConfig;
66 using ::android::hardware::camera::external::common::Size;
67 using ::android::hardware::camera::external::common::SizeHasher;
68 using ::android::hardware::graphics::common::V1_0::BufferUsage;
69 using ::android::hardware::graphics::common::V1_0::Dataspace;
70 using ::android::hardware::graphics::common::V1_0::PixelFormat;
71 using ::android::hardware::kSynchronizedReadWrite;
72 using ::android::hardware::MessageQueue;
73 using ::android::hardware::MQDescriptorSync;
74 using ::android::hardware::Return;
75 using ::android::hardware::Void;
76 using ::android::hardware::hidl_vec;
77 using ::android::hardware::hidl_string;
78 using ::android::sp;
79 using ::android::Mutex;
80 using ::android::base::unique_fd;
81 
82 using ::android::hardware::camera::device::V3_4::implementation::SupportedV4L2Format;
83 using ::android::hardware::camera::device::V3_4::implementation::CroppingType;
84 using ::android::hardware::camera::device::V3_4::implementation::CirculatingBuffers;
85 using ::android::hardware::camera::device::V3_4::implementation::HalRequest;
86 using ::android::hardware::camera::device::V3_4::implementation::OutputThreadInterface;
87 
88 struct ExternalCameraOfflineSession : public virtual RefBase,
89         public virtual OutputThreadInterface {
90 
91     ExternalCameraOfflineSession(
92             const CroppingType& croppingType,
93             const common::V1_0::helper::CameraMetadata& chars,
94             const std::string& cameraId,
95             const std::string& exifMake,
96             const std::string& exifModel,
97             uint32_t blobBufferSize,
98             bool afTrigger,
99             const hidl_vec<Stream>& offlineStreams,
100             std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
101             const std::map<int, CirculatingBuffers>& circulatingBuffers);
102 
103     bool initialize();
104 
105     virtual ~ExternalCameraOfflineSession();
106 
107     // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
108     // dealing with minor version revs and simultaneous implementation and interface inheritance
getInterfaceExternalCameraOfflineSession109     virtual sp<V3_6::ICameraOfflineSession> getInterface() {
110         return new TrampolineSessionInterface_3_6(this);
111     }
112 
113 protected:
114 
115     // Methods from OutputThreadInterface
116     virtual Status importBuffer(int32_t streamId,
117             uint64_t bufId, buffer_handle_t buf,
118             /*out*/buffer_handle_t** outBufPtr,
119             bool allowEmptyBuf) override;
120 
121     virtual Status processCaptureResult(std::shared_ptr<HalRequest>&) override;
122 
123     virtual Status processCaptureRequestError(const std::shared_ptr<HalRequest>&,
124             /*out*/std::vector<NotifyMsg>* msgs = nullptr,
125             /*out*/std::vector<CaptureResult>* results = nullptr) override;
126 
127     virtual ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const override;
128 
129     virtual void notifyError(uint32_t frameNumber, int32_t streamId, ErrorCode ec) override;
130     // End of OutputThreadInterface methods
131 
132     class OutputThread : public V3_5::implementation::ExternalCameraDeviceSession::OutputThread {
133     public:
OutputThreadExternalCameraOfflineSession134         OutputThread(
135                 wp<OutputThreadInterface> parent, CroppingType ct,
136                 const common::V1_0::helper::CameraMetadata& chars,
137                 sp<V3_5::implementation::ExternalCameraDeviceSession::BufferRequestThread> bufReqThread,
138                 std::deque<std::shared_ptr<HalRequest>>& offlineReqs) :
139                 V3_5::implementation::ExternalCameraDeviceSession::OutputThread(
140                         parent, ct, chars, bufReqThread),
141                 mOfflineReqs(offlineReqs) {}
142 
143         virtual bool threadLoop() override;
144 
145     protected:
146         std::deque<std::shared_ptr<HalRequest>> mOfflineReqs;
147     }; // OutputThread
148 
149 
150     Return<void> setCallback(const sp<ICameraDeviceCallback>& cb);
151 
152     Return<void> getCaptureResultMetadataQueue(
153             V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb);
154 
155     Return<void> close();
156 
157     void initOutputThread();
158 
159     void invokeProcessCaptureResultCallback(
160             hidl_vec<CaptureResult> &results, bool tryWriteFmq);
161 
162     status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
163 
164     void cleanupBuffersLocked(int id);
165 
166     // Protect (most of) HIDL interface methods from synchronized-entering
167     mutable Mutex mInterfaceLock;
168 
169     mutable Mutex mLock; // Protect all data members except otherwise noted
170 
171     bool mClosed = false;
172     const CroppingType mCroppingType;
173     const common::V1_0::helper::CameraMetadata mChars;
174     const std::string mCameraId;
175     const std::string mExifMake;
176     const std::string mExifModel;
177     const uint32_t mBlobBufferSize;
178 
179     std::mutex mAfTriggerLock; // protect mAfTrigger
180     bool mAfTrigger;
181 
182     const hidl_vec<Stream> mOfflineStreams;
183     std::deque<std::shared_ptr<HalRequest>> mOfflineReqs;
184 
185     // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
186     mutable Mutex mCbsLock;
187     std::map<int, CirculatingBuffers> mCirculatingBuffers;
188 
189     static HandleImporter sHandleImporter;
190 
191     using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
192     std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
193 
194     // Protect against invokeProcessCaptureResultCallback()
195     Mutex mProcessCaptureResultLock;
196 
197     sp<ICameraDeviceCallback> mCallback;
198 
199     sp<V3_5::implementation::ExternalCameraDeviceSession::BufferRequestThread> mBufferRequestThread;
200     sp<OutputThread> mOutputThread;
201 private:
202 
203     struct TrampolineSessionInterface_3_6 : public ICameraOfflineSession {
TrampolineSessionInterface_3_6ExternalCameraOfflineSession::TrampolineSessionInterface_3_6204         TrampolineSessionInterface_3_6(sp<ExternalCameraOfflineSession> parent) :
205                 mParent(parent) {}
206 
setCallbackExternalCameraOfflineSession::TrampolineSessionInterface_3_6207         virtual Return<void> setCallback(const sp<ICameraDeviceCallback>& cb) override {
208             return mParent->setCallback(cb);
209         }
210 
getCaptureResultMetadataQueueExternalCameraOfflineSession::TrampolineSessionInterface_3_6211         virtual Return<void> getCaptureResultMetadataQueue(
212                 V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override {
213             return mParent->getCaptureResultMetadataQueue(_hidl_cb);
214         }
215 
closeExternalCameraOfflineSession::TrampolineSessionInterface_3_6216         virtual Return<void> close() override {
217             return mParent->close();
218         }
219 
220     private:
221         sp<ExternalCameraOfflineSession> mParent;
222     };
223 };
224 
225 }  // namespace implementation
226 }  // namespace V3_6
227 }  // namespace device
228 }  // namespace camera
229 }  // namespace hardware
230 }  // namespace android
231 
232 #endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_6_EXTCAMERAOFFLINESESSION_H
233