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