305 lines
12 KiB
C++
305 lines
12 KiB
C++
|
|
/*
|
||
|
|
* Copyright (C) 2022 The Android Open Source Project
|
||
|
|
*
|
||
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
* you may not use this file except in compliance with the License.
|
||
|
|
* You may obtain a copy of the License at
|
||
|
|
*
|
||
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
*
|
||
|
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
* See the License for the specific language governing permissions and
|
||
|
|
* limitations under the License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#define LOG_TAG "AidlUtils"
|
||
|
|
|
||
|
|
#include <aidl/AidlUtils.h>
|
||
|
|
#include <aidl/VndkVersionMetadataTags.h>
|
||
|
|
#include <aidlcommonsupport/NativeHandle.h>
|
||
|
|
#include <device3/Camera3StreamInterface.h>
|
||
|
|
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
|
||
|
|
#include <mediautils/AImageReaderUtils.h>
|
||
|
|
|
||
|
|
namespace android::hardware::cameraservice::utils::conversion::aidl {
|
||
|
|
|
||
|
|
using aimg::AImageReader_getHGBPFromHandle;
|
||
|
|
using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
|
||
|
|
|
||
|
|
// Note: existing data in dst will be gone. Caller still owns the memory of src
|
||
|
|
void cloneToAidl(const camera_metadata_t* src, SCameraMetadata* dst) {
|
||
|
|
if (src == nullptr) {
|
||
|
|
ALOGW("%s:attempt to convert empty metadata to AIDL", __FUNCTION__);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
size_t size = get_camera_metadata_size(src);
|
||
|
|
uint8_t* startPtr = (uint8_t*)src;
|
||
|
|
uint8_t* endPtr = startPtr + size;
|
||
|
|
dst->metadata.assign(startPtr, endPtr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// The camera metadata here is cloned. Since we're reading metadata over
|
||
|
|
// the binder we would need to clone it in order to avoid alignment issues.
|
||
|
|
bool cloneFromAidl(const SCameraMetadata &src, CameraMetadata *dst) {
|
||
|
|
const camera_metadata_t *buffer =
|
||
|
|
reinterpret_cast<const camera_metadata_t*>(src.metadata.data());
|
||
|
|
size_t expectedSize = src.metadata.size();
|
||
|
|
if (buffer != nullptr) {
|
||
|
|
int res = validate_camera_metadata_structure(buffer, &expectedSize);
|
||
|
|
if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
|
||
|
|
*dst = buffer;
|
||
|
|
} else {
|
||
|
|
ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
int32_t convertFromAidl(SStreamConfigurationMode streamConfigurationMode) {
|
||
|
|
switch (streamConfigurationMode) {
|
||
|
|
case SStreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
|
||
|
|
return camera2::ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE;
|
||
|
|
case SStreamConfigurationMode::NORMAL_MODE:
|
||
|
|
return camera2::ICameraDeviceUser::NORMAL_MODE;
|
||
|
|
default:
|
||
|
|
// TODO: Fix this
|
||
|
|
return camera2::ICameraDeviceUser::VENDOR_MODE_START;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
UOutputConfiguration convertFromAidl(const SOutputConfiguration &src) {
|
||
|
|
std::vector<sp<IGraphicBufferProducer>> iGBPs;
|
||
|
|
auto &windowHandles = src.windowHandles;
|
||
|
|
iGBPs.reserve(windowHandles.size());
|
||
|
|
|
||
|
|
for (auto &handle : windowHandles) {
|
||
|
|
native_handle_t* nh = makeFromAidl(handle);
|
||
|
|
iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(nh)));
|
||
|
|
native_handle_delete(nh);
|
||
|
|
}
|
||
|
|
String16 physicalCameraId16(src.physicalCameraId.c_str());
|
||
|
|
UOutputConfiguration outputConfiguration(
|
||
|
|
iGBPs, convertFromAidl(src.rotation), physicalCameraId16,
|
||
|
|
src.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
|
||
|
|
(windowHandles.size() > 1));
|
||
|
|
return outputConfiguration;
|
||
|
|
}
|
||
|
|
|
||
|
|
USessionConfiguration convertFromAidl(const SSessionConfiguration &src) {
|
||
|
|
USessionConfiguration sessionConfig(src.inputWidth, src.inputHeight,
|
||
|
|
src.inputFormat, static_cast<int>(src.operationMode));
|
||
|
|
|
||
|
|
for (const auto& os : src.outputStreams) {
|
||
|
|
UOutputConfiguration config = convertFromAidl(os);
|
||
|
|
sessionConfig.addOutputConfiguration(config);
|
||
|
|
}
|
||
|
|
|
||
|
|
return sessionConfig;
|
||
|
|
}
|
||
|
|
|
||
|
|
int convertFromAidl(SOutputConfiguration::Rotation rotation) {
|
||
|
|
switch(rotation) {
|
||
|
|
case SOutputConfiguration::Rotation::R270:
|
||
|
|
return android::camera3::CAMERA_STREAM_ROTATION_270;
|
||
|
|
case SOutputConfiguration::Rotation::R180:
|
||
|
|
return android::camera3::CAMERA_STREAM_ROTATION_180;
|
||
|
|
case SOutputConfiguration::Rotation::R90:
|
||
|
|
return android::camera3::CAMERA_STREAM_ROTATION_90;
|
||
|
|
case SOutputConfiguration::Rotation::R0:
|
||
|
|
default:
|
||
|
|
return android::camera3::CAMERA_STREAM_ROTATION_0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int32_t convertFromAidl(STemplateId templateId) {
|
||
|
|
switch(templateId) {
|
||
|
|
case STemplateId::PREVIEW:
|
||
|
|
return camera2::ICameraDeviceUser::TEMPLATE_PREVIEW;
|
||
|
|
case STemplateId::STILL_CAPTURE:
|
||
|
|
return camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE;
|
||
|
|
case STemplateId::RECORD:
|
||
|
|
return camera2::ICameraDeviceUser::TEMPLATE_RECORD;
|
||
|
|
case STemplateId::VIDEO_SNAPSHOT:
|
||
|
|
return camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT;
|
||
|
|
case STemplateId::ZERO_SHUTTER_LAG:
|
||
|
|
return camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG;
|
||
|
|
case STemplateId::MANUAL:
|
||
|
|
return camera2::ICameraDeviceUser::TEMPLATE_MANUAL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void convertToAidl(const camera2::utils::SubmitInfo& submitInfo, SSubmitInfo* hSubmitInfo) {
|
||
|
|
hSubmitInfo->requestId = submitInfo.mRequestId;
|
||
|
|
hSubmitInfo->lastFrameNumber = submitInfo.mLastFrameNumber;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
SStatus convertToAidl(const binder::Status &status) {
|
||
|
|
if (status.isOk()) {
|
||
|
|
return SStatus::NO_ERROR;
|
||
|
|
}
|
||
|
|
if (status.exceptionCode() != EX_SERVICE_SPECIFIC) {
|
||
|
|
return SStatus::UNKNOWN_ERROR;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (status.serviceSpecificErrorCode()) {
|
||
|
|
case hardware::ICameraService::ERROR_DISCONNECTED:
|
||
|
|
return SStatus::DISCONNECTED;
|
||
|
|
case hardware::ICameraService::ERROR_CAMERA_IN_USE:
|
||
|
|
return SStatus::CAMERA_IN_USE;
|
||
|
|
case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
|
||
|
|
return SStatus::MAX_CAMERAS_IN_USE;
|
||
|
|
case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
|
||
|
|
return SStatus::ILLEGAL_ARGUMENT;
|
||
|
|
case hardware::ICameraService::ERROR_DEPRECATED_HAL:
|
||
|
|
// Should not reach here since we filtered legacy HALs earlier
|
||
|
|
return SStatus::DEPRECATED_HAL;
|
||
|
|
case hardware::ICameraService::ERROR_DISABLED:
|
||
|
|
return SStatus::DISABLED;
|
||
|
|
case hardware::ICameraService::ERROR_PERMISSION_DENIED:
|
||
|
|
return SStatus::PERMISSION_DENIED;
|
||
|
|
case hardware::ICameraService::ERROR_INVALID_OPERATION:
|
||
|
|
return SStatus::INVALID_OPERATION;
|
||
|
|
default:
|
||
|
|
return SStatus::UNKNOWN_ERROR;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
SCaptureResultExtras convertToAidl(const UCaptureResultExtras &src) {
|
||
|
|
SCaptureResultExtras dst;
|
||
|
|
dst.requestId = src.requestId;
|
||
|
|
dst.burstId = src.burstId;
|
||
|
|
dst.frameNumber = src.frameNumber;
|
||
|
|
dst.partialResultCount = src.partialResultCount;
|
||
|
|
dst.errorStreamId = src.errorStreamId;
|
||
|
|
dst.errorPhysicalCameraId = String8(src.errorPhysicalCameraId).string();
|
||
|
|
return dst;
|
||
|
|
}
|
||
|
|
|
||
|
|
SErrorCode convertToAidl(int32_t errorCode) {
|
||
|
|
switch(errorCode) {
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED:
|
||
|
|
return SErrorCode::CAMERA_DISCONNECTED;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
|
||
|
|
return SErrorCode::CAMERA_DEVICE;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE:
|
||
|
|
return SErrorCode::CAMERA_SERVICE;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
|
||
|
|
return SErrorCode::CAMERA_REQUEST;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
|
||
|
|
return SErrorCode::CAMERA_RESULT;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
|
||
|
|
return SErrorCode::CAMERA_BUFFER;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED:
|
||
|
|
return SErrorCode::CAMERA_DISABLED;
|
||
|
|
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR:
|
||
|
|
return SErrorCode::CAMERA_INVALID_ERROR;
|
||
|
|
default:
|
||
|
|
return SErrorCode::CAMERA_UNKNOWN_ERROR;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
std::vector<SPhysicalCaptureResultInfo> convertToAidl(
|
||
|
|
const std::vector<UPhysicalCaptureResultInfo>& src,
|
||
|
|
std::shared_ptr<CaptureResultMetadataQueue>& fmq) {
|
||
|
|
std::vector<SPhysicalCaptureResultInfo> dst;
|
||
|
|
dst.resize(src.size());
|
||
|
|
size_t i = 0;
|
||
|
|
for (auto &physicalCaptureResultInfo : src) {
|
||
|
|
dst[i++] = convertToAidl(physicalCaptureResultInfo, fmq);
|
||
|
|
}
|
||
|
|
return dst;
|
||
|
|
}
|
||
|
|
|
||
|
|
SPhysicalCaptureResultInfo convertToAidl(const UPhysicalCaptureResultInfo & src,
|
||
|
|
std::shared_ptr<CaptureResultMetadataQueue> & fmq) {
|
||
|
|
SPhysicalCaptureResultInfo dst;
|
||
|
|
dst.physicalCameraId = String8(src.mPhysicalCameraId).string();
|
||
|
|
|
||
|
|
const camera_metadata_t *rawMetadata = src.mPhysicalCameraMetadata.getAndLock();
|
||
|
|
// Try using fmq at first.
|
||
|
|
size_t metadata_size = get_camera_metadata_size(rawMetadata);
|
||
|
|
if ((metadata_size > 0) && (fmq->availableToWrite() > 0)) {
|
||
|
|
if (fmq->write((int8_t *)rawMetadata, metadata_size)) {
|
||
|
|
dst.physicalCameraMetadata.set<SCaptureMetadataInfo::fmqMetadataSize>(metadata_size);
|
||
|
|
} else {
|
||
|
|
ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
|
||
|
|
SCameraMetadata metadata;
|
||
|
|
cloneToAidl(rawMetadata, &metadata);
|
||
|
|
dst.physicalCameraMetadata.set<SCaptureMetadataInfo::metadata>(std::move(metadata));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
src.mPhysicalCameraMetadata.unlock(rawMetadata);
|
||
|
|
return dst;
|
||
|
|
}
|
||
|
|
|
||
|
|
void convertToAidl(const std::vector<hardware::CameraStatus> &src,
|
||
|
|
std::vector<SCameraStatusAndId>* dst) {
|
||
|
|
dst->resize(src.size());
|
||
|
|
size_t i = 0;
|
||
|
|
for (const auto &statusAndId : src) {
|
||
|
|
auto &a = (*dst)[i++];
|
||
|
|
a.cameraId = statusAndId.cameraId.c_str();
|
||
|
|
a.deviceStatus = convertCameraStatusToAidl(statusAndId.status);
|
||
|
|
size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
|
||
|
|
a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
|
||
|
|
for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
|
||
|
|
a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j].c_str();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
SCameraDeviceStatus convertCameraStatusToAidl(int32_t src) {
|
||
|
|
SCameraDeviceStatus deviceStatus = SCameraDeviceStatus::STATUS_UNKNOWN;
|
||
|
|
switch(src) {
|
||
|
|
case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
|
||
|
|
deviceStatus = SCameraDeviceStatus::STATUS_NOT_PRESENT;
|
||
|
|
break;
|
||
|
|
case hardware::ICameraServiceListener::STATUS_PRESENT:
|
||
|
|
deviceStatus = SCameraDeviceStatus::STATUS_PRESENT;
|
||
|
|
break;
|
||
|
|
case hardware::ICameraServiceListener::STATUS_ENUMERATING:
|
||
|
|
deviceStatus = SCameraDeviceStatus::STATUS_ENUMERATING;
|
||
|
|
break;
|
||
|
|
case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
|
||
|
|
deviceStatus = SCameraDeviceStatus::STATUS_NOT_AVAILABLE;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return deviceStatus;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool areBindersEqual(const ndk::SpAIBinder& b1, const ndk::SpAIBinder& b2) {
|
||
|
|
return !AIBinder_lt(b1.get(), b2.get()) && !AIBinder_lt(b2.get(), b1.get());
|
||
|
|
}
|
||
|
|
|
||
|
|
status_t filterVndkKeys(int vndkVersion, CameraMetadata &metadata, bool isStatic) {
|
||
|
|
if (vndkVersion == __ANDROID_API_FUTURE__) {
|
||
|
|
// VNDK version in ro.vndk.version is a version code-name that
|
||
|
|
// corresponds to the current version.
|
||
|
|
return OK;
|
||
|
|
}
|
||
|
|
const auto &apiLevelToKeys =
|
||
|
|
isStatic ? static_api_level_to_keys : dynamic_api_level_to_keys;
|
||
|
|
// Find the vndk versions above the given vndk version. All the vndk
|
||
|
|
// versions above the given one, need to have their keys filtered from the
|
||
|
|
// metadata in order to avoid metadata invalidation.
|
||
|
|
auto it = apiLevelToKeys.upper_bound(vndkVersion);
|
||
|
|
while (it != apiLevelToKeys.end()) {
|
||
|
|
for (const auto &key : it->second) {
|
||
|
|
status_t res = metadata.erase(key);
|
||
|
|
if (res != OK) {
|
||
|
|
ALOGE("%s metadata key %d could not be erased", __FUNCTION__, key);
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
it++;
|
||
|
|
}
|
||
|
|
return OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace android::hardware::cameraservice::utils::conversion::aidl
|