PFW: Parameter adaptation (platform interface)

BZ: 15069

Adaptation nodes have been added to integer parameter types in the structural
description.
They all convert values between a platform value and the actual parameter
value.
When a conversion node affects the definition of an integer type parameter,
its interface type becomes "double" (instead of integer).
For now only linear adaptation type is supported.

Linear adaptation:
=================
Linear adaptation nodes consists of the following attributes:
- slope numerator (double, default = 1)
- slope denominator (double, defult = 1)
- offset (signed integer, default = 0)
Conversions from user (platform) values to blackboard are done the follwing
way:
blackboard_value = user_value * slope_numerator / slope_denominator + offset

Change-Id: I00abe9ba5961d8e541b616225531bbc7c8b465b0
Signed-off-by: Patrick Benavoli <patrickx.benavoli@intel.com>
Reviewed-on: http://android.intel.com:8080/25407
Reviewed-by: Barthes, FabienX <fabienx.barthes@intel.com>
Tested-by: Barthes, FabienX <fabienx.barthes@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/parameter/Android.mk b/parameter/Android.mk
index 267d916..28989a0 100644
--- a/parameter/Android.mk
+++ b/parameter/Android.mk
@@ -89,7 +89,9 @@
         EnumParameterType.cpp \
         VirtualSubsystem.cpp \
         VirtualSyncer.cpp \
-        ParameterHandle.cpp
+        ParameterHandle.cpp \
+        ParameterAdaptation.cpp \
+        LinearParameterAdaptation.cpp
 
 
 LOCAL_MODULE:= libparameter
diff --git a/parameter/ComponentType.h b/parameter/ComponentType.h
index a6e04cd..fddb222 100644
--- a/parameter/ComponentType.h
+++ b/parameter/ComponentType.h
@@ -39,7 +39,8 @@
 public:
     CComponentType(const string& strName);
 
-    void populate(CElement* pElement) const;
+    // Object creation
+    virtual void populate(CElement* pElement) const;
 
     // Mapping info
     virtual bool getMappingData(const string& strKey, const string*& pStrValue) const;
diff --git a/parameter/Element.cpp b/parameter/Element.cpp
index 4e939c0..8981ba9 100644
--- a/parameter/Element.cpp
+++ b/parameter/Element.cpp
@@ -184,6 +184,15 @@
     return ostr.str();
 }
 
+string CElement::toString(double dValue)
+{
+    ostringstream ostr;
+
+    ostr << dValue;
+
+    return ostr.str();
+}
+
 // Content dumping
 void CElement::logValue(string& strValue, CErrorContext& errorContext) const
 {
diff --git a/parameter/Element.h b/parameter/Element.h
index af4fc33..0e592d6 100644
--- a/parameter/Element.h
+++ b/parameter/Element.h
@@ -103,6 +103,7 @@
     // Conversion utilities
     static string toString(uint32_t uiValue);
     static string toString(int32_t iValue);
+    static string toString(double dValue);
 
     // Checksum for integrity checks
     uint8_t computeStructureChecksum() const;
diff --git a/parameter/IntegerParameterType.cpp b/parameter/IntegerParameterType.cpp
index 71941c2..fb55f08 100644
--- a/parameter/IntegerParameterType.cpp
+++ b/parameter/IntegerParameterType.cpp
@@ -34,6 +34,7 @@
 #include <iomanip>
 #include "ParameterAccessContext.h"
 #include <assert.h>
+#include "ParameterAdaptation.h"
 
 #define base CParameterType
 
@@ -41,11 +42,18 @@
 {
 }
 
+// Kind
 string CIntegerParameterType::getKind() const
 {
     return "IntegerParameter";
 }
 
+// Deal with adaption node
+bool CIntegerParameterType::childrenAreDynamic() const
+{
+    return true;
+}
+
 // Element properties
 void CIntegerParameterType::showProperties(string& strResult) const
 {
@@ -65,6 +73,17 @@
     strResult += "Max: ";
     strResult += _bSigned ? toString((int32_t)_uiMax) : toString(_uiMax);
     strResult += "\n";
+
+    // Check if there's an adaptation object available
+    const CParameterAdaptation* pParameterAdaption = getParameterAdaptation();
+
+    if (pParameterAdaption) {
+
+        // Display adaptation properties
+        strResult += "Adaptation:\n";
+
+        pParameterAdaption->showProperties(strResult);
+    }
 }
 
 bool CIntegerParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
@@ -227,6 +246,7 @@
 
         return false;
     }
