diff options
| l---------[-rw-r--r--] | core/jni/android_media_MediaMetricsJNI.cpp | 91 | ||||
| l---------[-rw-r--r--] | core/jni/android_media_MediaMetricsJNI.h | 34 | ||||
| -rw-r--r-- | media/jni/Android.bp | 3 | ||||
| -rw-r--r-- | media/jni/android_media_MediaMetricsJNI.cpp | 142 | ||||
| -rw-r--r-- | media/jni/android_media_MediaMetricsJNI.h | 1 |
5 files changed, 145 insertions, 126 deletions
diff --git a/core/jni/android_media_MediaMetricsJNI.cpp b/core/jni/android_media_MediaMetricsJNI.cpp index 38f7a7e25389..3204317cab68 100644..120000 --- a/core/jni/android_media_MediaMetricsJNI.cpp +++ b/core/jni/android_media_MediaMetricsJNI.cpp @@ -1,90 +1 @@ -/* - * 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. - */ - -#include <android_runtime/AndroidRuntime.h> -#include <jni.h> -#include <nativehelper/JNIHelp.h> - -#include "android_media_MediaMetricsJNI.h" -#include <media/MediaAnalyticsItem.h> - - -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) { - ALOGD("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; -} - -}; // namespace android - +../../media/jni/android_media_MediaMetricsJNI.cpp
\ No newline at end of file diff --git a/core/jni/android_media_MediaMetricsJNI.h b/core/jni/android_media_MediaMetricsJNI.h index b3cb4d293399..c7a685beb7e5 100644..120000 --- a/core/jni/android_media_MediaMetricsJNI.h +++ b/core/jni/android_media_MediaMetricsJNI.h @@ -1,33 +1 @@ -/* - * 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. - */ - -#ifndef _ANDROID_MEDIA_MEDIAMETRICSJNI_H_ -#define _ANDROID_MEDIA_MEDIAMETRICSJNI_H_ - -#include <jni.h> -#include <nativehelper/JNIHelp.h> -#include <media/MediaAnalyticsItem.h> - -namespace android { - -class MediaMetricsJNI { -public: - static jobject writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle); -}; - -}; // namespace android - -#endif // _ANDROID_MEDIA_MEDIAMETRICSJNI_H_ +../../media/jni/android_media_MediaMetricsJNI.h
\ No newline at end of file diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 48dbf555e546..88ef30479674 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -101,7 +101,8 @@ cc_library_shared { "libhidlbase", "libhidlmemory", - "libmediametrics", // Used by MediaMetrics. Will be replaced with stable C API. + "libmediametrics_stable", + "libmediametrics", // until player2 starts calling the stable interface "libbinder", // Used by JWakeLock and MediaMetrics. "libutils", // Have to use shared lib to make libandroid_runtime behave correctly. diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp index 3ded8c260512..de60b085b87d 100644 --- a/media/jni/android_media_MediaMetricsJNI.cpp +++ b/media/jni/android_media_MediaMetricsJNI.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "MediaMetricsJNI" + #include <jni.h> #include <nativehelper/JNIHelp.h> @@ -21,7 +23,10 @@ #include <media/MediaAnalyticsItem.h> -// Copeid from core/jni/ (libandroid_runtime.so) +// 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 @@ -29,7 +34,7 @@ jobject MediaMetricsJNI::writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *i jclass clazzBundle = env->FindClass("android/os/PersistableBundle"); if (clazzBundle==NULL) { - ALOGD("can't find android/os/PersistableBundle"); + ALOGE("can't find android/os/PersistableBundle"); return NULL; } // sometimes the caller provides one for us to fill @@ -86,5 +91,138 @@ jobject MediaMetricsJNI::writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *i 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 diff --git a/media/jni/android_media_MediaMetricsJNI.h b/media/jni/android_media_MediaMetricsJNI.h index fd621ea7261d..a10780f5c5c3 100644 --- a/media/jni/android_media_MediaMetricsJNI.h +++ b/media/jni/android_media_MediaMetricsJNI.h @@ -27,6 +27,7 @@ namespace android { class MediaMetricsJNI { public: static jobject writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle); + static jobject writeAttributesToBundle(JNIEnv* env, jobject mybundle, char *buffer, size_t length); }; }; // namespace android |