Home | History | Annotate | Download | only in jni
      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 
     34 JNIHelper::JNIHelper(JavaVM *vm)
     35 {
     36     vm->AttachCurrentThread(&mEnv, NULL);
     37     mVM = vm;
     38 }
     39 
     40 JNIHelper::JNIHelper(JNIEnv *env)
     41 {
     42     mVM  = NULL;
     43     mEnv = env;
     44 }
     45 
     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 
     55 jobject JNIHelper::newGlobalRef(jobject obj) {
     56     return mEnv->NewGlobalRef(obj);
     57 }
     58 
     59 void JNIHelper::deleteGlobalRef(jobject obj) {
     60     mEnv->DeleteGlobalRef(obj);
     61 }
     62 
     63 jobject JNIHelper::newLocalRef(jobject obj) {
     64     return mEnv->NewLocalRef(obj);
     65 }
     66 
     67 void JNIHelper::deleteLocalRef(jobject obj) {
     68     mEnv->DeleteLocalRef(obj);
     69 }
     70 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    572 JNIObject<jobject> JNIHelper::createObject(const char *className) {
    573     return createObjectWithArgs(className, "()V");
    574 }
    575 
    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 
    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 
    621 JNIObject<jobject> JNIHelper::getObjectArrayElement(jobjectArray array, int index)
    622 {
    623     return JNIObject<jobject>(*this, mEnv->GetObjectArrayElement(array, index));
    624 }
    625 
    626 JNIObject<jobject> JNIHelper::getObjectArrayElement(jobject array, int index)
    627 {
    628     return getObjectArrayElement((jobjectArray)array, index);
    629 }
    630 
    631 int JNIHelper::getArrayLength(jarray array) {
    632     return mEnv->GetArrayLength(array);
    633 }
    634 
    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 
    645 JNIObject<jbyteArray> JNIHelper::newByteArray(int num) {
    646     return JNIObject<jbyteArray>(*this, mEnv->NewByteArray(num));
    647 }
    648 
    649 JNIObject<jintArray> JNIHelper::newIntArray(int num) {
    650     return JNIObject<jintArray>(*this, mEnv->NewIntArray(num));
    651 }
    652 
    653 JNIObject<jlongArray> JNIHelper::newLongArray(int num) {
    654     return JNIObject<jlongArray>(*this, mEnv->NewLongArray(num));
    655 }
    656 
    657 JNIObject<jstring> JNIHelper::newStringUTF(const char *utf) {
    658     return JNIObject<jstring>(*this, mEnv->NewStringUTF(utf));
    659 }
    660 
    661 void JNIHelper::setObjectArrayElement(jobjectArray array, int index, jobject obj) {
    662     mEnv->SetObjectArrayElement(array, index, obj);
    663 }
    664 
    665 void JNIHelper::setByteArrayRegion(jbyteArray array, int from, int to, const jbyte *bytes) {
    666     mEnv->SetByteArrayRegion(array, from, to, bytes);
    667 }
    668 
    669 void JNIHelper::setIntArrayRegion(jintArray array, int from, int to, const jint *ints) {
    670     mEnv->SetIntArrayRegion(array, from, to, ints);
    671 }
    672 
    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