jni_array.cc 19 KB

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