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