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

Commit f6039c22 authored by Shuzhen Wang's avatar Shuzhen Wang Committed by android-build-merger
Browse files

Camera: Filter logical camera ids to API1 app am: e8aceb53

am: 29880995

Change-Id: I6e803da88c31bba115e5c4526a035217301ca3ee
parents b699a5bf 29880995
Loading
Loading
Loading
Loading
+12 −41
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
+90 −10
Original line number Diff line number Diff line
@@ -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(),
@@ -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,
@@ -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) {
@@ -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) {
@@ -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;
@@ -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
+11 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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 {
@@ -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