1 /*
2 * Copyright 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "wifi"
18
19 #include "jni.h"
20 #include <ScopedUtfChars.h>
21 #include <utils/misc.h>
22 #include <android_runtime/AndroidRuntime.h>
23 #include <utils/Log.h>
24 #include <utils/String16.h>
25
26 #include "wifi.h"
27 #include "wifi_hal.h"
28 #include "jni_helper.h"
29
30 namespace android {
31
32 /* JNI Helpers for wifi_hal implementation */
33
JNIHelper(JavaVM * vm)34 JNIHelper::JNIHelper(JavaVM *vm)
35 {
36 vm->AttachCurrentThread(&mEnv, NULL);
37 mVM = vm;
38 }
39
JNIHelper(JNIEnv * env)40 JNIHelper::JNIHelper(JNIEnv *env)
41 {
42 mVM = NULL;
43 mEnv = env;
44 }
45
~JNIHelper()46 JNIHelper::~JNIHelper()
47 {
48 if (mVM != NULL) {
49 // mVM->DetachCurrentThread(); /* 'attempting to detach while still running code' */
50 mVM = NULL; /* not really required; but may help debugging */
51 mEnv = NULL; /* not really required; but may help debugging */
52 }
53 }
54
newGlobalRef(jobject obj)55 jobject JNIHelper::newGlobalRef(jobject obj) {
56 return mEnv->NewGlobalRef(obj);
57 }
58
deleteGlobalRef(jobject obj)59 void JNIHelper::deleteGlobalRef(jobject obj) {
60 mEnv->DeleteGlobalRef(obj);
61 }
62
newLocalRef(jobject obj)63 jobject JNIHelper::newLocalRef(jobject obj) {
64 return mEnv->NewLocalRef(obj);
65 }
66
deleteLocalRef(jobject obj)67 void JNIHelper::deleteLocalRef(jobject obj) {
68 mEnv->DeleteLocalRef(obj);
69 }
70
throwException(const char * message,int line)71 void JNIHelper::throwException(const char *message, int line)
72 {
73 ALOGE("error at line %d: %s", line, message);
74
75 const char *className = "java/lang/Exception";
76
77 jclass exClass = mEnv->FindClass(className );
78 if ( exClass == NULL ) {
79 ALOGE("Could not find exception class to throw error");
80 ALOGE("error at line %d: %s", line, message);
81 return;
82 }
83
84 mEnv->ThrowNew(exClass, message);
85 }
86
getBoolField(jobject obj,const char * name)87 jboolean JNIHelper::getBoolField(jobject obj, const char *name)
88 {
89 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
90 jfieldID field = mEnv->GetFieldID(cls, name, "Z");
91 if (field == 0) {
92 THROW(*this, "Error in accessing field");
93 return 0;
94 }
95
96 return mEnv->GetBooleanField(obj, field);
97 }
98
getIntField(jobject obj,const char * name)99 jint JNIHelper::getIntField(jobject obj, const char *name)
100 {
101 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
102 jfieldID field = mEnv->GetFieldID(cls, name, "I");
103 if (field == 0) {
104 THROW(*this, "Error in accessing field");
105 return 0;
106 }
107
108 return mEnv->GetIntField(obj, field);
109 }
110
getByteField(jobject obj,const char * name)111 jbyte JNIHelper::getByteField(jobject obj, const char *name)
112 {
113 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
114 jfieldID field = mEnv->GetFieldID(cls, name, "B");
115 if (field == 0) {
116 THROW(*this, "Error in accessing field");
117 return 0;
118 }
119
120 return mEnv->GetByteField(obj, field);
121 }
122
getLongField(jobject obj,const char * name)123 jlong JNIHelper::getLongField(jobject obj, const char *name)
124 {
125 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
126 jfieldID field = mEnv->GetFieldID(cls, name, "J");
127 if (field == 0) {
128 THROW(*this, "Error in accessing field");
129 return 0;
130 }
131
132 return mEnv->GetLongField(obj, field);
133 }
134
getStringField(jobject obj,const char * name)135 JNIObject<jstring> JNIHelper::getStringField(jobject obj, const char *name)
136 {
137 JNIObject<jobject> m = getObjectField(obj, name, "Ljava/lang/String;");
138 if (m == NULL) {
139 THROW(*this, "Error in accessing field");
140 return JNIObject<jstring>(*this, NULL);
141 }
142
143 return JNIObject<jstring>(*this, (jstring)m.detach());
144 }
145
getStringFieldValue(jobject obj,const char * name,char * buf,int size)146 bool JNIHelper::getStringFieldValue(jobject obj, const char *name, char *buf, int size)
147 {
148 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
149 jfieldID field = mEnv->GetFieldID(cls, name, "Ljava/lang/String;");
150 if (field == 0) {
151 THROW(*this, "Error in accessing field");
152 return 0;
153 }
154
155 JNIObject<jobject> value(*this, mEnv->GetObjectField(obj, field));
156 JNIObject<jstring> string(*this, (jstring)value.clone());
157 ScopedUtfChars chars(mEnv, string);
158
159 const char *utf = chars.c_str();
160 if (utf == NULL) {
161 THROW(*this, "Error in accessing value");
162 return false;
163 }
164
165 if (*utf != 0 && size < 1) {
166 return false;
167 }
168
169 strncpy(buf, utf, size);
170 if (size > 0) {
171 buf[size - 1] = 0;
172 }
173
174 return true;
175 }
176
getStaticLongField(jobject obj,const char * name)177 jlong JNIHelper::getStaticLongField(jobject obj, const char *name)
178 {
179 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
180 return getStaticLongField(cls, name);
181 }
182
getStaticLongField(jclass cls,const char * name)183 jlong JNIHelper::getStaticLongField(jclass cls, const char *name)
184 {
185 jfieldID field = mEnv->GetStaticFieldID(cls, name, "J");
186 if (field == 0) {
187 THROW(*this, "Error in accessing field");
188 return 0;
189 }
190 //ALOGE("getStaticLongField %s %p", name, cls);
191 return mEnv->GetStaticLongField(cls, field);
192 }
193
getObjectField(jobject obj,const char * name,const char * type)194 JNIObject<jobject> JNIHelper::getObjectField(jobject obj, const char *name, const char *type)
195 {
196 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
197 jfieldID field = mEnv->GetFieldID(cls, name, type);
198 if (field == 0) {
199 THROW(*this, "Error in accessing field");
200 return JNIObject<jobject>(*this, NULL);
201 }
202
203 return JNIObject<jobject>(*this, mEnv->GetObjectField(obj, field));
204 }
205
getArrayField(jobject obj,const char * name,const char * type)206 JNIObject<jobjectArray> JNIHelper::getArrayField(jobject obj, const char *name, const char *type)
207 {
208 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
209 jfieldID field = mEnv->GetFieldID(cls, name, type);
210 if (field == 0) {
211 THROW(*this, "Error in accessing field");
212 return JNIObject<jobjectArray>(*this, NULL);
213 }
214
215 return JNIObject<jobjectArray>(*this, (jobjectArray)mEnv->GetObjectField(obj, field));
216 }
217
getLongArrayField(jobject obj,const char * name,int index)218 jlong JNIHelper::getLongArrayField(jobject obj, const char *name, int index)
219 {
220 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
221 jfieldID field = mEnv->GetFieldID(cls, name, "[J");
222 if (field == 0) {
223 THROW(*this, "Error in accessing field definition");
224 return 0;
225 }
226
227 JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetObjectField(obj, field));
228 if (array == NULL) {
229 THROW(*this, "Error in accessing array");
230 return 0;
231 }
232
233 jlong *elem = mEnv->GetLongArrayElements(array, 0);
234 if (elem == NULL) {
235 THROW(*this, "Error in accessing index element");
236 return 0;
237 }
238
239 jlong value = elem[index];
240 mEnv->ReleaseLongArrayElements(array, elem, 0);
241 return value;
242 }
243
getByteArrayField(jobject obj,const char * name,byte * buf,int size)244 void JNIHelper::getByteArrayField(jobject obj, const char *name, byte* buf, int size) {
245 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
246 jfieldID field = mEnv->GetFieldID(cls, name, "[B");
247 if (field == 0) {
248 THROW(*this, "Error in accessing field definition");
249 return;
250 }
251
252 JNIObject<jbyteArray> array(*this, (jbyteArray)mEnv->GetObjectField(obj, field));
253 if (array == NULL) {
254 THROW(*this, "Error in accessing array");
255 return;
256 }
257
258 jbyte *elem = mEnv->GetByteArrayElements(array, 0);
259 if (elem == NULL) {
260 THROW(*this, "Error in accessing index element");
261 return;
262 }
263
264 memcpy(buf, elem, size);
265 mEnv->ReleaseByteArrayElements(array, elem, 0);
266 }
267
getStaticLongArrayField(jobject obj,const char * name,int index)268 jlong JNIHelper::getStaticLongArrayField(jobject obj, const char *name, int index)
269 {
270 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
271 return getStaticLongArrayField(cls, name, index);
272 }
273
getStaticLongArrayField(jclass cls,const char * name,int index)274 jlong JNIHelper::getStaticLongArrayField(jclass cls, const char *name, int index)
275 {
276 jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J");
277 if (field == 0) {
278 THROW(*this, "Error in accessing field definition");
279 return 0;
280 }
281
282 JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetStaticObjectField(cls, field));
283 jlong *elem = mEnv->GetLongArrayElements(array, 0);
284 if (elem == NULL) {
285 THROW(*this, "Error in accessing index element");
286 return 0;
287 }
288
289 jlong value = elem[index];
290 mEnv->ReleaseLongArrayElements(array, elem, 0);
291 return value;
292 }
293
getObjectArrayField(jobject obj,const char * name,const char * type,int index)294 JNIObject<jobject> JNIHelper::getObjectArrayField(jobject obj, const char *name, const char *type,
295 int index)
296 {
297 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
298 jfieldID field = mEnv->GetFieldID(cls, name, type);
299 if (field == 0) {
300 THROW(*this, "Error in accessing field definition");
301 return JNIObject<jobject>(*this, NULL);
302 }
303
304 JNIObject<jobjectArray> array(*this, (jobjectArray)mEnv->GetObjectField(obj, field));
305 JNIObject<jobject> elem(*this, mEnv->GetObjectArrayElement(array, index));
306 if (elem.isNull()) {
307 THROW(*this, "Error in accessing index element");
308 return JNIObject<jobject>(*this, NULL);
309 }
310 return elem;
311 }
312
setIntField(jobject obj,const char * name,jint value)313 void JNIHelper::setIntField(jobject obj, const char *name, jint value)
314 {
315 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
316 if (cls == NULL) {
317 THROW(*this, "Error in accessing class");
318 return;
319 }
320
321 jfieldID field = mEnv->GetFieldID(cls, name, "I");
322 if (field == NULL) {
323 THROW(*this, "Error in accessing field");
324 return;
325 }
326
327 mEnv->SetIntField(obj, field, value);
328 }
329
setByteField(jobject obj,const char * name,jbyte value)330 void JNIHelper::setByteField(jobject obj, const char *name, jbyte value)
331 {
332 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
333 if (cls == NULL) {
334 THROW(*this, "Error in accessing class");
335 return;
336 }
337
338 jfieldID field = mEnv->GetFieldID(cls, name, "B");
339 if (field == NULL) {
340 THROW(*this, "Error in accessing field");
341 return;
342 }
343
344 mEnv->SetByteField(obj, field, value);
345 }
346
setBooleanField(jobject obj,const char * name,jboolean value)347 void JNIHelper::setBooleanField(jobject obj, const char *name, jboolean value)
348 {
349 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
350 if (cls == NULL) {
351 THROW(*this, "Error in accessing class");
352 return;
353 }
354
355 jfieldID field = mEnv->GetFieldID(cls, name, "Z");
356 if (field == NULL) {
357 THROW(*this, "Error in accessing field");
358 return;
359 }
360
361 mEnv->SetBooleanField(obj, field, value);
362 }
363
setLongField(jobject obj,const char * name,jlong value)364 void JNIHelper::setLongField(jobject obj, const char *name, jlong value)
365 {
366 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
367 if (cls == NULL) {
368 THROW(*this, "Error in accessing class");
369 return;
370 }
371
372 jfieldID field = mEnv->GetFieldID(cls, name, "J");
373 if (field == NULL) {
374 THROW(*this, "Error in accessing field");
375 return;
376 }
377
378 mEnv->SetLongField(obj, field, value);
379 }
380
setStaticLongField(jobject obj,const char * name,jlong value)381 void JNIHelper::setStaticLongField(jobject obj, const char *name, jlong value)
382 {
383 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
384 if (cls == NULL) {
385 THROW(*this, "Error in accessing class");
386 return;
387 }
388
389 setStaticLongField(cls, name, value);
390 }
391
setStaticLongField(jclass cls,const char * name,jlong value)392 void JNIHelper::setStaticLongField(jclass cls, const char *name, jlong value)
393 {
394 jfieldID field = mEnv->GetStaticFieldID(cls, name, "J");
395 if (field == NULL) {
396 THROW(*this, "Error in accessing field");
397 return;
398 }
399
400 mEnv->SetStaticLongField(cls, field, value);
401 }
402
setLongArrayField(jobject obj,const char * name,jlongArray value)403 void JNIHelper::setLongArrayField(jobject obj, const char *name, jlongArray value)
404 {
405 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
406 if (cls == NULL) {
407 THROW(*this, "Error in accessing field");
408 return;
409 }
410
411 jfieldID field = mEnv->GetFieldID(cls, name, "[J");
412 if (field == NULL) {
413 THROW(*this, "Error in accessing field");
414 return;
415 }
416
417 mEnv->SetObjectField(obj, field, value);
418 }
419
setStaticLongArrayField(jobject obj,const char * name,jlongArray value)420 void JNIHelper::setStaticLongArrayField(jobject obj, const char *name, jlongArray value)
421 {
422 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
423 if (cls == NULL) {
424 THROW(*this, "Error in accessing field");
425 return;
426 }
427
428 setStaticLongArrayField(cls, name, value);
429 }
430
setStaticLongArrayField(jclass cls,const char * name,jlongArray value)431 void JNIHelper::setStaticLongArrayField(jclass cls, const char *name, jlongArray value)
432 {
433 jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J");
434 if (field == NULL) {
435 THROW(*this, "Error in accessing field");
436 return;
437 }
438
439 mEnv->SetStaticObjectField(cls, field, value);
440 ALOGD("array field set");
441 }
442
setLongArrayElement(jobject obj,const char * name,int index,jlong value)443 void JNIHelper::setLongArrayElement(jobject obj, const char *name, int index, jlong value)
444 {
445 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
446 if (cls == NULL) {
447 THROW(*this, "Error in accessing field");
448 return;
449 }
450
451 jfieldID field = mEnv->GetFieldID(cls, name, "[J");
452 if (field == NULL) {
453 THROW(*this, "Error in accessing field");
454 return;
455 }
456
457 JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetObjectField(obj, field));
458 if (array == NULL) {
459 THROW(*this, "Error in accessing array");
460 return;
461 }
462
463 jlong *elem = mEnv->GetLongArrayElements(array, NULL);
464 if (elem == NULL) {
465 THROW(*this, "Error in accessing index element");
466 return;
467 }
468
469 elem[index] = value;
470 mEnv->ReleaseLongArrayElements(array, elem, 0);
471 }
472
setObjectField(jobject obj,const char * name,const char * type,jobject value)473 void JNIHelper::setObjectField(jobject obj, const char *name, const char *type, jobject value)
474 {
475 JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
476 if (cls == NULL) {
477 THROW(*this, "Error in accessing class");
478 return;
479 }
480
481 jfieldID field = mEnv->GetFieldID(cls, name, type);
482 if (field == NULL) {
483 THROW(*this, "Error in accessing field");
484 return;
485 }
486
487 mEnv->SetObjectField(obj, field, value);
488 }
489
setStringField(jobject obj,const char * name,const char * value)490 jboolean JNIHelper::setStringField(jobject obj, const char *name, const char *value)
491 {
492 JNIObject<jstring> str(*this, mEnv->NewStringUTF(value));
493
494 if (mEnv->ExceptionCheck()) {
495 mEnv->ExceptionDescribe();
496 mEnv->ExceptionClear();
497 return false;
498 }
499
500 if (str == NULL) {
501 THROW(*this, "Error creating string");
502 return false;
503 }
504
505 setObjectField(obj, name, "Ljava/lang/String;", str);
506 return true;
507 }
508
reportEvent(jclass cls,const char * method,const char * signature,...)509 void JNIHelper::reportEvent(jclass cls, const char *method, const char *signature, ...)
510 {
511 va_list params;
512 va_start(params, signature);
513
514 jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
515 if (methodID == 0) {
516 ALOGE("Error in getting method ID");
517 return;
518 }
519
520 mEnv->CallStaticVoidMethodV(cls, methodID, params);
521 if (mEnv->ExceptionCheck()) {
522 mEnv->ExceptionDescribe();
523 mEnv->ExceptionClear();
524 }
525
526 va_end(params);
527 }
528
callMethod(jobject obj,const char * method,const char * signature,...)529 void JNIHelper::callMethod(jobject obj, const char *method, const char *signature, ...)
530 {
531 va_list params;
532 va_start(params, signature);
533
534 jclass cls = mEnv->GetObjectClass(obj);
535 jmethodID methodID = mEnv->GetMethodID(cls, method, signature);
536 if (methodID == 0) {
537 ALOGE("Error in getting method ID");
538 return;
539 }
540
541 mEnv->CallVoidMethodV(obj, methodID, params);
542 if (mEnv->ExceptionCheck()) {
543 mEnv->ExceptionDescribe();
544 mEnv->ExceptionClear();
545 }
546
547 va_end(params);
548 }
549
callStaticMethod(jclass cls,const char * method,const char * signature,...)550 jboolean JNIHelper::callStaticMethod(jclass cls, const char *method, const char *signature, ...)
551 {
552 va_list params;
553 va_start(params, signature);
554
555 jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
556 if (methodID == 0) {
557 ALOGE("Error in getting method ID");
558 return false;
559 }
560
561 jboolean result = mEnv->CallStaticBooleanMethodV(cls, methodID, params);
562 if (mEnv->ExceptionCheck()) {
563 mEnv->ExceptionDescribe();
564 mEnv->ExceptionClear();
565 return false;
566 }
567
568 va_end(params);
569 return result;
570 }
571
createObject(const char * className)572 JNIObject<jobject> JNIHelper::createObject(const char *className) {
573 return createObjectWithArgs(className, "()V");
574 }
575
createObjectWithArgs(const char * className,const char * signature,...)576 JNIObject<jobject> JNIHelper::createObjectWithArgs(
577 const char *className, const char *signature, ...)
578 {
579 va_list params;
580 va_start(params, signature);
581
582 JNIObject<jclass> cls(*this, mEnv->FindClass(className));
583 if (cls == NULL) {
584 ALOGE("Error in finding class %s", className);
585 return JNIObject<jobject>(*this, NULL);
586 }
587
588 jmethodID constructor = mEnv->GetMethodID(cls, "<init>", signature);
589 if (constructor == 0) {
590 ALOGE("Error in constructor ID for %s", className);
591 return JNIObject<jobject>(*this, NULL);
592 }
593
594 JNIObject<jobject> obj(*this, mEnv->NewObjectV(cls, constructor, params));
595 if (obj == NULL) {
596 ALOGE("Could not create new object of %s", className);
597 return JNIObject<jobject>(*this, NULL);
598 }
599
600 va_end(params);
601 return obj;
602 }
603
createObjectArray(const char * className,int num)604 JNIObject<jobjectArray> JNIHelper::createObjectArray(const char *className, int num)
605 {
606 JNIObject<jclass> cls(*this, mEnv->FindClass(className));
607 if (cls == NULL) {
608 ALOGE("Error in finding class %s", className);
609 return JNIObject<jobjectArray>(*this, NULL);
610 }
611
612 JNIObject<jobject> array(*this, mEnv->NewObjectArray(num, cls.get(), NULL));
613 if (array.get() == NULL) {
614 ALOGE("Error in creating array of class %s", className);
615 return JNIObject<jobjectArray>(*this, NULL);
616 }
617
618 return JNIObject<jobjectArray>(*this, (jobjectArray)array.detach());
619 }
620
getObjectArrayElement(jobjectArray array,int index)621 JNIObject<jobject> JNIHelper::getObjectArrayElement(jobjectArray array, int index)
622 {
623 return JNIObject<jobject>(*this, mEnv->GetObjectArrayElement(array, index));
624 }
625
getObjectArrayElement(jobject array,int index)626 JNIObject<jobject> JNIHelper::getObjectArrayElement(jobject array, int index)
627 {
628 return getObjectArrayElement((jobjectArray)array, index);
629 }
630
getArrayLength(jarray array)631 int JNIHelper::getArrayLength(jarray array) {
632 return mEnv->GetArrayLength(array);
633 }
634
newObjectArray(int num,const char * className,jobject val)635 JNIObject<jobjectArray> JNIHelper::newObjectArray(int num, const char *className, jobject val) {
636 JNIObject<jclass> cls(*this, mEnv->FindClass(className));
637 if (cls == NULL) {
638 ALOGE("Error in finding class %s", className);
639 return JNIObject<jobjectArray>(*this, NULL);
640 }
641
642 return JNIObject<jobjectArray>(*this, mEnv->NewObjectArray(num, cls, val));
643 }
644
newByteArray(int num)645 JNIObject<jbyteArray> JNIHelper::newByteArray(int num) {
646 return JNIObject<jbyteArray>(*this, mEnv->NewByteArray(num));
647 }
648
newIntArray(int num)649 JNIObject<jintArray> JNIHelper::newIntArray(int num) {
650 return JNIObject<jintArray>(*this, mEnv->NewIntArray(num));
651 }
652
newLongArray(int num)653 JNIObject<jlongArray> JNIHelper::newLongArray(int num) {
654 return JNIObject<jlongArray>(*this, mEnv->NewLongArray(num));
655 }
656
newStringUTF(const char * utf)657 JNIObject<jstring> JNIHelper::newStringUTF(const char *utf) {
658 return JNIObject<jstring>(*this, mEnv->NewStringUTF(utf));
659 }
660
setObjectArrayElement(jobjectArray array,int index,jobject obj)661 void JNIHelper::setObjectArrayElement(jobjectArray array, int index, jobject obj) {
662 mEnv->SetObjectArrayElement(array, index, obj);
663 }
664
setByteArrayRegion(jbyteArray array,int from,int to,const jbyte * bytes)665 void JNIHelper::setByteArrayRegion(jbyteArray array, int from, int to, const jbyte *bytes) {
666 mEnv->SetByteArrayRegion(array, from, to, bytes);
667 }
668
setIntArrayRegion(jintArray array,int from,int to,const jint * ints)669 void JNIHelper::setIntArrayRegion(jintArray array, int from, int to, const jint *ints) {
670 mEnv->SetIntArrayRegion(array, from, to, ints);
671 }
672
setLongArrayRegion(jlongArray array,int from,int to,const jlong * longs)673 void JNIHelper::setLongArrayRegion(jlongArray array, int from, int to, const jlong *longs) {
674 mEnv->SetLongArrayRegion(array, from, to, longs);
675 }
676
677 }; // namespace android
678
679
680