@@ -17,6 +17,7 @@
#include <libcamera/ipa/ipa_module_info.h>
#include "libcamera/internal/camera_manager.h"
+#include "libcamera/internal/global_configuration.h"
#include "libcamera/internal/ipa_module.h"
#include "libcamera/internal/pipeline_handler.h"
#include "libcamera/internal/pub_key.h"
@@ -28,7 +29,7 @@ LOG_DECLARE_CATEGORY(IPAManager)
class IPAManager
{
public:
- IPAManager();
+ IPAManager(const GlobalConfiguration &configuration);
~IPAManager();
template<typename T>
@@ -42,7 +43,8 @@ public:
if (!m)
return nullptr;
- std::unique_ptr<T> proxy = std::make_unique<T>(m, !self->isSignatureValid(m));
+ const GlobalConfiguration &configuration = cm->_d()->configuration();
+ std::unique_ptr<T> proxy = std::make_unique<T>(m, !self->isSignatureValid(m), configuration);
if (!proxy->isValid()) {
LOG(IPAManager, Error) << "Failed to load proxy";
return nullptr;
@@ -73,6 +75,7 @@ private:
#if HAVE_IPA_PUBKEY
static const uint8_t publicKeyData_[];
static const PubKey pubKey_;
+ bool forceIsolation_;
#endif
};
@@ -7,10 +7,14 @@
#pragma once
+#include <optional>
#include <string>
+#include <vector>
#include <libcamera/ipa/ipa_interface.h>
+#include "libcamera/internal/global_configuration.h"
+
namespace libcamera {
class IPAModule;
@@ -24,7 +28,7 @@ public:
ProxyRunning,
};
- IPAProxy(IPAModule *ipam);
+ IPAProxy(IPAModule *ipam, const GlobalConfiguration &configuration);
~IPAProxy();
bool isValid() const { return valid_; }
@@ -40,6 +44,8 @@ protected:
private:
IPAModule *ipam_;
+ std::vector<std::string> configPaths_;
+ std::vector<std::string> execPaths_;
};
} /* namespace libcamera */
@@ -41,7 +41,7 @@ LOG_DEFINE_CATEGORY(Camera)
CameraManager::Private::Private()
: initialized_(false)
{
- ipaManager_ = std::make_unique<IPAManager>();
+ ipaManager_ = std::make_unique<IPAManager>(this->configuration());
}
int CameraManager::Private::start()
@@ -10,12 +10,15 @@
#include <algorithm>
#include <dirent.h>
#include <string.h>
+#include <string>
#include <sys/types.h>
+#include <vector>
#include <libcamera/base/file.h>
#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>
+#include "libcamera/internal/global_configuration.h"
#include "libcamera/internal/ipa_module.h"
#include "libcamera/internal/ipa_proxy.h"
#include "libcamera/internal/pipeline_handler.h"
@@ -101,30 +104,37 @@ LOG_DEFINE_CATEGORY(IPAManager)
* The IPAManager class is meant to only be instantiated once, by the
* CameraManager.
*/
-IPAManager::IPAManager()
+IPAManager::IPAManager(const GlobalConfiguration &configuration)
{
#if HAVE_IPA_PUBKEY
if (!pubKey_.isValid())
LOG(IPAManager, Warning) << "Public key not valid";
+
+ char *force = utils::secure_getenv("LIBCAMERA_IPA_FORCE_ISOLATION");
+ forceIsolation_ = (force && force[0] != '\0') ||
+ (!force && configuration.option<bool>({ "ipa", "force_isolation" })
+ .value_or(false));
#endif
unsigned int ipaCount = 0;
/* User-specified paths take precedence. */
- const char *modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH");
- if (modulePaths) {
- for (const auto &dir : utils::split(modulePaths, ":")) {
- if (dir.empty())
- continue;
-
- ipaCount += addDir(dir.c_str());
- }
+ const auto modulePaths =
+ configuration.envListOption(
+ "LIBCAMERA_IPA_MODULE_PATH", { "ipa", "module_paths" })
+ .value_or(std::vector<std::string>());
+ for (const auto &dir : modulePaths) {
+ if (dir.empty())
+ continue;
- if (!ipaCount)
- LOG(IPAManager, Warning)
- << "No IPA found in '" << modulePaths << "'";
+ ipaCount += addDir(dir.c_str());
}
+ if (!ipaCount)
+ LOG(IPAManager, Warning) << "No IPA found in '"
+ << utils::join(modulePaths, ":")
+ << "'";
+
/*
* When libcamera is used before it is installed, load IPAs from the
* same build directory as the libcamera library itself.
@@ -279,11 +289,10 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,
bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
{
#if HAVE_IPA_PUBKEY
- char *force = utils::secure_getenv("LIBCAMERA_IPA_FORCE_ISOLATION");
- if (force && force[0] != '\0') {
+ if (forceIsolation_) {
LOG(IPAManager, Debug)
<< "Isolation of IPA module " << ipa->path()
- << " forced through environment variable";
+ << " forced through configuration";
return false;
}
@@ -7,13 +7,16 @@
#include "libcamera/internal/ipa_proxy.h"
+#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <vector>
#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>
+#include "libcamera/internal/global_configuration.h"
#include "libcamera/internal/ipa_module.h"
/**
@@ -27,7 +30,8 @@ LOG_DEFINE_CATEGORY(IPAProxy)
namespace {
-std::string ipaConfigurationFile(const std::string &ipaName, const std::string &name)
+std::string ipaConfigurationFile(const std::string &ipaName, const std::string &name,
+ const std::vector<std::string> &configPaths)
{
/*
* Start with any user override through the module-specific environment
@@ -47,20 +51,15 @@ std::string ipaConfigurationFile(const std::string &ipaName, const std::string &
int ret;
/*
- * Check the directory pointed to by the IPA config path environment
- * variable next.
+ * Check the directory pointed to by the IPA config path next.
*/
- const char *confPaths = utils::secure_getenv("LIBCAMERA_IPA_CONFIG_PATH");
- if (confPaths) {
- for (const auto &dir : utils::split(confPaths, ":")) {
- if (dir.empty())
- continue;
-
- std::string confPath = dir + "/" + ipaName + "/" + name;
- ret = stat(confPath.c_str(), &statbuf);
- if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
- return confPath;
- }
+ for (const auto &dir : configPaths) {
+ if (dir.empty())
+ continue;
+ std::string confPath = dir + "/" + ipaName + "/" + name;
+ ret = stat(confPath.c_str(), &statbuf);
+ if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
+ return confPath;
}
std::string root = utils::libcameraSourcePath();
@@ -120,9 +119,12 @@ std::string ipaConfigurationFile(const std::string &ipaName, const std::string &
/**
* \brief Construct an IPAProxy instance
* \param[in] ipam The IPA module
+ * \param[in] configuration The global configuration
*/
-IPAProxy::IPAProxy(IPAModule *ipam)
- : valid_(false), state_(ProxyStopped), ipam_(ipam)
+IPAProxy::IPAProxy(IPAModule *ipam, const GlobalConfiguration &configuration)
+ : valid_(false), state_(ProxyStopped), ipam_(ipam),
+ configPaths_(configuration.envListOption("LIBCAMERA_IPA_CONFIG_PATH", { "ipa", "config_paths" }).value_or(std::vector<std::string>())),
+ execPaths_(configuration.envListOption("LIBCAMERA_IPA_PROXY_PATH", { "ipa", "proxy_paths" }).value_or(std::vector<std::string>()))
{
}
@@ -175,7 +177,7 @@ std::string IPAProxy::configurationFile(const std::string &name,
* has been validated when loading the module.
*/
const std::string ipaName = ipam_->info().name;
- std::string confPath = ipaConfigurationFile(ipaName, name);
+ std::string confPath = ipaConfigurationFile(ipaName, name, configPaths_);
if (!confPath.empty()) {
LOG(IPAProxy, Info) << "Using tuning file " << confPath;
return confPath;
@@ -188,7 +190,7 @@ std::string IPAProxy::configurationFile(const std::string &name,
return std::string();
}
- confPath = ipaConfigurationFile(ipaName, fallbackName);
+ confPath = ipaConfigurationFile(ipaName, fallbackName, configPaths_);
LOG(IPAProxy, Warning)
<< "Configuration file '" << name
<< "' not found for IPA module '" << ipaName
@@ -214,18 +216,14 @@ std::string IPAProxy::resolvePath(const std::string &file) const
{
std::string proxyFile = "/" + file;
- /* Check env variable first. */
- const char *execPaths = utils::secure_getenv("LIBCAMERA_IPA_PROXY_PATH");
- if (execPaths) {
- for (const auto &dir : utils::split(execPaths, ":")) {
- if (dir.empty())
- continue;
-
- std::string proxyPath = dir;
- proxyPath += proxyFile;
- if (!access(proxyPath.c_str(), X_OK))
- return proxyPath;
- }
+ /* Check the configuration first. */
+ for (const auto &dir : execPaths_) {
+ if (dir.empty())
+ continue;
+
+ std::string proxyPath = dir + proxyFile;
+ if (!access(proxyPath.c_str(), X_OK))
+ return proxyPath;
}
/*
@@ -45,8 +45,8 @@ namespace {{ns}} {
{% endfor %}
{%- endif %}
-{{proxy_name}}::{{proxy_name}}(IPAModule *ipam, bool isolate)
- : IPAProxy(ipam), isolate_(isolate),
+{{proxy_name}}::{{proxy_name}}(IPAModule *ipam, bool isolate, const GlobalConfiguration &configuration)
+ : IPAProxy(ipam, configuration), isolate_(isolate),
controlSerializer_(ControlSerializer::Role::Proxy), seq_(0)
{
LOG(IPAProxy, Debug)
@@ -37,7 +37,7 @@ namespace {{ns}} {
class {{proxy_name}} : public IPAProxy, public {{interface_name}}, public Object
{
public:
- {{proxy_name}}(IPAModule *ipam, bool isolate);
+ {{proxy_name}}(IPAModule *ipam, bool isolate, const GlobalConfiguration &configuration);
~{{proxy_name}}();
{% for method in interface_main.methods %}