android_media_Utils.cpp revision 8f7a8f1eba590f4a0bb21988fc2a876dcb72dccd
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 278d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h> 288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 2979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongnamespace android { 3079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 318409c0691fb128fef6244305977342776bddf919Jaesung ChungFileStream::FileStream(const String8 filename) 328409c0691fb128fef6244305977342776bddf919Jaesung Chung : mPosition(0), 338409c0691fb128fef6244305977342776bddf919Jaesung Chung mSize(0) { 348409c0691fb128fef6244305977342776bddf919Jaesung Chung mFile = fopen(filename.string(), "r"); 358409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile == NULL) { 368409c0691fb128fef6244305977342776bddf919Jaesung Chung return; 378409c0691fb128fef6244305977342776bddf919Jaesung Chung } 388409c0691fb128fef6244305977342776bddf919Jaesung Chung // Get the size. 398409c0691fb128fef6244305977342776bddf919Jaesung Chung fseek(mFile, 0l, SEEK_END); 408409c0691fb128fef6244305977342776bddf919Jaesung Chung mSize = ftell(mFile); 418409c0691fb128fef6244305977342776bddf919Jaesung Chung fseek(mFile, 0l, SEEK_SET); 428409c0691fb128fef6244305977342776bddf919Jaesung Chung} 438409c0691fb128fef6244305977342776bddf919Jaesung Chung 448409c0691fb128fef6244305977342776bddf919Jaesung ChungFileStream::~FileStream() { 458409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile != NULL) { 468409c0691fb128fef6244305977342776bddf919Jaesung Chung fclose(mFile); 478409c0691fb128fef6244305977342776bddf919Jaesung Chung mFile = NULL; 488409c0691fb128fef6244305977342776bddf919Jaesung Chung } 498409c0691fb128fef6244305977342776bddf919Jaesung Chung} 508409c0691fb128fef6244305977342776bddf919Jaesung Chung 518409c0691fb128fef6244305977342776bddf919Jaesung Chungpiex::Error FileStream::GetData( 528409c0691fb128fef6244305977342776bddf919Jaesung Chung const size_t offset, const size_t length, std::uint8_t* data) { 538409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile == NULL) { 548409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kFail; 558409c0691fb128fef6244305977342776bddf919Jaesung Chung } 568409c0691fb128fef6244305977342776bddf919Jaesung Chung 578409c0691fb128fef6244305977342776bddf919Jaesung Chung // Seek first. 588409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mPosition != offset) { 598409c0691fb128fef6244305977342776bddf919Jaesung Chung fseek(mFile, offset, SEEK_SET); 608409c0691fb128fef6244305977342776bddf919Jaesung Chung } 618409c0691fb128fef6244305977342776bddf919Jaesung Chung 628409c0691fb128fef6244305977342776bddf919Jaesung Chung // Read bytes. 638409c0691fb128fef6244305977342776bddf919Jaesung Chung size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile); 648409c0691fb128fef6244305977342776bddf919Jaesung Chung mPosition += size; 658409c0691fb128fef6244305977342776bddf919Jaesung Chung 668409c0691fb128fef6244305977342776bddf919Jaesung Chung // Handle errors. 678409c0691fb128fef6244305977342776bddf919Jaesung Chung if (ferror(mFile) || (size == 0 && feof(mFile))) { 688409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length); 698409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kFail; 708409c0691fb128fef6244305977342776bddf919Jaesung Chung } 718409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kOk; 728409c0691fb128fef6244305977342776bddf919Jaesung Chung} 738409c0691fb128fef6244305977342776bddf919Jaesung Chung 748409c0691fb128fef6244305977342776bddf919Jaesung Chungbool FileStream::exists() const { 758409c0691fb128fef6244305977342776bddf919Jaesung Chung return mFile != NULL; 768409c0691fb128fef6244305977342776bddf919Jaesung Chung} 778409c0691fb128fef6244305977342776bddf919Jaesung Chung 788409c0691fb128fef6244305977342776bddf919Jaesung Chungsize_t FileStream::size() const { 798409c0691fb128fef6244305977342776bddf919Jaesung Chung return mSize; 808409c0691fb128fef6244305977342776bddf919Jaesung Chung} 818409c0691fb128fef6244305977342776bddf919Jaesung Chung 828409c0691fb128fef6244305977342776bddf919Jaesung Chungbool GetExifFromRawImage( 83d4c505c9b4d5b0e743301e3f385895efdb9785d4Jaesung Chung FileStream* stream, const String8& filename, piex::PreviewImageData& image_data) { 848f7a8f1eba590f4a0bb21988fc2a876dcb72dccdAnton Daubert // Reset the PreviewImageData to its default. 858f7a8f1eba590f4a0bb21988fc2a876dcb72dccdAnton Daubert image_data = piex::PreviewImageData(); 868409c0691fb128fef6244305977342776bddf919Jaesung Chung 878409c0691fb128fef6244305977342776bddf919Jaesung Chung if (!stream->exists()) { 888409c0691fb128fef6244305977342776bddf919Jaesung Chung // File is not exists. 898409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("File is not exists: %s", filename.string()); 908409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 918409c0691fb128fef6244305977342776bddf919Jaesung Chung } 928409c0691fb128fef6244305977342776bddf919Jaesung Chung 938409c0691fb128fef6244305977342776bddf919Jaesung Chung if (!piex::IsRaw(stream)) { 948409c0691fb128fef6244305977342776bddf919Jaesung Chung // Format not supported. 958409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Format not supported: %s", filename.string()); 968409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 978409c0691fb128fef6244305977342776bddf919Jaesung Chung } 988409c0691fb128fef6244305977342776bddf919Jaesung Chung 998409c0691fb128fef6244305977342776bddf919Jaesung Chung piex::Error err = piex::GetPreviewImageData(stream, &image_data); 1008409c0691fb128fef6244305977342776bddf919Jaesung Chung 1018409c0691fb128fef6244305977342776bddf919Jaesung Chung if (err != piex::Error::kOk) { 1028409c0691fb128fef6244305977342776bddf919Jaesung Chung // The input data seems to be broken. 1038409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err); 1048409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 1058409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1068409c0691fb128fef6244305977342776bddf919Jaesung Chung 1078409c0691fb128fef6244305977342776bddf919Jaesung Chung if (image_data.thumbnail_offset + image_data.thumbnail_length > stream->size()) { 1088409c0691fb128fef6244305977342776bddf919Jaesung Chung // Corrupted image. 1098409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Corrupted file: %s", filename.string()); 1108409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 1118409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1128409c0691fb128fef6244305977342776bddf919Jaesung Chung 1138409c0691fb128fef6244305977342776bddf919Jaesung Chung return true; 1148409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1158409c0691fb128fef6244305977342776bddf919Jaesung Chung 11679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongbool ConvertKeyValueArraysToKeyedVector( 11779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong JNIEnv *env, jobjectArray keys, jobjectArray values, 11879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong KeyedVector<String8, String8>* keyedVector) { 11979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 12079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong int nKeyValuePairs = 0; 12179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong bool failed = false; 12279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (keys != NULL && values != NULL) { 12379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong nKeyValuePairs = env->GetArrayLength(keys); 12479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = (nKeyValuePairs != env->GetArrayLength(values)); 12579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 12679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 12779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!failed) { 12879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = ((keys != NULL && values == NULL) || 12979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong (keys == NULL && values != NULL)); 13079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 13179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 13279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (failed) { 1333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("keys and values arrays have different length"); 13479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 13579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 13679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 13779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 13879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong for (int i = 0; i < nKeyValuePairs; ++i) { 13979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // No need to check on the ArrayIndexOutOfBoundsException, since 14079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // it won't happen here. 14179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring key = (jstring) env->GetObjectArrayElement(keys, i); 14279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring value = (jstring) env->GetObjectArrayElement(values, i); 14379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 14479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* keyStr = env->GetStringUTFChars(key, NULL); 14579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!keyStr) { // OutOfMemoryError 14679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 14779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 14879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 14979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* valueStr = env->GetStringUTFChars(value, NULL); 15079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!valueStr) { // OutOfMemoryError 15179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 15279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 15379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 15479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 15579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong keyedVector->add(String8(keyStr), String8(valueStr)); 15679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 15779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 15879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(value, valueStr); 15979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(key); 16079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(value); 16179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 16279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return true; 16379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} 16479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeIntegerObject(JNIEnv *env, int32_t value) { 1668d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer")); 1678d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 16888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1698d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID integerConstructID = 1708d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(I)V"); 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(integerConstructID != NULL); 17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1738d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), integerConstructID, value); 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jobject makeLongObject(JNIEnv *env, int64_t value) { 1778d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long")); 1788d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 17907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 1808d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V"); 18107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(longConstructID != NULL); 18207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 1838d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), longConstructID, value); 18407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber} 18507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeFloatObject(JNIEnv *env, float value) { 1878d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float")); 1888d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1908d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID floatConstructID = 1918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(F)V"); 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatConstructID != NULL); 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1948d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), floatConstructID, value); 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeByteBufferObject( 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const void *data, size_t size) { 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArrayObj = env->NewByteArray(size); 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data); 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2028d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer")); 2038d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID byteBufWrapID = 2068d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticMethodID( 2078d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;"); 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufWrapID != NULL); 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBufObj = env->CallStaticObjectMethod( 2118d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.get(), byteBufWrapID, byteArrayObj); 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL; 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return byteBufObj; 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 218b842599e51e2d3611503c3c7db1111358f99186dAndreas Huberstatic void SetMapInt32( 219b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID, 220b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber const char *key, int32_t value) { 221b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jstring keyObj = env->NewStringUTF(key); 222b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jobject valueObj = makeIntegerObject(env, value); 223b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 2245a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj); 225b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 226b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 227b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 228b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber} 229b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertMessageToMap( 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const sp<AMessage> &msg, jobject *map) { 2328d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> hashMapClazz( 2338d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("java/util/HashMap")); 23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2358d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (hashMapClazz.get() == NULL) { 23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapConstructID = 2408d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(hashMapClazz.get(), "<init>", "()V"); 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapConstructID == NULL) { 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapPutID = 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID( 2488d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber hashMapClazz.get(), 24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "put", 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapPutID == NULL) { 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2568d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID); 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < msg->countEntries(); ++i) { 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AMessage::Type valueType; 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *key = msg->getEntryNameAt(i, &valueType); 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = NULL; 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (valueType) { 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeInt32: 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int32_t val; 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findInt32(key, &val)); 26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeIntegerObject(env, val); 27107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber break; 27207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 27307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 27407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber case AMessage::kTypeInt64: 27507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber { 27607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber int64_t val; 27707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(msg->findInt64(key, &val)); 27807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 27907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber valueObj = makeLongObject(env, val); 28088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeFloat: 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber float val; 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findFloat(key, &val)); 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeFloatObject(env, val); 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeString: 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString val; 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findString(key, &val)); 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = env->NewStringUTF(val.c_str()); 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3015c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber case AMessage::kTypeBuffer: 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 3035c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber sp<ABuffer> buffer; 3045c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber CHECK(msg->findBuffer(key, &buffer)); 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeByteBufferObject( 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, buffer->data(), buffer->size()); 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 311b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber case AMessage::kTypeRect: 312b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber { 313b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber int32_t left, top, right, bottom; 314b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber CHECK(msg->findRect(key, &left, &top, &right, &bottom)); 315b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 316b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 317b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 318b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 319b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 320f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-left", key).c_str(), 321b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber left); 322b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 323b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 324b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 325b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 326b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 327f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-top", key).c_str(), 328b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber top); 329b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 330b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 331b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 332b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 333b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 334f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-right", key).c_str(), 335b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber right); 336b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 337b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 338b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 339b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 340b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 341f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-bottom", key).c_str(), 342b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber bottom); 343b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber break; 344b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber } 345b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (valueObj != NULL) { 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring keyObj = env->NewStringUTF(key); 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3535a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *map = hashMap; 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertKeyValueArraysToMessage( 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobjectArray keys, jobjectArray values, 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> *out) { 3688d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String")); 3698d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(stringClass.get() != NULL); 3708d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer")); 3718d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(integerClass.get() != NULL); 3728d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long")); 3738d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(longClass.get() != NULL); 3748d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float")); 3758d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(floatClass.get() != NULL); 3768d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer")); 3778d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(byteBufClass.get() != NULL); 37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg = new AMessage; 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jsize numEntries = 0; 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (keys != NULL) { 38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (values == NULL) { 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber numEntries = env->GetArrayLength(keys); 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (numEntries != env->GetArrayLength(values)) { 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (values != NULL) { 39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (jsize i = 0; i < numEntries; ++i) { 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject keyObj = env->GetObjectArrayElement(keys, i); 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4008d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (!env->IsInstanceOf(keyObj, stringClass.get())) { 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL); 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString key = tmp; 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)keyObj, tmp); 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = env->GetObjectArrayElement(values, i); 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4178d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (env->IsInstanceOf(valueObj, stringClass.get())) { 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *value = env->GetStringUTFChars((jstring)valueObj, NULL); 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (value == NULL) { 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 42388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setString(key.c_str(), value); 42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)valueObj, value); 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber value = NULL; 4288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, integerClass.get())) { 42988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID intValueID = 4308d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(integerClass.get(), "intValue", "()I"); 43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(intValueID != NULL); 43288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint value = env->CallIntMethod(valueObj, intValueID); 43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setInt32(key.c_str(), value); 4368d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, longClass.get())) { 4378d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID longValueID = 4388d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(longClass.get(), "longValue", "()J"); 4398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(longValueID != NULL); 4408d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 4418d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jlong value = env->CallLongMethod(valueObj, longValueID); 4428d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 4438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber msg->setInt64(key.c_str(), value); 4448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, floatClass.get())) { 44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatValueID = 4468d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(floatClass.get(), "floatValue", "()F"); 44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatValueID != NULL); 44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfloat value = env->CallFloatMethod(valueObj, floatValueID); 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setFloat(key.c_str(), value); 4528d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) { 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID positionID = 4548d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "position", "()I"); 45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(positionID != NULL); 45688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID limitID = 4588d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "limit", "()I"); 45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(limitID != NULL); 46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint position = env->CallIntMethod(valueObj, positionID); 46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint limit = env->CallIntMethod(valueObj, limitID); 46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ABuffer> buffer = new ABuffer(limit - position); 46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber void *data = env->GetDirectBufferAddress(valueObj); 46788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (data != NULL) { 46988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber memcpy(buffer->data(), 47088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (const uint8_t *)data + position, 47188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size()); 47288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 47388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID arrayID = 4748d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "array", "()[B"); 47588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(arrayID != NULL); 47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArray = 47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyteArray)env->CallObjectMethod(valueObj, arrayID); 47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteArray != NULL); 48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetByteArrayRegion( 48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteArray, 48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber position, 48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size(), 48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyte *)buffer->data()); 48688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArray); byteArray = NULL; 48888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 48988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4909b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber msg->setBuffer(key.c_str(), buffer); 49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *out = msg; 49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} // namespace android 50079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 501