Camera: Filter logical camera ids to API1 app

am: e8aceb53e9

Change-Id: Ia8bb669ba74bf637e6762d5b30b4281f5d6479f9
gugelfrei
Shuzhen Wang 6 years ago committed by android-build-merger
commit 29880995ae

@ -624,11 +624,19 @@ binder::Status CameraDeviceClient::createStream(
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
if (!checkPhysicalCameraId(physicalCameraId)) {
String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
if (physicalCameraId.size() > 0) {
std::vector<std::string> physicalCameraIds;
std::string physicalId(physicalCameraId.string());
bool logicalCamera =
CameraProviderManager::isLogicalCamera(mDevice->info(), &physicalCameraIds);
if (!logicalCamera ||
std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalId) ==
physicalCameraIds.end()) {
String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
mCameraIdStr.string(), physicalCameraId.string());
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
}
std::vector<sp<Surface>> surfaces;
std::vector<sp<IBinder>> binders;
@ -1144,43 +1152,6 @@ binder::Status CameraDeviceClient::createSurfaceFromGbp(
return binder::Status::ok();
}
bool CameraDeviceClient::checkPhysicalCameraId(const String8& physicalCameraId) {
if (0 == physicalCameraId.size()) {
return true;
}
CameraMetadata staticInfo = mDevice->info();
camera_metadata_entry_t entryCap;
bool isLogicalCam = false;
entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
for (size_t i = 0; i < entryCap.count; ++i) {
uint8_t capability = entryCap.data.u8[i];
if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
isLogicalCam = true;
}
}
if (!isLogicalCam) {
return false;
}
camera_metadata_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
const uint8_t* ids = entryIds.data.u8;
size_t start = 0;
for (size_t i = 0; i < entryIds.count; ++i) {
if (ids[i] == '\0') {
if (start != i) {
String8 currentId((const char*)ids+start);
if (currentId == physicalCameraId) {
return true;
}
}
start = i+1;
}
}
return false;
}
bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
/*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {

@ -98,9 +98,14 @@ std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds
std::lock_guard<std::mutex> lock(mInterfaceMutex);
std::vector<std::string> deviceIds;
for (auto& provider : mProviders) {
for (auto& id : provider->mUniqueAPI1CompatibleCameraIds) {
deviceIds.push_back(id);
}
std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
// API1 app doesn't handle logical and physical camera devices well. So
// for each [logical, physical1, physical2, ...] id combo, only take the
// first id advertised by HAL, and filter out the rest.
filterLogicalCameraIdsLocked(providerDeviceIds);
deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
}
std::sort(deviceIds.begin(), deviceIds.end(),
@ -172,11 +177,7 @@ status_t CameraProviderManager::getCameraInfo(const std::string &id,
status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
CameraMetadata* characteristics) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
return deviceInfo->getCameraCharacteristics(characteristics);
return getCameraCharacteristicsLocked(id, characteristics);
}
status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
@ -391,6 +392,37 @@ metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
return ret;
}
bool CameraProviderManager::isLogicalCamera(const CameraMetadata& staticInfo,
std::vector<std::string>* physicalCameraIds) {
bool isLogicalCam = false;
camera_metadata_ro_entry_t entryCap;
entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
for (size_t i = 0; i < entryCap.count; ++i) {
uint8_t capability = entryCap.data.u8[i];
if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
isLogicalCam = true;
break;
}
}
if (!isLogicalCam) {
return false;
}
camera_metadata_ro_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
const uint8_t* ids = entryIds.data.u8;
size_t start = 0;
for (size_t i = 0; i < entryIds.count; ++i) {
if (ids[i] == '\0') {
if (start != i) {
physicalCameraIds->push_back((const char*)ids+start);
}
start = i+1;
}
}
return true;
}
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
for (const auto& providerInfo : mProviders) {
if (providerInfo->mProviderName == newProvider) {
@ -599,7 +631,7 @@ status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
mUniqueCameraIds.insert(id);
if (isAPI1Compatible) {
mUniqueAPI1CompatibleCameraIds.insert(id);
mUniqueAPI1CompatibleCameraIds.push_back(id);
}
if (parsedId != nullptr) {
@ -613,7 +645,9 @@ void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
if ((*it)->mId == id) {
mUniqueCameraIds.erase(id);
if ((*it)->isAPI1Compatible()) {
mUniqueAPI1CompatibleCameraIds.erase(id);
mUniqueAPI1CompatibleCameraIds.erase(std::remove(
mUniqueAPI1CompatibleCameraIds.begin(),
mUniqueAPI1CompatibleCameraIds.end(), id));
}
mDevices.erase(it);
break;
@ -1417,5 +1451,51 @@ status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
return OK;
}
status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
CameraMetadata* characteristics) const {
auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
return deviceInfo->getCameraCharacteristics(characteristics);
}
void CameraProviderManager::filterLogicalCameraIdsLocked(
std::vector<std::string>& deviceIds) const
{
std::unordered_set<std::string> removedIds;
for (auto& deviceId : deviceIds) {
CameraMetadata info;
status_t res = getCameraCharacteristicsLocked(deviceId, &info);
if (res != OK) {
ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
deviceId.c_str());
return;
}
// idCombo contains the ids of a logical camera and its physical cameras
std::vector<std::string> idCombo;
bool logicalCamera = CameraProviderManager::isLogicalCamera(info, &idCombo);
if (!logicalCamera) {
continue;
}
idCombo.push_back(deviceId);
for (auto& id : deviceIds) {
auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
if (foundId == idCombo.end()) {
continue;
}
idCombo.erase(foundId);
removedIds.insert(idCombo.begin(), idCombo.end());
break;
}
}
deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
[&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
deviceIds.end());
}
} // namespace android

@ -230,6 +230,13 @@ public:
hardware::hidl_version minVersion = hardware::hidl_version{0,0},
hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
/*
* Check if a camera with staticInfo is a logical camera. And if yes, return
* the physical camera ids.
*/
static bool isLogicalCamera(const CameraMetadata& staticInfo,
std::vector<std::string>* physicalCameraIds);
private:
// All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
mutable std::mutex mInterfaceMutex;
@ -314,7 +321,7 @@ private:
std::vector<std::unique_ptr<DeviceInfo>> mDevices;
std::unordered_set<std::string> mUniqueCameraIds;
int mUniqueDeviceCount;
std::unordered_set<std::string> mUniqueAPI1CompatibleCameraIds;
std::vector<std::string> mUniqueAPI1CompatibleCameraIds;
// HALv1-specific camera fields, including the actual device interface
struct DeviceInfo1 : public DeviceInfo {
@ -414,6 +421,9 @@ private:
static const char* torchStatusToString(
const hardware::camera::common::V1_0::TorchModeStatus&);
status_t getCameraCharacteristicsLocked(const std::string &id,
CameraMetadata* characteristics) const;
void filterLogicalCameraIdsLocked(std::vector<std::string>& deviceIds) const;
};
} // namespace android

Loading…
Cancel
Save