+    // Do assign
     uiUserValue = uiValue;
 
     return true;
@@ -266,11 +286,84 @@
     // Sign extend
     signExtend(iValue);
 
+    // Do assign
     iUserValue = iValue;
 
     return true;
 }
 
+// Double
+bool CIntegerParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const
+{
+    // Check if there's an adaptation object available
+    const CParameterAdaptation* pParameterAdaption = getParameterAdaptation();
+
+    if (!pParameterAdaption) {
+
+        // Reject request and let upper class handle the error
+        return base::toBlackboard(dUserValue, uiValue, parameterAccessContext);
+    }
+
+    // Do the conversion
+    int64_t iConvertedValue = pParameterAdaption->fromUserValue(dUserValue);
+
+    // Check against range
+    if (_bSigned) {
+
+        if (iConvertedValue < (int32_t)_uiMin || iConvertedValue > (int32_t)_uiMax) {
+
+            parameterAccessContext.setError("Value out of range");
+
+            return false;
+        }
+    } else {
+
+        if (iConvertedValue < _uiMin || iConvertedValue > _uiMax) {
+
+            parameterAccessContext.setError("Value out of range");
+
+            return false;
+        }
+    }
+
+    // Do assign
+    uiValue = (uint32_t)iConvertedValue;
+
+    return true;
+}
+
+bool CIntegerParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const
+{
+    // Check if there's an adaptation object available
+    const CParameterAdaptation* pParameterAdaption = getParameterAdaptation();
+
+    if (!pParameterAdaption) {
+
+        // Reject request and let upper class handle the error
+        return base::fromBlackboard(dUserValue, uiValue, parameterAccessContext);
+    }
+
+    int64_t iValueToConvert;
+
+    // Deal with signed data
+    if (_bSigned) {
+
+        int32_t iValue = uiValue;
+
+        signExtend(iValue);
+
+        iValueToConvert = iValue;
+    } else {
+
+        iValueToConvert = uiValue;
+    }
+
+    // Do the conversion
+    dUserValue = pParameterAdaption->toUserValue(iValueToConvert);
+
+    return true;
+}
+
 // Default value handling (simulation only)
 uint32_t CIntegerParameterType::getDefaultValue() const
 {
@@ -306,3 +399,9 @@
     }
     return true;
 }
+
+// Adaptation element retrieval
+const CParameterAdaptation* CIntegerParameterType::getParameterAdaptation() const
+{
+    return static_cast<const CParameterAdaptation*>(findChildOfKind("Adaptation"));
+}
diff --git a/parameter/IntegerParameterType.h b/parameter/IntegerParameterType.h
index ddd6e79..e0b31a0 100644
--- a/parameter/IntegerParameterType.h
+++ b/parameter/IntegerParameterType.h
@@ -32,6 +32,8 @@
 
 #include "ParameterType.h"
 
