Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cce43761 authored by Lajos Molnar's avatar Lajos Molnar Committed by Android (Google) Code Review
Browse files

Merge "Codec2: Combine C2ParamField and C2FieldSupportedValues"

parents 6776e717 d274089a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ enum {

    // unknown fatal
    C2_CORRUPTED        = UNKNOWN_ERROR,        ///< some unexpected error prevented the operation
    C2_NO_INIT          = NO_INIT,              ///< status has not been initialized
};

/// @}
+26 −2
Original line number Diff line number Diff line
@@ -55,6 +55,31 @@ protected:
    virtual ~C2ComponentListener() = default;
};

struct C2FieldSupportedValuesQuery {
    enum Type : uint32_t {
        POSSIBLE, ///< query all possible values regardless of other settings
        CURRENT,  ///< query currently possible values given dependent settings
    };

    const C2ParamField field;
    const Type type;
    status_t status;
    C2FieldSupportedValues values;

    C2FieldSupportedValuesQuery(const C2ParamField &field_, Type type_)
        : field(field_), type(type_), status(C2_NO_INIT) { }

    static C2FieldSupportedValuesQuery&&
    Current(const C2ParamField &field_) {
        return std::move(C2FieldSupportedValuesQuery(field_, CURRENT));
    }

    static C2FieldSupportedValuesQuery&&
    Possible(const C2ParamField &field_) {
        return std::move(C2FieldSupportedValuesQuery(field_, POSSIBLE));
    }
};

/**
 * Component interface object. This object contains all of the configuration of a potential or
 * actual component. It can be created and used independently of an actual C2Component instance to
@@ -282,8 +307,7 @@ public:
     * fields in the same list?
     */
    virtual status_t getSupportedValues(
            const std::vector<const C2ParamField> &fields,
            std::vector<C2FieldSupportedValues>* const values) const = 0;
            std::vector<C2FieldSupportedValuesQuery> &fields) const = 0;

    virtual ~C2ComponentInterface() = default;
};
+102 −6
Original line number Diff line number Diff line
@@ -344,6 +344,10 @@ public:
    /// returns the parameter type: the parameter index without the stream ID
    inline uint32_t type() const { return _mIndex.type(); }

    /// returns the index of this parameter
    /// \todo: should we restrict this to C2ParamField?
    inline uint32_t index() const { return (uint32_t)_mIndex; }

    /// returns the kind of this parameter
    inline Kind kind() const { return _mIndex.kind(); }

@@ -562,7 +566,6 @@ struct _C2FieldId {
    /**
     * Constructor used to identify a field in an object.
     *
     * \param U[type] pointer to the object that contains this field
     * \param pm[im] member pointer to the field
     */
    template<typename R, typename T, typename B=typename std::remove_extent<R>::type>
@@ -597,23 +600,93 @@ private:
};

/**
 * Structure uniquely specifying a field in a configuration
 * Structure uniquely specifying a 'field' in a configuration. The field
 * can be a field of a configuration, a subfield of a field of a configuration,
 * and even the whole configuration. Moreover, if the field can point to an
 * element in a array field, or to the entire array field.
 *
 * This structure is used for querying supported values for a field, as well
 * as communicating configuration failures and conflicts when trying to change
 * a configuration for a component/interface or a store.
 */
struct C2ParamField {
//public:
    // TODO: fix what this is for T[] (for now size becomes T[1])
    /**
     * Create a field identifier using a configuration parameter (variable),
     * and a pointer to member.
     *
     * ~~~~~~~~~~~~~ (.cpp)
     *
     * struct C2SomeParam {
     *   uint32_t mField;
     *   uint32_t mArray[2];
     *   C2OtherStruct mStruct;
     *   uint32_t mFlexArray[];
     * } *mParam;
     *
     * C2ParamField(mParam, &mParam->mField);
     * C2ParamField(mParam, &mParam->mArray);
     * C2ParamField(mParam, &mParam->mArray[0]);
     * C2ParamField(mParam, &mParam->mStruct.mSubField);
     * C2ParamField(mParam, &mParam->mFlexArray);
     * C2ParamField(mParam, &mParam->mFlexArray[2]);
     *
     * ~~~~~~~~~~~~~
     *
     * \todo fix what this is for T[] (for now size becomes T[1])
     *
     * \param param pointer to parameter
     * \param offset member pointer
     */
    template<typename S, typename T>
    inline C2ParamField(S* param, T* offset)
        : _mIndex(param->index()),
          _mFieldId(offset) {}

