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