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

Commit 38e119b7 authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera1: Handle multiple logical cameras with same facing

For Camera1-HAL3 shim, the camera ID filtering logic is revised to
handle case of multiple logical cameras facing the same direction,
and are backed by same/different set of physical camera IDs.

Example 1 (all facing back):
ID1 = ID3 + ID4
ID2 = ID5 + ID6

Example 2 (all facing back):
ID5 = ID1 + ID2
ID6 = ID3 + ID4

In both examples, only ID1 will be advertised to camera1 app.

Test: Check cameras on devices with multiple logical cameras
Test: Camera CTS
Bug: 113705942
Change-Id: I76f370938b3311bbe7adcac8eddf8b6cf08e4571
parent 0e5a1b3b
Loading
Loading
Loading
Loading
+30 −14
Original line number Original line Diff line number Diff line
@@ -120,8 +120,8 @@ std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds
        std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
        std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;


        // API1 app doesn't handle logical and physical camera devices well. So
        // API1 app doesn't handle logical and physical camera devices well. So
        // for each [logical, physical1, physical2, ...] id combo, only take the
        // for each camera facing, only take the first id advertised by HAL in
        // first id advertised by HAL, and filter out the rest.
        // all [logical, physical1, physical2, ...] id combos, and filter out the rest.
        filterLogicalCameraIdsLocked(providerDeviceIds);
        filterLogicalCameraIdsLocked(providerDeviceIds);


        deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
        deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
@@ -2500,8 +2500,11 @@ status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string
void CameraProviderManager::filterLogicalCameraIdsLocked(
void CameraProviderManager::filterLogicalCameraIdsLocked(
        std::vector<std::string>& deviceIds) const
        std::vector<std::string>& deviceIds) const
{
{
    std::unordered_set<std::string> removedIds;
    // Map between camera facing and camera IDs related to logical camera.
    std::map<int, std::unordered_set<std::string>> idCombos;


    // Collect all logical and its underlying physical camera IDs for each
    // facing.
    for (auto& deviceId : deviceIds) {
    for (auto& deviceId : deviceIds) {
        auto deviceInfo = findDeviceInfoLocked(deviceId);
        auto deviceInfo = findDeviceInfoLocked(deviceId);
        if (deviceInfo == nullptr) continue;
        if (deviceInfo == nullptr) continue;
@@ -2509,25 +2512,38 @@ void CameraProviderManager::filterLogicalCameraIdsLocked(
        if (!deviceInfo->mIsLogicalCamera) {
        if (!deviceInfo->mIsLogicalCamera) {
            continue;
            continue;
        }
        }
        // idCombo contains the ids of a logical camera and its physical cameras
        std::vector<std::string> idCombo = deviceInfo->mPhysicalIds;
        idCombo.push_back(deviceId);


        // combo contains the ids of a logical camera and its physical cameras
        std::vector<std::string> combo = deviceInfo->mPhysicalIds;
        combo.push_back(deviceId);

        hardware::CameraInfo info;
        status_t res = deviceInfo->getCameraInfo(&info);
        if (res != OK) {
            ALOGE("%s: Error reading camera info: %s (%d)", __FUNCTION__, strerror(-res), res);
            continue;
        }
        idCombos[info.facing].insert(combo.begin(), combo.end());
    }

    // Only expose one camera ID per facing for all logical and underlying
    // physical camera IDs.
    for (auto& r : idCombos) {
        auto& removedIds = r.second;
        for (auto& id : deviceIds) {
        for (auto& id : deviceIds) {
            auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
            auto foundId = std::find(removedIds.begin(), removedIds.end(), id);
            if (foundId == idCombo.end()) {
            if (foundId == removedIds.end()) {
                continue;
                continue;
            }
            }


            idCombo.erase(foundId);
            removedIds.erase(foundId);
            removedIds.insert(idCombo.begin(), idCombo.end());
            break;
            break;
        }
        }
    }

        deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
        deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
            [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
                [&removedIds](const std::string& s) {
                return removedIds.find(s) != removedIds.end();}),
                deviceIds.end());
                deviceIds.end());
    }
    }
}


} // namespace android
} // namespace android