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

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

Merge changes from topic "AMsgItem" into pi-dev

* changes:
  stagefright/foundation: add entry getter/setters to AMessage
  stagefright: make AMessage::Rect public
  stagefright: hide helper classes from export
parents 3dd71b01 81fba534
Loading
Loading
Loading
Loading
+116 −0
Original line number Diff line number Diff line
@@ -944,6 +944,40 @@ const char *AMessage::getEntryNameAt(size_t index, Type *type) const {
    return mItems[index].mName;
}

AMessage::ItemData AMessage::getEntryAt(size_t index) const {
    ItemData it;
    if (index < mNumItems) {
        switch (mItems[index].mType) {
            case kTypeInt32:    it.set(mItems[index].u.int32Value); break;
            case kTypeInt64:    it.set(mItems[index].u.int64Value); break;
            case kTypeSize:     it.set(mItems[index].u.sizeValue); break;
            case kTypeFloat:    it.set(mItems[index].u.floatValue); break;
            case kTypeDouble:   it.set(mItems[index].u.doubleValue); break;
            case kTypePointer:  it.set(mItems[index].u.ptrValue); break;
            case kTypeRect:     it.set(mItems[index].u.rectValue); break;
            case kTypeString:   it.set(*mItems[index].u.stringValue); break;
            case kTypeObject: {
                sp<RefBase> obj = mItems[index].u.refValue;
                it.set(obj);
                break;
            }
            case kTypeMessage: {
                sp<AMessage> msg = static_cast<AMessage *>(mItems[index].u.refValue);
                it.set(msg);
                break;
            }
            case kTypeBuffer: {
                sp<ABuffer> buf = static_cast<ABuffer *>(mItems[index].u.refValue);
                it.set(buf);
                break;
            }
            default:
                break;
        }
    }
    return it;
}

