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

Commit 7612f161 authored by Jayant Chowdhary's avatar Jayant Chowdhary
Browse files

vts camera characteristtics: add tests for system camera restrictions.



The system camera kind of physical cameras which are public, should be the same as the
system camera kind of the logical cameras they back.

The system camera kinds of all logical cameras that share the same
hidden physical cameras must be the same.

Bug: 152053830

Test: VtsHalCameraProviderV2_4TargetTest
      --gtest_filter=PerInstance/CameraHidlTest.getCameraCharacter*

Test: VtsHalCameraProviderV2_4TargetTest
      --gtest_filter=PerInstance/CameraHidlTest.systemCamera*

Change-Id: Iba07a6aa4a5fb465e9e0c4d0adedf6becaba7d14
Signed-off-by: default avatarJayant Chowdhary <jchowdhary@google.com>
parent ec78149a
Loading
Loading
Loading
Loading
+166 −17
Original line number Diff line number Diff line
@@ -18,12 +18,13 @@

#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <list>
#include <mutex>
#include <regex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <condition_variable>

#include <inttypes.h>

@@ -165,6 +166,26 @@ enum ReprocessType {
    YUV_REPROCESS,
};

enum SystemCameraKind {
    /**
     * These camera devices are visible to all apps and system components alike
     */
    PUBLIC = 0,

    /**
     * These camera devices are visible only to processes having the
     * android.permission.SYSTEM_CAMERA permission. They are not exposed to 3P
     * apps.
     */
    SYSTEM_ONLY_CAMERA,

    /**
     * These camera devices are visible only to HAL clients (that try to connect
     * on a hwbinder thread).
     */
    HIDDEN_SECURE_CAMERA
};

namespace {
    // "device@<version>/legacy/<id>"
    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
@@ -851,6 +872,8 @@ public:
    static Status isAutoFocusModeAvailable(
            CameraParameters &cameraParams, const char *mode) ;
    static Status isMonochromeCamera(const camera_metadata_t *staticMeta);
    static Status getSystemCameraKind(const camera_metadata_t* staticMeta,
                                      SystemCameraKind* systemCameraKind);

    // Used by switchToOffline where a new result queue is created for offline reqs
    void updateInflightResultQueue(std::shared_ptr<ResultMetadataQueue> resultQueue);
@@ -2555,6 +2578,90 @@ TEST_P(CameraHidlTest, getSetParameters) {
    }
}

TEST_P(CameraHidlTest, systemCameraTest) {
    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
    std::map<std::string, std::list<SystemCameraKind>> hiddenPhysicalIdToLogicalMap;
    for (const auto& name : cameraDeviceNames) {
        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
        switch (deviceVersion) {
            case CAMERA_DEVICE_API_VERSION_3_6:
            case CAMERA_DEVICE_API_VERSION_3_5:
            case CAMERA_DEVICE_API_VERSION_3_4:
            case CAMERA_DEVICE_API_VERSION_3_3:
            case CAMERA_DEVICE_API_VERSION_3_2: {
                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
                ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
                Return<void> ret;
                ret = mProvider->getCameraDeviceInterface_V3_x(
                        name, [&](auto status, const auto& device) {
                            ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
                            ASSERT_EQ(Status::OK, status);
                            ASSERT_NE(device, nullptr);
                            device3_x = device;
                        });
                ASSERT_TRUE(ret.isOk());

                ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
                    ASSERT_EQ(status, Status::OK);
                    const camera_metadata_t* staticMeta =
                            reinterpret_cast<const camera_metadata_t*>(chars.data());
                    ASSERT_NE(staticMeta, nullptr);
                    Status rc = isLogicalMultiCamera(staticMeta);
                    ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc);
                    if (Status::METHOD_NOT_SUPPORTED == rc) {
                        return;
                    }
                    std::unordered_set<std::string> physicalIds;
                    ASSERT_EQ(Status::OK, getPhysicalCameraIds(staticMeta, &physicalIds));
                    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
                    rc = getSystemCameraKind(staticMeta, &systemCameraKind);
                    ASSERT_EQ(rc, Status::OK);
                    for (auto physicalId : physicalIds) {
                        bool isPublicId = false;
                        for (auto& deviceName : cameraDeviceNames) {
                            std::string publicVersion, publicId;
                            ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion,
                                                          &publicId));
                            if (physicalId == publicId) {
                                isPublicId = true;
                                break;
                            }
                        }
                        // For hidden physical cameras, collect their associated logical cameras
                        // and store the system camera kind.
                        if (!isPublicId) {
                            auto it = hiddenPhysicalIdToLogicalMap.find(physicalId);
                            if (it == hiddenPhysicalIdToLogicalMap.end()) {
                                hiddenPhysicalIdToLogicalMap.insert(std::make_pair(
                                        physicalId, std::list<SystemCameraKind>(systemCameraKind)));
                            } else {
                                it->second.push_back(systemCameraKind);
                            }
                        }
                    }
                });
                ASSERT_TRUE(ret.isOk());
            } break;
            case CAMERA_DEVICE_API_VERSION_1_0: {
                // Not applicable
            } break;
            default: {
                ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
                ADD_FAILURE();
            } break;
        }
    }

    // Check that the system camera kind of the logical cameras associated with
    // each hidden physical camera is the same.
    for (const auto& it : hiddenPhysicalIdToLogicalMap) {
        SystemCameraKind neededSystemCameraKind = it.second.front();
        for (auto foundSystemCamera : it.second) {
            ASSERT_EQ(neededSystemCameraKind, foundSystemCamera);
        }
    }
}

