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
This commit is contained in:
Shuzhen Wang
2019-02-08 16:12:30 -08:00
parent fbb176e069
commit 892e826a32
3 changed files with 84 additions and 28 deletions

View File

@@ -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<std::string>* 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<const char*>(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<camera_metadata_t*>(
mCameraInfoMap.valueFor(cameraId).static_camera_characteristics));
std::unordered_set<std::string> physicalIds;
camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
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);
}

View File

@@ -17,6 +17,9 @@
#ifndef CAMERA_COMMON_1_0_CAMERAMODULE_H
#define CAMERA_COMMON_1_0_CAMERAMODULE_H
#include <string>
#include <unordered_set>
#include <hardware/camera.h>
#include <utils/Mutex.h>
#include <utils/KeyedVector.h>
@@ -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<std::string>* physicalCameraIds);
private:
// Derive camera characteristics keys defined after HAL device version
static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);

View File

@@ -22,6 +22,7 @@
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
#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<const char*>(ids+start);
mPhysicalCameraIds.emplace(physicalId);
}
start = i + 1;
}
}
}
// Parse and store current logical camera's physical ids.
(void)CameraModule::isLogicalMultiCamera(mDeviceInfo, &mPhysicalCameraIds);
}
CameraDeviceSession::~CameraDeviceSession() {