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

Commit be70ec0f authored by shrikar's avatar shrikar
Browse files

Added config reader for shared session config xml

Bug: 372321187
Test: ConfigUtilsTest

Flag: com.android.internal.camera.flags.camera_multi_client
Change-Id: I636a99f20d758cf0f74d7ef08dd905602136eb61
parent 4101992d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ cc_defaults {
        "libsensorprivacy",
        "libstagefright",
        "libstagefright_foundation",
        "libtinyxml2",
        "libvendorsupport",
        "libxml2",
        "libyuv",
@@ -142,6 +143,8 @@ cc_library {
        "common/FrameProcessorBase.cpp",
        "common/hidl/HidlProviderInfo.cpp",
        "common/aidl/AidlProviderInfo.cpp",
        "config/SharedSessionConfigUtils.cpp",
        "config/SharedSessionConfigReader.cpp",
        "api1/Camera2Client.cpp",
        "api1/client2/Parameters.cpp",
        "api1/client2/FrameProcessor.cpp",
@@ -221,6 +224,7 @@ cc_library {
        "libcamera_client",
        "libfmq",
        "libsensorprivacy",
        "libtinyxml2",
    ],

    include_dirs: [
+56 −45
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@

#include "CameraProviderManager.h"

#include "config/SharedSessionConfigReader.h"

#include <aidl/android/hardware/camera/device/ICameraDevice.h>

#include <algorithm>
@@ -2090,60 +2092,69 @@ bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAutomotiveDevice() {
    return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
}

status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addSharedSessionConfigurationTags() {
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addSharedSessionConfigurationTags(
        const std::string &cameraId) {
    status_t res = OK;
    if (flags::camera_multi_client()) {
        SharedSessionConfigReader configReader;
        ErrorCode status =
                configReader.parseSharedSessionConfig(
                                    (std::string(SHARED_SESSION_FILE_PATH)
                                     + std::string(SHARED_SESSION_FILE_NAME)).c_str());
        if (status != 0) {
            ALOGE("%s: failed to initialize SharedSessionConfigReader with ErrorCode %s",
                  __FUNCTION__, SharedSessionConfigUtils::toString(status));
            return BAD_VALUE;
        }
        const int32_t sharedColorSpaceTag = ANDROID_SHARED_SESSION_COLOR_SPACE;
        const int32_t sharedOutputConfigurationsTag = ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS;
        auto& c = mCameraCharacteristics;
        int32_t colorSpace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED;

        status = configReader.getColorSpace(&colorSpace);
        if (status != 0) {
            ALOGE("%s: failed to get color space from config reader with ErrorCode %s",
                  __FUNCTION__, SharedSessionConfigUtils::toString(status));
            return BAD_VALUE;
        }

        res = c.update(sharedColorSpaceTag, &colorSpace, 1);
        if (res != OK) {
            ALOGE("%s: failed to update sharedColorSpaceTag with error %d", __FUNCTION__, res);
            return res;
        }

        std::vector<SharedSessionConfigReader::SharedSessionConfig> outputConfigurations;
        status = configReader.getAvailableSharedSessionConfigs(cameraId.c_str(),
                                                               &outputConfigurations);
        if (status != 0) {
            ALOGE("%s: failed to get output configurations from config reader with ErrorCode %s",
                  __FUNCTION__, SharedSessionConfigUtils::toString(status));
            return BAD_VALUE;
        }

        // ToDo: b/372321187 Hardcoding the shared session configuration. Update the code to
        // take these values from XML instead.
        std::vector<int64_t> sharedOutputConfigEntries;
        int64_t surfaceType1 =  OutputConfiguration::SURFACE_TYPE_IMAGE_READER;
        int64_t width = 1920;
        int64_t height = 1080;
        int64_t format1 = HAL_PIXEL_FORMAT_RGBA_8888;
        int64_t mirrorMode = OutputConfiguration::MIRROR_MODE_AUTO;
        int64_t timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT;
        int64_t usage1 = 3;
        int64_t dataspace = 0;
        int64_t useReadoutTimestamp = 0;
        int64_t streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
        int64_t physicalCamIdLen = 0;

        // Stream 1 configuration hardcoded
        sharedOutputConfigEntries.push_back(surfaceType1);
        sharedOutputConfigEntries.push_back(width);
        sharedOutputConfigEntries.push_back(height);
        sharedOutputConfigEntries.push_back(format1);
        sharedOutputConfigEntries.push_back(mirrorMode);
        sharedOutputConfigEntries.push_back(useReadoutTimestamp);
        sharedOutputConfigEntries.push_back(timestampBase);
        sharedOutputConfigEntries.push_back(dataspace);
        sharedOutputConfigEntries.push_back(usage1);
        sharedOutputConfigEntries.push_back(streamUseCase);
        sharedOutputConfigEntries.push_back(physicalCamIdLen);

        // Stream 2 configuration hardcoded
        int64_t surfaceType2 =  OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW;
        int64_t format2 = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
        int64_t usage2 = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_HW_COMPOSER;

        sharedOutputConfigEntries.push_back(surfaceType2);
        sharedOutputConfigEntries.push_back(width);
        sharedOutputConfigEntries.push_back(height);
        sharedOutputConfigEntries.push_back(format2);
        sharedOutputConfigEntries.push_back(mirrorMode);
        sharedOutputConfigEntries.push_back(useReadoutTimestamp);
        sharedOutputConfigEntries.push_back(timestampBase);
        sharedOutputConfigEntries.push_back(dataspace);
        sharedOutputConfigEntries.push_back(usage2);
        sharedOutputConfigEntries.push_back(streamUseCase);
        sharedOutputConfigEntries.push_back(physicalCamIdLen);

        for (auto outputConfig : outputConfigurations) {
            sharedOutputConfigEntries.push_back(outputConfig.surfaceType);
            sharedOutputConfigEntries.push_back(outputConfig.width);
            sharedOutputConfigEntries.push_back(outputConfig.height);
            sharedOutputConfigEntries.push_back(outputConfig.format);
            sharedOutputConfigEntries.push_back(outputConfig.mirrorMode);
            sharedOutputConfigEntries.push_back(outputConfig.useReadoutTimestamp);
            sharedOutputConfigEntries.push_back(outputConfig.timestampBase);
            sharedOutputConfigEntries.push_back(outputConfig.dataSpace);
            sharedOutputConfigEntries.push_back(outputConfig.usage);
            sharedOutputConfigEntries.push_back(outputConfig.streamUseCase);
            if (strcmp(outputConfig.physicalCameraId.c_str(), "")) {
                sharedOutputConfigEntries.push_back(outputConfig.physicalCameraId.length());
                for (char c : outputConfig.physicalCameraId) {
                    sharedOutputConfigEntries.push_back(c);
                }
            } else {
                sharedOutputConfigEntries.push_back(/* physical camera id len */ 0);
            }
        }

        res = c.update(sharedOutputConfigurationsTag, sharedOutputConfigEntries.data(),
                       sharedOutputConfigEntries.size());
+3 −1
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@
#include <binder/IServiceManager.h>
#include <camera/VendorTagDescriptor.h>

#include "config/SharedSessionConfigUtils.h"

namespace android {

using hardware::camera2::utils::CameraIdAndSessionConfiguration;
@@ -782,7 +784,7 @@ private:
            status_t addColorCorrectionAvailableModesTag(CameraMetadata& ch);
            status_t addAePriorityModeTags();
            status_t addSessionConfigQueryVersionTag();
            status_t addSharedSessionConfigurationTags();
            status_t addSharedSessionConfigurationTags(const std::string &cameraId);
            bool isAutomotiveDevice();

            static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
+5 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include "device3/DistortionMapper.h"
#include "device3/ZoomRatioMapper.h"
#include <filesystem>
#include <utils/AttributionAndPermissionUtils.h>
#include <utils/SessionConfigurationUtils.h>
#include <utils/Trace.h>
@@ -740,8 +741,10 @@ AidlProviderInfo::AidlDeviceInfo3::AidlDeviceInfo3(
                {ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, ANDROID_CONTROL_AE_TARGET_FPS_RANGE});
    }

    if (flags::camera_multi_client() && isAutomotiveDevice()) {
        addSharedSessionConfigurationTags();
    std::filesystem::path sharedSessionConfigFilePath =
            std::string(SHARED_SESSION_FILE_PATH) + std::string(SHARED_SESSION_FILE_NAME);
    if (flags::camera_multi_client() && std::filesystem::exists(sharedSessionConfigFilePath)) {
        addSharedSessionConfigurationTags(id);
    }

    if (!kEnableLazyHal) {
+239 −0
Original line number Diff line number Diff line
//
// Copyright 2024 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#define LOG_TAG "SharedSessionConfigReader"

#include "SharedSessionConfigReader.h"

#include <fstream>
#include <utils/Log.h>

using tinyxml2::XML_SUCCESS;
using tinyxml2::XMLDocument;
namespace android {

ErrorCode SharedSessionConfigReader::parseSharedSessionConfig(
        const char* sharedSessionConfigFilePath) {
    if (!mCameraIdToSharedSessionConfigs.empty()) {
        ALOGV("mCameraIdToSharedSessionConfigs already initialized.");
        return ErrorCode::STATUS_OK;
    }

    XMLDocument xmlDoc;

    // load and parse the configuration file
    xmlDoc.LoadFile(sharedSessionConfigFilePath);
    if (xmlDoc.ErrorID() != XML_SUCCESS) {
        ALOGE("%s: Failed to load/parse the configuration file: %s, with error: %s", __FUNCTION__,
              sharedSessionConfigFilePath, xmlDoc.ErrorStr());
        return ErrorCode::ERROR_READ_CONFIG_FILE;
    }

    ErrorCode status = parseSharedSessionConfigFromXMLDocument(xmlDoc);
    if (status != ErrorCode::STATUS_OK) {
        ALOGE("%s: Error while parsing XML elements of file at: %s", __FUNCTION__,
              sharedSessionConfigFilePath);
        return status;
    }

    return ErrorCode::STATUS_OK;
}

ErrorCode SharedSessionConfigReader::parseSharedSessionConfigFromXMLDocument(
        const XMLDocument& xmlDoc) {
    const XMLElement* rootElem = xmlDoc.RootElement();
    if (strcmp(rootElem->Name(), "SharedCameraSessionConfigurations")) {
        ALOGE("%s: Expected root element to be 'SharedCameraSessionConfigurations'. Instead got %s",
              __FUNCTION__, rootElem->Name());
        return ErrorCode::ERROR_READ_CONFIG_FILE;
    }

    ErrorCode status;
    const char* colorSpaceStr = rootElem->Attribute("colorSpace");
    status = SharedSessionConfigUtils::getColorSpaceFromStr(colorSpaceStr, &mColorSpace);
    if (status != ErrorCode::STATUS_OK) {
        ALOGE("%s: getColorSpaceFromStr has returned an error: %s", __FUNCTION__,
              SharedSessionConfigUtils::toString(status));
        return status;
    }

    std::unordered_map<std::string, std::vector<SharedSessionConfig>>
            cameraIdToSharedSessionConfigs;

    for (const XMLElement* sharedConfigElem =
                 rootElem->FirstChildElement("SharedCameraSessionConfiguration");
            sharedConfigElem != nullptr;
            sharedConfigElem =
                 sharedConfigElem->NextSiblingElement("SharedCameraSessionConfiguration")) {

        const char* cameraId = sharedConfigElem->Attribute("cameraId");
        if (cameraId == nullptr || !strcmp(cameraId, "")) {
            ALOGE("%s: cameraId attribute is empty", __FUNCTION__);
            return ErrorCode::ERROR_CONFIG_FILE_FORMAT;
        }

        for (const XMLElement* outputConfigElem =
                     sharedConfigElem->FirstChildElement("OutputConfiguration");
                outputConfigElem != nullptr;
                outputConfigElem = outputConfigElem->NextSiblingElement("OutputConfiguration")) {
            int64_t surfaceType;
            const XMLElement* surfaceTypeXml = outputConfigElem->FirstChildElement("surfaceType");
            status = SharedSessionConfigUtils::getSurfaceTypeFromXml(surfaceTypeXml, &surfaceType);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getSurfaceTypeFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t width;
            const XMLElement* widthXml = outputConfigElem->FirstChildElement("width");
            status = SharedSessionConfigUtils::getWidthFromXml(widthXml, &width);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getWidthFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t height;
            const XMLElement* heightXml = outputConfigElem->FirstChildElement("height");
            status = SharedSessionConfigUtils::getHeightFromXml(heightXml, &height);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getHeightFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            std::string physicalCameraId;
            const XMLElement* physicalCameraIdXml =
                    outputConfigElem->FirstChildElement("physicalCameraId");
            status = SharedSessionConfigUtils::getPhysicalCameraIdFromXml(physicalCameraIdXml,
                                                                          &physicalCameraId);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getPhysicalCameraIdFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t streamUseCase;
            const XMLElement* streamUseCaseXml =
                    outputConfigElem->FirstChildElement("streamUseCase");
            status = SharedSessionConfigUtils::getStreamUseCaseFromXml(streamUseCaseXml,
                                                                       &streamUseCase);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getStreamUseCaseFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t timestampBase;
            const XMLElement* timestampBaseXml =
                    outputConfigElem->FirstChildElement("timestampBase");
            status = SharedSessionConfigUtils::getTimestampBaseFromXml(timestampBaseXml,
                                                                       &timestampBase);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getTimestampBaseFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t mirrorMode;
            const XMLElement* mirrorModeXml = outputConfigElem->FirstChildElement("mirrorMode");
            status = SharedSessionConfigUtils::getMirrorModeFromXml(mirrorModeXml, &mirrorMode);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getMirrorModeFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            bool useReadoutTimestamp;
            const XMLElement* useReadoutTimestampXml =
                    outputConfigElem->FirstChildElement("useReadoutTimestamp");
            status = SharedSessionConfigUtils::getUseReadoutTimestampFromXml(useReadoutTimestampXml,
                                                                             &useReadoutTimestamp);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getUseReadoutTimestampFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t format;
            const XMLElement* formatXml = outputConfigElem->FirstChildElement("format");
            status = SharedSessionConfigUtils::getFormatFromXml(formatXml, &format, surfaceType);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getFormatFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t usage;
            const XMLElement* usageXml = outputConfigElem->FirstChildElement("usage");
            status = SharedSessionConfigUtils::getUsageFromXml(usageXml, &usage, surfaceType);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getUsageFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            int64_t dataSpace;
            const XMLElement* dataSpaceXml = outputConfigElem->FirstChildElement("dataSpace");
            status = SharedSessionConfigUtils::getDataSpaceFromXml(dataSpaceXml, &dataSpace);
            if (status != ErrorCode::STATUS_OK) {
                ALOGE("%s: getUsageFromXml has returned an error: %s", __FUNCTION__,
                      SharedSessionConfigUtils::toString(status));
                return status;
            }

            cameraIdToSharedSessionConfigs[cameraId].push_back(
                    SharedSessionConfig{surfaceType, width, height, physicalCameraId, streamUseCase,
                                        timestampBase, mirrorMode, useReadoutTimestamp, format,
                                        usage, dataSpace});
        }
    }

    if (cameraIdToSharedSessionConfigs.empty()) {
        ALOGE("%s: No elements with tag 'SharedCameraSessionConfiguration' in file", __FUNCTION__);
        return ErrorCode::ERROR_CONFIG_FILE_FORMAT;
    }

    mCameraIdToSharedSessionConfigs = cameraIdToSharedSessionConfigs;
    return ErrorCode::STATUS_OK;
}

ErrorCode SharedSessionConfigReader::getColorSpace(/* out */ int32_t* colorSpace) {
    *colorSpace = mColorSpace;
    return ErrorCode::STATUS_OK;
}

// Returns the cameraConfig parameters.
ErrorCode SharedSessionConfigReader::getAvailableSharedSessionConfigs(
        const char* cameraId, /* out */ std::vector<SharedSessionConfig>* availableConfigurations) {
    if (mCameraIdToSharedSessionConfigs.empty()) {
        ALOGE("%s: mCameraIdToSharedSessionConfigs is empty. Call initialize() first.",
              __FUNCTION__);
        return ErrorCode::ERROR_CONFIG_READER_UNINITIALIZED;
    }

    if (!mCameraIdToSharedSessionConfigs.contains(cameraId)) {
        ALOGE("%s: cameraId: %s not found in mCameraIdToSharedSessionConfigs.", __FUNCTION__,
              cameraId);
        return ErrorCode::ERROR_BAD_PARAMETER;
    }

    *availableConfigurations = mCameraIdToSharedSessionConfigs[cameraId];
    return ErrorCode::STATUS_OK;
}

}  // namespace android
Loading