1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/android/jni_array.h" 6 7 #include "base/android/jni_android.h" 8 #include "base/android/scoped_java_ref.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace base { 12 namespace android { 13 14 TEST(JniArray, BasicConversions) { 15 const uint8 kBytes[] = { 0, 1, 2, 3 }; 16 const size_t kLen = arraysize(kBytes); 17 JNIEnv* env = AttachCurrentThread(); 18 ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen); 19 ASSERT_TRUE(bytes.obj()); 20 21 std::vector<uint8> vec(5); 22 JavaByteArrayToByteVector(env, bytes.obj(), &vec); 23 EXPECT_EQ(4U, vec.size()); 24 EXPECT_EQ(std::vector<uint8>(kBytes, kBytes + kLen), vec); 25 26 AppendJavaByteArrayToByteVector(env, bytes.obj(), &vec); 27 EXPECT_EQ(8U, vec.size()); 28 } 29 30 void CheckIntConversion( 31 JNIEnv* env, 32 const int* int_array, 33 const size_t len, 34 const ScopedJavaLocalRef<jintArray>& ints) { 35 ASSERT_TRUE(ints.obj()); 36 37 jsize java_array_len = env->GetArrayLength(ints.obj()); 38 ASSERT_EQ(static_cast<jsize>(len), java_array_len); 39 40 jint value; 41 for (size_t i = 0; i < len; ++i) { 42 env->GetIntArrayRegion(ints.obj(), i, 1, &value); 43 ASSERT_EQ(int_array[i], value); 44 } 45 } 46 47 TEST(JniArray, IntConversions) { 48 const int kInts[] = { 0, 1, -1, kint32min, kint32max}; 49 const size_t kLen = arraysize(kInts); 50 51 JNIEnv* env = AttachCurrentThread(); 52 CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, kInts, kLen)); 53 54 const std::vector<int> vec(kInts, kInts + kLen); 55 CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, vec)); 56 } 57 58 void CheckLongConversion( 59 JNIEnv* env, 60 const int64* long_array, 61 const size_t len, 62 const ScopedJavaLocalRef<jlongArray>& longs) { 63 ASSERT_TRUE(longs.obj()); 64 65 jsize java_array_len = env->GetArrayLength(longs.obj()); 66 ASSERT_EQ(static_cast<jsize>(len), java_array_len); 67 68 jlong value; 69 for (size_t i = 0; i < len; ++i) { 70 env->GetLongArrayRegion(longs.obj(), i, 1, &value); 71 ASSERT_EQ(long_array[i], value); 72 } 73 } 74 75 TEST(JniArray, LongConversions) { 76 const int64 kLongs[] = { 0, 1, -1, kint64min, kint64max}; 77 const size_t kLen = arraysize(kLongs); 78 79 JNIEnv* env = AttachCurrentThread(); 80 CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen)); 81 82 const std::vector<int64> vec(kLongs, kLongs + kLen); 83 CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec)); 84 } 85 86 TEST(JniArray, JavaIntArrayToIntVector) { 87 const int kInts[] = {0, 1, -1}; 88 const size_t kLen = arraysize(kInts); 89 90 JNIEnv* env = AttachCurrentThread(); 91 ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen)); 92 ASSERT_TRUE(jints.obj()); 93 94 for (size_t i = 0; i < kLen; ++i) { 95 jint j = static_cast<jint>(kInts[i]); 96 env->SetIntArrayRegion(jints.obj(), i, 1, &j); 97 ASSERT_FALSE(HasException(env)); 98 } 99 100 std::vector<int> ints; 101 JavaIntArrayToIntVector(env, jints.obj(), &ints); 102 103 ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj())); 104 105 jint value; 106 for (size_t i = 0; i < kLen; ++i) { 107 env->GetIntArrayRegion(jints.obj(), i, 1, &value); 108 ASSERT_EQ(ints[i], value); 109 } 110 } 111 112 TEST(JniArray, JavaFloatArrayToFloatVector) { 113 const float kFloats[] = {0.0, 0.5, -0.5}; 114 const size_t kLen = arraysize(kFloats); 115 116 JNIEnv* env = AttachCurrentThread(); 117 ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen)); 118 ASSERT_TRUE(jfloats.obj()); 119 120 for (size_t i = 0; i < kLen; ++i) { 121 jfloat j = static_cast<jfloat>(kFloats[i]); 122 env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j); 123 ASSERT_FALSE(HasException(env)); 124 } 125 126 std::vector<float> floats; 127 JavaFloatArrayToFloatVector(env, jfloats.obj(), &floats); 128 129 ASSERT_EQ(static_cast<jsize>(floats.size()), 130 env->GetArrayLength(jfloats.obj())); 131 132 jfloat value; 133 for (size_t i = 0; i < kLen; ++i) { 134 env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value); 135 ASSERT_EQ(floats[i], value); 136 } 137 } 138 139 TEST(JniArray, JavaArrayOfByteArrayToStringVector) { 140 const int kMaxItems = 50; 141 JNIEnv* env = AttachCurrentThread(); 142 143 // Create a byte[][] object. 144 ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B")); 145 ASSERT_TRUE(byte_array_clazz.obj()); 146 147 ScopedJavaLocalRef<jobjectArray> array( 148 env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL)); 149 ASSERT_TRUE(array.obj()); 150 151 // Create kMaxItems byte buffers. 152 char text[16]; 153 for (int i = 0; i < kMaxItems; ++i) { 154 snprintf(text, sizeof text, "%d", i); 155 ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray( 156 env, reinterpret_cast<uint8*>(text), 157 static_cast<size_t>(strlen(text))); 158 ASSERT_TRUE(byte_array.obj()); 159 160 env->SetObjectArrayElement(array.obj(), i, byte_array.obj()); 161 ASSERT_FALSE(HasException(env)); 162 } 163 164 // Convert to std::vector<std::string>, check the content. 165 std::vector<std::string> vec; 166 JavaArrayOfByteArrayToStringVector(env, array.obj(), &vec); 167 168 EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size()); 169 for (int i = 0; i < kMaxItems; ++i) { 170 snprintf(text, sizeof text, "%d", i); 171 EXPECT_STREQ(text, vec[i].c_str()); 172 } 173 } 174 175 } // namespace android 176 } // namespace base 177