• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/check_op.h"
10 #include "base/numerics/safe_conversions.h"
11 
12 namespace base::android {
13 
ToJavaByteArray(JNIEnv * env,const uint8_t * bytes,size_t len)14 ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(JNIEnv* env,
15                                                const uint8_t* bytes,
16                                                size_t len) {
17   const jsize len_jsize = checked_cast<jsize>(len);
18   jbyteArray byte_array = env->NewByteArray(len_jsize);
19   CheckException(env);
20   DCHECK(byte_array);
21 
22   env->SetByteArrayRegion(byte_array, 0, len_jsize,
23                           reinterpret_cast<const jbyte*>(bytes));
24   CheckException(env);
25 
26   return ScopedJavaLocalRef<jbyteArray>(env, byte_array);
27 }
28 
ToJavaByteArray(JNIEnv * env,base::span<const uint8_t> bytes)29 ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
30     JNIEnv* env,
31     base::span<const uint8_t> bytes) {
32   return ToJavaByteArray(env, bytes.data(), bytes.size());
33 }
34 
ToJavaByteArray(JNIEnv * env,const std::string & str)35 ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(JNIEnv* env,
36                                                const std::string& str) {
37   return ToJavaByteArray(env, reinterpret_cast<const uint8_t*>(str.data()),
38                          str.size());
39 }
40 
ToJavaBooleanArray(JNIEnv * env,const bool * bools,size_t len)41 ScopedJavaLocalRef<jbooleanArray> ToJavaBooleanArray(JNIEnv* env,
42                                                      const bool* bools,
43                                                      size_t len) {
44   const jsize len_jsize = checked_cast<jsize>(len);
45   jbooleanArray boolean_array = env->NewBooleanArray(len_jsize);
46   CheckException(env);
47   DCHECK(boolean_array);
48 
49   env->SetBooleanArrayRegion(boolean_array, 0, len_jsize,
50                              reinterpret_cast<const jboolean*>(bools));
51   CheckException(env);
52 
53   return ScopedJavaLocalRef<jbooleanArray>(env, boolean_array);
54 }
55 
ToJavaIntArray(JNIEnv * env,const int * ints,size_t len)56 ScopedJavaLocalRef<jintArray> ToJavaIntArray(JNIEnv* env,
57                                              const int* ints,
58                                              size_t len) {
59   const jsize len_jsize = checked_cast<jsize>(len);
60   jintArray int_array = env->NewIntArray(len_jsize);
61   CheckException(env);
62   DCHECK(int_array);
63 
64   env->SetIntArrayRegion(int_array, 0, len_jsize,
65                          reinterpret_cast<const jint*>(ints));
66   CheckException(env);
67 
68   return ScopedJavaLocalRef<jintArray>(env, int_array);
69 }
70 
ToJavaIntArray(JNIEnv * env,base::span<const int> ints)71 ScopedJavaLocalRef<jintArray> ToJavaIntArray(JNIEnv* env,
72                                              base::span<const int> ints) {
73   return ToJavaIntArray(env, ints.data(), ints.size());
74 }
75 
ToJavaLongArray(JNIEnv * env,const int64_t * longs,size_t len)76 ScopedJavaLocalRef<jlongArray> ToJavaLongArray(JNIEnv* env,
77                                                const int64_t* longs,
78                                                size_t len) {
79   const jsize len_jsize = checked_cast<jsize>(len);
80   jlongArray long_array = env->NewLongArray(len_jsize);
81   CheckException(env);
82   DCHECK(long_array);
83 
84   env->SetLongArrayRegion(long_array, 0, len_jsize,
85                           reinterpret_cast<const jlong*>(longs));
86   CheckException(env);
87 
88   return ScopedJavaLocalRef<jlongArray>(env, long_array);
89 }
90 
91 // Returns a new Java long array converted from the given int64_t array.
ToJavaLongArray(JNIEnv * env,base::span<const int64_t> longs)92 BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
93     JNIEnv* env,
94     base::span<const int64_t> longs) {
95   return ToJavaLongArray(env, longs.data(), longs.size());
96 }
97 
98 // Returns a new Java float array converted from the given C++ float array.
99 BASE_EXPORT ScopedJavaLocalRef<jfloatArray>
ToJavaFloatArray(JNIEnv * env,const float * floats,size_t len)100 ToJavaFloatArray(JNIEnv* env, const float* floats, size_t len) {
101   const jsize len_jsize = checked_cast<jsize>(len);
102   jfloatArray float_array = env->NewFloatArray(len_jsize);
103   CheckException(env);
104   DCHECK(float_array);
105 
106   env->SetFloatArrayRegion(float_array, 0, len_jsize,
107                            reinterpret_cast<const jfloat*>(floats));
108   CheckException(env);
109 
110   return ScopedJavaLocalRef<jfloatArray>(env, float_array);
111 }
112 
ToJavaFloatArray(JNIEnv * env,base::span<const float> floats)113 BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray(
114     JNIEnv* env,
115     base::span<const float> floats) {
116   return ToJavaFloatArray(env, floats.data(), floats.size());
117 }
118 
119 BASE_EXPORT ScopedJavaLocalRef<jdoubleArray>
ToJavaDoubleArray(JNIEnv * env,const double * doubles,size_t len)120 ToJavaDoubleArray(JNIEnv* env, const double* doubles, size_t len) {
121   const jsize len_jsize = checked_cast<jsize>(len);
122   jdoubleArray double_array = env->NewDoubleArray(len_jsize);
123   CheckException(env);
124   DCHECK(double_array);
125 
126   env->SetDoubleArrayRegion(double_array, 0, len_jsize,
127                             reinterpret_cast<const jdouble*>(doubles));
128   CheckException(env);
129 
130   return ScopedJavaLocalRef<jdoubleArray>(env, double_array);
131 }
132 
ToJavaDoubleArray(JNIEnv * env,base::span<const double> doubles)133 BASE_EXPORT ScopedJavaLocalRef<jdoubleArray> ToJavaDoubleArray(
134     JNIEnv* env,
135     base::span<const double> doubles) {
136   return ToJavaDoubleArray(env, doubles.data(), doubles.size());
137 }
138 
ToJavaArrayOfObjects(JNIEnv * env,ScopedJavaLocalRef<jclass> clazz,base::span<const ScopedJavaLocalRef<jobject>> v)139 BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfObjects(
140     JNIEnv* env,
141     ScopedJavaLocalRef<jclass> clazz,
142     base::span<const ScopedJavaLocalRef<jobject>> v) {
143   jobjectArray joa =
144       env->NewObjectArray(checked_cast<jsize>(v.size()), clazz.obj(), nullptr);
145   CheckException(env);
146 
147   for (size_t i = 0; i < v.size(); ++i) {
148     env->SetObjectArrayElement(joa, static_cast<jsize>(i), v[i].obj());
149   }
150   return ScopedJavaLocalRef<jobjectArray>(env, joa);
151 }
152 
ToJavaArrayOfObjects(JNIEnv * env,base::span<const ScopedJavaLocalRef<jobject>> v)153 BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfObjects(
154     JNIEnv* env,
155     base::span<const ScopedJavaLocalRef<jobject>> v) {
156   return ToJavaArrayOfObjects(env, GetClass(env, "java/lang/Object"), v);
157 }
158 
ToJavaArrayOfObjects(JNIEnv * env,base::span<const ScopedJavaGlobalRef<jobject>> v)159 BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfObjects(
160     JNIEnv* env,
161     base::span<const ScopedJavaGlobalRef<jobject>> v) {
162   ScopedJavaLocalRef<jclass> object_array_clazz =
163       GetClass(env, "java/lang/Object");
164   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(v.size()),
165                                          object_array_clazz.obj(), nullptr);
166   CheckException(env);
167 
168   for (size_t i = 0; i < v.size(); ++i) {
169     env->SetObjectArrayElement(joa, static_cast<jsize>(i), v[i].obj());
170   }
171   return ScopedJavaLocalRef<jobjectArray>(env, joa);
172 }
173 
ToTypedJavaArrayOfObjects(JNIEnv * env,base::span<const ScopedJavaLocalRef<jobject>> v,const JavaRef<jclass> & type)174 BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToTypedJavaArrayOfObjects(
175     JNIEnv* env,
176     base::span<const ScopedJavaLocalRef<jobject>> v,
177     const JavaRef<jclass>& type) {
178   jobjectArray joa =
179       env->NewObjectArray(checked_cast<jsize>(v.size()), type.obj(), nullptr);
180   CheckException(env);
181 
182   for (size_t i = 0; i < v.size(); ++i) {
183     env->SetObjectArrayElement(joa, static_cast<jsize>(i), v[i].obj());
184   }
185   return ScopedJavaLocalRef<jobjectArray>(env, joa);
186 }
187 
ToTypedJavaArrayOfObjects(JNIEnv * env,base::span<const ScopedJavaGlobalRef<jobject>> v,const JavaRef<jclass> & type)188 BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToTypedJavaArrayOfObjects(
189     JNIEnv* env,
190     base::span<const ScopedJavaGlobalRef<jobject>> v,
191     const JavaRef<jclass>& type) {
192   jobjectArray joa =
193       env->NewObjectArray(checked_cast<jsize>(v.size()), type.obj(), nullptr);
194   CheckException(env);
195 
196   for (size_t i = 0; i < v.size(); ++i) {
197     env->SetObjectArrayElement(joa, static_cast<jsize>(i), v[i].obj());
198   }
199   return ScopedJavaLocalRef<jobjectArray>(env, joa);
200 }
201 
ToJavaArrayOfByteArray(JNIEnv * env,base::span<const std::string> v)202 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
203     JNIEnv* env,
204     base::span<const std::string> v) {
205   ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
206   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(v.size()),
207                                          byte_array_clazz.obj(), nullptr);
208   CheckException(env);
209 
210   for (size_t i = 0; i < v.size(); ++i) {
211     ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(
212         env, reinterpret_cast<const uint8_t*>(v[i].data()), v[i].length());
213     env->SetObjectArrayElement(joa, static_cast<jsize>(i), byte_array.obj());
214   }
215   return ScopedJavaLocalRef<jobjectArray>(env, joa);
216 }
217 
ToJavaArrayOfByteArray(JNIEnv * env,base::span<const std::vector<uint8_t>> v)218 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
219     JNIEnv* env,
220     base::span<const std::vector<uint8_t>> v) {
221   ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
222   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(v.size()),
223                                          byte_array_clazz.obj(), nullptr);
224   CheckException(env);
225 
226   for (size_t i = 0; i < v.size(); ++i) {
227     ScopedJavaLocalRef<jbyteArray> byte_array =
228         ToJavaByteArray(env, v[i].data(), v[i].size());
229     env->SetObjectArrayElement(joa, static_cast<jsize>(i), byte_array.obj());
230   }
231   return ScopedJavaLocalRef<jobjectArray>(env, joa);
232 }
233 
ToJavaArrayOfStrings(JNIEnv * env,base::span<const std::string> v)234 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
235     JNIEnv* env,
236     base::span<const std::string> v) {
237   ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
238   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(v.size()),
239                                          string_clazz.obj(), nullptr);
240   CheckException(env);
241 
242   for (size_t i = 0; i < v.size(); ++i) {
243     ScopedJavaLocalRef<jstring> item = ConvertUTF8ToJavaString(env, v[i]);
244     env->SetObjectArrayElement(joa, static_cast<jsize>(i), item.obj());
245   }
246   return ScopedJavaLocalRef<jobjectArray>(env, joa);
247 }
248 
ToJavaArrayOfStringArray(JNIEnv * env,base::span<const std::vector<std::string>> vec_outer)249 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStringArray(
250     JNIEnv* env,
251     base::span<const std::vector<std::string>> vec_outer) {
252   ScopedJavaLocalRef<jclass> string_array_clazz =
253       GetClass(env, "[Ljava/lang/String;");
254 
255   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(vec_outer.size()),
256                                          string_array_clazz.obj(), nullptr);
257   CheckException(env);
258 
259   for (size_t i = 0; i < vec_outer.size(); ++i) {
260     ScopedJavaLocalRef<jobjectArray> inner =
261         ToJavaArrayOfStrings(env, vec_outer[i]);
262     env->SetObjectArrayElement(joa, static_cast<jsize>(i), inner.obj());
263   }
264 
265   return ScopedJavaLocalRef<jobjectArray>(env, joa);
266 }
267 
ToJavaArrayOfStringArray(JNIEnv * env,base::span<const std::vector<std::u16string>> vec_outer)268 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStringArray(
269     JNIEnv* env,
270     base::span<const std::vector<std::u16string>> vec_outer) {
271   ScopedJavaLocalRef<jclass> string_array_clazz =
272       GetClass(env, "[Ljava/lang/String;");
273 
274   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(vec_outer.size()),
275                                          string_array_clazz.obj(), nullptr);
276   CheckException(env);
277 
278   for (size_t i = 0; i < vec_outer.size(); ++i) {
279     ScopedJavaLocalRef<jobjectArray> inner =
280         ToJavaArrayOfStrings(env, vec_outer[i]);
281     env->SetObjectArrayElement(joa, static_cast<jsize>(i), inner.obj());
282   }
283 
284   return ScopedJavaLocalRef<jobjectArray>(env, joa);
285 }
286 
ToJavaArrayOfStrings(JNIEnv * env,base::span<const std::u16string> v)287 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
288     JNIEnv* env,
289     base::span<const std::u16string> v) {
290   ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
291   jobjectArray joa = env->NewObjectArray(checked_cast<jsize>(v.size()),
292                                          string_clazz.obj(), nullptr);
293   CheckException(env);
294 
295   for (size_t i = 0; i < v.size(); ++i) {
296     ScopedJavaLocalRef<jstring> item = ConvertUTF16ToJavaString(env, v[i]);
297     env->SetObjectArrayElement(joa, static_cast<jsize>(i), item.obj());
298   }
299   return ScopedJavaLocalRef<jobjectArray>(env, joa);
300 }
301 
AppendJavaStringArrayToStringVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::u16string> * out)302 void AppendJavaStringArrayToStringVector(JNIEnv* env,
303                                          const JavaRef<jobjectArray>& array,
304                                          std::vector<std::u16string>* out) {
305   DCHECK(out);
306   if (!array)
307     return;
308   size_t len = SafeGetArrayLength(env, array);
309   size_t back = out->size();
310   out->resize(back + len);
311   for (size_t i = 0; i < len; ++i) {
312     ScopedJavaLocalRef<jstring> str(
313         env, static_cast<jstring>(env->GetObjectArrayElement(
314                  array.obj(), static_cast<jsize>(i))));
315     ConvertJavaStringToUTF16(env, str.obj(), out->data() + back + i);
316   }
317 }
318 
AppendJavaStringArrayToStringVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::string> * out)319 void AppendJavaStringArrayToStringVector(JNIEnv* env,
320                                          const JavaRef<jobjectArray>& array,
321                                          std::vector<std::string>* out) {
322   DCHECK(out);
323   if (!array)
324     return;
325   size_t len = SafeGetArrayLength(env, array);
326   size_t back = out->size();
327   out->resize(back + len);
328   for (size_t i = 0; i < len; ++i) {
329     ScopedJavaLocalRef<jstring> str(
330         env, static_cast<jstring>(env->GetObjectArrayElement(
331                  array.obj(), static_cast<jsize>(i))));
332     ConvertJavaStringToUTF8(env, str.obj(), out->data() + back + i);
333   }
334 }
335 
AppendJavaByteArrayToByteVector(JNIEnv * env,const JavaRef<jbyteArray> & byte_array,std::vector<uint8_t> * out)336 void AppendJavaByteArrayToByteVector(JNIEnv* env,
337                                      const JavaRef<jbyteArray>& byte_array,
338                                      std::vector<uint8_t>* out) {
339   DCHECK(out);
340   if (!byte_array)
341     return;
342   size_t len = SafeGetArrayLength(env, byte_array);
343   if (!len)
344     return;
345   size_t back = out->size();
346   out->resize(back + len);
347   env->GetByteArrayRegion(byte_array.obj(), 0, static_cast<jsize>(len),
348                           reinterpret_cast<int8_t*>(out->data() + back));
349 }
350 
JavaByteArrayToByteVector(JNIEnv * env,const JavaRef<jbyteArray> & byte_array,std::vector<uint8_t> * out)351 void JavaByteArrayToByteVector(JNIEnv* env,
352                                const JavaRef<jbyteArray>& byte_array,
353                                std::vector<uint8_t>* out) {
354   DCHECK(out);
355   DCHECK(byte_array);
356   out->clear();
357   AppendJavaByteArrayToByteVector(env, byte_array, out);
358 }
359 
JavaByteArrayToByteSpan(JNIEnv * env,const JavaRef<jbyteArray> & byte_array,base::span<uint8_t> dest)360 size_t JavaByteArrayToByteSpan(JNIEnv* env,
361                                const JavaRef<jbyteArray>& byte_array,
362                                base::span<uint8_t> dest) {
363   CHECK(byte_array);
364   size_t len = SafeGetArrayLength(env, byte_array);
365   size_t span_len = dest.size_bytes();
366   CHECK_GE(span_len, len) << "Target span is too small, java array size: "
367                           << len << ", span size: " << span_len;
368   env->GetByteArrayRegion(byte_array.obj(), 0, static_cast<jsize>(len),
369                           reinterpret_cast<int8_t*>(dest.data()));
370   return len;
371 }
372 
JavaByteArrayToString(JNIEnv * env,const JavaRef<jbyteArray> & byte_array,std::string * out)373 void JavaByteArrayToString(JNIEnv* env,
374                            const JavaRef<jbyteArray>& byte_array,
375                            std::string* out) {
376   DCHECK(out);
377   DCHECK(byte_array);
378 
379   std::vector<uint8_t> byte_vector;
380   JavaByteArrayToByteVector(env, byte_array, &byte_vector);
381   out->assign(byte_vector.begin(), byte_vector.end());
382 }
383 
JavaBooleanArrayToBoolVector(JNIEnv * env,const JavaRef<jbooleanArray> & boolean_array,std::vector<bool> * out)384 void JavaBooleanArrayToBoolVector(JNIEnv* env,
385                                   const JavaRef<jbooleanArray>& boolean_array,
386                                   std::vector<bool>* out) {
387   DCHECK(out);
388   if (!boolean_array)
389     return;
390   size_t len = SafeGetArrayLength(env, boolean_array);
391   if (!len)
392     return;
393   out->resize(len);
394   // It is not possible to get bool* out of vector<bool>.
395   jboolean* values = env->GetBooleanArrayElements(boolean_array.obj(), nullptr);
396   for (size_t i = 0; i < len; ++i) {
397     out->at(i) = static_cast<bool>(values[i]);
398   }
399   env->ReleaseBooleanArrayElements(boolean_array.obj(), values, JNI_ABORT);
400 }
401 
JavaIntArrayToIntVector(JNIEnv * env,const JavaRef<jintArray> & int_array,std::vector<int> * out)402 void JavaIntArrayToIntVector(JNIEnv* env,
403                              const JavaRef<jintArray>& int_array,
404                              std::vector<int>* out) {
405   DCHECK(out);
406   size_t len = SafeGetArrayLength(env, int_array);
407   out->resize(len);
408   if (!len)
409     return;
410   env->GetIntArrayRegion(int_array.obj(), 0, static_cast<jsize>(len),
411                          out->data());
412 }
413 
JavaLongArrayToInt64Vector(JNIEnv * env,const JavaRef<jlongArray> & long_array,std::vector<int64_t> * out)414 void JavaLongArrayToInt64Vector(JNIEnv* env,
415                                 const JavaRef<jlongArray>& long_array,
416                                 std::vector<int64_t>* out) {
417   DCHECK(out);
418   std::vector<jlong> temp;
419   JavaLongArrayToLongVector(env, long_array, &temp);
420   out->resize(0);
421   out->insert(out->begin(), temp.begin(), temp.end());
422 }
423 
JavaLongArrayToLongVector(JNIEnv * env,const JavaRef<jlongArray> & long_array,std::vector<jlong> * out)424 void JavaLongArrayToLongVector(JNIEnv* env,
425                                const JavaRef<jlongArray>& long_array,
426                                std::vector<jlong>* out) {
427   DCHECK(out);
428   size_t len = SafeGetArrayLength(env, long_array);
429   out->resize(len);
430   if (!len)
431     return;
432   env->GetLongArrayRegion(long_array.obj(), 0, static_cast<jsize>(len),
433                           out->data());
434 }
435 
JavaFloatArrayToFloatVector(JNIEnv * env,const JavaRef<jfloatArray> & float_array,std::vector<float> * out)436 void JavaFloatArrayToFloatVector(JNIEnv* env,
437                                  const JavaRef<jfloatArray>& float_array,
438                                  std::vector<float>* out) {
439   DCHECK(out);
440   size_t len = SafeGetArrayLength(env, float_array);
441   out->resize(len);
442   if (!len)
443     return;
444   env->GetFloatArrayRegion(float_array.obj(), 0, static_cast<jsize>(len),
445                            out->data());
446 }
447 
JavaDoubleArrayToDoubleVector(JNIEnv * env,const JavaRef<jdoubleArray> & double_array,std::vector<double> * out)448 void JavaDoubleArrayToDoubleVector(JNIEnv* env,
449                                    const JavaRef<jdoubleArray>& double_array,
450                                    std::vector<double>* out) {
451   DCHECK(out);
452   size_t len = SafeGetArrayLength(env, double_array);
453   out->resize(len);
454   if (!len)
455     return;
456   env->GetDoubleArrayRegion(double_array.obj(), 0, static_cast<jsize>(len),
457                             out->data());
458 }
459 
JavaArrayOfByteArrayToStringVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::string> * out)460 void JavaArrayOfByteArrayToStringVector(JNIEnv* env,
461                                         const JavaRef<jobjectArray>& array,
462                                         std::vector<std::string>* out) {
463   DCHECK(out);
464   size_t len = SafeGetArrayLength(env, array);
465   out->resize(len);
466   for (size_t i = 0; i < len; ++i) {
467     ScopedJavaLocalRef<jbyteArray> bytes_array(
468         env, static_cast<jbyteArray>(env->GetObjectArrayElement(
469                  array.obj(), static_cast<jsize>(i))));
470     size_t bytes_len = SafeGetArrayLength(env, bytes_array);
471     jbyte* bytes = env->GetByteArrayElements(bytes_array.obj(), nullptr);
472     (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
473     env->ReleaseByteArrayElements(bytes_array.obj(), bytes, JNI_ABORT);
474   }
475 }
476 
JavaArrayOfByteArrayToBytesVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::vector<uint8_t>> * out)477 void JavaArrayOfByteArrayToBytesVector(JNIEnv* env,
478                                        const JavaRef<jobjectArray>& array,
479                                        std::vector<std::vector<uint8_t>>* out) {
480   DCHECK(out);
481   const size_t len = SafeGetArrayLength(env, array);
482   out->resize(len);
483   for (size_t i = 0; i < len; ++i) {
484     ScopedJavaLocalRef<jbyteArray> bytes_array(
485         env, static_cast<jbyteArray>(env->GetObjectArrayElement(
486                  array.obj(), static_cast<jsize>(i))));
487     JavaByteArrayToByteVector(env, bytes_array, &(*out)[i]);
488   }
489 }
490 
Java2dStringArrayTo2dStringVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::vector<std::u16string>> * out)491 void Java2dStringArrayTo2dStringVector(
492     JNIEnv* env,
493     const JavaRef<jobjectArray>& array,
494     std::vector<std::vector<std::u16string>>* out) {
495   DCHECK(out);
496   size_t len = SafeGetArrayLength(env, array);
497   out->resize(len);
498   for (size_t i = 0; i < len; ++i) {
499     ScopedJavaLocalRef<jobjectArray> strings_array(
500         env, static_cast<jobjectArray>(env->GetObjectArrayElement(
501                  array.obj(), static_cast<jsize>(i))));
502 
503     out->at(i).clear();
504     AppendJavaStringArrayToStringVector(env, strings_array, &out->at(i));
505   }
506 }
507 
Java2dStringArrayTo2dStringVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::vector<std::string>> * out)508 void Java2dStringArrayTo2dStringVector(
509     JNIEnv* env,
510     const JavaRef<jobjectArray>& array,
511     std::vector<std::vector<std::string>>* out) {
512   DCHECK(out);
513   size_t len = SafeGetArrayLength(env, array);
514   out->resize(len);
515   for (size_t i = 0; i < len; ++i) {
516     ScopedJavaLocalRef<jobjectArray> strings_array(
517         env, static_cast<jobjectArray>(env->GetObjectArrayElement(
518                  array.obj(), static_cast<jsize>(i))));
519 
520     out->at(i).clear();
521     AppendJavaStringArrayToStringVector(env, strings_array, &out->at(i));
522   }
523 }
524 
JavaArrayOfIntArrayToIntVector(JNIEnv * env,const JavaRef<jobjectArray> & array,std::vector<std::vector<int>> * out)525 void JavaArrayOfIntArrayToIntVector(JNIEnv* env,
526                                     const JavaRef<jobjectArray>& array,
527                                     std::vector<std::vector<int>>* out) {
528   DCHECK(out);
529   size_t len = SafeGetArrayLength(env, array);
530   out->resize(len);
531   for (size_t i = 0; i < len; ++i) {
532     ScopedJavaLocalRef<jintArray> int_array(
533         env, static_cast<jintArray>(env->GetObjectArrayElement(
534                  array.obj(), static_cast<jsize>(i))));
535     JavaIntArrayToIntVector(env, int_array, &out->at(i));
536   }
537 }
538 
539 }  // namespace base::android
540