Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 403af6dd authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

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
parent 5762c467
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -363,16 +363,18 @@ void CameraService::addStates(const String8 id) {
    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 @@ void CameraService::addStates(const String8 id) {
    {
        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 @@ bool CameraService::SensorPrivacyPolicy::hasCameraPrivacyFeature() {
// ----------------------------------------------------------------------------

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 @@ SystemCameraKind CameraService::CameraState::getSystemCameraKind() const {
    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,19 +4357,10 @@ std::list<String16> CameraService::getLogicalCameras(
    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 (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalCameraId.c_str())
                == physicalCameraIds.end()) {
            // cameraId is not a physical camera of this logical multi-camera.
            continue;
        }

        if (state.second->containsPhysicalCamera(physicalCameraId.c_str())) {
            retList.emplace_back(String16(state.first));
        }
    }
    return retList;
}

+8 −1
Original line number Diff line number Diff line
@@ -571,7 +571,7 @@ private:
         * returned in the HAL's camera_info struct for each device.
         */
        CameraState(const String8& id, int cost, const std::set<String8>& conflicting,
                SystemCameraKind deviceKind);
                SystemCameraKind deviceKind, const std::vector<std::string>& physicalCameras);
        virtual ~CameraState();

        /**
@@ -628,6 +628,12 @@ private:
         */
        SystemCameraKind getSystemCameraKind() const;

        /**
         * Return whether this camera is a logical multi-camera and has a
         * particular physical sub-camera.
         */
        bool containsPhysicalCamera(const std::string& physicalCameraId) const;

        /**
         * Add/Remove the unavailable physical camera ID.
         */
@@ -649,6 +655,7 @@ private:
        mutable Mutex mStatusLock;
        CameraParameters mShimParams;
        const SystemCameraKind mSystemCameraKind;
        const std::vector<std::string> mPhysicalCameras; // Empty if not a logical multi-camera
    }; // class CameraState

    // Observer for UID lifecycle enforcing that UIDs in idle