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