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

Commit b5a34d6d authored by Ray Essick's avatar Ray Essick Committed by Android (Google) Code Review
Browse files

Merge changes from topic "mediametrics_stable_0118"

* changes:
  MediaPlayer2 using the new mediametrics stable interface
  Further work on libmediametrics stable API
parents 9a218f04 89269d69
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
// TODO: change it back to cc_library_shared when there is a way to
// expose media metrics as stable API.
cc_library {
cc_library_shared {
    name: "libmediametrics",

    srcs: [
@@ -32,12 +30,13 @@ cc_library {
        cfi: true,
    },

    // enumerate the stable interface
// this would mean nobody can use the C++ interface. have to rework some things.
//  stubs: {
//      symbol_file: "libmediametrics.map.txt",
//      versions: [
//          "1" ,
//      ]
//  },
    // enumerate stable entry points, for apex use
    stubs: {
        symbol_file: "libmediametrics.map.txt",
        versions: [
            "1" ,
        ]
    },
}

+1 −1
Original line number Diff line number Diff line
@@ -142,7 +142,7 @@ status_t BnMediaAnalyticsService::onTransact(
            CHECK_INTERFACE(IMediaAnalyticsService, data, reply);

            bool forcenew;
            MediaAnalyticsItem *item = new MediaAnalyticsItem;
            MediaAnalyticsItem *item = MediaAnalyticsItem::create();

            data.readBool(&forcenew);
            item->readFromParcel(data);
+204 −3
Original line number Diff line number Diff line
@@ -52,6 +52,17 @@ const char * const MediaAnalyticsItem::EnabledProperty = "media.metrics.enabled
const char * const MediaAnalyticsItem::EnabledPropertyPersist  = "persist.media.metrics.enabled";
const int MediaAnalyticsItem::EnabledProperty_default  = 1;

// So caller doesn't need to know size of allocated space
MediaAnalyticsItem *MediaAnalyticsItem::create()
{
    return MediaAnalyticsItem::create(kKeyNone);
}

MediaAnalyticsItem *MediaAnalyticsItem::create(MediaAnalyticsItem::Key key)
{
    MediaAnalyticsItem *item = new MediaAnalyticsItem(key);
    return item;
}

// access functions for the class
MediaAnalyticsItem::MediaAnalyticsItem()
@@ -642,6 +653,19 @@ bool MediaAnalyticsItem::growProps(int increment)
//

int32_t MediaAnalyticsItem::readFromParcel(const Parcel& data) {
    int32_t version = data.readInt32();

    switch(version) {
        case 0:
          return readFromParcel0(data);
          break;
        default:
          ALOGE("Unsupported MediaAnalyticsItem Parcel version: %d", version);
          return -1;
    }
}

int32_t MediaAnalyticsItem::readFromParcel0(const Parcel& data) {
    // into 'this' object
    // .. we make a copy of the string to put away.
    mKey = data.readCString();
@@ -691,8 +715,23 @@ int32_t MediaAnalyticsItem::readFromParcel(const Parcel& data) {
}

int32_t MediaAnalyticsItem::writeToParcel(Parcel *data) {

    if (data == NULL) return -1;

    int32_t version = 0;
    data->writeInt32(version);

    switch(version) {
        case 0:
          return writeToParcel0(data);
          break;
        default:
          ALOGE("Unsupported MediaAnalyticsItem Parcel version: %d", version);
          return -1;
    }
}

int32_t MediaAnalyticsItem::writeToParcel0(Parcel *data) {

    data->writeCString(mKey.c_str());
    data->writeInt32(mPid);
@@ -737,7 +776,6 @@ int32_t MediaAnalyticsItem::writeToParcel(Parcel *data) {
    return 0;
}


const char *MediaAnalyticsItem::toCString() {
   return toCString(PROTO_LAST);
}
@@ -876,8 +914,6 @@ bool MediaAnalyticsItem::selfrecord(bool forcenew) {
        }
        return true;
    } else {
        std::string p = this->toString();
        ALOGW("Unable to record: %s [forcenew=%d]", p.c_str(), forcenew);
        return false;
    }
}
@@ -1035,5 +1071,170 @@ bool MediaAnalyticsItem::merge(MediaAnalyticsItem *incoming) {
    return true;
}

// a byte array; contents are
// overall length (uint32) including the length field itself
// encoding version (uint32)
// count of properties (uint32)
// N copies of:
//     property name as length(int16), bytes
//         the bytes WILL include the null terminator of the name
//     type (uint8 -- 1 byte)
//     size of value field (int16 -- 2 bytes)
//     value (size based on type)
//       int32, int64, double -- little endian 4/8/8 bytes respectively
//       cstring -- N bytes of value [WITH terminator]

enum { kInt32 = 0, kInt64, kDouble, kRate, kCString};

bool MediaAnalyticsItem::dumpAttributes(char **pbuffer, size_t *plength) {

    char *build = NULL;

    if (pbuffer == NULL || plength == NULL)
        return false;

    // consistency for the caller, who owns whatever comes back in this pointer.
    *pbuffer = NULL;

    // first, let's calculate sizes
    int32_t goal = 0;
    int32_t version = 0;

    goal += sizeof(uint32_t);   // overall length, including the length field
    goal += sizeof(uint32_t);   // encoding version
    goal += sizeof(uint32_t);   // # properties

    int32_t count = mPropCount;
    for (int i = 0 ; i < count; i++ ) {
        Prop *prop = &mProps[i];
        goal += sizeof(uint16_t);           // name length
        goal += strlen(prop->mName) + 1;    // string + null
        goal += sizeof(uint8_t);            // type
        goal += sizeof(uint16_t);           // size of value
        switch (prop->mType) {
            case MediaAnalyticsItem::kTypeInt32:
                    goal += sizeof(uint32_t);
                    break;
            case MediaAnalyticsItem::kTypeInt64:
                    goal += sizeof(uint64_t);
                    break;
            case MediaAnalyticsItem::kTypeDouble:
                    goal += sizeof(double);
                    break;
            case MediaAnalyticsItem::kTypeRate:
                    goal += 2 * sizeof(uint64_t);
                    break;
            case MediaAnalyticsItem::kTypeCString:
                    // length + actual string + null
                    goal += strlen(prop->u.CStringValue) + 1;
                    break;
            default:
                    ALOGE("found bad Prop type: %d, idx %d, name %s",
                          prop->mType, i, prop->mName);
                    return false;
        }
    }

    // now that we have a size... let's allocate and fill
    build = (char *)malloc(goal);
    if (build == NULL)
        return false;

    memset(build, 0, goal);

    char *filling = build;

#define _INSERT(val, size) \
    { memcpy(filling, &(val), (size)); filling += (size);}
#define _INSERTSTRING(val, size) \
    { memcpy(filling, (val), (size)); filling += (size);}

    _INSERT(goal, sizeof(int32_t));
    _INSERT(version, sizeof(int32_t));
    _INSERT(count, sizeof(int32_t));

    for (int i = 0 ; i < count; i++ ) {
        Prop *prop = &mProps[i];
        int16_t attrNameLen = strlen(prop->mName) + 1;
        _INSERT(attrNameLen, sizeof(int16_t));
        _INSERTSTRING(prop->mName, attrNameLen);    // termination included
        int8_t elemtype;
        int16_t elemsize;
        switch (prop->mType) {
            case MediaAnalyticsItem::kTypeInt32:
                {
                    elemtype = kInt32;
                    _INSERT(elemtype, sizeof(int8_t));
                    elemsize = sizeof(int32_t);
                    _INSERT(elemsize, sizeof(int16_t));

                    _INSERT(prop->u.int32Value, sizeof(int32_t));
                    break;
                }
            case MediaAnalyticsItem::kTypeInt64:
                {
                    elemtype = kInt64;
                    _INSERT(elemtype, sizeof(int8_t));
                    elemsize = sizeof(int64_t);
                    _INSERT(elemsize, sizeof(int16_t));

                    _INSERT(prop->u.int64Value, sizeof(int64_t));
                    break;
                }
            case MediaAnalyticsItem::kTypeDouble:
                {
                    elemtype = kDouble;
                    _INSERT(elemtype, sizeof(int8_t));
                    elemsize = sizeof(double);
                    _INSERT(elemsize, sizeof(int16_t));

                    _INSERT(prop->u.doubleValue, sizeof(double));
                    break;
                }
            case MediaAnalyticsItem::kTypeRate:
                {
                    elemtype = kRate;
                    _INSERT(elemtype, sizeof(int8_t));
                    elemsize = 2 * sizeof(uint64_t);
                    _INSERT(elemsize, sizeof(int16_t));

                    _INSERT(prop->u.rate.count, sizeof(uint64_t));
                    _INSERT(prop->u.rate.duration, sizeof(uint64_t));
                    break;
                }
            case MediaAnalyticsItem::kTypeCString:
                {
                    elemtype = kCString;
                    _INSERT(elemtype, sizeof(int8_t));
                    elemsize = strlen(prop->u.CStringValue) + 1;
                    _INSERT(elemsize, sizeof(int16_t));

                    _INSERTSTRING(prop->u.CStringValue, elemsize);
                    break;
                }
            default:
                    // error if can't encode; warning if can't decode
                    ALOGE("found bad Prop type: %d, idx %d, name %s",
                          prop->mType, i, prop->mName);
                    goto badness;
        }
    }

    if (build + goal != filling) {
        ALOGE("problems populating; wrote=%d planned=%d",
              (int)(filling-build), goal);
        goto badness;
    }

    *pbuffer = build;
    *plength = goal;

    return true;

  badness:
    free(build);
    return false;
}

} // namespace android
+5 −14
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@

// manage the overall record
mediametrics_handle_t mediametrics_create(mediametricskey_t key) {
    android::MediaAnalyticsItem *item = new android::MediaAnalyticsItem(key);
    android::MediaAnalyticsItem *item = android::MediaAnalyticsItem::create(key);
    return (mediametrics_handle_t) item;
}

@@ -187,18 +187,9 @@ bool mediametrics_isEnabled() {
    return android::MediaAnalyticsItem::isEnabled();
}

#if 0
// do not expose this as is.
// need to revisit (or redefine) how the android::Parcel parameter is handled
// so that it meets the stable-API criteria for updateable components.
//
int32_t mediametrics_writeToParcel(mediametrics_handle_t handle, android::Parcel *parcel) {
bool mediametrics_getAttributes(mediametrics_handle_t handle, char **buffer, size_t *length) {
    android::MediaAnalyticsItem *item = (android::MediaAnalyticsItem *) handle;
    if (item == NULL) {
        return -1;
    }
    return item->writeToParcel(parcel);
}
#endif

    if (item == NULL) return false;
    return item->dumpAttributes(buffer, length);

}
+14 −1
Original line number Diff line number Diff line
@@ -17,9 +17,10 @@
#ifndef ANDROID_MEDIA_MEDIAANALYTICSITEM_H
#define ANDROID_MEDIA_MEDIAANALYTICSITEM_H

#include <cutils/properties.h>
#include <string>
#include <sys/types.h>

#include <cutils/properties.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
@@ -84,6 +85,10 @@ class MediaAnalyticsItem {

    public:

        // so clients do not need to know size details
        static MediaAnalyticsItem* create(Key key);
        static MediaAnalyticsItem* create();

        // access functions for the class
        MediaAnalyticsItem();
        MediaAnalyticsItem(Key);
@@ -175,6 +180,9 @@ class MediaAnalyticsItem {
        int32_t writeToParcel(Parcel *);
        int32_t readFromParcel(const Parcel&);

        // supports the stable interface
        bool dumpAttributes(char **pbuffer, size_t *plength);

        std::string toString();
        std::string toString(int version);
        const char *toCString();
@@ -183,6 +191,11 @@ class MediaAnalyticsItem {
        // are we collecting analytics data
        static bool isEnabled();

    private:
        // handle Parcel version 0
        int32_t writeToParcel0(Parcel *);
        int32_t readFromParcel0(const Parcel&);

    protected:

        // merge fields from arg into this
Loading