    /**
     * Create a field identifier using a configuration parameter (variable),
     * and a member pointer. This method cannot be used to refer to an
     * array element or a subfield.
     *
     * ~~~~~~~~~~~~~ (.cpp)
     *
     * C2SomeParam mParam;
     * C2ParamField(&mParam, &C2SomeParam::mMemberField);
     *
     * ~~~~~~~~~~~~~
     *
     * \param p pointer to parameter
     * \param T member pointer to the field member
     */
    template<typename R, typename T, typename U>
    inline C2ParamField(U *p, R T::* pm) : _mIndex(p->type()), _mFieldId(p, pm) { }
    inline C2ParamField(U *p, R T::* pm) : _mIndex(p->index()), _mFieldId(p, pm) { }

    /**
     * Create a field identifier to a configuration parameter (variable).
     *
     * ~~~~~~~~~~~~~ (.cpp)
     *
     * C2SomeParam mParam;
     * C2ParamField(&mParam);
     *
     * ~~~~~~~~~~~~~
     *
     * \param param pointer to parameter
     */
    template<typename S>
    inline C2ParamField(S* param)
        : _mIndex(param->index()), _mFieldId(0u, param->size()) {}

    /**
     * Equality operator.
     */
    inline bool operator==(const C2ParamField &other) const {
        return _mIndex == other._mIndex && _mFieldId == other._mFieldId;
    }

