1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/android/jni_array.h"
13 #include "base/android/jni_android.h"
14 #include "base/android/jni_string.h"
15 #include "base/android/scoped_java_ref.h"
16 #include "base/containers/span.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace base::android {
23 TEST(JniArray, GetLength) {
24 const uint8_t bytes[] = {0, 1, 2, 3};
25 const size_t len = std::size(bytes);
26 JNIEnv* env = AttachCurrentThread();
27 ScopedJavaLocalRef<jbyteArray> j_bytes = ToJavaByteArray(env, bytes, len);
29 ASSERT_EQ(4U, SafeGetArrayLength(env, j_bytes));
31 ScopedJavaLocalRef<jbyteArray> j_empty_bytes =
32 ToJavaByteArray(env, base::span<uint8_t>());
33 ASSERT_TRUE(j_empty_bytes);
34 ASSERT_EQ(0U, SafeGetArrayLength(env, j_empty_bytes));
37 TEST(JniArray, BasicConversions) {
38 const uint8_t kBytes[] = {0, 1, 2, 3};
39 const size_t kLen = std::size(kBytes);
40 JNIEnv* env = AttachCurrentThread();
41 ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen);
44 std::vector<uint8_t> inputVector(kBytes, kBytes + kLen);
45 ScopedJavaLocalRef<jbyteArray> bytesFromVector =
46 ToJavaByteArray(env, inputVector);
47 ASSERT_TRUE(bytesFromVector);
49 std::vector<uint8_t> vectorFromBytes(5);
50 std::vector<uint8_t> vectorFromVector(5);
51 JavaByteArrayToByteVector(env, bytes, &vectorFromBytes);
52 JavaByteArrayToByteVector(env, bytesFromVector, &vectorFromVector);
53 EXPECT_EQ(4U, vectorFromBytes.size());
54 EXPECT_EQ(4U, vectorFromVector.size());
55 std::vector<uint8_t> expected_vec(kBytes, kBytes + kLen);
56 EXPECT_EQ(expected_vec, vectorFromBytes);
57 EXPECT_EQ(expected_vec, vectorFromVector);
59 std::vector<uint8_t> vector_for_span_test(expected_vec.size());
60 JavaByteArrayToByteSpan(env, bytes, base::make_span(vector_for_span_test));
61 EXPECT_EQ(expected_vec, vector_for_span_test);
63 AppendJavaByteArrayToByteVector(env, bytes, &vectorFromBytes);
64 EXPECT_EQ(8U, vectorFromBytes.size());
65 expected_vec.insert(expected_vec.end(), kBytes, kBytes + kLen);
66 EXPECT_EQ(expected_vec, vectorFromBytes);
69 TEST(JniArray, ByteArrayStringConversions) {
70 JNIEnv* env = AttachCurrentThread();
71 std::string inputString("hello\0world");
72 ScopedJavaLocalRef<jbyteArray> bytesFromString =
73 ToJavaByteArray(env, inputString);
74 ASSERT_TRUE(bytesFromString);
76 std::string stringFromString;
77 JavaByteArrayToString(env, bytesFromString, &stringFromString);
78 EXPECT_EQ(inputString, stringFromString);
81 void CheckBoolConversion(JNIEnv* env,
82 const bool* bool_array,
84 const ScopedJavaLocalRef<jbooleanArray>& booleans) {
85 ASSERT_TRUE(booleans);
87 jsize java_array_len = env->GetArrayLength(booleans.obj());
88 ASSERT_EQ(static_cast<jsize>(len), java_array_len);
91 for (size_t i = 0; i < len; ++i) {
92 env->GetBooleanArrayRegion(booleans.obj(), i, 1, &value);
93 ASSERT_EQ(bool_array[i], value);
97 TEST(JniArray, BoolConversions) {
98 const bool kBools[] = {false, true, false};
99 const size_t kLen = std::size(kBools);
101 JNIEnv* env = AttachCurrentThread();
102 CheckBoolConversion(env, kBools, kLen, ToJavaBooleanArray(env, kBools, kLen));
105 void CheckIntConversion(
107 const int* int_array,
109 const ScopedJavaLocalRef<jintArray>& ints) {
112 jsize java_array_len = env->GetArrayLength(ints.obj());
113 ASSERT_EQ(static_cast<jsize>(len), java_array_len);
116 for (size_t i = 0; i < len; ++i) {
117 env->GetIntArrayRegion(ints.obj(), i, 1, &value);
118 ASSERT_EQ(int_array[i], value);
122 TEST(JniArray, IntConversions) {
123 const int kInts[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
124 std::numeric_limits<int32_t>::max()};
125 const size_t kLen = std::size(kInts);
127 JNIEnv* env = AttachCurrentThread();
128 CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, kInts, kLen));
130 const std::vector<int> vec(kInts, kInts + kLen);
131 CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, vec));
134 void CheckLongConversion(JNIEnv* env,
135 const int64_t* long_array,
137 const ScopedJavaLocalRef<jlongArray>& longs) {
140 jsize java_array_len = env->GetArrayLength(longs.obj());
141 ASSERT_EQ(static_cast<jsize>(len), java_array_len);
144 for (size_t i = 0; i < len; ++i) {
145 env->GetLongArrayRegion(longs.obj(), i, 1, &value);
146 ASSERT_EQ(long_array[i], value);
150 TEST(JniArray, LongConversions) {
151 const int64_t kLongs[] = {0, 1, -1, std::numeric_limits<int64_t>::min(),
152 std::numeric_limits<int64_t>::max()};
153 const size_t kLen = std::size(kLongs);
155 JNIEnv* env = AttachCurrentThread();
156 CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));
158 const std::vector<int64_t> vec(kLongs, kLongs + kLen);
159 CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
162 void CheckIntArrayConversion(JNIEnv* env,
163 ScopedJavaLocalRef<jintArray> jints,
164 std::vector<int> int_vector,
167 for (size_t i = 0; i < len; ++i) {
168 env->GetIntArrayRegion(jints.obj(), i, 1, &value);
169 ASSERT_EQ(int_vector[i], value);
173 void CheckBoolArrayConversion(JNIEnv* env,
174 ScopedJavaLocalRef<jbooleanArray> jbooleans,
175 std::vector<bool> bool_vector,
178 for (size_t i = 0; i < len; ++i) {
179 env->GetBooleanArrayRegion(jbooleans.obj(), i, 1, &value);
180 ASSERT_EQ(bool_vector[i], value);
184 void CheckFloatConversion(
186 const float* float_array,
188 const ScopedJavaLocalRef<jfloatArray>& floats) {
191 jsize java_array_len = env->GetArrayLength(floats.obj());
192 ASSERT_EQ(static_cast<jsize>(len), java_array_len);
195 for (size_t i = 0; i < len; ++i) {
196 env->GetFloatArrayRegion(floats.obj(), i, 1, &value);
197 ASSERT_EQ(float_array[i], value);
201 TEST(JniArray, ArrayOfStringArrayConversionUTF8) {
202 std::vector<std::vector<std::string>> kArrays = {
203 {"a", "f"}, {"a", ""}, {}, {""}, {"今日は"}};
205 JNIEnv* env = AttachCurrentThread();
206 ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);
208 std::vector<std::vector<std::string>> out;
209 Java2dStringArrayTo2dStringVector(env, joa, &out);
210 ASSERT_TRUE(kArrays == out);
213 TEST(JniArray, ArrayOfStringArrayConversionUTF16) {
214 std::vector<std::vector<std::u16string>> kArrays = {
215 {u"a", u"f"}, {u"a", u""}, {}, {u""}};
217 JNIEnv* env = AttachCurrentThread();
218 ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);
220 std::vector<std::vector<std::u16string>> out;
221 Java2dStringArrayTo2dStringVector(env, joa, &out);
222 ASSERT_TRUE(kArrays == out);
225 TEST(JniArray, FloatConversions) {
226 const float kFloats[] = { 0.0f, 1.0f, -10.0f};
227 const size_t kLen = std::size(kFloats);
229 JNIEnv* env = AttachCurrentThread();
230 CheckFloatConversion(env, kFloats, kLen,
231 ToJavaFloatArray(env, kFloats, kLen));
233 const std::vector<float> vec(kFloats, kFloats + kLen);
234 CheckFloatConversion(env, kFloats, kLen, ToJavaFloatArray(env, vec));
237 TEST(JniArray, JavaBooleanArrayToBoolVector) {
238 const bool kBools[] = {false, true, false};
239 const size_t kLen = std::size(kBools);
241 JNIEnv* env = AttachCurrentThread();
242 ScopedJavaLocalRef<jbooleanArray> jbooleans(env, env->NewBooleanArray(kLen));
243 ASSERT_TRUE(jbooleans);
245 for (size_t i = 0; i < kLen; ++i) {
246 jboolean j = static_cast<jboolean>(kBools[i]);
247 env->SetBooleanArrayRegion(jbooleans.obj(), i, 1, &j);
248 ASSERT_FALSE(HasException(env));
251 std::vector<bool> bools;
252 JavaBooleanArrayToBoolVector(env, jbooleans, &bools);
254 ASSERT_EQ(static_cast<jsize>(bools.size()),
255 env->GetArrayLength(jbooleans.obj()));
257 CheckBoolArrayConversion(env, jbooleans, bools, kLen);
260 TEST(JniArray, JavaIntArrayToIntVector) {
261 const int kInts[] = {0, 1, -1};
262 const size_t kLen = std::size(kInts);
264 JNIEnv* env = AttachCurrentThread();
265 ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
268 for (size_t i = 0; i < kLen; ++i) {
269 jint j = static_cast<jint>(kInts[i]);
270 env->SetIntArrayRegion(jints.obj(), i, 1, &j);
271 ASSERT_FALSE(HasException(env));
274 std::vector<int> ints;
275 JavaIntArrayToIntVector(env, jints, &ints);
277 ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
279 CheckIntArrayConversion(env, jints, ints, kLen);
282 TEST(JniArray, JavaLongArrayToInt64Vector) {
283 const int64_t kInt64s[] = {0LL, 1LL, -1LL};
284 const size_t kLen = std::size(kInt64s);
286 JNIEnv* env = AttachCurrentThread();
287 ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
290 for (size_t i = 0; i < kLen; ++i) {
291 jlong j = static_cast<jlong>(kInt64s[i]);
292 env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
293 ASSERT_FALSE(HasException(env));
296 std::vector<int64_t> int64s;
297 JavaLongArrayToInt64Vector(env, jlongs, &int64s);
299 ASSERT_EQ(static_cast<jsize>(int64s.size()),
300 env->GetArrayLength(jlongs.obj()));
303 for (size_t i = 0; i < kLen; ++i) {
304 env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
305 ASSERT_EQ(int64s[i], value);
306 ASSERT_EQ(kInt64s[i], int64s[i]);
310 TEST(JniArray, JavaLongArrayToLongVector) {
311 const int64_t kInt64s[] = {0LL, 1LL, -1LL};
312 const size_t kLen = std::size(kInt64s);
314 JNIEnv* env = AttachCurrentThread();
315 ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
318 for (size_t i = 0; i < kLen; ++i) {
319 jlong j = static_cast<jlong>(kInt64s[i]);
320 env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
321 ASSERT_FALSE(HasException(env));
324 std::vector<jlong> jlongs_vector;
325 JavaLongArrayToLongVector(env, jlongs, &jlongs_vector);
327 ASSERT_EQ(static_cast<jsize>(jlongs_vector.size()),
328 env->GetArrayLength(jlongs.obj()));
331 for (size_t i = 0; i < kLen; ++i) {
332 env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
333 ASSERT_EQ(jlongs_vector[i], value);
337 TEST(JniArray, JavaFloatArrayToFloatVector) {
338 const float kFloats[] = {0.0, 0.5, -0.5};
339 const size_t kLen = std::size(kFloats);
341 JNIEnv* env = AttachCurrentThread();
342 ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
343 ASSERT_TRUE(jfloats);
345 for (size_t i = 0; i < kLen; ++i) {
346 jfloat j = static_cast<jfloat>(kFloats[i]);
347 env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
348 ASSERT_FALSE(HasException(env));
351 std::vector<float> floats;
352 JavaFloatArrayToFloatVector(env, jfloats, &floats);
354 ASSERT_EQ(static_cast<jsize>(floats.size()),
355 env->GetArrayLength(jfloats.obj()));
358 for (size_t i = 0; i < kLen; ++i) {
359 env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
360 ASSERT_EQ(floats[i], value);
364 TEST(JniArray, JavaDoubleArrayToDoubleVector) {
365 const std::vector<double> kDoubles = {0.0, 0.5, -0.5,
366 std::numeric_limits<double>::min()};
367 JNIEnv* env = AttachCurrentThread();
368 ScopedJavaLocalRef<jdoubleArray> jdoubles(
369 env, env->NewDoubleArray(kDoubles.size()));
370 ASSERT_TRUE(jdoubles);
372 env->SetDoubleArrayRegion(jdoubles.obj(), 0, kDoubles.size(),
373 reinterpret_cast<const jdouble*>(kDoubles.data()));
374 ASSERT_FALSE(HasException(env));
376 std::vector<double> doubles;
377 JavaDoubleArrayToDoubleVector(env, jdoubles, &doubles);
378 ASSERT_EQ(kDoubles, doubles);
381 TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
382 const int kMaxItems = 50;
383 JNIEnv* env = AttachCurrentThread();
385 // Create a byte[][] object.
386 ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
387 ASSERT_TRUE(byte_array_clazz);
389 ScopedJavaLocalRef<jobjectArray> array(
390 env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
393 // Create kMaxItems byte buffers.
395 for (int i = 0; i < kMaxItems; ++i) {
396 snprintf(text, sizeof text, "%d", i);
397 ScopedJavaLocalRef<jbyteArray> byte_array =
398 ToJavaByteArray(env, reinterpret_cast<uint8_t*>(text),
399 static_cast<size_t>(strlen(text)));
400 ASSERT_TRUE(byte_array);
402 env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
403 ASSERT_FALSE(HasException(env));
406 // Convert to std::vector<std::string>, check the content.
407 std::vector<std::string> vec;
408 JavaArrayOfByteArrayToStringVector(env, array, &vec);
410 EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
411 for (int i = 0; i < kMaxItems; ++i) {
412 snprintf(text, sizeof text, "%d", i);
413 EXPECT_STREQ(text, vec[i].c_str());
417 TEST(JniArray, JavaArrayOfByteArrayToBytesVector) {
418 const size_t kMaxItems = 50;
419 const uint8_t kStep = 37;
420 JNIEnv* env = AttachCurrentThread();
422 // Create a byte[][] object.
423 ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
424 ASSERT_TRUE(byte_array_clazz);
426 ScopedJavaLocalRef<jobjectArray> array(
427 env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), nullptr));
430 // Create kMaxItems byte buffers with size |i|+1 on each step;
431 std::vector<std::vector<uint8_t>> input_bytes;
432 input_bytes.reserve(kMaxItems);
433 for (size_t i = 0; i < kMaxItems; ++i) {
434 std::vector<uint8_t> cur_bytes(i + 1);
435 for (size_t j = 0; j < cur_bytes.size(); ++j)
436 cur_bytes[j] = static_cast<uint8_t>(i + j * kStep);
437 ScopedJavaLocalRef<jbyteArray> byte_array =
438 ToJavaByteArray(env, cur_bytes.data(), cur_bytes.size());
439 ASSERT_TRUE(byte_array);
441 env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
442 ASSERT_FALSE(HasException(env));
444 input_bytes.push_back(std::move(cur_bytes));
446 ASSERT_EQ(kMaxItems, input_bytes.size());
448 // Convert to std::vector<std::vector<uint8_t>>, check the content.
449 std::vector<std::vector<uint8_t>> result;
450 JavaArrayOfByteArrayToBytesVector(env, array, &result);
452 EXPECT_EQ(input_bytes.size(), result.size());
453 for (size_t i = 0; i < kMaxItems; ++i)
454 EXPECT_THAT(result[i], ::testing::ElementsAreArray(input_bytes.at(i)));
457 TEST(JniArray, JavaArrayOfStringArrayToVectorOfStringVector) {
458 const std::vector<std::vector<std::u16string>> kArrays = {
459 {u"a", u"f"}, {u"a", u""}, {}, {u""}};
461 JNIEnv* env = AttachCurrentThread();
463 ScopedJavaLocalRef<jobjectArray> array(
464 env, env->NewObjectArray(kArrays.size(),
465 env->FindClass("[Ljava/lang/String;"), NULL));
468 ScopedJavaLocalRef<jclass> string_clazz(env,
469 env->FindClass("java/lang/String"));
470 ASSERT_TRUE(string_clazz);
472 for (size_t i = 0; i < kArrays.size(); ++i) {
473 const std::vector<std::u16string>& child_data = kArrays[i];
475 ScopedJavaLocalRef<jobjectArray> child_array(
476 env, env->NewObjectArray(child_data.size(), string_clazz.obj(), NULL));
477 ASSERT_TRUE(child_array);
479 for (size_t j = 0; j < child_data.size(); ++j) {
480 ScopedJavaLocalRef<jstring> item =
481 base::android::ConvertUTF16ToJavaString(env, child_data[j]);
482 env->SetObjectArrayElement(child_array.obj(), j, item.obj());
483 ASSERT_FALSE(HasException(env));
485 env->SetObjectArrayElement(array.obj(), i, child_array.obj());
488 std::vector<std::vector<std::u16string>> vec;
489 Java2dStringArrayTo2dStringVector(env, array, &vec);
491 ASSERT_EQ(kArrays, vec);
494 TEST(JniArray, JavaArrayOfIntArrayToIntVector) {
495 const size_t kNumItems = 4;
496 JNIEnv* env = AttachCurrentThread();
498 // Create an int[][] object.
499 ScopedJavaLocalRef<jclass> int_array_clazz(env, env->FindClass("[I"));
500 ASSERT_TRUE(int_array_clazz);
502 ScopedJavaLocalRef<jobjectArray> array(
503 env, env->NewObjectArray(kNumItems, int_array_clazz.obj(), nullptr));
506 // Populate int[][] object.
507 const int kInts0[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
508 std::numeric_limits<int32_t>::max()};
509 const size_t kLen0 = std::size(kInts0);
510 ScopedJavaLocalRef<jintArray> int_array0 = ToJavaIntArray(env, kInts0, kLen0);
511 env->SetObjectArrayElement(array.obj(), 0, int_array0.obj());
513 const int kInts1[] = {3, 4, 5};
514 const size_t kLen1 = std::size(kInts1);
515 ScopedJavaLocalRef<jintArray> int_array1 = ToJavaIntArray(env, kInts1, kLen1);
516 env->SetObjectArrayElement(array.obj(), 1, int_array1.obj());
518 const int kInts2[] = {};
519 const size_t kLen2 = 0;
520 ScopedJavaLocalRef<jintArray> int_array2 = ToJavaIntArray(env, kInts2, kLen2);
521 env->SetObjectArrayElement(array.obj(), 2, int_array2.obj());
523 const int kInts3[] = {16};
524 const size_t kLen3 = std::size(kInts3);
525 ScopedJavaLocalRef<jintArray> int_array3 = ToJavaIntArray(env, kInts3, kLen3);
526 env->SetObjectArrayElement(array.obj(), 3, int_array3.obj());
528 // Convert to std::vector<std::vector<int>>, check the content.
529 std::vector<std::vector<int>> out;
530 JavaArrayOfIntArrayToIntVector(env, array, &out);
532 EXPECT_EQ(kNumItems, out.size());
533 CheckIntArrayConversion(env, int_array0, out[0], kLen0);
534 CheckIntArrayConversion(env, int_array1, out[1], kLen1);
535 CheckIntArrayConversion(env, int_array2, out[2], kLen2);
536 CheckIntArrayConversion(env, int_array3, out[3], kLen3);
539 TEST(JniArray, ToJavaArrayOfObjectsOfClass) {
540 JNIEnv* env = AttachCurrentThread();
542 std::vector<ScopedJavaLocalRef<jobject>> objects = {
543 ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
544 ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
545 ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
548 ScopedJavaLocalRef<jobjectArray> j_array =
549 ToJavaArrayOfObjects(env, GetClass(env, "java/lang/String"), objects);
550 ASSERT_TRUE(j_array);
553 ConvertJavaStringToUTF8(
554 env, ScopedJavaLocalRef<jstring>(
555 env, static_cast<jstring>(env->GetObjectArrayElement(
556 j_array.obj(), 0)))));
558 ConvertJavaStringToUTF8(
559 env, ScopedJavaLocalRef<jstring>(
560 env, static_cast<jstring>(env->GetObjectArrayElement(
561 j_array.obj(), 1)))));
563 ConvertJavaStringToUTF8(
564 env, ScopedJavaLocalRef<jstring>(
565 env, static_cast<jstring>(env->GetObjectArrayElement(
566 j_array.obj(), 2)))));
569 TEST(JniArray, ToJavaArrayOfObjectLocalRef) {
570 JNIEnv* env = AttachCurrentThread();
572 std::vector<ScopedJavaLocalRef<jobject>> objects = {
573 ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
574 ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
575 ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
578 ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
579 ASSERT_TRUE(j_array);
582 ConvertJavaStringToUTF8(
583 env, ScopedJavaLocalRef<jstring>(
584 env, static_cast<jstring>(env->GetObjectArrayElement(
585 j_array.obj(), 0)))));
587 ConvertJavaStringToUTF8(
588 env, ScopedJavaLocalRef<jstring>(
589 env, static_cast<jstring>(env->GetObjectArrayElement(
590 j_array.obj(), 1)))));
592 ConvertJavaStringToUTF8(
593 env, ScopedJavaLocalRef<jstring>(
594 env, static_cast<jstring>(env->GetObjectArrayElement(
595 j_array.obj(), 2)))));
598 TEST(JniArray, ToJavaArrayOfObjectGlobalRef) {
599 JNIEnv* env = AttachCurrentThread();
601 std::vector<ScopedJavaGlobalRef<jobject>> objects = {
602 ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
603 ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
604 ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
607 ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
608 ASSERT_TRUE(j_array);
611 ConvertJavaStringToUTF8(
612 env, ScopedJavaLocalRef<jstring>(
613 env, static_cast<jstring>(env->GetObjectArrayElement(
614 j_array.obj(), 0)))));
616 ConvertJavaStringToUTF8(
617 env, ScopedJavaLocalRef<jstring>(
618 env, static_cast<jstring>(env->GetObjectArrayElement(
619 j_array.obj(), 1)))));
621 ConvertJavaStringToUTF8(
622 env, ScopedJavaLocalRef<jstring>(
623 env, static_cast<jstring>(env->GetObjectArrayElement(
624 j_array.obj(), 2)))));
626 } // namespace base::android