+class CParameterAdaptation;
+
 class CIntegerParameterType : public CParameterType
 {
 public:
@@ -50,6 +52,9 @@
     // Signed Integer
     virtual bool toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const;
     virtual bool fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const;
+    // Double
+    virtual bool toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const;
+    virtual bool fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const;
 
     // Default value handling (simulation only)
     virtual uint32_t getDefaultValue() const;
@@ -60,9 +65,15 @@
     // CElement
     virtual string getKind() const;
 private:
+    // Returns true if children dynamic creation is to be dealt with
+    virtual bool childrenAreDynamic() const;
+
     // Range checking
     template <typename type> bool checkValueAgainstRange(const string& strValue, type value, CParameterAccessContext& parameterAccessContext, bool bHexaValue) const;
 
+    // Adaptation element retrieval
+    const CParameterAdaptation* getParameterAdaptation() const;
+
     // Signing
     bool _bSigned;
     // Range
diff --git a/parameter/LinearParameterAdaptation.cpp b/parameter/LinearParameterAdaptation.cpp
new file mode 100644
index 0000000..063eeaa
--- /dev/null
+++ b/parameter/LinearParameterAdaptation.cpp
@@ -0,0 +1,98 @@
+/* <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 "LinearParameterAdaptation.h"
+
+#define base CParameterAdaptation
+
+CLinearParameterAdaptation::CLinearParameterAdaptation() : base("Linear"), _dSlopeNumerator(1), _dSlopeDenominator(1)
+{
+}
+
+// Element properties
+void CLinearParameterAdaptation::showProperties(string& strResult) const
+{
+    base::showProperties(strResult);
+
+    // SlopeNumerator
+    strResult += " - SlopeNumerator: ";
+    strResult += toString(_dSlopeNumerator);
+    strResult += "\n";
+
+    // SlopeDenominator
+    strResult += " - SlopeDenominator: ";
+    strResult += toString(_dSlopeDenominator);
+    strResult += "\n";
+}
+
+// From IXmlSink
+bool CLinearParameterAdaptation::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
+{
+    // Get SlopeNumerator
+    if (xmlElement.hasAttribute("SlopeNumerator")) {
+
+        _dSlopeNumerator = xmlElement.getAttributeDouble("SlopeNumerator");
+
+    } else {
+        // Default
+        _dSlopeNumerator = 1;
+    }
+    // Get SlopeDenominator
+    if (xmlElement.hasAttribute("SlopeDenominator")) {
+
+        _dSlopeDenominator = xmlElement.getAttributeDouble("SlopeDenominator");
+
+        // Avoid by 0 division errors
+        if (_dSlopeDenominator == 0) {
+
+            serializingContext.setError("SlopeDenominator attribute can't be 0 on element" + xmlElement.getPath());
+
+            return false;
+        }
+
+    } else {
+        // Default
+        _dSlopeDenominator = 1;
+    }
+
+    // Base
+    return base::fromXml(xmlElement, serializingContext);
+}
+
+// Conversions
+int64_t CLinearParameterAdaptation::fromUserValue(double dValue) const
+{
+    return base::fromUserValue(dValue * _dSlopeNumerator / _dSlopeDenominator);
+}
+
+double CLinearParameterAdaptation::toUserValue(int64_t iValue) const
+{
+    return base::toUserValue(iValue) * _dSlopeDenominator / _dSlopeNumerator;
+}
diff --git a/parameter/LinearParameterAdaptation.h b/parameter/LinearParameterAdaptation.h
new file mode 100644
index 0000000..a3bc905
--- /dev/null
+++ b/parameter/LinearParameterAdaptation.h
@@ -0,0 +1,53 @@
+/* <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>
+ */
+#pragma once
+
+#include "ParameterAdaptation.h"
+
+class CLinearParameterAdaptation : public CParameterAdaptation
+{
+public:
+    CLinearParameterAdaptation();
+
+    // Conversions
+    virtual int64_t fromUserValue(double dValue) const;
+    virtual double toUserValue(int64_t iValue) const;
+
+    // Element properties
+    virtual void showProperties(string& strResult) const;
+
+    // From IXmlSink
+    virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext);
+private:
+    // Slope attributes
+    double _dSlopeNumerator;
+    double _dSlopeDenominator;
+};
diff --git a/parameter/ParameterAdaptation.cpp b/parameter/ParameterAdaptation.cpp
new file mode 100644
index 0000000..0a4c0c0
--- /dev/null
+++ b/parameter/ParameterAdaptation.cpp
@@ -0,0 +1,90 @@
+/* <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 "ParameterAdaptation.h"
+
+#define base CElement
+
+CParameterAdaptation::CParameterAdaptation(const string& strType) : base(strType), _iOffset(0)
+{
+}
+// CElement
+string CParameterAdaptation::getKind() const
+{
+    return "Adaptation";
+}
+
+// Attributes
+int32_t CParameterAdaptation::getOffset() const
+{
+    return _iOffset;
+}
+
+// Element properties
+void CParameterAdaptation::showProperties(string& strResult) const
+{
+    // Adaptation type
+    strResult += " - Type: ";
+    strResult += getName();
+    strResult += "\n";
+
+    // Offset
+    strResult += " - Offset: ";
+    strResult += toString(_iOffset);
+    strResult += "\n";
+}
+
+// From IXmlSink
+bool CParameterAdaptation::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
+{
+    // Get offset
+    if (xmlElement.hasAttribute("Offset")) {
+
+        _iOffset = xmlElement.getAttributeSignedInteger("Offset");
+
+    } else {
+        // Default
+        _iOffset = 0;
+    }
+
+    // Base
+    return base::fromXml(xmlElement, serializingContext);
+}
+
+// Conversions
+int64_t CParameterAdaptation::fromUserValue(double dValue) const
+{
+    return (int64_t)dValue + _iOffset;
+}
+
+double CParameterAdaptation::toUserValue(int64_t iValue) const
+{
+    return (double)(iValue - _iOffset);
+}
diff --git a/parameter/ParameterAdaptation.h b/parameter/ParameterAdaptation.h
new file mode 100644
index 0000000..4ba40d9
--- /dev/null
+++ b/parameter/ParameterAdaptation.h
@@ -0,0 +1,60 @@
+/* <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>
+ */
+#pragma once
+
+#include "Element.h"
+
+class CParameterAdaptation : public CElement
+{
+public:
+    CParameterAdaptation(const string& strType);
+
+    // Element properties
+    virtual void showProperties(string& strResult) const;
+
+    // From IXmlSink
+    virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext);
+
+    // Conversions
+    virtual int64_t fromUserValue(double dValue) const;
+    virtual double toUserValue(int64_t iValue) const;
+
+    // CElement
+    virtual string getKind() const;
+protected:
+    // Attributes
+    int32_t getOffset() const;
+
+private:
+    // Offset
+    int32_t _iOffset;
+};
+
diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp
index 1e1a562..f1dd9eb 100644
--- a/parameter/ParameterMgr.cpp
+++ b/parameter/ParameterMgr.cpp
@@ -76,6 +76,7 @@
 #include <dlfcn.h>
 #include <assert.h>
 #include "ParameterHandle.h"
