@ -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