jni_array_unittest.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  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. #include "base/android/jni_array.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <algorithm>
  8. #include <limits>
  9. #include "base/android/jni_android.h"
  10. #include "base/android/jni_string.h"
  11. #include "base/android/scoped_java_ref.h"
  12. #include "base/strings/utf_string_conversions.h"
  13. #include "testing/gmock/include/gmock/gmock.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. namespace base {
  16. namespace android {
  17. TEST(JniArray, BasicConversions) {
  18. const uint8_t kBytes[] = {0, 1, 2, 3};
  19. const size_t kLen = std::size(kBytes);
  20. JNIEnv* env = AttachCurrentThread();
  21. ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen);
  22. ASSERT_TRUE(bytes);
  23. std::vector<uint8_t> inputVector(kBytes, kBytes + kLen);
  24. ScopedJavaLocalRef<jbyteArray> bytesFromVector =
  25. ToJavaByteArray(env, inputVector);
  26. ASSERT_TRUE(bytesFromVector);
  27. std::vector<uint8_t> vectorFromBytes(5);
  28. std::vector<uint8_t> vectorFromVector(5);
  29. JavaByteArrayToByteVector(env, bytes, &vectorFromBytes);
  30. JavaByteArrayToByteVector(env, bytesFromVector, &vectorFromVector);
  31. EXPECT_EQ(4U, vectorFromBytes.size());
  32. EXPECT_EQ(4U, vectorFromVector.size());
  33. std::vector<uint8_t> expected_vec(kBytes, kBytes + kLen);
  34. EXPECT_EQ(expected_vec, vectorFromBytes);
  35. EXPECT_EQ(expected_vec, vectorFromVector);
  36. AppendJavaByteArrayToByteVector(env, bytes, &vectorFromBytes);
  37. EXPECT_EQ(8U, vectorFromBytes.size());
  38. expected_vec.insert(expected_vec.end(), kBytes, kBytes + kLen);
  39. EXPECT_EQ(expected_vec, vectorFromBytes);
  40. }
  41. TEST(JniArray, ByteArrayStringConversions) {
  42. JNIEnv* env = AttachCurrentThread();
  43. std::string inputString("hello\0world");
  44. ScopedJavaLocalRef<jbyteArray> bytesFromString =
  45. ToJavaByteArray(env, inputString);
  46. ASSERT_TRUE(bytesFromString);
  47. std::string stringFromString;
  48. JavaByteArrayToString(env, bytesFromString, &stringFromString);
  49. EXPECT_EQ(inputString, stringFromString);
  50. }
  51. void CheckBoolConversion(JNIEnv* env,
  52. const bool* bool_array,
  53. const size_t len,
  54. const ScopedJavaLocalRef<jbooleanArray>& booleans) {
  55. ASSERT_TRUE(booleans);
  56. jsize java_array_len = env->GetArrayLength(booleans.obj());
  57. ASSERT_EQ(static_cast<jsize>(len), java_array_len);
  58. jboolean value;
  59. for (size_t i = 0; i < len; ++i) {
  60. env->GetBooleanArrayRegion(booleans.obj(), i, 1, &value);
  61. ASSERT_EQ(bool_array[i], value);
  62. }
  63. }
  64. TEST(JniArray, BoolConversions) {
  65. const bool kBools[] = {false, true, false};
  66. const size_t kLen = std::size(kBools);
  67. JNIEnv* env = AttachCurrentThread();
  68. CheckBoolConversion(env, kBools, kLen, ToJavaBooleanArray(env, kBools, kLen));
  69. }
  70. void CheckIntConversion(
  71. JNIEnv* env,
  72. const int* int_array,
  73. const size_t len,
  74. const ScopedJavaLocalRef<jintArray>& ints) {
  75. ASSERT_TRUE(ints);
  76. jsize java_array_len = env->GetArrayLength(ints.obj());
  77. ASSERT_EQ(static_cast<jsize>(len), java_array_len);
  78. jint value;
  79. for (size_t i = 0; i < len; ++i) {
  80. env->GetIntArrayRegion(ints.obj(), i, 1, &value);
  81. ASSERT_EQ(int_array[i], value);
  82. }
  83. }
  84. TEST(JniArray, IntConversions) {
  85. const int kInts[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
  86. std::numeric_limits<int32_t>::max()};
  87. const size_t kLen = std::size(kInts);
  88. JNIEnv* env = AttachCurrentThread();
  89. CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, kInts, kLen));
  90. const std::vector<int> vec(kInts, kInts + kLen);
  91. CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, vec));
  92. }
  93. void CheckLongConversion(JNIEnv* env,
  94. const int64_t* long_array,
  95. const size_t len,
  96. const ScopedJavaLocalRef<jlongArray>& longs) {
  97. ASSERT_TRUE(longs);
  98. jsize java_array_len = env->GetArrayLength(longs.obj());
  99. ASSERT_EQ(static_cast<jsize>(len), java_array_len);
  100. jlong value;
  101. for (size_t i = 0; i < len; ++i) {
  102. env->GetLongArrayRegion(longs.obj(), i, 1, &value);
  103. ASSERT_EQ(long_array[i], value);
  104. }
  105. }
  106. TEST(JniArray, LongConversions) {
  107. const int64_t kLongs[] = {0, 1, -1, std::numeric_limits<int64_t>::min(),
  108. std::numeric_limits<int64_t>::max()};
  109. const size_t kLen = std::size(kLongs);
  110. JNIEnv* env = AttachCurrentThread();
  111. CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));
  112. const std::vector<int64_t> vec(kLongs, kLongs + kLen);
  113. CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
  114. }
  115. void CheckIntArrayConversion(JNIEnv* env,
  116. ScopedJavaLocalRef<jintArray> jints,
  117. std::vector<int> int_vector,
  118. const size_t len) {
  119. jint value;
  120. for (size_t i = 0; i < len; ++i) {
  121. env->GetIntArrayRegion(jints.obj(), i, 1, &value);
  122. ASSERT_EQ(int_vector[i], value);
  123. }
  124. }
  125. void CheckBoolArrayConversion(JNIEnv* env,
  126. ScopedJavaLocalRef<jbooleanArray> jbooleans,
  127. std::vector<bool> bool_vector,
  128. const size_t len) {
  129. jboolean value;
  130. for (size_t i = 0; i < len; ++i) {
  131. env->GetBooleanArrayRegion(jbooleans.obj(), i, 1, &value);
  132. ASSERT_EQ(bool_vector[i], value);
  133. }
  134. }
  135. void CheckFloatConversion(
  136. JNIEnv* env,
  137. const float* float_array,
  138. const size_t len,
  139. const ScopedJavaLocalRef<jfloatArray>& floats) {
  140. ASSERT_TRUE(floats);
  141. jsize java_array_len = env->GetArrayLength(floats.obj());
  142. ASSERT_EQ(static_cast<jsize>(len), java_array_len);
  143. jfloat value;
  144. for (size_t i = 0; i < len; ++i) {
  145. env->GetFloatArrayRegion(floats.obj(), i, 1, &value);
  146. ASSERT_EQ(float_array[i], value);
  147. }
  148. }
  149. TEST(JniArray, ArrayOfStringArrayConversionUTF8) {
  150. std::vector<std::vector<std::string>> kArrays = {
  151. {"a", "f"}, {"a", ""}, {}, {""}, {"今日は"}};
  152. JNIEnv* env = AttachCurrentThread();
  153. ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);
  154. std::vector<std::vector<std::string>> out;
  155. Java2dStringArrayTo2dStringVector(env, joa, &out);
  156. ASSERT_TRUE(kArrays == out);
  157. }
  158. TEST(JniArray, ArrayOfStringArrayConversionUTF16) {
  159. std::vector<std::vector<std::u16string>> kArrays = {
  160. {u"a", u"f"}, {u"a", u""}, {}, {u""}};
  161. JNIEnv* env = AttachCurrentThread();
  162. ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);
  163. std::vector<std::vector<std::u16string>> out;
  164. Java2dStringArrayTo2dStringVector(env, joa, &out);
  165. ASSERT_TRUE(kArrays == out);
  166. }
  167. TEST(JniArray, FloatConversions) {
  168. const float kFloats[] = { 0.0f, 1.0f, -10.0f};
  169. const size_t kLen = std::size(kFloats);
  170. JNIEnv* env = AttachCurrentThread();
  171. CheckFloatConversion(env, kFloats, kLen,
  172. ToJavaFloatArray(env, kFloats, kLen));
  173. const std::vector<float> vec(kFloats, kFloats + kLen);
  174. CheckFloatConversion(env, kFloats, kLen, ToJavaFloatArray(env, vec));
  175. }
  176. TEST(JniArray, JavaBooleanArrayToBoolVector) {
  177. const bool kBools[] = {false, true, false};
  178. const size_t kLen = std::size(kBools);
  179. JNIEnv* env = AttachCurrentThread();
  180. ScopedJavaLocalRef<jbooleanArray> jbooleans(env, env->NewBooleanArray(kLen));
  181. ASSERT_TRUE(jbooleans);
  182. for (size_t i = 0; i < kLen; ++i) {
  183. jboolean j = static_cast<jboolean>(kBools[i]);
  184. env->SetBooleanArrayRegion(jbooleans.obj(), i, 1, &j);
  185. ASSERT_FALSE(HasException(env));
  186. }
  187. std::vector<bool> bools;
  188. JavaBooleanArrayToBoolVector(env, jbooleans, &bools);
  189. ASSERT_EQ(static_cast<jsize>(bools.size()),
  190. env->GetArrayLength(jbooleans.obj()));
  191. CheckBoolArrayConversion(env, jbooleans, bools, kLen);
  192. }
  193. TEST(JniArray, JavaIntArrayToIntVector) {
  194. const int kInts[] = {0, 1, -1};
  195. const size_t kLen = std::size(kInts);
  196. JNIEnv* env = AttachCurrentThread();
  197. ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
  198. ASSERT_TRUE(jints);
  199. for (size_t i = 0; i < kLen; ++i) {
  200. jint j = static_cast<jint>(kInts[i]);
  201. env->SetIntArrayRegion(jints.obj(), i, 1, &j);
  202. ASSERT_FALSE(HasException(env));
  203. }
  204. std::vector<int> ints;
  205. JavaIntArrayToIntVector(env, jints, &ints);
  206. ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
  207. CheckIntArrayConversion(env, jints, ints, kLen);
  208. }
  209. TEST(JniArray, JavaLongArrayToInt64Vector) {
  210. const int64_t kInt64s[] = {0LL, 1LL, -1LL};
  211. const size_t kLen = std::size(kInt64s);
  212. JNIEnv* env = AttachCurrentThread();
  213. ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
  214. ASSERT_TRUE(jlongs);
  215. for (size_t i = 0; i < kLen; ++i) {
  216. jlong j = static_cast<jlong>(kInt64s[i]);
  217. env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
  218. ASSERT_FALSE(HasException(env));
  219. }
  220. std::vector<int64_t> int64s;
  221. JavaLongArrayToInt64Vector(env, jlongs, &int64s);
  222. ASSERT_EQ(static_cast<jsize>(int64s.size()),
  223. env->GetArrayLength(jlongs.obj()));
  224. jlong value;
  225. for (size_t i = 0; i < kLen; ++i) {
  226. env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
  227. ASSERT_EQ(int64s[i], value);
  228. ASSERT_EQ(kInt64s[i], int64s[i]);
  229. }
  230. }
  231. TEST(JniArray, JavaLongArrayToLongVector) {
  232. const int64_t kInt64s[] = {0LL, 1LL, -1LL};
  233. const size_t kLen = std::size(kInt64s);
  234. JNIEnv* env = AttachCurrentThread();
  235. ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
  236. ASSERT_TRUE(jlongs);
  237. for (size_t i = 0; i < kLen; ++i) {
  238. jlong j = static_cast<jlong>(kInt64s[i]);
  239. env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
  240. ASSERT_FALSE(HasException(env));
  241. }
  242. std::vector<jlong> jlongs_vector;
  243. JavaLongArrayToLongVector(env, jlongs, &jlongs_vector);
  244. ASSERT_EQ(static_cast<jsize>(jlongs_vector.size()),
  245. env->GetArrayLength(jlongs.obj()));
  246. jlong value;
  247. for (size_t i = 0; i < kLen; ++i) {
  248. env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
  249. ASSERT_EQ(jlongs_vector[i], value);
  250. }
  251. }
  252. TEST(JniArray, JavaFloatArrayToFloatVector) {
  253. const float kFloats[] = {0.0, 0.5, -0.5};
  254. const size_t kLen = std::size(kFloats);
  255. JNIEnv* env = AttachCurrentThread();
  256. ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
  257. ASSERT_TRUE(jfloats);
  258. for (size_t i = 0; i < kLen; ++i) {
  259. jfloat j = static_cast<jfloat>(kFloats[i]);
  260. env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
  261. ASSERT_FALSE(HasException(env));
  262. }
  263. std::vector<float> floats;
  264. JavaFloatArrayToFloatVector(env, jfloats, &floats);
  265. ASSERT_EQ(static_cast<jsize>(floats.size()),
  266. env->GetArrayLength(jfloats.obj()));
  267. jfloat value;
  268. for (size_t i = 0; i < kLen; ++i) {
  269. env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
  270. ASSERT_EQ(floats[i], value);
  271. }
  272. }
  273. TEST(JniArray, JavaDoubleArrayToDoubleVector) {
  274. const std::vector<double> kDoubles = {0.0, 0.5, -0.5,
  275. std::numeric_limits<double>::min()};
  276. JNIEnv* env = AttachCurrentThread();
  277. ScopedJavaLocalRef<jdoubleArray> jdoubles(
  278. env, env->NewDoubleArray(kDoubles.size()));
  279. ASSERT_TRUE(jdoubles);
  280. env->SetDoubleArrayRegion(jdoubles.obj(), 0, kDoubles.size(),
  281. reinterpret_cast<const jdouble*>(kDoubles.data()));
  282. ASSERT_FALSE(HasException(env));
  283. std::vector<double> doubles;
  284. JavaDoubleArrayToDoubleVector(env, jdoubles, &doubles);
  285. ASSERT_EQ(kDoubles, doubles);
  286. }
  287. TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
  288. const int kMaxItems = 50;
  289. JNIEnv* env = AttachCurrentThread();
  290. // Create a byte[][] object.
  291. ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
  292. ASSERT_TRUE(byte_array_clazz);
  293. ScopedJavaLocalRef<jobjectArray> array(
  294. env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
  295. ASSERT_TRUE(array);
  296. // Create kMaxItems byte buffers.
  297. char text[16];
  298. for (int i = 0; i < kMaxItems; ++i) {
  299. snprintf(text, sizeof text, "%d", i);
  300. ScopedJavaLocalRef<jbyteArray> byte_array =
  301. ToJavaByteArray(env, reinterpret_cast<uint8_t*>(text),
  302. static_cast<size_t>(strlen(text)));
  303. ASSERT_TRUE(byte_array);
  304. env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
  305. ASSERT_FALSE(HasException(env));
  306. }
  307. // Convert to std::vector<std::string>, check the content.
  308. std::vector<std::string> vec;
  309. JavaArrayOfByteArrayToStringVector(env, array, &vec);
  310. EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
  311. for (int i = 0; i < kMaxItems; ++i) {
  312. snprintf(text, sizeof text, "%d", i);
  313. EXPECT_STREQ(text, vec[i].c_str());
  314. }
  315. }
  316. TEST(JniArray, JavaArrayOfByteArrayToBytesVector) {
  317. const size_t kMaxItems = 50;
  318. const uint8_t kStep = 37;
  319. JNIEnv* env = AttachCurrentThread();
  320. // Create a byte[][] object.
  321. ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
  322. ASSERT_TRUE(byte_array_clazz);
  323. ScopedJavaLocalRef<jobjectArray> array(
  324. env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), nullptr));
  325. ASSERT_TRUE(array);
  326. // Create kMaxItems byte buffers with size |i|+1 on each step;
  327. std::vector<std::vector<uint8_t>> input_bytes;
  328. input_bytes.reserve(kMaxItems);
  329. for (size_t i = 0; i < kMaxItems; ++i) {
  330. std::vector<uint8_t> cur_bytes(i + 1);
  331. for (size_t j = 0; j < cur_bytes.size(); ++j)
  332. cur_bytes[j] = static_cast<uint8_t>(i + j * kStep);
  333. ScopedJavaLocalRef<jbyteArray> byte_array =
  334. ToJavaByteArray(env, cur_bytes.data(), cur_bytes.size());
  335. ASSERT_TRUE(byte_array);
  336. env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
  337. ASSERT_FALSE(HasException(env));
  338. input_bytes.push_back(std::move(cur_bytes));
  339. }
  340. ASSERT_EQ(kMaxItems, input_bytes.size());
  341. // Convert to std::vector<std::vector<uint8_t>>, check the content.
  342. std::vector<std::vector<uint8_t>> result;
  343. JavaArrayOfByteArrayToBytesVector(env, array, &result);
  344. EXPECT_EQ(input_bytes.size(), result.size());
  345. for (size_t i = 0; i < kMaxItems; ++i)
  346. EXPECT_THAT(result[i], ::testing::ElementsAreArray(input_bytes.at(i)));
  347. }
  348. TEST(JniArray, JavaArrayOfStringArrayToVectorOfStringVector) {
  349. const std::vector<std::vector<std::u16string>> kArrays = {
  350. {u"a", u"f"}, {u"a", u""}, {}, {u""}};
  351. JNIEnv* env = AttachCurrentThread();
  352. ScopedJavaLocalRef<jobjectArray> array(
  353. env, env->NewObjectArray(kArrays.size(),
  354. env->FindClass("[Ljava/lang/String;"), NULL));
  355. ASSERT_TRUE(array);
  356. ScopedJavaLocalRef<jclass> string_clazz(env,
  357. env->FindClass("java/lang/String"));
  358. ASSERT_TRUE(string_clazz);
  359. for (size_t i = 0; i < kArrays.size(); ++i) {
  360. const std::vector<std::u16string>& child_data = kArrays[i];
  361. ScopedJavaLocalRef<jobjectArray> child_array(
  362. env, env->NewObjectArray(child_data.size(), string_clazz.obj(), NULL));
  363. ASSERT_TRUE(child_array);
  364. for (size_t j = 0; j < child_data.size(); ++j) {
  365. ScopedJavaLocalRef<jstring> item =
  366. base::android::ConvertUTF16ToJavaString(env, child_data[j]);
  367. env->SetObjectArrayElement(child_array.obj(), j, item.obj());
  368. ASSERT_FALSE(HasException(env));
  369. }
  370. env->SetObjectArrayElement(array.obj(), i, child_array.obj());
  371. }
  372. std::vector<std::vector<std::u16string>> vec;
  373. Java2dStringArrayTo2dStringVector(env, array, &vec);
  374. ASSERT_EQ(kArrays, vec);
  375. }
  376. TEST(JniArray, JavaArrayOfIntArrayToIntVector) {
  377. const size_t kNumItems = 4;
  378. JNIEnv* env = AttachCurrentThread();
  379. // Create an int[][] object.
  380. ScopedJavaLocalRef<jclass> int_array_clazz(env, env->FindClass("[I"));
  381. ASSERT_TRUE(int_array_clazz);
  382. ScopedJavaLocalRef<jobjectArray> array(
  383. env, env->NewObjectArray(kNumItems, int_array_clazz.obj(), nullptr));
  384. ASSERT_TRUE(array);
  385. // Populate int[][] object.
  386. const int kInts0[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
  387. std::numeric_limits<int32_t>::max()};
  388. const size_t kLen0 = std::size(kInts0);
  389. ScopedJavaLocalRef<jintArray> int_array0 = ToJavaIntArray(env, kInts0, kLen0);
  390. env->SetObjectArrayElement(array.obj(), 0, int_array0.obj());
  391. const int kInts1[] = {3, 4, 5};
  392. const size_t kLen1 = std::size(kInts1);
  393. ScopedJavaLocalRef<jintArray> int_array1 = ToJavaIntArray(env, kInts1, kLen1);
  394. env->SetObjectArrayElement(array.obj(), 1, int_array1.obj());
  395. const int kInts2[] = {};
  396. const size_t kLen2 = 0;
  397. ScopedJavaLocalRef<jintArray> int_array2 = ToJavaIntArray(env, kInts2, kLen2);
  398. env->SetObjectArrayElement(array.obj(), 2, int_array2.obj());
  399. const int kInts3[] = {16};
  400. const size_t kLen3 = std::size(kInts3);
  401. ScopedJavaLocalRef<jintArray> int_array3 = ToJavaIntArray(env, kInts3, kLen3);
  402. env->SetObjectArrayElement(array.obj(), 3, int_array3.obj());
  403. // Convert to std::vector<std::vector<int>>, check the content.
  404. std::vector<std::vector<int>> out;
  405. JavaArrayOfIntArrayToIntVector(env, array, &out);
  406. EXPECT_EQ(kNumItems, out.size());
  407. CheckIntArrayConversion(env, int_array0, out[0], kLen0);
  408. CheckIntArrayConversion(env, int_array1, out[1], kLen1);
  409. CheckIntArrayConversion(env, int_array2, out[2], kLen2);
  410. CheckIntArrayConversion(env, int_array3, out[3], kLen3);
  411. }
  412. TEST(JniArray, ToJavaArrayOfObjectsOfClass) {
  413. JNIEnv* env = AttachCurrentThread();
  414. std::vector<ScopedJavaLocalRef<jobject>> objects = {
  415. ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
  416. ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
  417. ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
  418. };
  419. ScopedJavaLocalRef<jobjectArray> j_array =
  420. ToJavaArrayOfObjects(env, GetClass(env, "java/lang/String"), objects);
  421. ASSERT_TRUE(j_array);
  422. EXPECT_EQ("one",
  423. ConvertJavaStringToUTF8(
  424. env, ScopedJavaLocalRef<jstring>(
  425. env, static_cast<jstring>(env->GetObjectArrayElement(
  426. j_array.obj(), 0)))));
  427. EXPECT_EQ("two",
  428. ConvertJavaStringToUTF8(
  429. env, ScopedJavaLocalRef<jstring>(
  430. env, static_cast<jstring>(env->GetObjectArrayElement(
  431. j_array.obj(), 1)))));
  432. EXPECT_EQ("three",
  433. ConvertJavaStringToUTF8(
  434. env, ScopedJavaLocalRef<jstring>(
  435. env, static_cast<jstring>(env->GetObjectArrayElement(
  436. j_array.obj(), 2)))));
  437. }
  438. TEST(JniArray, ToJavaArrayOfObjectLocalRef) {
  439. JNIEnv* env = AttachCurrentThread();
  440. std::vector<ScopedJavaLocalRef<jobject>> objects = {
  441. ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
  442. ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
  443. ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
  444. };
  445. ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
  446. ASSERT_TRUE(j_array);
  447. EXPECT_EQ("one",
  448. ConvertJavaStringToUTF8(
  449. env, ScopedJavaLocalRef<jstring>(
  450. env, static_cast<jstring>(env->GetObjectArrayElement(
  451. j_array.obj(), 0)))));
  452. EXPECT_EQ("two",
  453. ConvertJavaStringToUTF8(
  454. env, ScopedJavaLocalRef<jstring>(
  455. env, static_cast<jstring>(env->GetObjectArrayElement(
  456. j_array.obj(), 1)))));
  457. EXPECT_EQ("three",
  458. ConvertJavaStringToUTF8(
  459. env, ScopedJavaLocalRef<jstring>(
  460. env, static_cast<jstring>(env->GetObjectArrayElement(
  461. j_array.obj(), 2)))));
  462. }
  463. TEST(JniArray, ToJavaArrayOfObjectGlobalRef) {
  464. JNIEnv* env = AttachCurrentThread();
  465. std::vector<ScopedJavaGlobalRef<jobject>> objects = {
  466. ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
  467. ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
  468. ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
  469. };
  470. ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
  471. ASSERT_TRUE(j_array);
  472. EXPECT_EQ("one",
  473. ConvertJavaStringToUTF8(
  474. env, ScopedJavaLocalRef<jstring>(
  475. env, static_cast<jstring>(env->GetObjectArrayElement(
  476. j_array.obj(), 0)))));
  477. EXPECT_EQ("two",
  478. ConvertJavaStringToUTF8(
  479. env, ScopedJavaLocalRef<jstring>(
  480. env, static_cast<jstring>(env->GetObjectArrayElement(
  481. j_array.obj(), 1)))));
  482. EXPECT_EQ("three",
  483. ConvertJavaStringToUTF8(
  484. env, ScopedJavaLocalRef<jstring>(
  485. env, static_cast<jstring>(env->GetObjectArrayElement(
  486. j_array.obj(), 2)))));
  487. }
  488. } // namespace android
  489. } // namespace base