// Verify that the static camera characteristics can be retrieved
// successfully.
TEST_P(CameraHidlTest, getCameraCharacteristics) {
@@ -5671,6 +5778,39 @@ Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta,
    return ret;
}

Status CameraHidlTest::getSystemCameraKind(const camera_metadata_t* staticMeta,
                                           SystemCameraKind* systemCameraKind) {
    Status ret = Status::OK;
    if (nullptr == staticMeta || nullptr == systemCameraKind) {
        return Status::ILLEGAL_ARGUMENT;
    }

    camera_metadata_ro_entry entry;
    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
                                           &entry);
    if (0 != rc) {
        return Status::ILLEGAL_ARGUMENT;
    }

    if (entry.count == 1 &&
        entry.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA) {
        *systemCameraKind = SystemCameraKind::HIDDEN_SECURE_CAMERA;
        return ret;
    }

    // Go through the capabilities and check if it has
    // ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA
    for (size_t i = 0; i < entry.count; ++i) {
        uint8_t capability = entry.data.u8[i];
        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA) {
            *systemCameraKind = SystemCameraKind::SYSTEM_ONLY_CAMERA;
            return ret;
        }
    }
    *systemCameraKind = SystemCameraKind::PUBLIC;
    return ret;
}

// Check whether this is a monochrome camera using the static camera characteristics.
Status CameraHidlTest::isMonochromeCamera(const camera_metadata_t *staticMeta) {
    Status ret = Status::METHOD_NOT_SUPPORTED;
@@ -6391,8 +6531,10 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
        const hidl_vec<hidl_string>& deviceNames) {
    const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
    ASSERT_NE(nullptr, metadata);

    Status rc = isLogicalMultiCamera(metadata);
    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
    Status rc = getSystemCameraKind(metadata, &systemCameraKind);
    ASSERT_EQ(rc, Status::OK);
    rc = isLogicalMultiCamera(metadata);
    ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc);
    if (Status::METHOD_NOT_SUPPORTED == rc) {
        return;
@@ -6411,6 +6553,7 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
        ASSERT_NE(physicalId, cameraId);
        bool isPublicId = false;
        std::string fullPublicId;
        SystemCameraKind physSystemCameraKind = SystemCameraKind::PUBLIC;
        for (auto& deviceName : deviceNames) {
            std::string publicVersion, publicId;
            ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
@@ -6434,8 +6577,15 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
            ret = subDevice->getCameraCharacteristics(
                    [&](auto status, const auto& chars) {
                ASSERT_EQ(Status::OK, status);
                retcode = find_camera_metadata_ro_entry(
                        (const camera_metadata_t *)chars.data(),
                const camera_metadata_t* staticMeta =
                        reinterpret_cast<const camera_metadata_t*>(chars.data());
                rc = getSystemCameraKind(staticMeta, &physSystemCameraKind);
                ASSERT_EQ(rc, Status::OK);
                // Make sure that the system camera kind of a non-hidden
                // physical cameras is the same as the logical camera associated
                // with it.
                ASSERT_EQ(physSystemCameraKind, systemCameraKind);
                retcode = find_camera_metadata_ro_entry(staticMeta,
                                                        ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
                bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2);
                ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange);
@@ -6452,13 +6602,12 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
        ASSERT_NE(device3_5, nullptr);

        // Check camera characteristics for hidden camera id
        Return<void> ret = device3_5->getPhysicalCameraCharacteristics(physicalId,
                [&](auto status, const auto& chars) {
        Return<void> ret = device3_5->getPhysicalCameraCharacteristics(
                physicalId, [&](auto status, const auto& chars) {
                    verifyCameraCharacteristics(status, chars);
                    verifyMonochromeCharacteristics(chars, deviceVersion);

            retcode = find_camera_metadata_ro_entry(
                    (const camera_metadata_t *)chars.data(),
                    retcode =
                            find_camera_metadata_ro_entry((const camera_metadata_t*)chars.data(),
                                                          ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
                    bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2);
                    ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange);