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