|
|
|
@ -63,51 +63,6 @@ mediametrics::Item::~Item() {
|
|
|
|
|
if (DEBUG_ALLOCATIONS) {
|
|
|
|
|
ALOGD("Destroy mediametrics::Item @ %p", this);
|
|
|
|
|
}
|
|
|
|
|
clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mediametrics::Item::clear() {
|
|
|
|
|
|
|
|
|
|
// clean allocated storage from key
|
|
|
|
|
mKey.clear();
|
|
|
|
|
|
|
|
|
|
// clean attributes
|
|
|
|
|
// contents of the attributes
|
|
|
|
|
for (size_t i = 0 ; i < mPropCount; i++ ) {
|
|
|
|
|
mProps[i].clear();
|
|
|
|
|
}
|
|
|
|
|
// the attribute records themselves
|
|
|
|
|
if (mProps != NULL) {
|
|
|
|
|
free(mProps);
|
|
|
|
|
mProps = NULL;
|
|
|
|
|
}
|
|
|
|
|
mPropSize = 0;
|
|
|
|
|
mPropCount = 0;
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make a deep copy of myself
|
|
|
|
|
mediametrics::Item *mediametrics::Item::dup() {
|
|
|
|
|
mediametrics::Item *dst = new mediametrics::Item(this->mKey);
|
|
|
|
|
|
|
|
|
|
if (dst != NULL) {
|
|
|
|
|
// key as part of constructor
|
|
|
|
|
dst->mPid = this->mPid;
|
|
|
|
|
dst->mUid = this->mUid;
|
|
|
|
|
dst->mPkgName = this->mPkgName;
|
|
|
|
|
dst->mPkgVersionCode = this->mPkgVersionCode;
|
|
|
|
|
dst->mTimestamp = this->mTimestamp;
|
|
|
|
|
|
|
|
|
|
// properties aka attributes
|
|
|
|
|
dst->growProps(this->mPropCount);
|
|
|
|
|
for(size_t i=0;i<mPropCount;i++) {
|
|
|
|
|
dst->mProps[i] = this->mProps[i];
|
|
|
|
|
}
|
|
|
|
|
dst->mPropCount = this->mPropCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mediametrics::Item &mediametrics::Item::setTimestamp(nsecs_t ts) {
|
|
|
|
@ -151,84 +106,12 @@ int64_t mediametrics::Item::getPkgVersionCode() const {
|
|
|
|
|
return mPkgVersionCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find the proper entry in the list
|
|
|
|
|
size_t mediametrics::Item::findPropIndex(const char *name) const
|
|
|
|
|
{
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
for (; i < mPropCount; i++) {
|
|
|
|
|
if (mProps[i].isNamed(name)) break;
|
|
|
|
|
}
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mediametrics::Item::Prop *mediametrics::Item::findProp(const char *name) const {
|
|
|
|
|
const size_t i = findPropIndex(name);
|
|
|
|
|
if (i < mPropCount) {
|
|
|
|
|
return &mProps[i];
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// consider this "find-or-allocate".
|
|
|
|
|
// caller validates type and uses clearPropValue() accordingly
|
|
|
|
|
mediametrics::Item::Prop *mediametrics::Item::allocateProp(const char *name) {
|
|
|
|
|
const size_t i = findPropIndex(name);
|
|
|
|
|
if (i < mPropCount) {
|
|
|
|
|
return &mProps[i]; // already have it, return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Prop *prop = allocateProp(); // get a new prop
|
|
|
|
|
if (prop == nullptr) return nullptr;
|
|
|
|
|
prop->setName(name);
|
|
|
|
|
return prop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mediametrics::Item::Prop *mediametrics::Item::allocateProp() {
|
|
|
|
|
if (mPropCount == mPropSize && growProps() == false) {
|
|
|
|
|
ALOGE("%s: failed allocation for new properties", __func__);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return &mProps[mPropCount++];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// used within the summarizers; return whether property existed
|
|
|
|
|
bool mediametrics::Item::removeProp(const char *name) {
|
|
|
|
|
const size_t i = findPropIndex(name);
|
|
|
|
|
if (i < mPropCount) {
|
|
|
|
|
mProps[i].clear();
|
|
|
|
|
if (i != mPropCount-1) {
|
|
|
|
|
// in the middle, bring last one down to fill gap
|
|
|
|
|
mProps[i].swap(mProps[mPropCount-1]);
|
|
|
|
|
}
|
|
|
|
|
mPropCount--;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove indicated keys and their values
|
|
|
|
|
// return value is # keys removed
|
|
|
|
|
size_t mediametrics::Item::filter(size_t n, const char *attrs[]) {
|
|
|
|
|
size_t zapped = 0;
|
|
|
|
|
for (size_t i = 0; i < n; ++i) {
|
|
|
|
|
const char *name = attrs[i];
|
|
|
|
|
size_t j = findPropIndex(name);
|
|
|
|
|
if (j >= mPropCount) {
|
|
|
|
|
// not there
|
|
|
|
|
continue;
|
|
|
|
|
} else if (j + 1 == mPropCount) {
|
|
|
|
|
// last one, shorten
|
|
|
|
|
zapped++;
|
|
|
|
|
mProps[j].clear();
|
|
|
|
|
mPropCount--;
|
|
|
|
|
} else {
|
|
|
|
|
// in the middle, bring last one down and shorten
|
|
|
|
|
zapped++;
|
|
|
|
|
mProps[j].clear();
|
|
|
|
|
mProps[j] = mProps[mPropCount-1];
|
|
|
|
|
mPropCount--;
|
|
|
|
|
}
|
|
|
|
|
zapped += mProps.erase(attrs[i]);
|
|
|
|
|
}
|
|
|
|
|
return zapped;
|
|
|
|
|
}
|
|
|
|
@ -238,49 +121,17 @@ size_t mediametrics::Item::filter(size_t n, const char *attrs[]) {
|
|
|
|
|
size_t mediametrics::Item::filterNot(size_t n, const char *attrs[]) {
|
|
|
|
|
std::set<std::string> check(attrs, attrs + n);
|
|
|
|
|
size_t zapped = 0;
|
|
|
|
|
for (size_t j = 0; j < mPropCount;) {
|
|
|
|
|
if (check.find(mProps[j].getName()) != check.end()) {
|
|
|
|
|
++j;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (j + 1 == mPropCount) {
|
|
|
|
|
// last one, shorten
|
|
|
|
|
zapped++;
|
|
|
|
|
mProps[j].clear();
|
|
|
|
|
mPropCount--;
|
|
|
|
|
break;
|
|
|
|
|
for (auto it = mProps.begin(); it != mProps.end();) {
|
|
|
|
|
if (check.find(it->first) != check.end()) {
|
|
|
|
|
++it;
|
|
|
|
|
} else {
|
|
|
|
|
// in the middle, bring last one down and shorten
|
|
|
|
|
zapped++;
|
|
|
|
|
mProps[j].clear();
|
|
|
|
|
mProps[j] = mProps[mPropCount-1];
|
|
|
|
|
mPropCount--;
|
|
|
|
|
it = mProps.erase(it);
|
|
|
|
|
++zapped;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return zapped;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mediametrics::Item::growProps(int increment)
|
|
|
|
|
{
|
|
|
|
|
if (increment <= 0) {
|
|
|
|
|
increment = kGrowProps;
|
|
|
|
|
}
|
|
|
|
|
int nsize = mPropSize + increment;
|
|
|
|
|
Prop *ni = (Prop *)realloc(mProps, sizeof(Prop) * nsize);
|
|
|
|
|
|
|
|
|
|
if (ni != NULL) {
|
|
|
|
|
for (int i = mPropSize; i < nsize; i++) {
|
|
|
|
|
new (&ni[i]) Prop(); // placement new
|
|
|
|
|
}
|
|
|
|
|
mProps = ni;
|
|
|
|
|
mPropSize = nsize;
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
ALOGW("mediametrics::Item::growProps fails");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parcel / serialize things for binder calls
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
@ -315,10 +166,11 @@ status_t mediametrics::Item::readFromParcel0(const Parcel& data) {
|
|
|
|
|
if (count < 0) return BAD_VALUE;
|
|
|
|
|
mPkgVersionCode = version;
|
|
|
|
|
mTimestamp = timestamp;
|
|
|
|
|
for (int i = 0; i < count ; i++) {
|
|
|
|
|
Prop *prop = allocateProp();
|
|
|
|
|
status_t status = prop->readFromParcel(data);
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
|
Prop prop;
|
|
|
|
|
status_t status = prop.readFromParcel(data);
|
|
|
|
|
if (status != NO_ERROR) return status;
|
|
|
|
|
mProps[prop.getName()] = std::move(prop);
|
|
|
|
|
}
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
@ -349,9 +201,9 @@ status_t mediametrics::Item::writeToParcel0(Parcel *data) const {
|
|
|
|
|
?: data->writeInt64(mTimestamp);
|
|
|
|
|
if (status != NO_ERROR) return status;
|
|
|
|
|
|
|
|
|
|
data->writeInt32((int32_t)mPropCount);
|
|
|
|
|
for (size_t i = 0 ; i < mPropCount; ++i) {
|
|
|
|
|
status = mProps[i].writeToParcel(data);
|
|
|
|
|
data->writeInt32((int32_t)mProps.size());
|
|
|
|
|
for (auto &prop : *this) {
|
|
|
|
|
status = prop.writeToParcel(data);
|
|
|
|
|
if (status != NO_ERROR) return status;
|
|
|
|
|
}
|
|
|
|
|
return NO_ERROR;
|
|
|
|
@ -376,10 +228,10 @@ std::string mediametrics::Item::toString(int version) const {
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "[%d:%s:%d:%d:%lld:%s:%zu:",
|
|
|
|
|
version, mKey.c_str(), mPid, mUid, (long long)mTimestamp,
|
|
|
|
|
mPkgName.c_str(), mPropCount);
|
|
|
|
|
mPkgName.c_str(), mProps.size());
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
for (size_t i = 0 ; i < mPropCount; ++i) {
|
|
|
|
|
mProps[i].toString(buffer, sizeof(buffer));
|
|
|
|
|
for (auto &prop : *this) {
|
|
|
|
|
prop.toString(buffer, sizeof(buffer));
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
}
|
|
|
|
|
result.append("]");
|
|
|
|
@ -390,7 +242,7 @@ std::string mediametrics::Item::toString(int version) const {
|
|
|
|
|
// calls the appropriate daemon
|
|
|
|
|
bool mediametrics::Item::selfrecord() {
|
|
|
|
|
ALOGD_IF(DEBUG_API, "%s: delivering %s", __func__, this->toString().c_str());
|
|
|
|
|
sp<IMediaMetricsService> svc = getInstance();
|
|
|
|
|
sp<IMediaMetricsService> svc = getService();
|
|
|
|
|
if (svc != NULL) {
|
|
|
|
|
status_t status = svc->submit(this);
|
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
@ -460,7 +312,7 @@ bool BaseItem::submitBuffer(const char *buffer, size_t size) {
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
ALOGD_IF(DEBUG_API, "%s: delivering %zu bytes", __func__, size);
|
|
|
|
|
sp<IMediaMetricsService> svc = getInstance();
|
|
|
|
|
sp<IMediaMetricsService> svc = getService();
|
|
|
|
|
if (svc != nullptr) {
|
|
|
|
|
const status_t status = svc->submitBuffer(buffer, size);
|
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
@ -473,7 +325,7 @@ bool BaseItem::submitBuffer(const char *buffer, size_t size) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//static
|
|
|
|
|
sp<IMediaMetricsService> BaseItem::getInstance() {
|
|
|
|
|
sp<IMediaMetricsService> BaseItem::getService() {
|
|
|
|
|
static const char *servicename = "media.metrics";
|
|
|
|
|
static const bool enabled = isEnabled(); // singleton initialized
|
|
|
|
|
|
|
|
|
@ -512,47 +364,6 @@ sp<IMediaMetricsService> BaseItem::getInstance() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// merge the info from 'incoming' into this record.
|
|
|
|
|
// we finish with a union of this+incoming and special handling for collisions
|
|
|
|
|
bool mediametrics::Item::merge(mediametrics::Item *incoming) {
|
|
|
|
|
|
|
|
|
|
// if I don't have key or session id, take them from incoming
|
|
|
|
|
// 'this' should never be missing both of them...
|
|
|
|
|
if (mKey.empty()) {
|
|
|
|
|
mKey = incoming->mKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for each attribute from 'incoming', resolve appropriately
|
|
|
|
|
int nattr = incoming->mPropCount;
|
|
|
|
|
for (int i = 0 ; i < nattr; i++ ) {
|
|
|
|
|
Prop *iprop = &incoming->mProps[i];
|
|
|
|
|
const char *p = iprop->mName;
|
|
|
|
|
size_t len = strlen(p);
|
|
|
|
|
|
|
|
|
|
// should ignore a zero length name...
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Prop *oprop = findProp(iprop->mName);
|
|
|
|
|
|
|
|
|
|
if (oprop == NULL) {
|
|
|
|
|
// no oprop, so we insert the new one
|
|
|
|
|
oprop = allocateProp(p);
|
|
|
|
|
if (oprop != NULL) {
|
|
|
|
|
*oprop = *iprop;
|
|
|
|
|
} else {
|
|
|
|
|
ALOGW("dropped property '%s'", iprop->mName);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
*oprop = *iprop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// not sure when we'd return false...
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
@ -647,14 +458,14 @@ status_t mediametrics::Item::writeToByteString(char **pbuffer, size_t *plength)
|
|
|
|
|
uint32_t size = header_size
|
|
|
|
|
+ sizeof(uint32_t) // # properties
|
|
|
|
|
;
|
|
|
|
|
for (size_t i = 0 ; i < mPropCount; ++i) {
|
|
|
|
|
const size_t propSize = mProps[i].getByteStringSize();
|
|
|
|
|
for (auto &prop : *this) {
|
|
|
|
|
const size_t propSize = prop.getByteStringSize();
|
|
|
|
|
if (propSize > UINT16_MAX) {
|
|
|
|
|
ALOGW("%s: prop %zu size %zu too large", __func__, i, propSize);
|
|
|
|
|
ALOGW("%s: prop %s size %zu too large", __func__, prop.getName(), propSize);
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
if (__builtin_add_overflow(size, propSize, &size)) {
|
|
|
|
|
ALOGW("%s: item size overflow at property %zu", __func__, i);
|
|
|
|
|
ALOGW("%s: item size overflow at property %s", __func__, prop.getName());
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -674,16 +485,16 @@ status_t mediametrics::Item::writeToByteString(char **pbuffer, size_t *plength)
|
|
|
|
|
|| insert((int32_t)mPid, &filling, buildmax) != NO_ERROR
|
|
|
|
|
|| insert((int32_t)mUid, &filling, buildmax) != NO_ERROR
|
|
|
|
|
|| insert((int64_t)mTimestamp, &filling, buildmax) != NO_ERROR
|
|
|
|
|
|| insert((uint32_t)mPropCount, &filling, buildmax) != NO_ERROR) {
|
|
|
|
|
|| insert((uint32_t)mProps.size(), &filling, buildmax) != NO_ERROR) {
|
|
|
|
|
ALOGE("%s:could not write header", __func__); // shouldn't happen
|
|
|
|
|
free(build);
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0 ; i < mPropCount; ++i) {
|
|
|
|
|
if (mProps[i].writeToByteString(&filling, buildmax) != NO_ERROR) {
|
|
|
|
|
for (auto &prop : *this) {
|
|
|
|
|
if (prop.writeToByteString(&filling, buildmax) != NO_ERROR) {
|
|
|
|
|
free(build);
|
|
|
|
|
// shouldn't happen
|
|
|
|
|
ALOGE("%s:could not write prop %zu of %zu", __func__, i, mPropCount);
|
|
|
|
|
ALOGE("%s:could not write prop %s", __func__, prop.getName());
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -750,11 +561,12 @@ status_t mediametrics::Item::readFromByteString(const char *bufferptr, size_t le
|
|
|
|
|
mUid = uid;
|
|
|
|
|
mTimestamp = timestamp;
|
|
|
|
|
for (size_t i = 0; i < propCount; ++i) {
|
|
|
|
|
Prop *prop = allocateProp();
|
|
|
|
|
if (prop->readFromByteString(&read, readend) != NO_ERROR) {
|
|
|
|
|
Prop prop;
|
|
|
|
|
if (prop.readFromByteString(&read, readend) != NO_ERROR) {
|
|
|
|
|
ALOGW("%s: cannot read prop %zu", __func__, i);
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
mProps[prop.getName()] = std::move(prop);
|
|
|
|
|
}
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
@ -762,29 +574,29 @@ status_t mediametrics::Item::readFromByteString(const char *bufferptr, size_t le
|
|
|
|
|
status_t mediametrics::Item::Prop::writeToParcel(Parcel *data) const
|
|
|
|
|
{
|
|
|
|
|
switch (mType) {
|
|
|
|
|
case kTypeInt32:
|
|
|
|
|
return data->writeCString(mName)
|
|
|
|
|
case mediametrics::kTypeInt32:
|
|
|
|
|
return data->writeCString(mName.c_str())
|
|
|
|
|
?: data->writeInt32(mType)
|
|
|
|
|
?: data->writeInt32(u.int32Value);
|
|
|
|
|
case kTypeInt64:
|
|
|
|
|
return data->writeCString(mName)
|
|
|
|
|
case mediametrics::kTypeInt64:
|
|
|
|
|
return data->writeCString(mName.c_str())
|
|
|
|
|
?: data->writeInt32(mType)
|
|
|
|
|
?: data->writeInt64(u.int64Value);
|
|
|
|
|
case kTypeDouble:
|
|
|
|
|
return data->writeCString(mName)
|
|
|
|
|
case mediametrics::kTypeDouble:
|
|
|
|
|
return data->writeCString(mName.c_str())
|
|
|
|
|
?: data->writeInt32(mType)
|
|
|
|
|
?: data->writeDouble(u.doubleValue);
|
|
|
|
|
case kTypeRate:
|
|
|
|
|
return data->writeCString(mName)
|
|
|
|
|
case mediametrics::kTypeRate:
|
|
|
|
|
return data->writeCString(mName.c_str())
|
|
|
|
|
?: data->writeInt32(mType)
|
|
|
|
|
?: data->writeInt64(u.rate.first)
|
|
|
|
|
?: data->writeInt64(u.rate.second);
|
|
|
|
|
case kTypeCString:
|
|
|
|
|
return data->writeCString(mName)
|
|
|
|
|
case mediametrics::kTypeCString:
|
|
|
|
|
return data->writeCString(mName.c_str())
|
|
|
|
|
?: data->writeInt32(mType)
|
|
|
|
|
?: data->writeCString(u.CStringValue);
|
|
|
|
|
default:
|
|
|
|
|
ALOGE("%s: found bad type: %d, name %s", __func__, mType, mName);
|
|
|
|
|
ALOGE("%s: found bad type: %d, name %s", __func__, mType, mName.c_str());
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -797,22 +609,22 @@ status_t mediametrics::Item::Prop::readFromParcel(const Parcel& data)
|
|
|
|
|
status_t status = data.readInt32(&type);
|
|
|
|
|
if (status != NO_ERROR) return status;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case kTypeInt32:
|
|
|
|
|
case mediametrics::kTypeInt32:
|
|
|
|
|
status = data.readInt32(&u.int32Value);
|
|
|
|
|
break;
|
|
|
|
|
case kTypeInt64:
|
|
|
|
|
case mediametrics::kTypeInt64:
|
|
|
|
|
status = data.readInt64(&u.int64Value);
|
|
|
|
|
break;
|
|
|
|
|
case kTypeDouble:
|
|
|
|
|
case mediametrics::kTypeDouble:
|
|
|
|
|
status = data.readDouble(&u.doubleValue);
|
|
|
|
|
break;
|
|
|
|
|
case kTypeCString: {
|
|
|
|
|
case mediametrics::kTypeCString: {
|
|
|
|
|
const char *s = data.readCString();
|
|
|
|
|
if (s == nullptr) return BAD_VALUE;
|
|
|
|
|
set(s);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case kTypeRate: {
|
|
|
|
|
case mediametrics::kTypeRate: {
|
|
|
|
|
std::pair<int64_t, int64_t> rate;
|
|
|
|
|
status = data.readInt64(&rate.first)
|
|
|
|
|
?: data.readInt64(&rate.second);
|
|
|
|
@ -827,7 +639,7 @@ status_t mediametrics::Item::Prop::readFromParcel(const Parcel& data)
|
|
|
|
|
}
|
|
|
|
|
if (status == NO_ERROR) {
|
|
|
|
|
setName(key);
|
|
|
|
|
mType = (Type)type;
|
|
|
|
|
mType = (mediametrics::Type)type;
|
|
|
|
|
}
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
@ -835,25 +647,25 @@ status_t mediametrics::Item::Prop::readFromParcel(const Parcel& data)
|
|
|
|
|
void mediametrics::Item::Prop::toString(char *buffer, size_t length) const
|
|
|
|
|
{
|
|
|
|
|
switch (mType) {
|
|
|
|
|
case kTypeInt32:
|
|
|
|
|
snprintf(buffer, length, "%s=%d:", mName, u.int32Value);
|
|
|
|
|
case mediametrics::kTypeInt32:
|
|
|
|
|
snprintf(buffer, length, "%s=%d:", mName.c_str(), u.int32Value);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeInt64:
|
|
|
|
|
snprintf(buffer, length, "%s=%lld:", mName, (long long)u.int64Value);
|
|
|
|
|
case mediametrics::kTypeInt64:
|
|
|
|
|
snprintf(buffer, length, "%s=%lld:", mName.c_str(), (long long)u.int64Value);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeDouble:
|
|
|
|
|
snprintf(buffer, length, "%s=%e:", mName, u.doubleValue);
|
|
|
|
|
case mediametrics::kTypeDouble:
|
|
|
|
|
snprintf(buffer, length, "%s=%e:", mName.c_str(), u.doubleValue);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeRate:
|
|
|
|
|
case mediametrics::kTypeRate:
|
|
|
|
|
snprintf(buffer, length, "%s=%lld/%lld:",
|
|
|
|
|
mName, (long long)u.rate.first, (long long)u.rate.second);
|
|
|
|
|
mName.c_str(), (long long)u.rate.first, (long long)u.rate.second);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeCString:
|
|
|
|
|
case mediametrics::kTypeCString:
|
|
|
|
|
// TODO sanitize string for ':' '='
|
|
|
|
|
snprintf(buffer, length, "%s=%s:", mName, u.CStringValue);
|
|
|
|
|
snprintf(buffer, length, "%s=%s:", mName.c_str(), u.CStringValue);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ALOGE("%s: bad item type: %d for %s", __func__, mType, mName);
|
|
|
|
|
ALOGE("%s: bad item type: %d for %s", __func__, mType, mName.c_str());
|
|
|
|
|
if (length > 0) buffer[0] = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -864,27 +676,27 @@ size_t mediametrics::Item::Prop::getByteStringSize() const
|
|
|
|
|
const size_t header =
|
|
|
|
|
sizeof(uint16_t) // length
|
|
|
|
|
+ sizeof(uint8_t) // type
|
|
|
|
|
+ strlen(mName) + 1; // mName + 0 termination
|
|
|
|
|
+ mName.size() + 1; // mName + 0 termination
|
|
|
|
|
size_t payload = 0;
|
|
|
|
|
switch (mType) {
|
|
|
|
|
case mediametrics::Item::kTypeInt32:
|
|
|
|
|
case mediametrics::kTypeInt32:
|
|
|
|
|
payload = sizeof(u.int32Value);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeInt64:
|
|
|
|
|
case mediametrics::kTypeInt64:
|
|
|
|
|
payload = sizeof(u.int64Value);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeDouble:
|
|
|
|
|
case mediametrics::kTypeDouble:
|
|
|
|
|
payload = sizeof(u.doubleValue);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeRate:
|
|
|
|
|
case mediametrics::kTypeRate:
|
|
|
|
|
payload = sizeof(u.rate.first) + sizeof(u.rate.second);
|
|
|
|
|
break;
|
|
|
|
|
case mediametrics::Item::kTypeCString:
|
|
|
|
|
case mediametrics::kTypeCString:
|
|
|
|
|
payload = strlen(u.CStringValue) + 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ALOGE("%s: found bad prop type: %d, name %s",
|
|
|
|
|
__func__, mType, mName); // no payload computed
|
|
|
|
|
__func__, mType, mName.c_str()); // no payload computed
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return header + payload;
|
|
|
|
@ -898,7 +710,7 @@ status_t BaseItem::writeToByteString(
|
|
|
|
|
const size_t len = 2 + 1 + strlen(name) + 1 + sizeof(value);
|
|
|
|
|
if (len > UINT16_MAX) return BAD_VALUE;
|
|
|
|
|
return insert((uint16_t)len, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)kTypeInt32, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)mediametrics::kTypeInt32, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(name, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(value, bufferpptr, bufferptrmax);
|
|
|
|
|
}
|
|
|
|
@ -909,7 +721,7 @@ status_t BaseItem::writeToByteString(
|
|
|
|
|
const size_t len = 2 + 1 + strlen(name) + 1 + sizeof(value);
|
|
|
|
|
if (len > UINT16_MAX) return BAD_VALUE;
|
|
|
|
|
return insert((uint16_t)len, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)kTypeInt64, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)mediametrics::kTypeInt64, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(name, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(value, bufferpptr, bufferptrmax);
|
|
|
|
|
}
|
|
|
|
@ -920,7 +732,7 @@ status_t BaseItem::writeToByteString(
|
|
|
|
|
const size_t len = 2 + 1 + strlen(name) + 1 + sizeof(value);
|
|
|
|
|
if (len > UINT16_MAX) return BAD_VALUE;
|
|
|
|
|
return insert((uint16_t)len, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)kTypeDouble, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)mediametrics::kTypeDouble, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(name, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(value, bufferpptr, bufferptrmax);
|
|
|
|
|
}
|
|
|
|
@ -931,7 +743,7 @@ status_t BaseItem::writeToByteString(
|
|
|
|
|
const size_t len = 2 + 1 + strlen(name) + 1 + 8 + 8;
|
|
|
|
|
if (len > UINT16_MAX) return BAD_VALUE;
|
|
|
|
|
return insert((uint16_t)len, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)kTypeRate, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)mediametrics::kTypeRate, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(name, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(value.first, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(value.second, bufferpptr, bufferptrmax);
|
|
|
|
@ -949,7 +761,7 @@ status_t BaseItem::writeToByteString(
|
|
|
|
|
const size_t len = 2 + 1 + strlen(name) + 1 + strlen(value) + 1;
|
|
|
|
|
if (len > UINT16_MAX) return BAD_VALUE;
|
|
|
|
|
return insert((uint16_t)len, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)kTypeCString, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)mediametrics::kTypeCString, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(name, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(value, bufferpptr, bufferptrmax);
|
|
|
|
|
}
|
|
|
|
@ -961,7 +773,7 @@ status_t BaseItem::writeToByteString(
|
|
|
|
|
const size_t len = 2 + 1 + strlen(name) + 1;
|
|
|
|
|
if (len > UINT16_MAX) return BAD_VALUE;
|
|
|
|
|
return insert((uint16_t)len, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)kTypeCString, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert((uint8_t)mediametrics::kTypeCString, bufferpptr, bufferptrmax)
|
|
|
|
|
?: insert(name, bufferpptr, bufferptrmax);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -970,21 +782,22 @@ status_t mediametrics::Item::Prop::writeToByteString(
|
|
|
|
|
char **bufferpptr, char *bufferptrmax) const
|
|
|
|
|
{
|
|
|
|
|
switch (mType) {
|
|
|
|
|
case kTypeInt32:
|
|
|
|
|
return BaseItem::writeToByteString(mName, u.int32Value, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeInt64:
|
|
|
|
|
return BaseItem::writeToByteString(mName, u.int64Value, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeDouble:
|
|
|
|
|
return BaseItem::writeToByteString(mName, u.doubleValue, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeRate:
|
|
|
|
|
return BaseItem::writeToByteString(mName, u.rate, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeCString:
|
|
|
|
|
return BaseItem::writeToByteString(mName, u.CStringValue, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeNone:
|
|
|
|
|
return BaseItem::writeToByteString(mName, none_t{}, bufferpptr, bufferptrmax);
|
|
|
|
|
case mediametrics::kTypeInt32:
|
|
|
|
|
return BaseItem::writeToByteString(mName.c_str(), u.int32Value, bufferpptr, bufferptrmax);
|
|
|
|
|
case mediametrics::kTypeInt64:
|
|
|
|
|
return BaseItem::writeToByteString(mName.c_str(), u.int64Value, bufferpptr, bufferptrmax);
|
|
|
|
|
case mediametrics::kTypeDouble:
|
|
|
|
|
return BaseItem::writeToByteString(mName.c_str(), u.doubleValue, bufferpptr, bufferptrmax);
|
|
|
|
|
case mediametrics::kTypeRate:
|
|
|
|
|
return BaseItem::writeToByteString(mName.c_str(), u.rate, bufferpptr, bufferptrmax);
|
|
|
|
|
case mediametrics::kTypeCString:
|
|
|
|
|
return BaseItem::writeToByteString(
|
|
|
|
|
mName.c_str(), u.CStringValue, bufferpptr, bufferptrmax);
|
|
|
|
|
case mediametrics::kTypeNone:
|
|
|
|
|
return BaseItem::writeToByteString(mName.c_str(), none_t{}, bufferpptr, bufferptrmax);
|
|
|
|
|
default:
|
|
|
|
|
ALOGE("%s: found bad prop type: %d, name %s",
|
|
|
|
|
__func__, mType, mName); // no payload sent
|
|
|
|
|
__func__, mType, mName.c_str()); // no payload sent
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -999,35 +812,32 @@ status_t mediametrics::Item::Prop::readFromByteString(
|
|
|
|
|
?: extract(&type, bufferpptr, bufferptrmax)
|
|
|
|
|
?: extract(&name, bufferpptr, bufferptrmax);
|
|
|
|
|
if (status != NO_ERROR) return status;
|
|
|
|
|
if (mName != nullptr) {
|
|
|
|
|
free(mName);
|
|
|
|
|
}
|
|
|
|
|
mName = name;
|
|
|
|
|
if (mType == kTypeCString) {
|
|
|
|
|
if (mType == mediametrics::kTypeCString) {
|
|
|
|
|
free(u.CStringValue);
|
|
|
|
|
u.CStringValue = nullptr;
|
|
|
|
|
}
|
|
|
|
|
mType = (Type)type;
|
|
|
|
|
mType = (mediametrics::Type)type;
|
|
|
|
|
switch (mType) {
|
|
|
|
|
case kTypeInt32:
|
|
|
|
|
case mediametrics::kTypeInt32:
|
|
|
|
|
return extract(&u.int32Value, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeInt64:
|
|
|
|
|
case mediametrics::kTypeInt64:
|
|
|
|
|
return extract(&u.int64Value, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeDouble:
|
|
|
|
|
case mediametrics::kTypeDouble:
|
|
|
|
|
return extract(&u.doubleValue, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeRate:
|
|
|
|
|
case mediametrics::kTypeRate:
|
|
|
|
|
return extract(&u.rate.first, bufferpptr, bufferptrmax)
|
|
|
|
|
?: extract(&u.rate.second, bufferpptr, bufferptrmax);
|
|
|
|
|
case kTypeCString:
|
|
|
|
|
case mediametrics::kTypeCString:
|
|
|
|
|
status = extract(&u.CStringValue, bufferpptr, bufferptrmax);
|
|
|
|
|
if (status != NO_ERROR) mType = kTypeNone;
|
|
|
|
|
if (status != NO_ERROR) mType = mediametrics::kTypeNone;
|
|
|
|
|
return status;
|
|
|
|
|
case kTypeNone:
|
|
|
|
|
case mediametrics::kTypeNone:
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
default:
|
|
|
|
|
mType = kTypeNone;
|
|
|
|
|
mType = mediametrics::kTypeNone;
|
|
|
|
|
ALOGE("%s: found bad prop type: %d, name %s",
|
|
|
|
|
__func__, mType, mName); // no payload sent
|
|
|
|
|
__func__, mType, mName.c_str()); // no payload sent
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|