Camera: Pre-populate physical camera Ids when creating CameraState
Query the physical camera IDs when creating CameraState rather than
during updateStatus().
This is more efficient, as well as fixing below deadlock:
- updateStatus acquires mCameraStatesLock, waits for mInterfaceMutex
- CameraProviderManager::dump acquires mInterfaceMutex, waits for binder
transact
- HAL process handles dump(), wait for an internal lock
- HAL in the middle of close(), holding the internal lock while calling
torchModeStatusChanged
- torchModeStatusChanged waits for mCameraStatesLock
Test: Vendor testing, camera CTS
Bug: 210185710
Change-Id: I34a93da4cc92e7318d179ef8fbaee007dd04ff73
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index fb043a4..0b6b1fb 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -363,16 +363,18 @@
std::string cameraId(id.c_str());
hardware::camera::common::V1_0::CameraResourceCost cost;
status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
- SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (res != OK) {
ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
return;
}
+ SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
res = mCameraProviderManager->getSystemCameraKind(cameraId, &deviceKind);
if (res != OK) {
ALOGE("Failed to query device kind: %s (%d)", strerror(-res), res);
return;
}
+ std::vector<std::string> physicalCameraIds;
+ mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds);
std::set<String8> conflicting;
for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
@@ -381,7 +383,7 @@
{
Mutex::Autolock lock(mCameraStatesLock);
mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
- conflicting, deviceKind));
+ conflicting, deviceKind, physicalCameraIds));
}
if (mFlashlight->hasFlashUnit(id)) {
@@ -3690,9 +3692,10 @@
// ----------------------------------------------------------------------------
CameraService::CameraState::CameraState(const String8& id, int cost,
- const std::set<String8>& conflicting, SystemCameraKind systemCameraKind) : mId(id),
+ const std::set<String8>& conflicting, SystemCameraKind systemCameraKind,
+ const std::vector<std::string>& physicalCameras) : mId(id),
mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting),
- mSystemCameraKind(systemCameraKind) {}
+ mSystemCameraKind(systemCameraKind), mPhysicalCameras(physicalCameras) {}
CameraService::CameraState::~CameraState() {}
@@ -3731,6 +3734,11 @@
return mSystemCameraKind;
}
+bool CameraService::CameraState::containsPhysicalCamera(const std::string& physicalCameraId) const {
+ return std::find(mPhysicalCameras.begin(), mPhysicalCameras.end(), physicalCameraId)
+ != mPhysicalCameras.end();
+}
+
bool CameraService::CameraState::addUnavailablePhysicalId(const String8& physicalId) {
Mutex::Autolock lock(mStatusLock);
auto result = mUnavailablePhysicalIds.insert(physicalId);
@@ -4349,18 +4357,9 @@
std::list<String16> retList;
Mutex::Autolock lock(mCameraStatesLock);
for (const auto& state : mCameraStates) {
- std::vector<std::string> physicalCameraIds;
- if (!mCameraProviderManager->isLogicalCamera(state.first.c_str(), &physicalCameraIds)) {
- // This is not a logical multi-camera.
- continue;
+ if (state.second->containsPhysicalCamera(physicalCameraId.c_str())) {
+ retList.emplace_back(String16(state.first));
}
- if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalCameraId.c_str())
- == physicalCameraIds.end()) {
- // cameraId is not a physical camera of this logical multi-camera.
- continue;
- }
-
- retList.emplace_back(String16(state.first));
}
return retList;
}