diff options
Diffstat (limited to 'src/android/camera_hal_config.cpp')
-rw-r--r-- | src/android/camera_hal_config.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp new file mode 100644 index 00000000..7ef451ef --- /dev/null +++ b/src/android/camera_hal_config.cpp @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * Camera HAL configuration file manager + */ +#include "camera_hal_config.h" + +#include <stdlib.h> +#include <string> + +#include <libcamera/base/file.h> +#include <libcamera/base/log.h> + +#include "libcamera/internal/yaml_parser.h" + +#include <hardware/camera3.h> + +using namespace libcamera; + +LOG_DEFINE_CATEGORY(HALConfig) + +class CameraHalConfig::Private : public Extensible::Private +{ + LIBCAMERA_DECLARE_PUBLIC(CameraHalConfig) + +public: + Private(); + + int parseConfigFile(File &file, std::map<std::string, CameraConfigData> *cameras); + +private: + int parseCameraConfigData(const std::string &cameraId, const YamlObject &); + int parseLocation(const YamlObject &, CameraConfigData &cameraConfigData); + int parseRotation(const YamlObject &, CameraConfigData &cameraConfigData); + + std::map<std::string, CameraConfigData> *cameras_; +}; + +CameraHalConfig::Private::Private() +{ +} + +int CameraHalConfig::Private::parseConfigFile(File &file, + std::map<std::string, CameraConfigData> *cameras) +{ + /* + * Parse the HAL properties. + * + * Each camera properties block is a list of properties associated + * with the ID (as assembled by CameraSensor::generateId()) of the + * camera they refer to. + * + * cameras: + * "camera0 id": + * location: value + * rotation: value + * ... + * + * "camera1 id": + * location: value + * rotation: value + * ... + */ + + cameras_ = cameras; + + std::unique_ptr<YamlObject> root = YamlParser::parse(file); + if (!root) + return -EINVAL; + + if (!root->isDictionary()) + return -EINVAL; + + /* Parse property "cameras" */ + if (!root->contains("cameras")) + return -EINVAL; + + const YamlObject &yamlObjectCameras = (*root)["cameras"]; + + if (!yamlObjectCameras.isDictionary()) + return -EINVAL; + + for (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) { + if (parseCameraConfigData(cameraId, configData)) + return -EINVAL; + } + + return 0; +} + +int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId, + const YamlObject &cameraObject) + +{ + if (!cameraObject.isDictionary()) + return -EINVAL; + + CameraConfigData &cameraConfigData = (*cameras_)[cameraId]; + + /* Parse property "location" */ + if (parseLocation(cameraObject, cameraConfigData)) + return -EINVAL; + + /* Parse property "rotation" */ + if (parseRotation(cameraObject, cameraConfigData)) + return -EINVAL; + + return 0; +} + +int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject, + CameraConfigData &cameraConfigData) +{ + if (!cameraObject.contains("location")) + return -EINVAL; + + std::string location = cameraObject["location"].get<std::string>(""); + + if (location == "front") + cameraConfigData.facing = CAMERA_FACING_FRONT; + else if (location == "back") + cameraConfigData.facing = CAMERA_FACING_BACK; + else + return -EINVAL; + + return 0; +} + +int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject, + CameraConfigData &cameraConfigData) +{ + if (!cameraObject.contains("rotation")) + return -EINVAL; + + int32_t rotation = cameraObject["rotation"].get<int32_t>(-1); + + if (rotation < 0 || rotation >= 360) { + LOG(HALConfig, Error) + << "Unknown rotation: " << rotation; + return -EINVAL; + } + + cameraConfigData.rotation = rotation; + return 0; +} + +CameraHalConfig::CameraHalConfig() + : Extensible(std::make_unique<Private>()), exists_(false), valid_(false) +{ + parseConfigurationFile(); +} + +/* + * Open the HAL configuration file and validate its content. + * Return 0 on success, a negative error code otherwise + * retval -ENOENT The configuration file is not available + * retval -EINVAL The configuration file is available but not valid + */ +int CameraHalConfig::parseConfigurationFile() +{ + std::string filePath = LIBCAMERA_SYSCONF_DIR "/camera_hal.yaml"; + + File file(filePath); + if (!file.exists()) { + LOG(HALConfig, Debug) + << "Configuration file: \"" << filePath << "\" not found"; + return -ENOENT; + } + + if (!file.open(File::OpenModeFlag::ReadOnly)) { + int ret = file.error(); + LOG(HALConfig, Error) << "Failed to open configuration file " + << filePath << ": " << strerror(-ret); + return ret; + } + + exists_ = true; + + int ret = _d()->parseConfigFile(file, &cameras_); + if (ret) + return -EINVAL; + + valid_ = true; + + for (const auto &c : cameras_) { + const std::string &cameraId = c.first; + const CameraConfigData &camera = c.second; + LOG(HALConfig, Debug) << "'" << cameraId << "' " + << "(" << camera.facing << ")[" + << camera.rotation << "]"; + } + + return 0; +} + +const CameraConfigData *CameraHalConfig::cameraConfigData(const std::string &cameraId) const +{ + const auto &it = cameras_.find(cameraId); + if (it == cameras_.end()) { + LOG(HALConfig, Error) + << "Camera '" << cameraId + << "' not described in the HAL configuration file"; + return nullptr; + } + + return &it->second; +} |