• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 #include <android/hardware/camera/device/3.2/types.h>
18 #include <cutils/properties.h>
19 #include <gui/Surface.h>
20 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
21 
22 #include <aidl/AidlUtils.h>
23 #include <hidl/AidlCameraDeviceCallbacks.h>
24 #include <hidl/HidlCameraDeviceUser.h>
25 #include <hidl/Utils.h>
26 #include <android/hardware/camera/device/3.2/types.h>
27 #include <android-base/properties.h>
28 
29 namespace android {
30 namespace frameworks {
31 namespace cameraservice {
32 namespace device {
33 namespace V2_1 {
34 namespace implementation {
35 
36 using hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
37 using hardware::cameraservice::utils::conversion::convertToHidl;
38 using hardware::cameraservice::utils::conversion::convertFromHidl;
39 using hardware::cameraservice::utils::conversion::B2HStatus;
40 
41 using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
42 using hardware::hidl_vec;
43 using hardware::Return;
44 using hardware::Void;
45 using HSubmitInfo = device::V2_0::SubmitInfo;
46 using hardware::camera2::params::OutputConfiguration;
47 using hardware::camera2::params::SessionConfiguration;
48 
49 static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
50 static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
51 
disconnect()52 Return<void> HidlCameraDeviceUser::disconnect() {
53     mDeviceRemote->disconnect();
54     return Void();
55 }
56 
HidlCameraDeviceUser(const sp<hardware::camera2::ICameraDeviceUser> & deviceRemote)57 HidlCameraDeviceUser::HidlCameraDeviceUser(
58     const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
59   : mDeviceRemote(deviceRemote) {
60     mInitSuccess = initDevice();
61     mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
62 }
63 
initDevice()64 bool HidlCameraDeviceUser::initDevice() {
65     // TODO: Get request and result metadata queue size from a system property.
66     int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
67 
68     mCaptureRequestMetadataQueue =
69         std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
70                                                       false /* non blocking */);
71     if (!mCaptureRequestMetadataQueue->isValid()) {
72         ALOGE("%s: invalid request fmq", __FUNCTION__);
73         return false;
74     }
75 
76     int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
77     mCaptureResultMetadataQueue =
78         std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
79                                                      false /* non blocking */);
80     if (!mCaptureResultMetadataQueue->isValid()) {
81         ALOGE("%s: invalid result fmq", __FUNCTION__);
82         return false;
83     }
84     return true;
85 }
86 
getCaptureRequestMetadataQueue(getCaptureRequestMetadataQueue_cb _hidl_cb)87 Return<void> HidlCameraDeviceUser::getCaptureRequestMetadataQueue(
88     getCaptureRequestMetadataQueue_cb _hidl_cb) {
89     if (mInitSuccess) {
90         _hidl_cb(*mCaptureRequestMetadataQueue->getDesc());
91     }
92     return Void();
93 }
94 
getCaptureResultMetadataQueue(getCaptureResultMetadataQueue_cb _hidl_cb)95 Return<void> HidlCameraDeviceUser::getCaptureResultMetadataQueue(
96     getCaptureResultMetadataQueue_cb _hidl_cb) {
97     if (mInitSuccess) {
98         _hidl_cb(*mCaptureResultMetadataQueue->getDesc());
99     }
100     return Void();
101 }
102 
103 /**
104  * To be used only by submitRequestList implementation, since it requires
105  * clients to call this method serially, incase fmq is used to send metadata.
106  */
copyPhysicalCameraSettings(const hidl_vec<HPhysicalCameraSettings> & hPhysicalCameraSettings,std::vector<CaptureRequest::PhysicalCameraSettings> * physicalCameraSettings)107 bool HidlCameraDeviceUser::copyPhysicalCameraSettings(
108     const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
109     std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings) {
110     bool converted = false;
111     for (auto &e : hPhysicalCameraSettings) {
112         physicalCameraSettings->emplace_back();
113         CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
114             physicalCameraSettings->back();
115         physicalCameraSetting.id = e.id.c_str();
116 
117         // Read the settings either from the fmq or straightaway from the
118         // request. We don't need any synchronization, since submitRequestList
119         // is guaranteed to be called serially by the client if it decides to
120         // use fmq.
121         if (e.settings.getDiscriminator() ==
122             V2_0::FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
123             /**
124              * Get settings from the fmq.
125              */
126             HCameraMetadata settingsFmq;
127             settingsFmq.resize(e.settings.fmqMetadataSize());
128             bool read = mCaptureRequestMetadataQueue->read(settingsFmq.data(),
129                                                            e.settings.fmqMetadataSize());
130             if (!read) {
131                 ALOGE("%s capture request settings could't be read from fmq size",
132                       __FUNCTION__);
133                 converted = false;
134             } else {
135                 converted = convertFromHidl(settingsFmq, &physicalCameraSetting.settings);
136             }
137         } else {
138             /**
139              * The settings metadata is contained in request settings field.
140              */
141             converted =
142                 convertFromHidl(e.settings.metadata(),
143                                 &physicalCameraSetting.settings);
144         }
145         if (!converted) {
146           ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
147           return false;
148         }
149     }
150     return true;
151 }
152 
convertRequestFromHidl(const HCaptureRequest & hRequest,CaptureRequest * request)153 bool HidlCameraDeviceUser::convertRequestFromHidl(const HCaptureRequest &hRequest,
154                                                   CaptureRequest *request) {
155     // No reprocessing support.
156     request->mIsReprocess = false;
157     for (const auto &streamAndWindowId : hRequest.streamAndWindowIds) {
158         request->mStreamIdxList.push_back(streamAndWindowId.streamId);
159         request->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
160     }
161     return copyPhysicalCameraSettings(hRequest.physicalCameraSettings,
162                                       &(request->mPhysicalCameraSettings));
163 }
164 
submitRequestList(const hidl_vec<HCaptureRequest> & hRequestList,bool streaming,submitRequestList_cb _hidl_cb)165 Return<void> HidlCameraDeviceUser::submitRequestList(const hidl_vec<HCaptureRequest>& hRequestList,
166                                                      bool streaming,
167                                                      submitRequestList_cb _hidl_cb) {
168     hardware::camera2::utils::SubmitInfo submitInfo;
169     HSubmitInfo hSubmitInfo;
170     /**
171      * Create AIDL CaptureRequest from requestList and graphicBufferProducers.
172      */
173     std::vector<hardware::camera2::CaptureRequest> requests;
174     for (auto &hRequest : hRequestList) {
175         requests.emplace_back();
176         auto &request = requests.back();
177         if (!convertRequestFromHidl(hRequest, &request)) {
178             _hidl_cb(HStatus::ILLEGAL_ARGUMENT, hSubmitInfo);
179             return Void();
180         }
181     }
182     mDeviceRemote->submitRequestList(requests, streaming, &submitInfo);
183     mRequestId = submitInfo.mRequestId;
184     convertToHidl(submitInfo, &hSubmitInfo);
185     _hidl_cb(HStatus::NO_ERROR, hSubmitInfo);
186     return Void();
187 }
188 
cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb)189 Return<void> HidlCameraDeviceUser::cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) {
190     int64_t lastFrameNumber = 0;
191     binder::Status ret = mDeviceRemote->cancelRequest(mRequestId, &lastFrameNumber);
192     _hidl_cb(B2HStatus(ret), lastFrameNumber);
193     return Void();
194 }
195 
beginConfigure()196 Return<HStatus> HidlCameraDeviceUser::beginConfigure() {
197     binder::Status ret = mDeviceRemote->beginConfigure();
198     return B2HStatus(ret);
199 }
200 
endConfigure(StreamConfigurationMode operatingMode,const hidl_vec<uint8_t> & sessionParams)201 Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
202                                                    const hidl_vec<uint8_t>& sessionParams) {
203     return endConfigure_2_1(operatingMode, sessionParams, systemTime());
204 }
205 
endConfigure_2_1(StreamConfigurationMode operatingMode,const hidl_vec<uint8_t> & sessionParams,nsecs_t startTimeNs)206 Return<HStatus> HidlCameraDeviceUser::endConfigure_2_1(StreamConfigurationMode operatingMode,
207                                                    const hidl_vec<uint8_t>& sessionParams,
208                                                    nsecs_t startTimeNs) {
209     android::CameraMetadata cameraMetadata;
210     if (!convertFromHidl(sessionParams, &cameraMetadata)) {
211         return HStatus::ILLEGAL_ARGUMENT;
212     }
213 
214     std::vector<int> offlineStreamIds;
215     binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
216                                                      cameraMetadata, ns2ms(startTimeNs),
217                                                      &offlineStreamIds);
218     return B2HStatus(ret);
219 }
220 
deleteStream(int32_t streamId)221 Return<HStatus> HidlCameraDeviceUser::deleteStream(int32_t streamId) {
222     binder::Status ret = mDeviceRemote->deleteStream(streamId);
223     return B2HStatus(ret);
224 }
225 
createStream(const HOutputConfiguration & hOutputConfiguration,createStream_cb hidl_cb_)226 Return<void> HidlCameraDeviceUser::createStream(const HOutputConfiguration& hOutputConfiguration,
227                                                 createStream_cb hidl_cb_) {
228     OutputConfiguration outputConfiguration =
229         convertFromHidl(hOutputConfiguration);
230     int32_t newStreamId = 0;
231     binder::Status ret = mDeviceRemote->createStream(outputConfiguration, &newStreamId);
232     HStatus status = B2HStatus(ret);
233     hidl_cb_(status, newStreamId);
234     return Void();
235 }
236 
createDefaultRequest(TemplateId templateId,createDefaultRequest_cb _hidl_cb)237 Return<void> HidlCameraDeviceUser::createDefaultRequest(TemplateId templateId,
238                                                         createDefaultRequest_cb _hidl_cb) {
239     android::CameraMetadata cameraMetadata;
240     binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
241                                                              &cameraMetadata);
242 
243     HCameraMetadata hidlMetadata;
244     if (filterVndkKeys(mVndkVersion, cameraMetadata, /*isStatic*/false) != OK) {
245         ALOGE("%s: Unable to filter vndk metadata keys for version %d",
246               __FUNCTION__, mVndkVersion);
247         _hidl_cb(HStatus::UNKNOWN_ERROR, hidlMetadata);
248         return Void();
249     }
250 
251     HStatus hStatus = B2HStatus(ret);
252     const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
253     convertToHidl(rawMetadata, &hidlMetadata);
254     _hidl_cb(hStatus, hidlMetadata);
255     cameraMetadata.unlock(rawMetadata);
256     return Void();
257 }
258 
waitUntilIdle()259 Return<HStatus> HidlCameraDeviceUser::waitUntilIdle() {
260     binder::Status ret = mDeviceRemote->waitUntilIdle();
261     return B2HStatus(ret);
262 }
263 
flush(flush_cb _hidl_cb)264 Return<void> HidlCameraDeviceUser::flush(flush_cb _hidl_cb) {
265     int64_t lastFrameNumber = 0;
266     binder::Status ret = mDeviceRemote->flush(&lastFrameNumber);
267     _hidl_cb(B2HStatus(ret),lastFrameNumber);
268     return Void();
269 }
270 
updateOutputConfiguration(int32_t streamId,const HOutputConfiguration & hOutputConfiguration)271 Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
272     int32_t streamId,
273     const HOutputConfiguration& hOutputConfiguration) {
274     OutputConfiguration outputConfiguration = convertFromHidl(hOutputConfiguration);
275     binder::Status ret = mDeviceRemote->updateOutputConfiguration(streamId, outputConfiguration);
276     return B2HStatus(ret);
277 }
278 
isSessionConfigurationSupported(const HSessionConfiguration & hSessionConfiguration,isSessionConfigurationSupported_cb _hidl_cb)279 Return<void> HidlCameraDeviceUser::isSessionConfigurationSupported(
280     const HSessionConfiguration& hSessionConfiguration,
281     isSessionConfigurationSupported_cb _hidl_cb) {
282     bool supported = false;
283     SessionConfiguration sessionConfiguration = convertFromHidl(hSessionConfiguration);
284     binder::Status ret = mDeviceRemote->isSessionConfigurationSupported(
285             sessionConfiguration, &supported);
286     HStatus status = B2HStatus(ret);
287     _hidl_cb(status, supported);
288     return Void();
289 }
290 
291 } // implementation
292 } // V2_0
293 } // device
294 } // cameraservice
295 } // frameworks
296 } // android
297