android_media_Utils.cpp revision 88572f7a3e9d7ef85c26865a0150f3c2041561c2
179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong/* 279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * Copyright 2011, The Android Open Source Project 379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * 479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * you may not use this file except in compliance with the License. 679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * You may obtain a copy of the License at 779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * 879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * http://www.apache.org/licenses/LICENSE-2.0 979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * 1079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * Unless required by applicable law or agreed to in writing, software 1179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * See the License for the specific language governing permissions and 1479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * limitations under the License. 1579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong */ 1679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 1779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong// #define LOG_NDEBUG 0 1879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong#define LOG_TAG "AndroidMediaUtils" 1979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 2079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong#include <utils/Log.h> 2179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong#include "android_media_Utils.h" 2279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 2388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongnamespace android { 2879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 2979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongbool ConvertKeyValueArraysToKeyedVector( 3079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong JNIEnv *env, jobjectArray keys, jobjectArray values, 3179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong KeyedVector<String8, String8>* keyedVector) { 3279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 3379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong int nKeyValuePairs = 0; 3479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong bool failed = false; 3579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (keys != NULL && values != NULL) { 3679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong nKeyValuePairs = env->GetArrayLength(keys); 3779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = (nKeyValuePairs != env->GetArrayLength(values)); 3879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 3979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 4079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!failed) { 4179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = ((keys != NULL && values == NULL) || 4279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong (keys == NULL && values != NULL)); 4379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 4479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 4579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (failed) { 463762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("keys and values arrays have different length"); 4779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 4879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 4979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 5079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 5179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong for (int i = 0; i < nKeyValuePairs; ++i) { 5279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // No need to check on the ArrayIndexOutOfBoundsException, since 5379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // it won't happen here. 5479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring key = (jstring) env->GetObjectArrayElement(keys, i); 5579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring value = (jstring) env->GetObjectArrayElement(values, i); 5679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 5779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* keyStr = env->GetStringUTFChars(key, NULL); 5879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!keyStr) { // OutOfMemoryError 5979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 6079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 6179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 6279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* valueStr = env->GetStringUTFChars(value, NULL); 6379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!valueStr) { // OutOfMemoryError 6479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 6579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 6679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 6779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 6879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong keyedVector->add(String8(keyStr), String8(valueStr)); 6979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 7079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 7179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(value, valueStr); 7279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(key); 7379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(value); 7479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 7579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return true; 7679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} 7779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeIntegerObject(JNIEnv *env, int32_t value) { 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("java/lang/Integer"); 8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID integerConstructID = env->GetMethodID(clazz, "<init>", "(I)V"); 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(integerConstructID != NULL); 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return env->NewObject(clazz, integerConstructID, value); 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeFloatObject(JNIEnv *env, float value) { 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("java/lang/Float"); 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatConstructID = env->GetMethodID(clazz, "<init>", "(F)V"); 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatConstructID != NULL); 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return env->NewObject(clazz, floatConstructID, value); 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeByteBufferObject( 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const void *data, size_t size) { 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArrayObj = env->NewByteArray(size); 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data); 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("java/nio/ByteBuffer"); 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID byteBufWrapID = 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetStaticMethodID(clazz, "wrap", "([B)Ljava/nio/ByteBuffer;"); 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufWrapID != NULL); 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBufObj = env->CallStaticObjectMethod( 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber clazz, byteBufWrapID, byteArrayObj); 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL; 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return byteBufObj; 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertMessageToMap( 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const sp<AMessage> &msg, jobject *map) { 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass hashMapClazz = env->FindClass("java/util/HashMap"); 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapClazz == NULL) { 12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapConstructID = 12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(hashMapClazz, "<init>", "()V"); 12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapConstructID == NULL) { 13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapPutID = 13488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID( 13588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber hashMapClazz, 13688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "put", 13788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 13888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapPutID == NULL) { 14088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 14288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject hashMap = env->NewObject(hashMapClazz, hashMapConstructID); 14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < msg->countEntries(); ++i) { 14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AMessage::Type valueType; 14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *key = msg->getEntryNameAt(i, &valueType); 14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = NULL; 15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (valueType) { 15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeInt32: 15388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 15488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int32_t val; 15588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findInt32(key, &val)); 15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeIntegerObject(env, val); 15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 16088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeFloat: 16288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber float val; 16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findFloat(key, &val)); 16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeFloatObject(env, val); 16788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 16888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeString: 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString val; 17388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findString(key, &val)); 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = env->NewStringUTF(val.c_str()); 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeObject: 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<RefBase> obj; 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findObject(key, &obj)); 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber // XXX dangerous, object is not guaranteed to be a buffer. 18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeByteBufferObject( 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, buffer->data(), buffer->size()); 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (valueObj != NULL) { 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring keyObj = env->NewStringUTF(key); 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject res = env->CallObjectMethod( 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber hashMap, hashMapPutID, keyObj, valueObj); 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 20688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *map = hashMap; 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertKeyValueArraysToMessage( 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobjectArray keys, jobjectArray values, 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> *out) { 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass stringClass = env->FindClass("java/lang/String"); 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(stringClass != NULL); 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass integerClass = env->FindClass("java/lang/Integer"); 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(integerClass != NULL); 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass floatClass = env->FindClass("java/lang/Float"); 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatClass != NULL); 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass byteBufClass = env->FindClass("java/nio/ByteBuffer"); 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufClass != NULL); 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg = new AMessage; 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jsize numEntries = 0; 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (keys != NULL) { 23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (values == NULL) { 23388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 23588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber numEntries = env->GetArrayLength(keys); 23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (numEntries != env->GetArrayLength(values)) { 23988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 24088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (values != NULL) { 24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (jsize i = 0; i < numEntries; ++i) { 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject keyObj = env->GetObjectArrayElement(keys, i); 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (!env->IsInstanceOf(keyObj, stringClass)) { 24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL); 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString key = tmp; 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)keyObj, tmp); 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = env->GetObjectArrayElement(values, i); 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (env->IsInstanceOf(valueObj, stringClass)) { 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *value = env->GetStringUTFChars((jstring)valueObj, NULL); 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (value == NULL) { 26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 27088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setString(key.c_str(), value); 27388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)valueObj, value); 27588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber value = NULL; 27688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (env->IsInstanceOf(valueObj, integerClass)) { 27788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID intValueID = 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(integerClass, "intValue", "()I"); 27988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(intValueID != NULL); 28088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint value = env->CallIntMethod(valueObj, intValueID); 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setInt32(key.c_str(), value); 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (env->IsInstanceOf(valueObj, floatClass)) { 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatValueID = 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(floatClass, "floatValue", "()F"); 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatValueID != NULL); 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfloat value = env->CallFloatMethod(valueObj, floatValueID); 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setFloat(key.c_str(), value); 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (env->IsInstanceOf(valueObj, byteBufClass)) { 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID positionID = 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(byteBufClass, "position", "()I"); 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(positionID != NULL); 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID limitID = 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(byteBufClass, "limit", "()I"); 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(limitID != NULL); 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint position = env->CallIntMethod(valueObj, positionID); 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint limit = env->CallIntMethod(valueObj, limitID); 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ABuffer> buffer = new ABuffer(limit - position); 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber void *data = env->GetDirectBufferAddress(valueObj); 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (data != NULL) { 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber memcpy(buffer->data(), 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (const uint8_t *)data + position, 31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size()); 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID arrayID = 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(byteBufClass, "array", "()[B"); 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(arrayID != NULL); 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArray = 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyteArray)env->CallObjectMethod(valueObj, arrayID); 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteArray != NULL); 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetByteArrayRegion( 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteArray, 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber position, 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size(), 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyte *)buffer->data()); 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArray); byteArray = NULL; 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setObject(key.c_str(), buffer); 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *out = msg; 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} // namespace android 34079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 341