Loading services/camera/libcameraservice/CameraService.cpp +28 −9 Original line number Original line Diff line number Diff line Loading @@ -3745,9 +3745,14 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId, __FUNCTION__, cameraId.string()); __FUNCTION__, cameraId.string()); return; return; } } // Collect the logical cameras without holding mStatusLock in updateStatus // as that can lead to a deadlock(b/162192331). auto logicalCameraIds = getLogicalCameras(cameraId); // Update the status for this camera state, then send the onStatusChangedCallbacks to each // Update the status for this camera state, then send the onStatusChangedCallbacks to each // of the listeners with both the mStatusLock and mStatusListenerLock held // of the listeners with both the mStatusLock and mStatusListenerLock held state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, &supportsHAL3] state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, &supportsHAL3, &logicalCameraIds] (const String8& cameraId, StatusInternal status) { (const String8& cameraId, StatusInternal status) { if (status != StatusInternal::ENUMERATING) { if (status != StatusInternal::ENUMERATING) { Loading @@ -3767,8 +3772,8 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId, } } Mutex::Autolock lock(mStatusListenerLock); Mutex::Autolock lock(mStatusListenerLock); notifyPhysicalCameraStatusLocked(mapToInterface(status), String16(cameraId), notifyPhysicalCameraStatusLocked(mapToInterface(status), cameraId, deviceKind); logicalCameraIds, deviceKind); for (auto& listener : mListenerList) { for (auto& listener : mListenerList) { bool isVendorListener = listener->isVendorListener(); bool isVendorListener = listener->isVendorListener(); Loading Loading @@ -3886,8 +3891,9 @@ status_t CameraService::setTorchStatusLocked(const String8& cameraId, return OK; return OK; } } void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const String8& cameraId, std::list<String16> CameraService::getLogicalCameras( SystemCameraKind deviceKind) { const String8& physicalCameraId) { std::list<String16> retList; Mutex::Autolock lock(mCameraStatesLock); Mutex::Autolock lock(mCameraStatesLock); for (const auto& state : mCameraStates) { for (const auto& state : mCameraStates) { std::vector<std::string> physicalCameraIds; std::vector<std::string> physicalCameraIds; Loading @@ -3895,26 +3901,39 @@ void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const Strin // This is not a logical multi-camera. // This is not a logical multi-camera. continue; continue; } } if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), cameraId.c_str()) if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalCameraId.c_str()) == physicalCameraIds.end()) { == physicalCameraIds.end()) { // cameraId is not a physical camera of this logical multi-camera. // cameraId is not a physical camera of this logical multi-camera. continue; continue; } } String16 id16(state.first), physicalId16(cameraId); retList.emplace_back(String16(state.first)); } return retList; } void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const String16& physicalCameraId, const std::list<String16>& logicalCameraIds, SystemCameraKind deviceKind) { // mStatusListenerLock is expected to be locked for (const auto& logicalCameraId : logicalCameraIds) { for (auto& listener : mListenerList) { for (auto& listener : mListenerList) { // Note: we check only the deviceKind of the physical camera id // since, logical camera ids and their physical camera ids are // guaranteed to have the same system camera kind. if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(), if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(), listener->getListenerPid(), listener->getListenerUid())) { listener->getListenerPid(), listener->getListenerUid())) { ALOGV("Skipping discovery callback for system-only camera device %s", ALOGV("Skipping discovery callback for system-only camera device %s", cameraId.c_str()); String8(physicalCameraId).c_str()); continue; continue; } } listener->getListener()->onPhysicalCameraStatusChanged(status, listener->getListener()->onPhysicalCameraStatusChanged(status, id16, physicalId16); logicalCameraId, physicalCameraId); } } } } } } void CameraService::blockClientsForUid(uid_t uid) { void CameraService::blockClientsForUid(uid_t uid) { const auto clients = mActiveClientManager.getAll(); const auto clients = mActiveClientManager.getAll(); for (auto& current : clients) { for (auto& current : clients) { Loading services/camera/libcameraservice/CameraService.h +8 −2 Original line number Original line Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <set> #include <set> #include <string> #include <string> #include <list> #include <map> #include <map> #include <memory> #include <memory> #include <optional> #include <optional> Loading Loading @@ -1006,8 +1007,13 @@ private: hardware::camera::common::V1_0::TorchModeStatus status); hardware::camera::common::V1_0::TorchModeStatus status); // notify physical camera status when the physical camera is public. // notify physical camera status when the physical camera is public. void notifyPhysicalCameraStatusLocked(int32_t status, const String8& cameraId, // Expects mStatusListenerLock to be locked. SystemCameraKind deviceKind); void notifyPhysicalCameraStatusLocked(int32_t status, const String16& physicalCameraId, const std::list<String16>& logicalCameraIds, SystemCameraKind deviceKind); // get list of logical cameras which are backed by physicalCameraId std::list<String16> getLogicalCameras(const String8& physicalCameraId); // IBinder::DeathRecipient implementation // IBinder::DeathRecipient implementation virtual void binderDied(const wp<IBinder> &who); virtual void binderDied(const wp<IBinder> &who); Loading Loading
services/camera/libcameraservice/CameraService.cpp +28 −9 Original line number Original line Diff line number Diff line Loading @@ -3745,9 +3745,14 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId, __FUNCTION__, cameraId.string()); __FUNCTION__, cameraId.string()); return; return; } } // Collect the logical cameras without holding mStatusLock in updateStatus // as that can lead to a deadlock(b/162192331). auto logicalCameraIds = getLogicalCameras(cameraId); // Update the status for this camera state, then send the onStatusChangedCallbacks to each // Update the status for this camera state, then send the onStatusChangedCallbacks to each // of the listeners with both the mStatusLock and mStatusListenerLock held // of the listeners with both the mStatusLock and mStatusListenerLock held state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, &supportsHAL3] state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, &supportsHAL3, &logicalCameraIds] (const String8& cameraId, StatusInternal status) { (const String8& cameraId, StatusInternal status) { if (status != StatusInternal::ENUMERATING) { if (status != StatusInternal::ENUMERATING) { Loading @@ -3767,8 +3772,8 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId, } } Mutex::Autolock lock(mStatusListenerLock); Mutex::Autolock lock(mStatusListenerLock); notifyPhysicalCameraStatusLocked(mapToInterface(status), String16(cameraId), notifyPhysicalCameraStatusLocked(mapToInterface(status), cameraId, deviceKind); logicalCameraIds, deviceKind); for (auto& listener : mListenerList) { for (auto& listener : mListenerList) { bool isVendorListener = listener->isVendorListener(); bool isVendorListener = listener->isVendorListener(); Loading Loading @@ -3886,8 +3891,9 @@ status_t CameraService::setTorchStatusLocked(const String8& cameraId, return OK; return OK; } } void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const String8& cameraId, std::list<String16> CameraService::getLogicalCameras( SystemCameraKind deviceKind) { const String8& physicalCameraId) { std::list<String16> retList; Mutex::Autolock lock(mCameraStatesLock); Mutex::Autolock lock(mCameraStatesLock); for (const auto& state : mCameraStates) { for (const auto& state : mCameraStates) { std::vector<std::string> physicalCameraIds; std::vector<std::string> physicalCameraIds; Loading @@ -3895,26 +3901,39 @@ void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const Strin // This is not a logical multi-camera. // This is not a logical multi-camera. continue; continue; } } if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), cameraId.c_str()) if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalCameraId.c_str()) == physicalCameraIds.end()) { == physicalCameraIds.end()) { // cameraId is not a physical camera of this logical multi-camera. // cameraId is not a physical camera of this logical multi-camera. continue; continue; } } String16 id16(state.first), physicalId16(cameraId); retList.emplace_back(String16(state.first)); } return retList; } void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const String16& physicalCameraId, const std::list<String16>& logicalCameraIds, SystemCameraKind deviceKind) { // mStatusListenerLock is expected to be locked for (const auto& logicalCameraId : logicalCameraIds) { for (auto& listener : mListenerList) { for (auto& listener : mListenerList) { // Note: we check only the deviceKind of the physical camera id // since, logical camera ids and their physical camera ids are // guaranteed to have the same system camera kind. if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(), if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(), listener->getListenerPid(), listener->getListenerUid())) { listener->getListenerPid(), listener->getListenerUid())) { ALOGV("Skipping discovery callback for system-only camera device %s", ALOGV("Skipping discovery callback for system-only camera device %s", cameraId.c_str()); String8(physicalCameraId).c_str()); continue; continue; } } listener->getListener()->onPhysicalCameraStatusChanged(status, listener->getListener()->onPhysicalCameraStatusChanged(status, id16, physicalId16); logicalCameraId, physicalCameraId); } } } } } } void CameraService::blockClientsForUid(uid_t uid) { void CameraService::blockClientsForUid(uid_t uid) { const auto clients = mActiveClientManager.getAll(); const auto clients = mActiveClientManager.getAll(); for (auto& current : clients) { for (auto& current : clients) { Loading
services/camera/libcameraservice/CameraService.h +8 −2 Original line number Original line Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <set> #include <set> #include <string> #include <string> #include <list> #include <map> #include <map> #include <memory> #include <memory> #include <optional> #include <optional> Loading Loading @@ -1006,8 +1007,13 @@ private: hardware::camera::common::V1_0::TorchModeStatus status); hardware::camera::common::V1_0::TorchModeStatus status); // notify physical camera status when the physical camera is public. // notify physical camera status when the physical camera is public. void notifyPhysicalCameraStatusLocked(int32_t status, const String8& cameraId, // Expects mStatusListenerLock to be locked. SystemCameraKind deviceKind); void notifyPhysicalCameraStatusLocked(int32_t status, const String16& physicalCameraId, const std::list<String16>& logicalCameraIds, SystemCameraKind deviceKind); // get list of logical cameras which are backed by physicalCameraId std::list<String16> getLogicalCameras(const String8& physicalCameraId); // IBinder::DeathRecipient implementation // IBinder::DeathRecipient implementation virtual void binderDied(const wp<IBinder> &who); virtual void binderDied(const wp<IBinder> &who); Loading