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