    /**
     * Ordering operator.
     */
    inline bool operator<(const C2ParamField &other) const {
        return _mIndex < other._mIndex ||
            (_mIndex == other._mIndex && _mFieldId < other._mFieldId);
@@ -622,8 +695,8 @@ struct C2ParamField {
    DEFINE_OTHER_COMPARISON_OPERATORS(C2ParamField)

private:
    C2Param::Index _mIndex;
    _C2FieldId _mFieldId;
    C2Param::Index _mIndex; ///< parameter index
    _C2FieldId _mFieldId;   ///< field identifier
};

/**
@@ -1153,6 +1226,7 @@ protected:
struct C2FieldSupportedValues {
//public:
    enum Type {
        EMPTY,      ///< no supported values
        RANGE,      ///< a numeric range that can be continuous or discrete
        VALUES,     ///< a list of values
        FLAGS       ///< a list of flags that can be OR-ed
@@ -1171,6 +1245,10 @@ struct C2FieldSupportedValues {
    } range;
    std::vector<Primitive> values;

    C2FieldSupportedValues()
        : type(EMPTY) {
    }

    template<typename T>
    C2FieldSupportedValues(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
        : type(RANGE),
@@ -1199,6 +1277,9 @@ struct C2FieldSupportedValues {
        }
    }

    /// \internal
    /// \todo: create separate values vs. flags initializer as for flags we want
    /// to list both allowed and disallowed flags
    template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)0))>
    C2FieldSupportedValues(bool flags, const T*)
        : type(flags ? FLAGS : VALUES),
@@ -1210,6 +1291,21 @@ struct C2FieldSupportedValues {
    }
};

/**
 * Spported values for a specific field.
 *
 * This is a pair of the field specifier together with an optional supported values object.
 * This structure is used when reporting parameter configuration failures and conflicts.
 */
struct C2ParamFieldValues {
    C2ParamField paramOrField; ///< the field or parameter
    /// optional supported values for the field if paramOrField specifies an actual field that is
    /// numeric (non struct, blob or string). Supported values for arrays (including string and
    /// blobs) describe the supported values for each element (character for string, and bytes for
    /// blobs). It is optional for read-only strings and blobs.
    std::unique_ptr<C2FieldSupportedValues> values;
};

/// @}

}  // namespace android
+27 −6
Original line number Diff line number Diff line
@@ -35,21 +35,42 @@ namespace android {
/// \defgroup work Work and data processing
/// @{

/**
 * Information describing the reason a parameter settings may fail, or
 * may be overriden.
 */
struct C2SettingResult {
    enum Failure {
    enum Failure : uint32_t {
        READ_ONLY,  ///< parameter is read-only and cannot be set
        MISMATCH,   ///< parameter mismatches input data
        BAD_VALUE,  ///< parameter does not accept value
        BAD_TYPE,   ///< parameter is not supported
        BAD_PORT,   ///< parameter is not supported on the specific port
        BAD_INDEX,  ///< parameter is not supported on the specific stream
        CONFLICT,   ///< parameter is in conflict with another setting
        CONFLICT,   ///< parameter is in conflict with an/other setting(s)
        /// parameter is out of range due to other settings (this failure mode
        /// can only be used for strict parameters)
        UNSUPPORTED,


        /// requested parameter value is in conflict with an/other setting(s)
        /// and has been corrected to the closest supported value. This failure
        /// mode is given to provide suggestion to the client as to how to
        /// enable the requested parameter value.
        INFO_CONFLICT,
    };

    C2ParamField field;
    Failure failure;
    std::unique_ptr<C2FieldSupportedValues> supportedValues; //< if different from normal (e.g. in conflict w/another param or input data)
    std::list<C2ParamField> conflictingFields;
    Failure failure;    ///< failure code

    /// Failing (or corrected) field. Currently supported values for the field. This is set if
    /// different from the globally supported values (e.g. due to restrictions by another param or
    /// input data)
    /// \todo need to define suggestions for masks to be set and unset.
    C2ParamFieldValues field;

    /// Conflicting parameters or fields with optional suggestions with (optional) suggested values
    /// for any conflicting fields to avoid the conflict.
    std::list<C2ParamFieldValues> conflicts;
};

// ================================================================================================
+15 −9
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ private:
    //                   config() should be failed if these values are used as new values.
    // This function should be called only for writable and supported parameters.
    template <typename TField>
    void getTestValues(const std::vector<C2FieldSupportedValues> &validValueInfos,
    void getTestValues(const C2FieldSupportedValues &validValueInfos,
                       std::vector<TField> *const validValues,
                       std::vector<TField> *const invalidValues);

@@ -325,7 +325,7 @@ void C2CompIntfTest::configWritableParamInvalidValue(const T &newParam) {
// If another field type is added, it is necessary to add function for that.
template <>
void C2CompIntfTest::getTestValues(
        const std::vector<C2FieldSupportedValues> &validValueInfos,
        const C2FieldSupportedValues &validValueInfos,
        std::vector<C2DomainKind> *const validValues,
        std::vector<C2DomainKind> *const invalidValues) {
    UNUSED(validValueInfos);
@@ -339,7 +339,7 @@ void C2CompIntfTest::getTestValues(

template <typename TField>
void C2CompIntfTest::getTestValues(
        const std::vector<C2FieldSupportedValues> &validValueInfos,
        const C2FieldSupportedValues &validValueInfos,
        std::vector<TField> *const validValues,
        std::vector<TField> *const invalidValues) {

@@ -366,9 +366,14 @@ void C2CompIntfTest::getTestValues(
    };

    // The size of validValueInfos is one.
    const auto &c2FSV = validValueInfos[0];
    const auto &c2FSV = validValueInfos;

    switch (c2FSV.type) {
    case C2FieldSupportedValues::Type::EMPTY: {
        invalidValues->emplace_back(TField(0));
        // TODO(hiroh) : Should other invalid values be tested?
        break;
    }
    case C2FieldSupportedValues::Type::RANGE: {
        const auto &range = c2FSV.range;
        auto rmin = prim2Value(range.min);
@@ -584,15 +589,16 @@ void C2CompIntfTest::outputResults(const std::string &name) {
#define TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, field_name_) \
    do {                                                                \
        std::unique_ptr<TParam_> param = makeParam<TParam_>();          \
        std::vector<C2FieldSupportedValues> validValueInfos;            \
        std::vector<C2FieldSupportedValuesQuery> validValueInfos = {    \
            C2FieldSupportedValuesQuery::Current(                       \
                    C2ParamField(param.get(), &field_type_name_::field_name_)) \
        };                                                              \
        ASSERT_EQ(C2_OK,                                                \
                  mIntf->getSupportedValues(                            \
                          {C2ParamField(param.get(), &field_type_name_::field_name_)}, \
                          &validValueInfos));                           \
                  mIntf->getSupportedValues(validValueInfos));          \
        ASSERT_EQ(1u, validValueInfos.size());                          \
        std::vector<decltype(param->field_name_)> validValues;          \
        std::vector<decltype(param->field_name_)> invalidValues;        \
        getTestValues(validValueInfos, &validValues, &invalidValues);   \
        getTestValues(validValueInfos[0].values, &validValues, &invalidValues);   \
        testWritableParam(param.get(), &param->field_name_, validValues,\
                          invalidValues);                               \
    } while (0)
Loading