+#include "LinearParameterAdaptation.h"
 
 #define base CElement
 
@@ -1713,6 +1714,7 @@
     pParameterCreationLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CParameterBlockType>("ParameterBlock"));
     pParameterCreationLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CBooleanParameterType>("BooleanParameter"));
     pParameterCreationLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CIntegerParameterType>("IntegerParameter"));
+    pParameterCreationLibrary->addElementBuilder(new TElementBuilderTemplate<CLinearParameterAdaptation>("LinearAdaptation"));
     pParameterCreationLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CEnumParameterType>("EnumParameter"));
     pParameterCreationLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CFixedPointParameterType>("FixedPointParameter"));
     pParameterCreationLibrary->addElementBuilder(new TKindElementBuilderTemplate<CXmlFileIncluderElement>("SubsystemInclude"));
diff --git a/parameter/ParameterType.cpp b/parameter/ParameterType.cpp
index ffa8d76..7079a46 100644
--- a/parameter/ParameterType.cpp
+++ b/parameter/ParameterType.cpp
@@ -43,6 +43,13 @@
 {
 }
 
+// Object creation
+void CParameterType::populate(CElement* pElement) const
+{
+    (void)pElement;
+    // Prevent further digging for instantiaton since we're leaf on the strcture tree
+}
+
 // Size
 void CParameterType::setSize(uint32_t uiSize)
 {
diff --git a/parameter/ParameterType.h b/parameter/ParameterType.h
index 37ba869..83e3c34 100644
--- a/parameter/ParameterType.h
+++ b/parameter/ParameterType.h
@@ -79,6 +79,8 @@
     // Default value handling (simulation only)
     virtual uint32_t getDefaultValue() const;
 protected:
+    // Object creation
+    virtual void populate(CElement* pElement) const;
     // Size
     void setSize(uint32_t uiSize);
     // Sign extension