c535a55cd6
implement a missing method (for inflight metrics), enumerate exported symbols. Reconcile common source files core/jni/android_media_MediaMetricsJNI and media/jni/android_media_MediaMetricsJNI use new "libmediametrics_stable" library for mediaplayer2 Bug: 119675363 Test: build, CTS media/codec tests Change-Id: Ide72dfe891231c3764329686955e1b4682094b1e
229 lines
8.2 KiB
C++
229 lines
8.2 KiB
C++
/*
|
|
* Copyright 2017, The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define LOG_TAG "MediaMetricsJNI"
|
|
|
|
#include <jni.h>
|
|
#include <nativehelper/JNIHelp.h>
|
|
|
|
#include "android_media_MediaMetricsJNI.h"
|
|
#include <media/MediaAnalyticsItem.h>
|
|
|
|
|
|
// This source file is compiled and linked into both:
|
|
// core/jni/ (libandroid_runtime.so)
|
|
// media/jni (libmedia2_jni.so)
|
|
|
|
namespace android {
|
|
|
|
// place the attributes into a java PersistableBundle object
|
|
jobject MediaMetricsJNI::writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle) {
|
|
|
|
jclass clazzBundle = env->FindClass("android/os/PersistableBundle");
|
|
if (clazzBundle==NULL) {
|
|
ALOGE("can't find android/os/PersistableBundle");
|
|
return NULL;
|
|
}
|
|
// sometimes the caller provides one for us to fill
|
|
if (mybundle == NULL) {
|
|
// create the bundle
|
|
jmethodID constructID = env->GetMethodID(clazzBundle, "<init>", "()V");
|
|
mybundle = env->NewObject(clazzBundle, constructID);
|
|
if (mybundle == NULL) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// grab methods that we can invoke
|
|
jmethodID setIntID = env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V");
|
|
jmethodID setLongID = env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V");
|
|
jmethodID setDoubleID = env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V");
|
|
jmethodID setStringID = env->GetMethodID(clazzBundle, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");
|
|
|
|
// env, class, method, {parms}
|
|
//env->CallVoidMethod(env, mybundle, setIntID, jstr, jint);
|
|
|
|
// iterate through my attributes
|
|
// -- get name, get type, get value
|
|
// -- insert appropriately into the bundle
|
|
for (size_t i = 0 ; i < item->mPropCount; i++ ) {
|
|
MediaAnalyticsItem::Prop *prop = &item->mProps[i];
|
|
// build the key parameter from prop->mName
|
|
jstring keyName = env->NewStringUTF(prop->mName);
|
|
// invoke the appropriate method to insert
|
|
switch (prop->mType) {
|
|
case MediaAnalyticsItem::kTypeInt32:
|
|
env->CallVoidMethod(mybundle, setIntID,
|
|
keyName, (jint) prop->u.int32Value);
|
|
break;
|
|
case MediaAnalyticsItem::kTypeInt64:
|
|
env->CallVoidMethod(mybundle, setLongID,
|
|
keyName, (jlong) prop->u.int64Value);
|
|
break;
|
|
case MediaAnalyticsItem::kTypeDouble:
|
|
env->CallVoidMethod(mybundle, setDoubleID,
|
|
keyName, (jdouble) prop->u.doubleValue);
|
|
break;
|
|
case MediaAnalyticsItem::kTypeCString:
|
|
env->CallVoidMethod(mybundle, setStringID, keyName,
|
|
env->NewStringUTF(prop->u.CStringValue));
|
|
break;
|
|
default:
|
|
ALOGE("to_String bad item type: %d for %s",
|
|
prop->mType, prop->mName);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mybundle;
|
|
}
|
|
|
|
// convert the specified batch metrics attributes to a persistent bundle.
|
|
// The encoding of the byte array is specified in
|
|
// frameworks/av/media/libmediametrics/MediaAnalyticsItem.cpp
|
|
//
|
|
// type encodings; matches frameworks/av/media/libmediametrics/MediaAnalyticsItem.cpp
|
|
enum { kInt32 = 0, kInt64, kDouble, kRate, kCString};
|
|
|
|
jobject MediaMetricsJNI::writeAttributesToBundle(JNIEnv* env, jobject mybundle, char *buffer, size_t length) {
|
|
ALOGV("writeAttributes()");
|
|
|
|
if (buffer == NULL || length <= 0) {
|
|
ALOGW("bad parameters to writeAttributesToBundle()");
|
|
return NULL;
|
|
}
|
|
|
|
jclass clazzBundle = env->FindClass("android/os/PersistableBundle");
|
|
if (clazzBundle==NULL) {
|
|
ALOGE("can't find android/os/PersistableBundle");
|
|
return NULL;
|
|
}
|
|
// sometimes the caller provides one for us to fill
|
|
if (mybundle == NULL) {
|
|
// create the bundle
|
|
jmethodID constructID = env->GetMethodID(clazzBundle, "<init>", "()V");
|
|
mybundle = env->NewObject(clazzBundle, constructID);
|
|
if (mybundle == NULL) {
|
|
ALOGD("unable to create mybundle");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
int left = length;
|
|
char *buf = buffer;
|
|
|
|
// grab methods that we can invoke
|
|
jmethodID setIntID = env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V");
|
|
jmethodID setLongID = env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V");
|
|
jmethodID setDoubleID = env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V");
|
|
jmethodID setStringID = env->GetMethodID(clazzBundle, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");
|
|
|
|
|
|
#define _EXTRACT(size, val) \
|
|
{ if ((size) > left) goto badness; memcpy(&val, buf, (size)); buf += (size); left -= (size);}
|
|
#define _SKIP(size) \
|
|
{ if ((size) > left) goto badness; buf += (size); left -= (size);}
|
|
|
|
int32_t bufsize;
|
|
_EXTRACT(sizeof(int32_t), bufsize);
|
|
if (bufsize != length) {
|
|
goto badness;
|
|
}
|
|
int32_t proto;
|
|
_EXTRACT(sizeof(int32_t), proto);
|
|
if (proto != 0) {
|
|
ALOGE("unsupported wire protocol %d", proto);
|
|
goto badness;
|
|
}
|
|
|
|
int32_t count;
|
|
_EXTRACT(sizeof(int32_t), count);
|
|
|
|
// iterate through my attributes
|
|
// -- get name, get type, get value, insert into bundle appropriately.
|
|
for (int i = 0 ; i < count; i++ ) {
|
|
// prop name len (int16)
|
|
int16_t keylen;
|
|
_EXTRACT(sizeof(int16_t), keylen);
|
|
if (keylen <= 0) goto badness;
|
|
// prop name itself
|
|
char *key = buf;
|
|
jstring keyName = env->NewStringUTF(buf);
|
|
_SKIP(keylen);
|
|
|
|
// prop type (int8_t)
|
|
int8_t attrType;
|
|
_EXTRACT(sizeof(int8_t), attrType);
|
|
|
|
int16_t attrSize;
|
|
_EXTRACT(sizeof(int16_t), attrSize);
|
|
|
|
switch (attrType) {
|
|
case kInt32:
|
|
{
|
|
int32_t i32;
|
|
_EXTRACT(sizeof(int32_t), i32);
|
|
env->CallVoidMethod(mybundle, setIntID,
|
|
keyName, (jint) i32);
|
|
break;
|
|
}
|
|
case kInt64:
|
|
{
|
|
int64_t i64;
|
|
_EXTRACT(sizeof(int64_t), i64);
|
|
env->CallVoidMethod(mybundle, setLongID,
|
|
keyName, (jlong) i64);
|
|
break;
|
|
}
|
|
case kDouble:
|
|
{
|
|
double d64;
|
|
_EXTRACT(sizeof(double), d64);
|
|
env->CallVoidMethod(mybundle, setDoubleID,
|
|
keyName, (jdouble) d64);
|
|
break;
|
|
}
|
|
case kCString:
|
|
{
|
|
jstring value = env->NewStringUTF(buf);
|
|
env->CallVoidMethod(mybundle, setStringID,
|
|
keyName, value);
|
|
_SKIP(attrSize);
|
|
break;
|
|
}
|
|
default:
|
|
ALOGW("ignoring Attribute '%s' unknown type: %d",
|
|
key, attrType);
|
|
_SKIP(attrSize);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// should have consumed it all
|
|
if (left != 0) {
|
|
ALOGW("did not consume entire buffer; left(%d) != 0", left);
|
|
goto badness;
|
|
}
|
|
|
|
return mybundle;
|
|
|
|
badness:
|
|
return NULL;
|
|
}
|
|
|
|
}; // namespace android
|
|
|