Loading services/camera/libcameraservice/api2/CameraDeviceClient.cpp +12 −41 Original line number Diff line number Diff line Loading @@ -624,12 +624,20 @@ binder::Status CameraDeviceClient::createStream( return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive"); } if (!checkPhysicalCameraId(physicalCameraId)) { 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()); } } std::vector<sp<Surface>> surfaces; std::vector<sp<IBinder>> binders; status_t err; Loading Loading @@ -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) { Loading services/camera/libcameraservice/common/CameraProviderManager.cpp +90 −10 Original line number Diff line number Diff line Loading @@ -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(), Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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 services/camera/libcameraservice/common/CameraProviderManager.h +11 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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 Loading
services/camera/libcameraservice/api2/CameraDeviceClient.cpp +12 −41 Original line number Diff line number Diff line Loading @@ -624,12 +624,20 @@ binder::Status CameraDeviceClient::createStream( return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive"); } if (!checkPhysicalCameraId(physicalCameraId)) { 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()); } } std::vector<sp<Surface>> surfaces; std::vector<sp<IBinder>> binders; status_t err; Loading Loading @@ -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) { Loading
services/camera/libcameraservice/common/CameraProviderManager.cpp +90 −10 Original line number Diff line number Diff line Loading @@ -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(), Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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
services/camera/libcameraservice/common/CameraProviderManager.h +11 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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