aboutsummaryrefslogtreecommitdiffstats
path: root/parameter/ConfigurableElement.cpp
diff options
context:
space:
mode:
authorPatrick Benavoli <patrickx.benavoli@intel.com>2011-08-31 11:23:23 +0200
committerbuildbot <buildbot@intel.com>2011-09-08 06:18:29 -0700
commit68a912857707864bbaaff9808717813105072a6e (patch)
tree81b5bc104eec1f4aab75cc14f262dd9783e49946 /parameter/ConfigurableElement.cpp
parenta929d05b870a8947f272a2b4321d396fee9778c3 (diff)
downloadexternal_parameter-framework-68a912857707864bbaaff9808717813105072a6e.zip
external_parameter-framework-68a912857707864bbaaff9808717813105072a6e.tar.gz
external_parameter-framework-68a912857707864bbaaff9808717813105072a6e.tar.bz2
parameter-framework: initial commit
BZ: 6081 Parameter-framework is still-under-development, Intel proprietary, multi-platform (standard C++, for now only linux, no dependency on Android) software that allows system-wide parameter management. It relies on a number of configurations files, from which it knows how / when to hand out settings towards the hardware (subsystems) at runtime. 3 kinds of configuration files are used: - Structure description files indicating the actual parameter structure, types, min/max values, data representation. - Configurable domain description file containing the actual distribution of parameters over different domains, that is, different set of configurations, each of which being dynamically activated based on selection criteria rules that are themselves configurable. Configurable domains file contain the tuned settings along the tuning process, that is during the period where the system is being tuned. - Binary settings file used to store the settings when the tuning process is complete. Changing any of those files causes no recompilation of the framework. This project is based on a open plugin architecture allowing any kind of subsystems to be handled, whatever their respective Endianness. It fully relies on the platform SW to provide it with with the kowledge of exisitng selection criteria (selected device, current mode), as well as change events that occuring on them, thus triggering the application of corresponding configuration settings wherever appropriate. It supports handling mutliple parameter classes (Audio, Energy management) through TCP/IP interface. For now tuning commands can be sent to parameter-framework instances through a command-line utility, via adb over USB or via ethernet/WIFI. Change-Id: If7709c464db118f367f953e0824f49cce9fd0402 Orig-Change-Id: I7842e8808a4cfc0c615e0365e6d02101971ae2dc Signed-off-by: Patrick Benavoli <patrickx.benavoli@intel.com> Reviewed-on: http://android.intel.com:8080/16877 Reviewed-by: Mahe, Erwan <erwan.mahe@intel.com> Tested-by: Barthes, FabienX <fabienx.barthes@intel.com> Reviewed-by: buildbot <buildbot@intel.com> Tested-by: buildbot <buildbot@intel.com>
Diffstat (limited to 'parameter/ConfigurableElement.cpp')
-rw-r--r--parameter/ConfigurableElement.cpp539
1 files changed, 539 insertions, 0 deletions
diff --git a/parameter/ConfigurableElement.cpp b/parameter/ConfigurableElement.cpp
new file mode 100644
index 0000000..9707fb2
--- /dev/null
+++ b/parameter/ConfigurableElement.cpp
@@ -0,0 +1,539 @@
+/* <auto_header>
+ * <FILENAME>
+ *
+ * INTEL CONFIDENTIAL
+ * Copyright © 2011 Intel
+ * Corporation All Rights Reserved.
+ *
+ * The source code contained or described herein and all documents related to
+ * the source code ("Material") are owned by Intel Corporation or its suppliers
+ * or licensors. Title to the Material remains with Intel Corporation or its
+ * suppliers and licensors. The Material contains trade secrets and proprietary
+ * and confidential information of Intel or its suppliers and licensors. The
+ * Material is protected by worldwide copyright and trade secret laws and
+ * treaty provisions. No part of the Material may be used, copied, reproduced,
+ * modified, published, uploaded, posted, transmitted, distributed, or
+ * disclosed in any way without Intel’s prior express written permission.
+ *
+ * No license under any patent, copyright, trade secret or other intellectual
+ * property right is granted to or conferred upon you by disclosure or delivery
+ * of the Materials, either expressly, by implication, inducement, estoppel or
+ * otherwise. Any license under such intellectual property rights must be
+ * express and approved by Intel in writing.
+ *
+ * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com)
+ * CREATED: 2011-06-01
+ * UPDATED: 2011-07-27
+ *
+ *
+ * </auto_header>
+ */
+#include "ConfigurableElement.h"
+#include "MappingData.h"
+#include "SyncerSet.h"
+#include "ConfigurableDomain.h"
+#include "ConfigurationAccessContext.h"
+#include "ConfigurableElementAggregator.h"
+#include <assert.h>
+
+#define base CElement
+
+CConfigurableElement::CConfigurableElement(const string& strName) : base(strName), _uiOffset(0)
+{
+}
+
+CConfigurableElement::~CConfigurableElement()
+{
+}
+
+// XML configuration settings parsing
+bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const
+{
+ uint32_t uiIndex;
+ uint32_t uiNbChildren = getNbChildren();
+
+ if (!configurationAccessContext.serializeOut()) {
+ // Just do basic checks and propagate to children
+ CXmlElement::CChildIterator it(xmlConfigurableElementSettingsElement);
+
+ CXmlElement xmlChildConfigurableElementSettingsElement;
+
+ // Propagate to children
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ // Get child
+ const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
+
+ if (!it.next(xmlChildConfigurableElementSettingsElement)) {
+
+ // Structure error
+ configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
+
+ return false;
+ }
+
+ // Check element type matches in type
+ if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
+
+ // Type error
+ configurationAccessContext.setError("Configuration settings parsing: Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
+
+ return false;
+ }
+
+ // Check element type matches in name
+ if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != pChildConfigurableElement->getName()) {
+
+ // Name error
+ configurationAccessContext.setError("Configuration settings parsing: Under configurable elememnt " + getName() + ", expected element name " + pChildConfigurableElement->getName() + " but found " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead");
+
+ return false;
+ }
+
+ // Parse child configurable element's settings
+ if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
+
+ return false;
+ }
+ }
+ // There should remain no configurable element to parse
+ if (it.next(xmlChildConfigurableElementSettingsElement)) {
+
+ // Structure error
+ configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
+
+ return false;
+ }
+ } else {
+ // Propagate to children
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
+
+ // Create corresponding child element
+ CXmlElement xmlChildConfigurableElementSettingsElement;
+
+ xmlConfigurableElementSettingsElement.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
+
+ // Handle element name attribute
+ xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
+
+ // Propagate
+ pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
+ }
+ }
+ // Done
+ return true;
+}
+
+#if 0
+bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const
+{
+ if (!configurationAccessContext.serializeOut()) {
+ // Just do basic checks and propagate to children
+ CXmlElement::CChildIterator it(xmlConfigurableElementSettingsElement);
+
+ CXmlElement xmlChildConfigurableElementSettingsElement;
+
+ while (it.next(xmlChildConfigurableElementSettingsElement)) {
+
+ // Find child configurable element
+ const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(findChild(xmlChildConfigurableElementSettingsElement.getNameAttribute()));
+
+ if (!pChildConfigurableElement) {
+
+ configurationAccessContext.setError("Configuration settings parsing: Unable to find configurable element " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " under configurable element " + getName());
+
+ return false;
+ }
+
+ // Check element type matches
+ if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
+
+ configurationAccessContext.setError("Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
+
+ return false;
+ }
+
+ // Parse child configurable element's settings
+ if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
+
+ return false;
+ }
+ }
+ } else {
+ // Propagate to children
+ uint32_t uiIndex;
+ uint32_t uiNbChildren = getNbChildren();
+
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
+
+ // Create corresponding child element
+ CXmlElement xmlChildConfigurableElementSettingsElement;
+
+ xmlConfigurableElementSettingsElement.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
+
+ // Handle element name attribute
+ xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
+
+ // Propagate
+ pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
+ }
+ }
+ // Done
+ return true;
+}
+#endif
+
+// Parameter access
+bool CConfigurableElement::setValue(CPathNavigator& pathNavigator, const string& strValue, CErrorContext& errorContext) const
+{
+ string* pStrChildName = pathNavigator.next();
+
+ if (!pStrChildName) {
+
+ errorContext.setError("Non settable element");
+
+ return false;
+ }
+
+ const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
+
+ if (!pChild) {
+
+ errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
+
+ return false;
+ }
+
+ return pChild->setValue(pathNavigator, strValue, errorContext);
+}
+
+bool CConfigurableElement::getValue(CPathNavigator& pathNavigator, string& strValue, CErrorContext& errorContext) const
+{
+ string* pStrChildName = pathNavigator.next();
+
+ if (!pStrChildName) {
+
+ errorContext.setError("Non gettable element");
+
+ return false;
+ }
+
+ const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
+
+ if (!pChild) {
+
+ errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
+
+ return false;
+ }
+
+ return pChild->getValue(pathNavigator, strValue, errorContext);
+}
+
+// Used for simulation only
+void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
+{
+ // Propagate to children
+ uint32_t uiIndex;
+ uint32_t uiNbChildren = getNbChildren();
+
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
+
+ pConfigurableElement->setDefaultValues(parameterAccessContext);
+ }
+}
+
+// Offset
+void CConfigurableElement::setOffset(uint32_t uiOffset)
+{
+ // Assign offset locally
+ _uiOffset = uiOffset;
+
+ // Propagate to children
+ uint32_t uiIndex;
+ uint32_t uiNbChildren = getNbChildren();
+
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
+
+ pConfigurableElement->setOffset(uiOffset);
+
+ uiOffset += pConfigurableElement->getFootPrint();
+ }
+}
+
+uint32_t CConfigurableElement::getOffset() const
+{
+ return _uiOffset;
+}
+
+// Memory
+uint32_t CConfigurableElement::getFootPrint() const
+{
+ uint32_t uiSize = 0;
+ uint32_t uiIndex;
+ uint32_t uiNbChildren = getNbChildren();
+
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
+
+ uiSize += pConfigurableElement->getFootPrint();
+ }
+
+ return uiSize;
+}
+
+// Browse parent path to find syncer
+ISyncer* CConfigurableElement::getSyncer() const
+{
+ // Check parent
+ const CElement* pParent = getParent();
+
+ if (isOfConfigurableElementType(pParent)) {
+
+ return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
+ }
+ return false;
+}
+
+// Syncer set (me, ascendant or descendant ones)
+void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
+{
+ // Try me or ascendants
+ ISyncer* pMineOrAscendantSyncer = getSyncer();
+
+ if (pMineOrAscendantSyncer) {
+
+ // Provide found syncer object
+ syncerSet += pMineOrAscendantSyncer;
+
+ // Done
+ return;
+ }
+ // Fetch descendant ones
+ fillSyncerSetFromDescendant(syncerSet);
+}
+
+// Syncer set (descendant)
+void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
+{
+ // Dig
+ uint32_t uiIndex;
+ uint32_t uiNbChildren = getNbChildren();
+
+ for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
+
+ const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
+
+ pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
+ }
+}
+
+// Configurable domain association
+void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
+{
+ _configurableDomainList.push_back(pConfigurableDomain);
+}
+
+void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
+{
+ _configurableDomainList.remove(pConfigurableDomain);
+}
+
+// Belonging domain
+bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
+{
+ if (containsConfigurableDomain(pConfigurableDomain)) {
+
+ return true;
+ }
+ return belongsToDomainAscending(pConfigurableDomain);
+}
+
+// Belonging domains
+void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
+{
+ configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
+
+ // Check parent
+ const CElement* pParent = getParent();
+
+ if (isOfConfigurableElementType(pParent)) {
+
+ static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
+ }
+}
+
+void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
+{
+ // Get belonging domain list
+ list<const CConfigurableDomain*> configurableDomainList;
+
+ getBelongingDomains(configurableDomainList);
+
+ // Fill list
+ listDomains(configurableDomainList, strResult, bVertical);
+}
+
+// Elements with no domains
+void CConfigurableElement::listRogueElements(string& strResult) const
+{
+ strResult = "\n";
+
+ // Get rogue element aggregate list (no associated domain)
+ list<const CConfigurableElement*> rogueElementList;
+
+ CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
+
+ configurableElementAggregator.aggegate(this);
+
+ // Build list as string
+ list<const CConfigurableElement*>::const_iterator it;
+
+ for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
+
+ const CConfigurableElement* pConfigurableElement = *it;
+
+ strResult += pConfigurableElement->getPath() + "\n";
+ }
+}
+
+// Matching check for no domain association
+bool CConfigurableElement::hasNoDomainAssociated() const
+{
+ return _configurableDomainList.empty();
+}
+
+// Matching check for no valid associated domains
+bool CConfigurableElement::hasNoValidDomainAssociated() const
+{
+ if (_configurableDomainList.empty()) {
+
+ // No domains associated
+ return true;
+ }
+
+ ConfigurableDomainListConstIterator it;
+
+ // Browse all configurable domains for validity checking
+ for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
+
+ const CConfigurableDomain* pConfigurableDomain = *it;
+
+ if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Owning domains
+void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
+{
+ // Fill list
+ listDomains(_configurableDomainList, strResult, bVertical);
+}
+
+uint32_t CConfigurableElement::getBelongingDomainCount() const
+{
+ // Get belonging domain list
+ list<const CConfigurableDomain*> configurableDomainList;
+
+ getBelongingDomains(configurableDomainList);
+
+ return configurableDomainList.size();
+}
+
+void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
+{
+ if (bVertical && configurableDomainList.empty()) {
+
+ strResult = "\n";
+ }
+
+ // Fill list
+ ConfigurableDomainListConstIterator it;
+ bool bFirst = true;
+
+ // Browse all configurable domains for comparison
+ for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
+
+ const CConfigurableDomain* pConfigurableDomain = *it;
+
+ if (!bVertical && !bFirst) {
+
+ strResult += ", ";
+ }
+
+ strResult += pConfigurableDomain->getName();
+
+ if (bVertical) {
+
+ strResult += "\n";
+ } else {
+
+ bFirst = false;
+ }
+ }
+}
+
+bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
+{
+ ConfigurableDomainListConstIterator it;
+
+ // Browse all configurable domains for comparison
+ for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
+
+ if (pConfigurableDomain == *it) {
+
+ return true;
+ }
+ }
+ return false;
+}
+
+// Belonging domain ascending search
+bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
+{
+ // Check parent
+ const CElement* pParent = getParent();
+
+ if (isOfConfigurableElementType(pParent)) {
+
+ return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
+ }
+ return false;
+}
+
+// Belonging subsystem
+const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
+{
+ const CElement* pParent = getParent();
+
+ // Stop at sytem class
+ if (!pParent->getParent()) {
+
+ return NULL;
+ }
+
+ return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
+}
+
+// Check parent is still of current type (by structure knowledge)
+bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
+{
+ assert(pParent);
+
+ // Up to system class
+ return !!pParent->getParent();
+}