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