blob: 48d78e1bda6e9709ef3323776864ff25f7ce4a3a [file] [log] [blame]
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -07001/*
2 * Copyright (C) 2022 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#define LOG_TAG "AidlUtils"
18
19#include <aidl/AidlUtils.h>
Emilian Peev3a4fa462024-02-15 19:56:20 +000020#include <aidl/ExtensionMetadataTags.h>
Avichal Rakesh4baf7262024-03-20 19:16:04 -070021#include <aidl/SessionCharacteristicsTags.h>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070022#include <aidl/VndkVersionMetadataTags.h>
23#include <aidlcommonsupport/NativeHandle.h>
Emilian Peev3a4fa462024-02-15 19:56:20 +000024#include <camera/StringUtils.h>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070025#include <device3/Camera3StreamInterface.h>
26#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
27#include <mediautils/AImageReaderUtils.h>
28
29namespace android::hardware::cameraservice::utils::conversion::aidl {
30
31using aimg::AImageReader_getHGBPFromHandle;
32using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
33
34// Note: existing data in dst will be gone. Caller still owns the memory of src
35void cloneToAidl(const camera_metadata_t* src, SCameraMetadata* dst) {
36 if (src == nullptr) {
37 ALOGW("%s:attempt to convert empty metadata to AIDL", __FUNCTION__);
38 return;
39 }
40 size_t size = get_camera_metadata_size(src);
41 uint8_t* startPtr = (uint8_t*)src;
42 uint8_t* endPtr = startPtr + size;
43 dst->metadata.assign(startPtr, endPtr);
44}
45
46// The camera metadata here is cloned. Since we're reading metadata over
47// the binder we would need to clone it in order to avoid alignment issues.
48bool cloneFromAidl(const SCameraMetadata &src, CameraMetadata *dst) {
49 const camera_metadata_t *buffer =
50 reinterpret_cast<const camera_metadata_t*>(src.metadata.data());
51 size_t expectedSize = src.metadata.size();
52 if (buffer != nullptr) {
53 int res = validate_camera_metadata_structure(buffer, &expectedSize);
54 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
55 *dst = buffer;
56 } else {
57 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
58 return false;
59 }
60 }
61 return true;
62}
63
64int32_t convertFromAidl(SStreamConfigurationMode streamConfigurationMode) {
65 switch (streamConfigurationMode) {
66 case SStreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
67 return camera2::ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE;
68 case SStreamConfigurationMode::NORMAL_MODE:
69 return camera2::ICameraDeviceUser::NORMAL_MODE;
70 default:
71 // TODO: Fix this
72 return camera2::ICameraDeviceUser::VENDOR_MODE_START;
73 }
74}
75
76UOutputConfiguration convertFromAidl(const SOutputConfiguration &src) {
77 std::vector<sp<IGraphicBufferProducer>> iGBPs;
Avichal Rakesh62d45f12023-10-25 12:54:45 -070078 if (!src.surfaces.empty()) {
79 auto& surfaces = src.surfaces;
80 iGBPs.reserve(surfaces.size());
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070081
Avichal Rakesh62d45f12023-10-25 12:54:45 -070082 for (auto& sSurface : surfaces) {
83 sp<IGraphicBufferProducer> igbp =
84 Surface::getIGraphicBufferProducer(sSurface.get());
85 if (igbp == nullptr) {
86 ALOGE("%s: ANativeWindow (%p) not backed by a Surface.",
87 __FUNCTION__, sSurface.get());
88 continue;
89 }
90 iGBPs.push_back(igbp);
Avichal Rakeshb8610162023-11-08 18:21:10 -080091 }
Avichal Rakesh62d45f12023-10-25 12:54:45 -070092 } else {
93#pragma clang diagnostic push
94#pragma clang diagnostic ignored "-Wdeprecated-declarations"
95 // HIDL token manager (and consequently 'windowHandles') is deprecated and will be removed
96 // in the future. However, cameraservice must still support old NativeHandle pathway until
97 // all vendors have moved away from using NativeHandles
98 auto &windowHandles = src.windowHandles;
99#pragma clang diagnostic pop
100
101 iGBPs.reserve(windowHandles.size());
102
103 for (auto &handle : windowHandles) {
104 native_handle_t* nh = makeFromAidl(handle);
105 auto igbp = AImageReader_getHGBPFromHandle(nh);
106 if (igbp == nullptr) {
107 ALOGE("%s: Could not get HGBP from NativeHandle: %s. Skipping.",
108 __FUNCTION__, handle.toString().c_str());
109 continue;
110 }
111
112 iGBPs.push_back(new H2BGraphicBufferProducer(igbp));
113 native_handle_delete(nh);
114 }
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700115 }
Avichal Rakesh62d45f12023-10-25 12:54:45 -0700116
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700117 UOutputConfiguration outputConfiguration(
Xin Li65d53082023-08-25 14:16:11 -0700118 iGBPs, convertFromAidl(src.rotation), src.physicalCameraId,
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700119 src.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
Avichal Rakesh62d45f12023-10-25 12:54:45 -0700120 (iGBPs.size() > 1));
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700121 return outputConfiguration;
122}
123
124USessionConfiguration convertFromAidl(const SSessionConfiguration &src) {
125 USessionConfiguration sessionConfig(src.inputWidth, src.inputHeight,
126 src.inputFormat, static_cast<int>(src.operationMode));
127
128 for (const auto& os : src.outputStreams) {
129 UOutputConfiguration config = convertFromAidl(os);
130 sessionConfig.addOutputConfiguration(config);
131 }
132
133 return sessionConfig;
134}
135
136int convertFromAidl(SOutputConfiguration::Rotation rotation) {
137 switch(rotation) {
138 case SOutputConfiguration::Rotation::R270:
139 return android::camera3::CAMERA_STREAM_ROTATION_270;
140 case SOutputConfiguration::Rotation::R180:
141 return android::camera3::CAMERA_STREAM_ROTATION_180;
142 case SOutputConfiguration::Rotation::R90:
143 return android::camera3::CAMERA_STREAM_ROTATION_90;
144 case SOutputConfiguration::Rotation::R0:
145 default:
146 return android::camera3::CAMERA_STREAM_ROTATION_0;
147 }
148}
149
150int32_t convertFromAidl(STemplateId templateId) {
151 switch(templateId) {
152 case STemplateId::PREVIEW:
153 return camera2::ICameraDeviceUser::TEMPLATE_PREVIEW;
154 case STemplateId::STILL_CAPTURE:
155 return camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE;
156 case STemplateId::RECORD:
157 return camera2::ICameraDeviceUser::TEMPLATE_RECORD;
158 case STemplateId::VIDEO_SNAPSHOT:
159 return camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT;
160 case STemplateId::ZERO_SHUTTER_LAG:
161 return camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG;
162 case STemplateId::MANUAL:
163 return camera2::ICameraDeviceUser::TEMPLATE_MANUAL;
164 }
165}
166
167void convertToAidl(const camera2::utils::SubmitInfo& submitInfo, SSubmitInfo* hSubmitInfo) {
168 hSubmitInfo->requestId = submitInfo.mRequestId;
169 hSubmitInfo->lastFrameNumber = submitInfo.mLastFrameNumber;
170}
171
172
173SStatus convertToAidl(const binder::Status &status) {
174 if (status.isOk()) {
175 return SStatus::NO_ERROR;
176 }
177 if (status.exceptionCode() != EX_SERVICE_SPECIFIC) {
178 return SStatus::UNKNOWN_ERROR;
179 }
180
181 switch (status.serviceSpecificErrorCode()) {
182 case hardware::ICameraService::ERROR_DISCONNECTED:
183 return SStatus::DISCONNECTED;
184 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
185 return SStatus::CAMERA_IN_USE;
186 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
187 return SStatus::MAX_CAMERAS_IN_USE;
188 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
189 return SStatus::ILLEGAL_ARGUMENT;
190 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
191 // Should not reach here since we filtered legacy HALs earlier
192 return SStatus::DEPRECATED_HAL;
193 case hardware::ICameraService::ERROR_DISABLED:
194 return SStatus::DISABLED;
195 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
196 return SStatus::PERMISSION_DENIED;
197 case hardware::ICameraService::ERROR_INVALID_OPERATION:
198 return SStatus::INVALID_OPERATION;
199 default:
200 return SStatus::UNKNOWN_ERROR;
201 }
202}
203
204SCaptureResultExtras convertToAidl(const UCaptureResultExtras &src) {
205 SCaptureResultExtras dst;
206 dst.requestId = src.requestId;
207 dst.burstId = src.burstId;
208 dst.frameNumber = src.frameNumber;
209 dst.partialResultCount = src.partialResultCount;
210 dst.errorStreamId = src.errorStreamId;
Xin Li65d53082023-08-25 14:16:11 -0700211 dst.errorPhysicalCameraId = src.errorPhysicalCameraId;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700212 return dst;
213}
214
215SErrorCode convertToAidl(int32_t errorCode) {
216 switch(errorCode) {
217 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED:
218 return SErrorCode::CAMERA_DISCONNECTED;
219 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
220 return SErrorCode::CAMERA_DEVICE;
221 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE:
222 return SErrorCode::CAMERA_SERVICE;
223 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
224 return SErrorCode::CAMERA_REQUEST;
225 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
226 return SErrorCode::CAMERA_RESULT;
227 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
228 return SErrorCode::CAMERA_BUFFER;
229 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED:
230 return SErrorCode::CAMERA_DISABLED;
231 case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR:
232 return SErrorCode::CAMERA_INVALID_ERROR;
233 default:
234 return SErrorCode::CAMERA_UNKNOWN_ERROR;
235 }
236}
237
238std::vector<SPhysicalCaptureResultInfo> convertToAidl(
239 const std::vector<UPhysicalCaptureResultInfo>& src,
240 std::shared_ptr<CaptureResultMetadataQueue>& fmq) {
241 std::vector<SPhysicalCaptureResultInfo> dst;
242 dst.resize(src.size());
243 size_t i = 0;
244 for (auto &physicalCaptureResultInfo : src) {
245 dst[i++] = convertToAidl(physicalCaptureResultInfo, fmq);
246 }
247 return dst;
248}
249
250SPhysicalCaptureResultInfo convertToAidl(const UPhysicalCaptureResultInfo & src,
251 std::shared_ptr<CaptureResultMetadataQueue> & fmq) {
252 SPhysicalCaptureResultInfo dst;
Xin Li65d53082023-08-25 14:16:11 -0700253 dst.physicalCameraId = src.mPhysicalCameraId;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700254
255 const camera_metadata_t *rawMetadata = src.mPhysicalCameraMetadata.getAndLock();
256 // Try using fmq at first.
257 size_t metadata_size = get_camera_metadata_size(rawMetadata);
258 if ((metadata_size > 0) && (fmq->availableToWrite() > 0)) {
259 if (fmq->write((int8_t *)rawMetadata, metadata_size)) {
260 dst.physicalCameraMetadata.set<SCaptureMetadataInfo::fmqMetadataSize>(metadata_size);
261 } else {
262 ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
263 SCameraMetadata metadata;
264 cloneToAidl(rawMetadata, &metadata);
265 dst.physicalCameraMetadata.set<SCaptureMetadataInfo::metadata>(std::move(metadata));
266 }
267 }
268 src.mPhysicalCameraMetadata.unlock(rawMetadata);
269 return dst;
270}
271
272void convertToAidl(const std::vector<hardware::CameraStatus> &src,
273 std::vector<SCameraStatusAndId>* dst) {
274 dst->resize(src.size());
275 size_t i = 0;
276 for (const auto &statusAndId : src) {
277 auto &a = (*dst)[i++];
Xin Li65d53082023-08-25 14:16:11 -0700278 a.cameraId = statusAndId.cameraId;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700279 a.deviceStatus = convertCameraStatusToAidl(statusAndId.status);
280 size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
281 a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
282 for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
Xin Li65d53082023-08-25 14:16:11 -0700283 a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j];
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700284 }
285 }
286}
287
288SCameraDeviceStatus convertCameraStatusToAidl(int32_t src) {
289 SCameraDeviceStatus deviceStatus = SCameraDeviceStatus::STATUS_UNKNOWN;
290 switch(src) {
291 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
292 deviceStatus = SCameraDeviceStatus::STATUS_NOT_PRESENT;
293 break;
294 case hardware::ICameraServiceListener::STATUS_PRESENT:
295 deviceStatus = SCameraDeviceStatus::STATUS_PRESENT;
296 break;
297 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
298 deviceStatus = SCameraDeviceStatus::STATUS_ENUMERATING;
299 break;
300 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
301 deviceStatus = SCameraDeviceStatus::STATUS_NOT_AVAILABLE;
302 break;
303 default:
304 break;
305 }
306 return deviceStatus;
307}
308
309bool areBindersEqual(const ndk::SpAIBinder& b1, const ndk::SpAIBinder& b2) {
310 return !AIBinder_lt(b1.get(), b2.get()) && !AIBinder_lt(b2.get(), b1.get());
311}
312
313status_t filterVndkKeys(int vndkVersion, CameraMetadata &metadata, bool isStatic) {
314 if (vndkVersion == __ANDROID_API_FUTURE__) {
Avichal Rakesh74b5ae72023-12-27 16:56:45 -0800315 // VNDK version derived from ro.board.api_level is a version code-name that
316 // corresponds to the current SDK version.
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700317 return OK;
318 }
319 const auto &apiLevelToKeys =
320 isStatic ? static_api_level_to_keys : dynamic_api_level_to_keys;
321 // Find the vndk versions above the given vndk version. All the vndk
322 // versions above the given one, need to have their keys filtered from the
323 // metadata in order to avoid metadata invalidation.
324 auto it = apiLevelToKeys.upper_bound(vndkVersion);
325 while (it != apiLevelToKeys.end()) {
326 for (const auto &key : it->second) {
327 status_t res = metadata.erase(key);
328 if (res != OK) {
329 ALOGE("%s metadata key %d could not be erased", __FUNCTION__, key);
330 return res;
331 }
332 }
333 it++;
334 }
335 return OK;
336}
337
Avichal Rakesh4baf7262024-03-20 19:16:04 -0700338status_t copySessionCharacteristics(const CameraMetadata& from, CameraMetadata* to,
339 int queryVersion) {
340 // Ensure the vendor ID are the same before attempting
341 // anything else. If vendor IDs differ we cannot safely copy the characteristics.
342 if (from.getVendorId() != to->getVendorId()) {
343 ALOGE("%s: Incompatible CameraMetadata objects. Vendor IDs differ. From: %lu; To: %lu",
344 __FUNCTION__, from.getVendorId(), to->getVendorId());
345 return BAD_VALUE;
346 }
347
348 // Allow public tags according to the queryVersion
349 std::unordered_set<uint32_t> validPublicTags;
350 auto last = api_level_to_session_characteristic_keys.upper_bound(queryVersion);
351 for (auto it = api_level_to_session_characteristic_keys.begin(); it != last; it++) {
352 validPublicTags.insert(it->second.cbegin(), it->second.cend());
353 }
354
355 const camera_metadata_t* src = from.getAndLock();
356 camera_metadata_ro_entry_t entry{};
357 for (size_t i = 0; i < get_camera_metadata_entry_count(src); i++) {
358 int ret = get_camera_metadata_ro_entry(src, i, &entry);
359 if (ret != OK) {
360 ALOGE("%s: Could not fetch entry at index %lu. Error: %d", __FUNCTION__, i, ret);
361 from.unlock(src);
362 return BAD_VALUE;
363 }
364
365 if (entry.tag < (uint32_t)VENDOR_SECTION_START &&
366 validPublicTags.find(entry.tag) == validPublicTags.end()) {
367 ALOGI("%s: Session Characteristics contains tag %s but not supported by query version "
368 "(%d)",
369 __FUNCTION__, get_camera_metadata_tag_name(entry.tag), queryVersion);
370 continue;
371 }
372
373 // The entry is either a vendor tag, or a valid session characteristic key.
374 // Copy over the value
375 to->update(entry);
376 }
377 from.unlock(src);
378 return OK;
379}
380
Emilian Peev3a4fa462024-02-15 19:56:20 +0000381bool areExtensionKeysSupported(const CameraMetadata& metadata) {
382 auto requestKeys = metadata.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
383 if (requestKeys.count == 0) {
384 ALOGE("%s: No ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS entries!", __FUNCTION__);
385 return false;
386 }
387
388 auto resultKeys = metadata.find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
389 if (resultKeys.count == 0) {
390 ALOGE("%s: No ANDROID_REQUEST_AVAILABLE_RESULT_KEYS entries!", __FUNCTION__);
391 return false;
392 }
393
394 for (const auto& extensionKey : extension_metadata_keys) {
395 if (std::find(requestKeys.data.i32, requestKeys.data.i32 + requestKeys.count, extensionKey)
396 != requestKeys.data.i32 + requestKeys.count) {
397 return true;
398 }
399
400 if (std::find(resultKeys.data.i32, resultKeys.data.i32 + resultKeys.count, extensionKey)
401 != resultKeys.data.i32 + resultKeys.count) {
402 return true;
403 }
404 }
405
406 return false;
407}
408
409status_t filterExtensionKeys(CameraMetadata* metadata /*out*/) {
410 if (metadata == nullptr) {
411 return BAD_VALUE;
412 }
413
414 for (const auto& key : extension_metadata_keys) {
415 status_t res = metadata->erase(key);
416 if (res != OK) {
417 ALOGE("%s metadata key %d could not be erased", __FUNCTION__, key);
418 return res;
419 }
420 }
421 return OK;
422}
423
Xin Li65d53082023-08-25 14:16:11 -0700424} // namespace android::hardware::cameraservice::utils::conversion::aidl