diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 99394adec27db..3833c6bfb6764 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -211,48 +211,6 @@ static fields_t gFields; namespace { -// Helper function to convert a native PersistableBundle to a Java -// PersistableBundle. -jobject nativeToJavaPersistableBundle(JNIEnv *env, jobject thiz, - PersistableBundle* nativeBundle) { - if (env == NULL || thiz == NULL || nativeBundle == NULL) { - ALOGE("Unexpected NULL parmeter"); - return NULL; - } - - // Create a Java parcel with the native parcel data. - // Then create a new PersistableBundle with that parcel as a parameter. - jobject jParcel = android::createJavaParcelObject(env); - if (jParcel == NULL) { - ALOGE("Failed to create a Java Parcel."); - return NULL; - } - - android::Parcel* nativeParcel = android::parcelForJavaObject(env, jParcel); - if (nativeParcel == NULL) { - ALOGE("Failed to get the native Parcel."); - return NULL; - } - - android::status_t result = nativeBundle->writeToParcel(nativeParcel); - nativeParcel->setDataPosition(0); - if (result != android::OK) { - ALOGE("Failed to write nativeBundle to Parcel: %d.", result); - return NULL; - } - - jobject newBundle = env->CallObjectMethod(gFields.bundleCreator, - gFields.createFromParcelId, - jParcel); - if (newBundle == NULL) { - ALOGE("Failed to create a new PersistableBundle " - "from the createFromParcel call."); - } - - return newBundle; -} - - jbyteArray hidlVectorToJByteArray(const hardware::hidl_vec &vector) { JNIEnv *env = AndroidRuntime::getJNIEnv(); size_t length = vector.size(); @@ -1937,7 +1895,7 @@ android_media_MediaDrm_native_getMetrics(JNIEnv *env, jobject thiz) return (jobject) NULL; } - return nativeToJavaPersistableBundle(env, thiz, &metrics); + return MediaMetricsJNI::nativeToJavaPersistableBundle(env, &metrics); } static jbyteArray android_media_MediaDrm_signRSANative( diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp index e7487c3cbc67c..5ddfcfce072ec 100644 --- a/media/jni/android_media_MediaMetricsJNI.cpp +++ b/media/jni/android_media_MediaMetricsJNI.cpp @@ -20,7 +20,9 @@ #include #include "android_media_MediaMetricsJNI.h" +#include "android_os_Parcel.h" #include +#include // This source file is compiled and linked into: @@ -223,5 +225,72 @@ jobject MediaMetricsJNI::writeAttributesToBundle(JNIEnv* env, jobject mybundle, return NULL; } +// Helper function to convert a native PersistableBundle to a Java +// PersistableBundle. +jobject MediaMetricsJNI::nativeToJavaPersistableBundle(JNIEnv *env, + os::PersistableBundle* nativeBundle) { + if (env == NULL || nativeBundle == NULL) { + ALOGE("Unexpected NULL parmeter"); + return NULL; + } + + // Create a Java parcel with the native parcel data. + // Then create a new PersistableBundle with that parcel as a parameter. + jobject jParcel = android::createJavaParcelObject(env); + if (jParcel == NULL) { + ALOGE("Failed to create a Java Parcel."); + return NULL; + } + + android::Parcel* nativeParcel = android::parcelForJavaObject(env, jParcel); + if (nativeParcel == NULL) { + ALOGE("Failed to get the native Parcel."); + return NULL; + } + + android::status_t result = nativeBundle->writeToParcel(nativeParcel); + nativeParcel->setDataPosition(0); + if (result != android::OK) { + ALOGE("Failed to write nativeBundle to Parcel: %d.", result); + return NULL; + } + +#define STATIC_INIT_JNI(T, obj, method, globalref, ...) \ + static T obj{};\ + if (obj == NULL) { \ + obj = method(__VA_ARGS__); \ + if (obj == NULL) { \ + ALOGE("%s can't find " #obj, __func__); \ + return NULL; \ + } else { \ + obj = globalref; \ + }\ + } \ + + STATIC_INIT_JNI(jclass, clazzBundle, env->FindClass, + static_cast(env->NewGlobalRef(clazzBundle)), + "android/os/PersistableBundle"); + STATIC_INIT_JNI(jfieldID, bundleCreatorId, env->GetStaticFieldID, + bundleCreatorId, + clazzBundle, "CREATOR", "Landroid/os/Parcelable$Creator;"); + STATIC_INIT_JNI(jobject, bundleCreator, env->GetStaticObjectField, + env->NewGlobalRef(bundleCreator), + clazzBundle, bundleCreatorId); + STATIC_INIT_JNI(jclass, clazzCreator, env->FindClass, + static_cast(env->NewGlobalRef(clazzCreator)), + "android/os/Parcelable$Creator"); + STATIC_INIT_JNI(jmethodID, createFromParcelId, env->GetMethodID, + createFromParcelId, + clazzCreator, "createFromParcel", "(Landroid/os/Parcel;)Ljava/lang/Object;"); + + jobject newBundle = env->CallObjectMethod(bundleCreator, createFromParcelId, jParcel); + if (newBundle == NULL) { + ALOGE("Failed to create a new PersistableBundle " + "from the createFromParcel call."); + } + + return newBundle; +} + }; // namespace android diff --git a/media/jni/android_media_MediaMetricsJNI.h b/media/jni/android_media_MediaMetricsJNI.h index a10780f5c5c3c..e879da01c6ef2 100644 --- a/media/jni/android_media_MediaMetricsJNI.h +++ b/media/jni/android_media_MediaMetricsJNI.h @@ -20,6 +20,7 @@ #include #include #include +#include // Copeid from core/jni/ (libandroid_runtime.so) namespace android { @@ -28,6 +29,7 @@ class MediaMetricsJNI { public: static jobject writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle); static jobject writeAttributesToBundle(JNIEnv* env, jobject mybundle, char *buffer, size_t length); + static jobject nativeToJavaPersistableBundle(JNIEnv*, os::PersistableBundle*); }; }; // namespace android