15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_array.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/scoped_java_ref.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(JniArray, BasicConversions) { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 kBytes[] = { 0, 1, 2, 3 }; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kLen = arraysize(kBytes); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bytes.obj()); 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8> vec(5); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JavaByteArrayToByteVector(env, bytes.obj(), &vec); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4U, vec.size()); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::vector<uint8>(kBytes, kBytes + kLen), vec); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendJavaByteArrayToByteVector(env, bytes.obj(), &vec); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8U, vec.size()); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CheckLongConversion( 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int64* long_array, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t len, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ScopedJavaLocalRef<jlongArray>& longs) { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(longs.obj()); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) jsize java_array_len = env->GetArrayLength(longs.obj()); 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(static_cast<jsize>(len), java_array_len); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) jlong value; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < len; ++i) { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) env->GetLongArrayRegion(longs.obj(), i, 1, &value); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(long_array[i], value); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(JniArray, LongConversions) { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int64 kLongs[] = { 0, 1, -1, kint64min, kint64max}; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t kLen = arraysize(kLongs); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen)); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<int64> vec(kLongs, kLongs + kLen); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec)); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(JniArray, JavaIntArrayToIntVector) { 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int kInts[] = {0, 1, -1}; 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t kLen = arraysize(kInts); 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen)); 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(jints.obj()); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < kLen; ++i) { 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) jint j = static_cast<jint>(kInts[i]); 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) env->SetIntArrayRegion(jints.obj(), i, 1, &j); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(HasException(env)); 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<int> ints; 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) JavaIntArrayToIntVector(env, jints.obj(), &ints); 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj())); 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) jint value; 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < kLen; ++i) { 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) env->GetIntArrayRegion(jints.obj(), i, 1, &value); 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(ints[i], value); 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(JniArray, JavaFloatArrayToFloatVector) { 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const float kFloats[] = {0.0, 0.5, -0.5}; 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t kLen = arraysize(kFloats); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen)); 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(jfloats.obj()); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < kLen; ++i) { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) jfloat j = static_cast<jfloat>(kFloats[i]); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j); 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(HasException(env)); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<float> floats; 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) JavaFloatArrayToFloatVector(env, jfloats.obj(), &floats); 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(static_cast<jsize>(floats.size()), 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) env->GetArrayLength(jfloats.obj())); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) jfloat value; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < kLen; ++i) { 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value); 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(floats[i], value); 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(JniArray, JavaArrayOfByteArrayToStringVector) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kMaxItems = 50; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a byte[][] object. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B")); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(byte_array_clazz.obj()); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedJavaLocalRef<jobjectArray> array( 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL)); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(array.obj()); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create kMaxItems byte buffers. 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char text[16]; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < kMaxItems; ++i) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) snprintf(text, sizeof text, "%d", i); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray( 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) env, reinterpret_cast<uint8*>(text), 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<size_t>(strlen(text))); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(byte_array.obj()); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) env->SetObjectArrayElement(array.obj(), i, byte_array.obj()); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(HasException(env)); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert to std::vector<std::string>, check the content. 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> vec; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JavaArrayOfByteArrayToStringVector(env, array.obj(), &vec); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size()); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < kMaxItems; ++i) { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) snprintf(text, sizeof text, "%d", i); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_STREQ(text, vec[i].c_str()); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace android 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 149