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