summaryrefslogtreecommitdiff
path: root/src/android/camera_hal_config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/camera_hal_config.cpp')
-rw-r--r--src/android/camera_hal_config.cpp208
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;
+}