android_media_Utils.cpp revision b842599e51e2d3611503c3c7db1111358f99186d
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 8807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jobject makeLongObject(JNIEnv *env, int64_t value) { 8907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber jclass clazz = env->FindClass("java/lang/Long"); 9007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(clazz != NULL); 9107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 9207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber jmethodID longConstructID = env->GetMethodID(clazz, "<init>", "(J)V"); 9307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(longConstructID != NULL); 9407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 9507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return env->NewObject(clazz, longConstructID, value); 9607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber} 9707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeFloatObject(JNIEnv *env, float value) { 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("java/lang/Float"); 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatConstructID = env->GetMethodID(clazz, "<init>", "(F)V"); 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatConstructID != NULL); 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return env->NewObject(clazz, floatConstructID, value); 10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeByteBufferObject( 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const void *data, size_t size) { 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArrayObj = env->NewByteArray(size); 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data); 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("java/nio/ByteBuffer"); 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID byteBufWrapID = 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetStaticMethodID(clazz, "wrap", "([B)Ljava/nio/ByteBuffer;"); 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufWrapID != NULL); 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBufObj = env->CallStaticObjectMethod( 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber clazz, byteBufWrapID, byteArrayObj); 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL; 12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return byteBufObj; 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 128b842599e51e2d3611503c3c7db1111358f99186dAndreas Huberstatic void SetMapInt32( 129b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID, 130b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber const char *key, int32_t value) { 131b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jstring keyObj = env->NewStringUTF(key); 132b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jobject valueObj = makeIntegerObject(env, value); 133b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 134b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jobject res = env->CallObjectMethod( 135b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapObj, hashMapPutID, keyObj, valueObj); 136b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 137b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 138b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 139b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber} 140b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertMessageToMap( 14288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const sp<AMessage> &msg, jobject *map) { 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass hashMapClazz = env->FindClass("java/util/HashMap"); 14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapClazz == NULL) { 14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapConstructID = 15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(hashMapClazz, "<init>", "()V"); 15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapConstructID == NULL) { 15388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 15488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 15588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapPutID = 15788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID( 15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber hashMapClazz, 15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "put", 16088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapPutID == NULL) { 16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject hashMap = env->NewObject(hashMapClazz, hashMapConstructID); 16788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < msg->countEntries(); ++i) { 16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AMessage::Type valueType; 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *key = msg->getEntryNameAt(i, &valueType); 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = NULL; 17388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (valueType) { 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeInt32: 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int32_t val; 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findInt32(key, &val)); 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeIntegerObject(env, val); 18107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber break; 18207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 18307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 18407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber case AMessage::kTypeInt64: 18507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber { 18607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber int64_t val; 18707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(msg->findInt64(key, &val)); 18807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 18907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber valueObj = makeLongObject(env, val); 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeFloat: 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber float val; 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findFloat(key, &val)); 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeFloatObject(env, val); 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeString: 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString val; 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findString(key, &val)); 20688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = env->NewStringUTF(val.c_str()); 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2115c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber case AMessage::kTypeBuffer: 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 2135c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber sp<ABuffer> buffer; 2145c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber CHECK(msg->findBuffer(key, &buffer)); 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeByteBufferObject( 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, buffer->data(), buffer->size()); 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 221b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber case AMessage::kTypeRect: 222b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber { 223b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber int32_t left, top, right, bottom; 224b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber CHECK(msg->findRect(key, &left, &top, &right, &bottom)); 225b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 226b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 227b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 228b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 229b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 230b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber StringPrintf("%s-left", key).c_str(), 231b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber left); 232b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 233b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 234b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 235b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 236b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 237b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber StringPrintf("%s-top", key).c_str(), 238b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber top); 239b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 240b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 241b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 242b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 243b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 244b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber StringPrintf("%s-right", key).c_str(), 245b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber right); 246b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 247b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 248b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 249b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 250b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 251b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber StringPrintf("%s-bottom", key).c_str(), 252b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber bottom); 253b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber break; 254b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber } 255b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (valueObj != NULL) { 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring keyObj = env->NewStringUTF(key); 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject res = env->CallObjectMethod( 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber hashMap, hashMapPutID, keyObj, valueObj); 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 27088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *map = hashMap; 27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 27488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 27588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertKeyValueArraysToMessage( 27788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobjectArray keys, jobjectArray values, 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> *out) { 27988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass stringClass = env->FindClass("java/lang/String"); 28088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(stringClass != NULL); 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass integerClass = env->FindClass("java/lang/Integer"); 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(integerClass != NULL); 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass floatClass = env->FindClass("java/lang/Float"); 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatClass != NULL); 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass byteBufClass = env->FindClass("java/nio/ByteBuffer"); 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufClass != NULL); 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg = new AMessage; 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jsize numEntries = 0; 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (keys != NULL) { 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (values == NULL) { 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber numEntries = env->GetArrayLength(keys); 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (numEntries != env->GetArrayLength(values)) { 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (values != NULL) { 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (jsize i = 0; i < numEntries; ++i) { 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject keyObj = env->GetObjectArrayElement(keys, i); 31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (!env->IsInstanceOf(keyObj, stringClass)) { 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL); 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString key = tmp; 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)keyObj, tmp); 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = env->GetObjectArrayElement(values, i); 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (env->IsInstanceOf(valueObj, stringClass)) { 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *value = env->GetStringUTFChars((jstring)valueObj, NULL); 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (value == NULL) { 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setString(key.c_str(), value); 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)valueObj, value); 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber value = NULL; 34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (env->IsInstanceOf(valueObj, integerClass)) { 34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID intValueID = 34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(integerClass, "intValue", "()I"); 34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(intValueID != NULL); 34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint value = env->CallIntMethod(valueObj, intValueID); 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setInt32(key.c_str(), value); 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (env->IsInstanceOf(valueObj, floatClass)) { 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatValueID = 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(floatClass, "floatValue", "()F"); 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatValueID != NULL); 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfloat value = env->CallFloatMethod(valueObj, floatValueID); 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setFloat(key.c_str(), value); 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (env->IsInstanceOf(valueObj, byteBufClass)) { 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID positionID = 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(byteBufClass, "position", "()I"); 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(positionID != NULL); 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID limitID = 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(byteBufClass, "limit", "()I"); 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(limitID != NULL); 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint position = env->CallIntMethod(valueObj, positionID); 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint limit = env->CallIntMethod(valueObj, limitID); 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ABuffer> buffer = new ABuffer(limit - position); 36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber void *data = env->GetDirectBufferAddress(valueObj); 37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (data != NULL) { 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber memcpy(buffer->data(), 37488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (const uint8_t *)data + position, 37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size()); 37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID arrayID = 37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID(byteBufClass, "array", "()[B"); 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(arrayID != NULL); 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArray = 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyteArray)env->CallObjectMethod(valueObj, arrayID); 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteArray != NULL); 38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetByteArrayRegion( 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteArray, 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber position, 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size(), 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyte *)buffer->data()); 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArray); byteArray = NULL; 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3949b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber msg->setBuffer(key.c_str(), buffer); 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *out = msg; 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} // namespace android 40479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 405