Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / android / jni_array_unittest.cc
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.
4
5 #include "base/android/jni_array.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <algorithm>
11 #include <limits>
12
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"
20
21 namespace base::android {
22
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);
28   ASSERT_TRUE(j_bytes);
29   ASSERT_EQ(4U, SafeGetArrayLength(env, j_bytes));
30
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));
35 }
36
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);
42   ASSERT_TRUE(bytes);
43
44   std::vector<uint8_t> inputVector(kBytes, kBytes + kLen);
45   ScopedJavaLocalRef<jbyteArray> bytesFromVector =
46       ToJavaByteArray(env, inputVector);
47   ASSERT_TRUE(bytesFromVector);
48
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);
58
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);
62
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);
67 }
68
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);
75
76   std::string stringFromString;
77   JavaByteArrayToString(env, bytesFromString, &stringFromString);
78   EXPECT_EQ(inputString, stringFromString);
79 }
80
81 void CheckBoolConversion(JNIEnv* env,
82                          const bool* bool_array,
83                          const size_t len,
84                          const ScopedJavaLocalRef<jbooleanArray>& booleans) {
85   ASSERT_TRUE(booleans);
86
87   jsize java_array_len = env->GetArrayLength(booleans.obj());
88   ASSERT_EQ(static_cast<jsize>(len), java_array_len);
89
90   jboolean value;
91   for (size_t i = 0; i < len; ++i) {
92     env->GetBooleanArrayRegion(booleans.obj(), i, 1, &value);
93     ASSERT_EQ(bool_array[i], value);
94   }
95 }
96
97 TEST(JniArray, BoolConversions) {
98   const bool kBools[] = {false, true, false};
99   const size_t kLen = std::size(kBools);
100
101   JNIEnv* env = AttachCurrentThread();
102   CheckBoolConversion(env, kBools, kLen, ToJavaBooleanArray(env, kBools, kLen));
103 }
104
105 void CheckIntConversion(
106     JNIEnv* env,
107     const int* int_array,
108     const size_t len,
109     const ScopedJavaLocalRef<jintArray>& ints) {
110   ASSERT_TRUE(ints);
111
112   jsize java_array_len = env->GetArrayLength(ints.obj());
113   ASSERT_EQ(static_cast<jsize>(len), java_array_len);
114
115   jint value;
116   for (size_t i = 0; i < len; ++i) {
117     env->GetIntArrayRegion(ints.obj(), i, 1, &value);
118     ASSERT_EQ(int_array[i], value);
119   }
120 }
121
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);
126
127   JNIEnv* env = AttachCurrentThread();
128   CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, kInts, kLen));
129
130   const std::vector<int> vec(kInts, kInts + kLen);
131   CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, vec));
132 }
133
134 void CheckLongConversion(JNIEnv* env,
135                          const int64_t* long_array,
136                          const size_t len,
137                          const ScopedJavaLocalRef<jlongArray>& longs) {
138   ASSERT_TRUE(longs);
139
140   jsize java_array_len = env->GetArrayLength(longs.obj());
141   ASSERT_EQ(static_cast<jsize>(len), java_array_len);
142
143   jlong value;
144   for (size_t i = 0; i < len; ++i) {
145     env->GetLongArrayRegion(longs.obj(), i, 1, &value);
146     ASSERT_EQ(long_array[i], value);
147   }
148 }
149
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);
154
155   JNIEnv* env = AttachCurrentThread();
156   CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));
157
158   const std::vector<int64_t> vec(kLongs, kLongs + kLen);
159   CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
160 }
161
162 void CheckIntArrayConversion(JNIEnv* env,
163                              ScopedJavaLocalRef<jintArray> jints,
164                              std::vector<int> int_vector,
165                              const size_t len) {
166   jint value;
167   for (size_t i = 0; i < len; ++i) {
168     env->GetIntArrayRegion(jints.obj(), i, 1, &value);
169     ASSERT_EQ(int_vector[i], value);
170   }
171 }
172
173 void CheckBoolArrayConversion(JNIEnv* env,
174                               ScopedJavaLocalRef<jbooleanArray> jbooleans,
175                               std::vector<bool> bool_vector,
176                               const size_t len) {
177   jboolean value;
178   for (size_t i = 0; i < len; ++i) {
179     env->GetBooleanArrayRegion(jbooleans.obj(), i, 1, &value);
180     ASSERT_EQ(bool_vector[i], value);
181   }
182 }
183
184 void CheckFloatConversion(
185     JNIEnv* env,
186     const float* float_array,
187     const size_t len,
188     const ScopedJavaLocalRef<jfloatArray>& floats) {
189   ASSERT_TRUE(floats);
190
191   jsize java_array_len = env->GetArrayLength(floats.obj());
192   ASSERT_EQ(static_cast<jsize>(len), java_array_len);
193
194   jfloat value;
195   for (size_t i = 0; i < len; ++i) {
196     env->GetFloatArrayRegion(floats.obj(), i, 1, &value);
197     ASSERT_EQ(float_array[i], value);
198   }
199 }
200
201 TEST(JniArray, ArrayOfStringArrayConversionUTF8) {
202   std::vector<std::vector<std::string>> kArrays = {
203       {"a", "f"}, {"a", ""}, {}, {""}, {"今日は"}};
204
205   JNIEnv* env = AttachCurrentThread();
206   ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);
207
208   std::vector<std::vector<std::string>> out;
209   Java2dStringArrayTo2dStringVector(env, joa, &out);
210   ASSERT_TRUE(kArrays == out);
211 }
212
213 TEST(JniArray, ArrayOfStringArrayConversionUTF16) {
214   std::vector<std::vector<std::u16string>> kArrays = {
215       {u"a", u"f"}, {u"a", u""}, {}, {u""}};
216
217   JNIEnv* env = AttachCurrentThread();
218   ScopedJavaLocalRef<jobjectArray> joa = ToJavaArrayOfStringArray(env, kArrays);
219
220   std::vector<std::vector<std::u16string>> out;
221   Java2dStringArrayTo2dStringVector(env, joa, &out);
222   ASSERT_TRUE(kArrays == out);
223 }
224
225 TEST(JniArray, FloatConversions) {
226   const float kFloats[] = { 0.0f, 1.0f, -10.0f};
227   const size_t kLen = std::size(kFloats);
228
229   JNIEnv* env = AttachCurrentThread();
230   CheckFloatConversion(env, kFloats, kLen,
231                        ToJavaFloatArray(env, kFloats, kLen));
232
233   const std::vector<float> vec(kFloats, kFloats + kLen);
234   CheckFloatConversion(env, kFloats, kLen, ToJavaFloatArray(env, vec));
235 }
236
237 TEST(JniArray, JavaBooleanArrayToBoolVector) {
238   const bool kBools[] = {false, true, false};
239   const size_t kLen = std::size(kBools);
240
241   JNIEnv* env = AttachCurrentThread();
242   ScopedJavaLocalRef<jbooleanArray> jbooleans(env, env->NewBooleanArray(kLen));
243   ASSERT_TRUE(jbooleans);
244
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));
249   }
250
251   std::vector<bool> bools;
252   JavaBooleanArrayToBoolVector(env, jbooleans, &bools);
253
254   ASSERT_EQ(static_cast<jsize>(bools.size()),
255             env->GetArrayLength(jbooleans.obj()));
256
257   CheckBoolArrayConversion(env, jbooleans, bools, kLen);
258 }
259
260 TEST(JniArray, JavaIntArrayToIntVector) {
261   const int kInts[] = {0, 1, -1};
262   const size_t kLen = std::size(kInts);
263
264   JNIEnv* env = AttachCurrentThread();
265   ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
266   ASSERT_TRUE(jints);
267
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));
272   }
273
274   std::vector<int> ints;
275   JavaIntArrayToIntVector(env, jints, &ints);
276
277   ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
278
279   CheckIntArrayConversion(env, jints, ints, kLen);
280 }
281
282 TEST(JniArray, JavaLongArrayToInt64Vector) {
283   const int64_t kInt64s[] = {0LL, 1LL, -1LL};
284   const size_t kLen = std::size(kInt64s);
285
286   JNIEnv* env = AttachCurrentThread();
287   ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
288   ASSERT_TRUE(jlongs);
289
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));
294   }
295
296   std::vector<int64_t> int64s;
297   JavaLongArrayToInt64Vector(env, jlongs, &int64s);
298
299   ASSERT_EQ(static_cast<jsize>(int64s.size()),
300             env->GetArrayLength(jlongs.obj()));
301
302   jlong value;
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]);
307   }
308 }
309
310 TEST(JniArray, JavaLongArrayToLongVector) {
311   const int64_t kInt64s[] = {0LL, 1LL, -1LL};
312   const size_t kLen = std::size(kInt64s);
313
314   JNIEnv* env = AttachCurrentThread();
315   ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
316   ASSERT_TRUE(jlongs);
317
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));
322   }
323
324   std::vector<jlong> jlongs_vector;
325   JavaLongArrayToLongVector(env, jlongs, &jlongs_vector);
326
327   ASSERT_EQ(static_cast<jsize>(jlongs_vector.size()),
328             env->GetArrayLength(jlongs.obj()));
329
330   jlong value;
331   for (size_t i = 0; i < kLen; ++i) {
332     env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
333     ASSERT_EQ(jlongs_vector[i], value);
334   }
335 }
336
337 TEST(JniArray, JavaFloatArrayToFloatVector) {
338   const float kFloats[] = {0.0, 0.5, -0.5};
339   const size_t kLen = std::size(kFloats);
340
341   JNIEnv* env = AttachCurrentThread();
342   ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
343   ASSERT_TRUE(jfloats);
344
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));
349   }
350
351   std::vector<float> floats;
352   JavaFloatArrayToFloatVector(env, jfloats, &floats);
353
354   ASSERT_EQ(static_cast<jsize>(floats.size()),
355       env->GetArrayLength(jfloats.obj()));
356
357   jfloat value;
358   for (size_t i = 0; i < kLen; ++i) {
359     env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
360     ASSERT_EQ(floats[i], value);
361   }
362 }
363
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);
371
372   env->SetDoubleArrayRegion(jdoubles.obj(), 0, kDoubles.size(),
373                             reinterpret_cast<const jdouble*>(kDoubles.data()));
374   ASSERT_FALSE(HasException(env));
375
376   std::vector<double> doubles;
377   JavaDoubleArrayToDoubleVector(env, jdoubles, &doubles);
378   ASSERT_EQ(kDoubles, doubles);
379 }
380
381 TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
382   const int kMaxItems = 50;
383   JNIEnv* env = AttachCurrentThread();
384
385   // Create a byte[][] object.
386   ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
387   ASSERT_TRUE(byte_array_clazz);
388
389   ScopedJavaLocalRef<jobjectArray> array(
390       env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
391   ASSERT_TRUE(array);
392
393   // Create kMaxItems byte buffers.
394   char text[16];
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);
401
402     env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
403     ASSERT_FALSE(HasException(env));
404   }
405
406   // Convert to std::vector<std::string>, check the content.
407   std::vector<std::string> vec;
408   JavaArrayOfByteArrayToStringVector(env, array, &vec);
409
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());
414   }
415 }
416
417 TEST(JniArray, JavaArrayOfByteArrayToBytesVector) {
418   const size_t kMaxItems = 50;
419   const uint8_t kStep = 37;
420   JNIEnv* env = AttachCurrentThread();
421
422   // Create a byte[][] object.
423   ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
424   ASSERT_TRUE(byte_array_clazz);
425
426   ScopedJavaLocalRef<jobjectArray> array(
427       env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), nullptr));
428   ASSERT_TRUE(array);
429
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);
440
441     env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
442     ASSERT_FALSE(HasException(env));
443
444     input_bytes.push_back(std::move(cur_bytes));
445   }
446   ASSERT_EQ(kMaxItems, input_bytes.size());
447
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);
451
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)));
455 }
456
457 TEST(JniArray, JavaArrayOfStringArrayToVectorOfStringVector) {
458   const std::vector<std::vector<std::u16string>> kArrays = {
459       {u"a", u"f"}, {u"a", u""}, {}, {u""}};
460
461   JNIEnv* env = AttachCurrentThread();
462
463   ScopedJavaLocalRef<jobjectArray> array(
464       env, env->NewObjectArray(kArrays.size(),
465                                env->FindClass("[Ljava/lang/String;"), NULL));
466   ASSERT_TRUE(array);
467
468   ScopedJavaLocalRef<jclass> string_clazz(env,
469                                           env->FindClass("java/lang/String"));
470   ASSERT_TRUE(string_clazz);
471
472   for (size_t i = 0; i < kArrays.size(); ++i) {
473     const std::vector<std::u16string>& child_data = kArrays[i];
474
475     ScopedJavaLocalRef<jobjectArray> child_array(
476         env, env->NewObjectArray(child_data.size(), string_clazz.obj(), NULL));
477     ASSERT_TRUE(child_array);
478
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));
484     }
485     env->SetObjectArrayElement(array.obj(), i, child_array.obj());
486   }
487
488   std::vector<std::vector<std::u16string>> vec;
489   Java2dStringArrayTo2dStringVector(env, array, &vec);
490
491   ASSERT_EQ(kArrays, vec);
492 }
493
494 TEST(JniArray, JavaArrayOfIntArrayToIntVector) {
495   const size_t kNumItems = 4;
496   JNIEnv* env = AttachCurrentThread();
497
498   // Create an int[][] object.
499   ScopedJavaLocalRef<jclass> int_array_clazz(env, env->FindClass("[I"));
500   ASSERT_TRUE(int_array_clazz);
501
502   ScopedJavaLocalRef<jobjectArray> array(
503       env, env->NewObjectArray(kNumItems, int_array_clazz.obj(), nullptr));
504   ASSERT_TRUE(array);
505
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());
512
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());
517
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());
522
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());
527
528   // Convert to std::vector<std::vector<int>>, check the content.
529   std::vector<std::vector<int>> out;
530   JavaArrayOfIntArrayToIntVector(env, array, &out);
531
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);
537 }
538
539 TEST(JniArray, ToJavaArrayOfObjectsOfClass) {
540   JNIEnv* env = AttachCurrentThread();
541
542   std::vector<ScopedJavaLocalRef<jobject>> objects = {
543       ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
544       ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
545       ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
546   };
547
548   ScopedJavaLocalRef<jobjectArray> j_array =
549       ToJavaArrayOfObjects(env, GetClass(env, "java/lang/String"), objects);
550   ASSERT_TRUE(j_array);
551
552   EXPECT_EQ("one",
553             ConvertJavaStringToUTF8(
554                 env, ScopedJavaLocalRef<jstring>(
555                          env, static_cast<jstring>(env->GetObjectArrayElement(
556                                   j_array.obj(), 0)))));
557   EXPECT_EQ("two",
558             ConvertJavaStringToUTF8(
559                 env, ScopedJavaLocalRef<jstring>(
560                          env, static_cast<jstring>(env->GetObjectArrayElement(
561                                   j_array.obj(), 1)))));
562   EXPECT_EQ("three",
563             ConvertJavaStringToUTF8(
564                 env, ScopedJavaLocalRef<jstring>(
565                          env, static_cast<jstring>(env->GetObjectArrayElement(
566                                   j_array.obj(), 2)))));
567 }
568
569 TEST(JniArray, ToJavaArrayOfObjectLocalRef) {
570   JNIEnv* env = AttachCurrentThread();
571
572   std::vector<ScopedJavaLocalRef<jobject>> objects = {
573       ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
574       ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
575       ScopedJavaLocalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
576   };
577
578   ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
579   ASSERT_TRUE(j_array);
580
581   EXPECT_EQ("one",
582             ConvertJavaStringToUTF8(
583                 env, ScopedJavaLocalRef<jstring>(
584                          env, static_cast<jstring>(env->GetObjectArrayElement(
585                                   j_array.obj(), 0)))));
586   EXPECT_EQ("two",
587             ConvertJavaStringToUTF8(
588                 env, ScopedJavaLocalRef<jstring>(
589                          env, static_cast<jstring>(env->GetObjectArrayElement(
590                                   j_array.obj(), 1)))));
591   EXPECT_EQ("three",
592             ConvertJavaStringToUTF8(
593                 env, ScopedJavaLocalRef<jstring>(
594                          env, static_cast<jstring>(env->GetObjectArrayElement(
595                                   j_array.obj(), 2)))));
596 }
597
598 TEST(JniArray, ToJavaArrayOfObjectGlobalRef) {
599   JNIEnv* env = AttachCurrentThread();
600
601   std::vector<ScopedJavaGlobalRef<jobject>> objects = {
602       ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "one")),
603       ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "two")),
604       ScopedJavaGlobalRef<jobject>(ConvertUTF8ToJavaString(env, "three")),
605   };
606
607   ScopedJavaLocalRef<jobjectArray> j_array = ToJavaArrayOfObjects(env, objects);
608   ASSERT_TRUE(j_array);
609
610   EXPECT_EQ("one",
611             ConvertJavaStringToUTF8(
612                 env, ScopedJavaLocalRef<jstring>(
613                          env, static_cast<jstring>(env->GetObjectArrayElement(
614                                   j_array.obj(), 0)))));
615   EXPECT_EQ("two",
616             ConvertJavaStringToUTF8(
617                 env, ScopedJavaLocalRef<jstring>(
618                          env, static_cast<jstring>(env->GetObjectArrayElement(
619                                   j_array.obj(), 1)))));
620   EXPECT_EQ("three",
621             ConvertJavaStringToUTF8(
622                 env, ScopedJavaLocalRef<jstring>(
623                          env, static_cast<jstring>(env->GetObjectArrayElement(
624                                   j_array.obj(), 2)))));
625 }
626 }  // namespace base::android