status_t AMessage::setEntryNameAt(size_t index, const char *name) {
    if (index >= mNumItems) {
        return BAD_INDEX;
@@ -964,6 +998,60 @@ status_t AMessage::setEntryNameAt(size_t index, const char *name) {
    return OK;
}

status_t AMessage::setEntryAt(size_t index, const ItemData &item) {
    AString stringValue;
    sp<RefBase> refValue;
    sp<AMessage> msgValue;
    sp<ABuffer> bufValue;

    if (index >= mNumItems) {
        return BAD_INDEX;
    }
    if (!item.used()) {
        return BAD_VALUE;
    }
    Item *dst = &mItems[index];
    freeItemValue(dst);

    // some values can be directly set with the getter. others need items to be allocated
    if (item.find(&dst->u.int32Value)) {
        dst->mType = kTypeInt32;
    } else if (item.find(&dst->u.int64Value)) {
        dst->mType = kTypeInt64;
    } else if (item.find(&dst->u.sizeValue)) {
        dst->mType = kTypeSize;
    } else if (item.find(&dst->u.floatValue)) {
        dst->mType = kTypeFloat;
    } else if (item.find(&dst->u.doubleValue)) {
        dst->mType = kTypeDouble;
    } else if (item.find(&dst->u.ptrValue)) {
        dst->mType = kTypePointer;
    } else if (item.find(&dst->u.rectValue)) {
        dst->mType = kTypeRect;
    } else if (item.find(&stringValue)) {
        dst->u.stringValue = new AString(stringValue);
        dst->mType = kTypeString;
    } else if (item.find(&refValue)) {
        if (refValue != NULL) { refValue->incStrong(this); }
        dst->u.refValue = refValue.get();
        dst->mType = kTypeObject;
    } else if (item.find(&msgValue)) {
        if (msgValue != NULL) { msgValue->incStrong(this); }
        dst->u.refValue = msgValue.get();
        dst->mType = kTypeMessage;
    } else if (item.find(&bufValue)) {
        if (bufValue != NULL) { bufValue->incStrong(this); }
        dst->u.refValue = bufValue.get();
        dst->mType = kTypeBuffer;
    } else {
        // unsupported item - we should not be here.
        dst->mType = kTypeInt32;
        dst->u.int32Value = 0xDEADDEAD;
        return BAD_TYPE;
    }
    return OK;
}

status_t AMessage::removeEntryAt(size_t index) {
    if (index >= mNumItems) {
        return BAD_INDEX;
@@ -983,6 +1071,34 @@ status_t AMessage::removeEntryAt(size_t index) {
    return OK;
}

void AMessage::setItem(const char *name, const ItemData &item) {
    if (item.used()) {
        Item *it = allocateItem(name);
        if (it != nullptr) {
            setEntryAt(it - mItems, item);
        }
    }
}

AMessage::ItemData AMessage::findItem(const char *name) const {
    return getEntryAt(findEntryByName(name));
}

void AMessage::extend(const sp<AMessage> &other) {
    // ignore null messages
    if (other == nullptr) {
        return;
    }

    for (size_t ix = 0; ix < other->mNumItems; ++ix) {
        Item *it = allocateItem(other->mItems[ix].mName);
        if (it != nullptr) {
            ItemData data = other->getEntryAt(ix);
            setEntryAt(it - mItems, data);
        }
    }
}

size_t AMessage::findEntryByName(const char *name) const {
    return name == nullptr ? countEntries() : findItemIndex(name, strlen(name));
}
+13 −10
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@
#include <media/stagefright/foundation/TypeTraits.h>
#include <media/stagefright/foundation/Flagged.h>

#undef HIDE
#define HIDE __attribute__((visibility("hidden")))

namespace android {

/**
@@ -78,7 +81,7 @@ namespace android {
 * This class is needed as member function specialization is not allowed for a
 * templated class.
 */
struct _AUnion_impl {
struct HIDE _AUnion_impl {
    /**
     * Calls placement constuctor for type T with arbitrary arguments for a storage at an address.
     * Storage MUST be large enough to contain T.
@@ -113,13 +116,13 @@ struct _AUnion_impl {

/** Constructor specialization for void type */
template<>
inline void _AUnion_impl::emplace<void>(size_t totalSize, void *addr) {
HIDE inline void _AUnion_impl::emplace<void>(size_t totalSize, void *addr) {
    memset(addr, 0, totalSize);
}

/** Destructor specialization for void type */
template<>
inline void _AUnion_impl::del<void>(void *) {
HIDE inline void _AUnion_impl::del<void>(void *) {
}

/// \endcond
@@ -221,7 +224,7 @@ public:
template<
        typename T,
        bool=std::is_copy_assignable<T>::value>
struct _AData_copier {
struct HIDE _AData_copier {
    static_assert(std::is_copy_assignable<T>::value, "T must be copy assignable here");

    /**
@@ -294,7 +297,7 @@ struct _AData_copier {
 *
 */
template<typename T>
struct _AData_copier<T, false> {
struct HIDE _AData_copier<T, false> {
    static_assert(!std::is_copy_assignable<T>::value, "T must not be copy assignable here");
    static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible here");

@@ -318,7 +321,7 @@ struct _AData_copier<T, false> {
template<
        typename T,
        bool=std::is_move_assignable<T>::value>
struct _AData_mover {
struct HIDE _AData_mover {
    static_assert(std::is_move_assignable<T>::value, "T must be move assignable here");

    /**
@@ -389,7 +392,7 @@ struct _AData_mover {
 *
 */
template<typename T>
struct _AData_mover<T, false> {
struct HIDE _AData_mover<T, false> {
    static_assert(!std::is_move_assignable<T>::value, "T must not be move assignable here");
    static_assert(std::is_move_constructible<T>::value, "T must be move constructible here");

@@ -407,13 +410,13 @@ struct _AData_mover<T, false> {
 * \param Ts types to consider for the member
 */
template<typename Flagger, typename U, typename ...Ts>
struct _AData_deleter;
struct HIDE _AData_deleter;

/**
 * Template specialization when there are still types to consider (T and rest)
 */
template<typename Flagger, typename U, typename T, typename ...Ts>
struct _AData_deleter<Flagger, U, T, Ts...> {
struct HIDE _AData_deleter<Flagger, U, T, Ts...> {
    static bool del(typename Flagger::type flags, U &data) {
        if (Flagger::canDeleteAs(flags, Flagger::flagFor((T*)0))) {
            data.template del<T>();
@@ -427,7 +430,7 @@ struct _AData_deleter<Flagger, U, T, Ts...> {
 * Template specialization when there are no more types to consider.
 */
template<typename Flagger, typename U>
struct _AData_deleter<Flagger, U> {
struct HIDE _AData_deleter<Flagger, U> {
    inline static bool del(typename Flagger::type, U &) {
        return false;
    }
+46 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#define A_MESSAGE_H_

#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AData.h>
#include <media/stagefright/foundation/ALooper.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
@@ -155,6 +156,9 @@ struct AMessage : public RefBase {
    // their refcount incremented.
    sp<AMessage> dup() const;

    // Adds all items from other into this.
    void extend(const sp<AMessage> &other);

    // Performs a shallow or deep comparison of |this| and |other| and returns
    // an AMessage with the differences.
    // Warning: RefBase items, i.e. "objects" are _not_ copied but only have
@@ -180,9 +184,38 @@ struct AMessage : public RefBase {
        kTypeBuffer,
    };

    struct Rect {
        int32_t mLeft, mTop, mRight, mBottom;
    };

    size_t countEntries() const;
    const char *getEntryNameAt(size_t index, Type *type) const;

    /**
     * Retrieves the item at a specific index.
     */
    typedef AData<
        int32_t, int64_t, size_t, float, double, Rect, AString,
        void *, sp<AMessage>, sp<ABuffer>, sp<RefBase>>::Basic ItemData;

    /**
     * Finds an item by name. This can be used if the type is unknown.
     *
     * \param name name of the item
     * Returns an empty item if no item is present with that name.
     */
    ItemData findItem(const char *name) const;

    /**
     * Sets an item of arbitrary type. Does nothing if the item value is empty.
     *
     * \param name name of the item
     * \param item value of the item
     */
    void setItem(const char *name, const ItemData &item);

    ItemData getEntryAt(size_t index) const;

    /**
     * Finds an entry by name and returns its index.
     *
@@ -203,6 +236,19 @@ struct AMessage : public RefBase {
     */
    status_t setEntryNameAt(size_t index, const char *name);

    /**
     * Sets the item of an entry based on index.
     *
     * \param index index of the entry
     * \param item new item of the entry
     *
     * \retval OK the item was set successfully
     * \retval BAD_INDEX invalid index
     * \retval BAD_VALUE item is invalid (null)
     * \retval BAD_TYPE type is unsupported (should not happen)
     */
    status_t setEntryAt(size_t index, const ItemData &item);

    /**
     * Removes an entry based on index.
     *
@@ -227,10 +273,6 @@ private:
    wp<AHandler> mHandler;
    wp<ALooper> mLooper;

    struct Rect {
        int32_t mLeft, mTop, mRight, mBottom;
    };

    struct Item {
        union {
            int32_t int32Value;
+25 −22
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@

#include <type_traits>

#undef HIDE
#define HIDE __attribute__((visibility("hidden")))

namespace android {

/**
@@ -31,7 +34,7 @@ namespace android {
 * Type support utility class to check if a type is an integral type or an enum.
 */
template<typename T>
struct is_integral_or_enum
struct HIDE is_integral_or_enum
    : std::integral_constant<bool, std::is_integral<T>::value || std::is_enum<T>::value> { };

/**
@@ -46,7 +49,7 @@ template<typename T,
        typename U=typename std::enable_if<is_integral_or_enum<T>::value>::type,
        bool=std::is_enum<T>::value,
        bool=std::is_integral<T>::value>
struct underlying_integral_type {
struct HIDE underlying_integral_type {
    static_assert(!std::is_enum<T>::value, "T should not be enum here");
    static_assert(!std::is_integral<T>::value, "T should not be integral here");
    typedef U type;
@@ -54,7 +57,7 @@ struct underlying_integral_type {

/** Specialization for enums. */
template<typename T, typename U>
struct underlying_integral_type<T, U, true, false> {
struct HIDE underlying_integral_type<T, U, true, false> {
    static_assert(std::is_enum<T>::value, "T should be enum here");
    static_assert(!std::is_integral<T>::value, "T should not be integral here");
    typedef typename std::underlying_type<T>::type type;
@@ -62,7 +65,7 @@ struct underlying_integral_type<T, U, true, false> {

/** Specialization for non-enum std-integral types. */
template<typename T, typename U>
struct underlying_integral_type<T, U, false, true> {
struct HIDE underlying_integral_type<T, U, false, true> {
    static_assert(!std::is_enum<T>::value, "T should not be enum here");
    static_assert(std::is_integral<T>::value, "T should be integral here");
    typedef T type;
@@ -72,7 +75,7 @@ struct underlying_integral_type<T, U, false, true> {
 * Type support utility class to check if the underlying integral type is signed.
 */
template<typename T>
struct is_signed_integral
struct HIDE is_signed_integral
    : std::integral_constant<bool, std::is_signed<
            typename underlying_integral_type<T, unsigned>::type>::value> { };

@@ -80,7 +83,7 @@ struct is_signed_integral
 * Type support utility class to check if the underlying integral type is unsigned.
 */
template<typename T>
struct is_unsigned_integral
struct HIDE is_unsigned_integral
    : std::integral_constant<bool, std::is_unsigned<
            typename underlying_integral_type<T, signed>::type>::value> {
};
@@ -92,26 +95,26 @@ struct is_unsigned_integral
 * member constant |value| equal to true. Otherwise value is false.
 */
template<typename T, typename ...Us>
struct is_one_of;
struct HIDE is_one_of;

/// \if 0
/**
 * Template specialization when first type matches the searched type.
 */
template<typename T, typename ...Us>
struct is_one_of<T, T, Us...> : std::true_type {};
struct HIDE is_one_of<T, T, Us...> : std::true_type {};

/**
 * Template specialization when first type does not match the searched type.
 */
template<typename T, typename U, typename ...Us>
struct is_one_of<T, U, Us...> : is_one_of<T, Us...> {};
struct HIDE is_one_of<T, U, Us...> : is_one_of<T, Us...> {};

/**
 * Template specialization when there are no types to search.
 */
template<typename T>
struct is_one_of<T> : std::false_type {};
struct HIDE is_one_of<T> : std::false_type {};
/// \endif

/**
@@ -121,44 +124,44 @@ struct is_one_of<T> : std::false_type {};
 * Otherwise value is false.
 */
template<typename ...Us>
struct are_unique;
struct HIDE are_unique;

/// \if 0
/**
 * Template specialization when there are no types.
 */
template<>
struct are_unique<> : std::true_type {};
struct HIDE are_unique<> : std::true_type {};

/**
 * Template specialization when there is at least one type to check.
 */
template<typename T, typename ...Us>
struct are_unique<T, Us...>
struct HIDE are_unique<T, Us...>
    : std::integral_constant<bool, are_unique<Us...>::value && !is_one_of<T, Us...>::value> {};
/// \endif

/// \if 0
template<size_t Base, typename T, typename ...Us>
struct _find_first_impl;
struct HIDE _find_first_impl;

/**
 * Template specialization when there are no types to search.
 */
template<size_t Base, typename T>
struct _find_first_impl<Base, T> : std::integral_constant<size_t, 0> {};
struct HIDE _find_first_impl<Base, T> : std::integral_constant<size_t, 0> {};

/**
 * Template specialization when T is the first type in Us.
 */
template<size_t Base, typename T, typename ...Us>
struct _find_first_impl<Base, T, T, Us...> : std::integral_constant<size_t, Base> {};
struct HIDE _find_first_impl<Base, T, T, Us...> : std::integral_constant<size_t, Base> {};

/**
 * Template specialization when T is not the first type in Us.
 */
template<size_t Base, typename T, typename U, typename ...Us>
struct _find_first_impl<Base, T, U, Us...>
struct HIDE _find_first_impl<Base, T, U, Us...>
    : std::integral_constant<size_t, _find_first_impl<Base + 1, T, Us...>::value> {};

/// \endif
@@ -169,7 +172,7 @@ struct _find_first_impl<Base, T, U, Us...>
 * If T occurs in Us, index is the 1-based left-most index of T in Us. Otherwise, index is 0.
 */
template<typename T, typename ...Us>
struct find_first {
struct HIDE find_first {
    static constexpr size_t index = _find_first_impl<1, T, Us...>::value;
};

@@ -180,13 +183,13 @@ struct find_first {
 * Adds a base index.
 */
template<size_t Base, typename T, typename ...Us>
struct _find_first_convertible_to_helper;
struct HIDE _find_first_convertible_to_helper;

/**
 * Template specialization for when there are more types to consider
 */
template<size_t Base, typename T, typename U, typename ...Us>
struct _find_first_convertible_to_helper<Base, T, U, Us...> {
struct HIDE _find_first_convertible_to_helper<Base, T, U, Us...> {
    static constexpr size_t index =
        std::is_convertible<T, U>::value ? Base :
                _find_first_convertible_to_helper<Base + 1, T, Us...>::index;
@@ -199,7 +202,7 @@ struct _find_first_convertible_to_helper<Base, T, U, Us...> {
 * Template specialization for when there are no more types to consider
 */
template<size_t Base, typename T>
struct _find_first_convertible_to_helper<Base, T> {
struct HIDE _find_first_convertible_to_helper<Base, T> {
    static constexpr size_t index = 0;
    typedef void type;
};
@@ -216,7 +219,7 @@ struct _find_first_convertible_to_helper<Base, T> {
 * \param Us types into which the conversion is considered
 */
template<typename T, typename ...Us>
struct find_first_convertible_to : public _find_first_convertible_to_helper<1, T, Us...> { };
struct HIDE find_first_convertible_to : public _find_first_convertible_to_helper<1, T, Us...> { };

}  // namespace android