From 892e826a3286a138f246a7e8303051e161a19318 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 8 Feb 2019 16:12:30 -0800 Subject: [PATCH] Camera: Handle binder call failure due to static metadata size For physical camera static metadata, we should reduce its size before passing it across binder if possible. Test: Camera CTS Bug: 124129552 Change-Id: I0d9129642ddcbb4c1a1c7fcf7a88bac734be4f5a --- camera/common/1.0/default/CameraModule.cpp | 74 ++++++++++++++++++- .../common/1.0/default/include/CameraModule.h | 7 ++ .../3.4/default/CameraDeviceSession.cpp | 31 ++------ 3 files changed, 84 insertions(+), 28 deletions(-) diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp index 3e3ef433a5..467c121a94 100644 --- a/camera/common/1.0/default/CameraModule.cpp +++ b/camera/common/1.0/default/CameraModule.cpp @@ -253,6 +253,14 @@ CameraModule::~CameraModule() } mCameraInfoMap.removeItemsAt(0); } + + while (mPhysicalCameraInfoMap.size() > 0) { + camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0); + if (metadata != NULL) { + free_camera_metadata(metadata); + } + mPhysicalCameraInfoMap.removeItemsAt(0); + } } int CameraModule::init() { @@ -351,7 +359,14 @@ int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t return ret; } - index = mPhysicalCameraInfoMap.add(physicalCameraId, info); + // The camera_metadata_t returned by get_physical_camera_info could be using + // more memory than necessary due to unused reserved space. Reduce the + // size by appending it to a new CameraMetadata object, which internally + // calls resizeIfNeeded. + CameraMetadata m; + m.append(info); + camera_metadata_t* derivedMetadata = m.release(); + index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata); } assert(index != NAME_NOT_FOUND); @@ -473,6 +488,43 @@ void CameraModule::notifyDeviceStateChange(uint64_t deviceState) { } } +bool CameraModule::isLogicalMultiCamera( + const common::V1_0::helper::CameraMetadata& metadata, + std::unordered_set* physicalCameraIds) { + if (physicalCameraIds == nullptr) { + ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__); + return false; + } + + bool isLogicalMultiCamera = false; + camera_metadata_ro_entry_t capabilities = + metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); + for (size_t i = 0; i < capabilities.count; i++) { + if (capabilities.data.u8[i] == + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) { + isLogicalMultiCamera = true; + break; + } + } + + if (isLogicalMultiCamera) { + camera_metadata_ro_entry_t entry = + metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS); + const uint8_t* ids = entry.data.u8; + size_t start = 0; + for (size_t i = 0; i < entry.count; ++i) { + if (ids[i] == '\0') { + if (start != i) { + const char* physicalId = reinterpret_cast(ids+start); + physicalCameraIds->emplace(physicalId); + } + start = i + 1; + } + } + } + return isLogicalMultiCamera; +} + status_t CameraModule::filterOpenErrorCode(status_t err) { switch(err) { case NO_ERROR: @@ -487,8 +539,24 @@ status_t CameraModule::filterOpenErrorCode(status_t err) { } void CameraModule::removeCamera(int cameraId) { - free_camera_metadata(const_cast( - mCameraInfoMap.valueFor(cameraId).static_camera_characteristics)); + std::unordered_set physicalIds; + camera_metadata_t *metadata = const_cast( + mCameraInfoMap.valueFor(cameraId).static_camera_characteristics); + common::V1_0::helper::CameraMetadata hidlMetadata(metadata); + + if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) { + for (const auto& id : physicalIds) { + int idInt = std::stoi(id); + if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) { + free_camera_metadata(mPhysicalCameraInfoMap[idInt]); + mPhysicalCameraInfoMap.removeItem(idInt); + } else { + ALOGE("%s: Cannot find corresponding static metadata for physical id %s", + __FUNCTION__, id.c_str()); + } + } + } + free_camera_metadata(metadata); mCameraInfoMap.removeItem(cameraId); mDeviceVersionMap.removeItem(cameraId); } diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h index 32c387f107..c89e934655 100644 --- a/camera/common/1.0/default/include/CameraModule.h +++ b/camera/common/1.0/default/include/CameraModule.h @@ -17,6 +17,9 @@ #ifndef CAMERA_COMMON_1_0_CAMERAMODULE_H #define CAMERA_COMMON_1_0_CAMERAMODULE_H +#include +#include + #include #include #include @@ -69,6 +72,10 @@ public: int isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams); void notifyDeviceStateChange(uint64_t deviceState); + static bool isLogicalMultiCamera( + const common::V1_0::helper::CameraMetadata& metadata, + std::unordered_set* physicalCameraIds); + private: // Derive camera characteristics keys defined after HAL device version static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars); diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp index e52577cfb9..c937834928 100644 --- a/camera/device/3.4/default/CameraDeviceSession.cpp +++ b/camera/device/3.4/default/CameraDeviceSession.cpp @@ -22,6 +22,7 @@ #include #include #include "CameraDeviceSession.h" +#include "CameraModule.h" namespace android { namespace hardware { @@ -30,6 +31,8 @@ namespace device { namespace V3_4 { namespace implementation { +using ::android::hardware::camera::common::V1_0::helper::CameraModule; + CameraDeviceSession::CameraDeviceSession( camera3_device_t* device, const camera_metadata_t* deviceInfo, @@ -54,31 +57,9 @@ CameraDeviceSession::CameraDeviceSession( mResultBatcher_3_4.setNumPartialResults(mNumPartialResults); - camera_metadata_entry_t capabilities = - mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); - bool isLogicalMultiCamera = false; - for (size_t i = 0; i < capabilities.count; i++) { - if (capabilities.data.u8[i] == - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) { - isLogicalMultiCamera = true; - break; - } - } - if (isLogicalMultiCamera) { - camera_metadata_entry entry = - mDeviceInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS); - const uint8_t* ids = entry.data.u8; - size_t start = 0; - for (size_t i = 0; i < entry.count; ++i) { - if (ids[i] == '\0') { - if (start != i) { - const char* physicalId = reinterpret_cast(ids+start); - mPhysicalCameraIds.emplace(physicalId); - } - start = i + 1; - } - } - } + // Parse and store current logical camera's physical ids. + (void)CameraModule::isLogicalMultiCamera(mDeviceInfo, &mPhysicalCameraIds); + } CameraDeviceSession::~CameraDeviceSession() {