• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2008, 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 
getStaticLongArrayField(jobject obj,const char * name,int index)244 jlong JNIHelper::getStaticLongArrayField(jobject obj, const char *name, int index)
245 {
246     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
247     return getStaticLongArrayField(cls, name, index);
248 }
249 
getStaticLongArrayField(jclass cls,const char * name,int index)250 jlong JNIHelper::getStaticLongArrayField(jclass cls, const char *name, int index)
251 {
252     jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J");
253     if (field == 0) {
254         THROW(*this, "Error in accessing field definition");
255         return 0;
256     }
257 
258     JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetStaticObjectField(cls, field));
259     jlong *elem = mEnv->GetLongArrayElements(array, 0);
260     if (elem == NULL) {
261         THROW(*this, "Error in accessing index element");
262         return 0;
263     }
264 
265     jlong value = elem[index];
266     mEnv->ReleaseLongArrayElements(array, elem, 0);
267     return value;
268 }
269 
getObjectArrayField(jobject obj,const char * name,const char * type,int index)270 JNIObject<jobject> JNIHelper::getObjectArrayField(jobject obj, const char *name, const char *type,
271 int index)
272 {
273     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
274     jfieldID field = mEnv->GetFieldID(cls, name, type);
275     if (field == 0) {
276         THROW(*this, "Error in accessing field definition");
277         return JNIObject<jobject>(*this, NULL);
278     }
279 
280     JNIObject<jobjectArray> array(*this, (jobjectArray)mEnv->GetObjectField(obj, field));
281     JNIObject<jobject> elem(*this, mEnv->GetObjectArrayElement(array, index));
282     if (elem.isNull()) {
283         THROW(*this, "Error in accessing index element");
284         return JNIObject<jobject>(*this, NULL);
285     }
286     return elem;
287 }
288 
setIntField(jobject obj,const char * name,jint value)289 void JNIHelper::setIntField(jobject obj, const char *name, jint value)
290 {
291     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
292     if (cls == NULL) {
293         THROW(*this, "Error in accessing class");
294         return;
295     }
296 
297     jfieldID field = mEnv->GetFieldID(cls, name, "I");
298     if (field == NULL) {
299         THROW(*this, "Error in accessing field");
300         return;
301     }
302 
303     mEnv->SetIntField(obj, field, value);
304 }
305 
setByteField(jobject obj,const char * name,jbyte value)306 void JNIHelper::setByteField(jobject obj, const char *name, jbyte value)
307 {
308     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
309     if (cls == NULL) {
310         THROW(*this, "Error in accessing class");
311         return;
312     }
313 
314     jfieldID field = mEnv->GetFieldID(cls, name, "B");
315     if (field == NULL) {
316         THROW(*this, "Error in accessing field");
317         return;
318     }
319 
320     mEnv->SetByteField(obj, field, value);
321 }
322 
setBooleanField(jobject obj,const char * name,jboolean value)323 void JNIHelper::setBooleanField(jobject obj, const char *name, jboolean value)
324 {
325     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
326     if (cls == NULL) {
327         THROW(*this, "Error in accessing class");
328         return;
329     }
330 
331     jfieldID field = mEnv->GetFieldID(cls, name, "Z");
332     if (field == NULL) {
333         THROW(*this, "Error in accessing field");
334         return;
335     }
336 
337     mEnv->SetBooleanField(obj, field, value);
338 }
339 
setLongField(jobject obj,const char * name,jlong value)340 void JNIHelper::setLongField(jobject obj, const char *name, jlong value)
341 {
342     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
343     if (cls == NULL) {
344         THROW(*this, "Error in accessing class");
345         return;
346     }
347 
348     jfieldID field = mEnv->GetFieldID(cls, name, "J");
349     if (field == NULL) {
350         THROW(*this, "Error in accessing field");
351         return;
352     }
353 
354     mEnv->SetLongField(obj, field, value);
355 }
356 
setStaticLongField(jobject obj,const char * name,jlong value)357 void JNIHelper::setStaticLongField(jobject obj, const char *name, jlong value)
358 {
359     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
360     if (cls == NULL) {
361         THROW(*this, "Error in accessing class");
362         return;
363     }
364 
365     setStaticLongField(cls, name, value);
366 }
367 
setStaticLongField(jclass cls,const char * name,jlong value)368 void JNIHelper::setStaticLongField(jclass cls, const char *name, jlong value)
369 {
370     jfieldID field = mEnv->GetStaticFieldID(cls, name, "J");
371     if (field == NULL) {
372         THROW(*this, "Error in accessing field");
373         return;
374     }
375 
376     mEnv->SetStaticLongField(cls, field, value);
377 }
378 
setLongArrayField(jobject obj,const char * name,jlongArray value)379 void JNIHelper::setLongArrayField(jobject obj, const char *name, jlongArray value)
380 {
381     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
382     if (cls == NULL) {
383         THROW(*this, "Error in accessing field");
384         return;
385     }
386 
387     jfieldID field = mEnv->GetFieldID(cls, name, "[J");
388     if (field == NULL) {
389         THROW(*this, "Error in accessing field");
390         return;
391     }
392 
393     mEnv->SetObjectField(obj, field, value);
394 }
395 
setStaticLongArrayField(jobject obj,const char * name,jlongArray value)396 void JNIHelper::setStaticLongArrayField(jobject obj, const char *name, jlongArray value)
397 {
398     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
399     if (cls == NULL) {
400         THROW(*this, "Error in accessing field");
401         return;
402     }
403 
404     setStaticLongArrayField(cls, name, value);
405 }
406 
setStaticLongArrayField(jclass cls,const char * name,jlongArray value)407 void JNIHelper::setStaticLongArrayField(jclass cls, const char *name, jlongArray value)
408 {
409     jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J");
410     if (field == NULL) {
411         THROW(*this, "Error in accessing field");
412         return;
413     }
414 
415     mEnv->SetStaticObjectField(cls, field, value);
416     ALOGD("array field set");
417 }
418 
setLongArrayElement(jobject obj,const char * name,int index,jlong value)419 void JNIHelper::setLongArrayElement(jobject obj, const char *name, int index, jlong value)
420 {
421     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
422     if (cls == NULL) {
423         THROW(*this, "Error in accessing field");
424         return;
425     }
426 
427     jfieldID field = mEnv->GetFieldID(cls, name, "[J");
428     if (field == NULL) {
429         THROW(*this, "Error in accessing field");
430         return;
431     }
432 
433     JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetObjectField(obj, field));
434     if (array == NULL) {
435         THROW(*this, "Error in accessing array");
436         return;
437     }
438 
439     jlong *elem = mEnv->GetLongArrayElements(array, NULL);
440     if (elem == NULL) {
441         THROW(*this, "Error in accessing index element");
442         return;
443     }
444 
445     elem[index] = value;
446     mEnv->ReleaseLongArrayElements(array, elem, 0);
447 }
448 
setObjectField(jobject obj,const char * name,const char * type,jobject value)449 void JNIHelper::setObjectField(jobject obj, const char *name, const char *type, jobject value)
450 {
451     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
452     if (cls == NULL) {
453         THROW(*this, "Error in accessing class");
454         return;
455     }
456 
457     jfieldID field = mEnv->GetFieldID(cls, name, type);
458     if (field == NULL) {
459         THROW(*this, "Error in accessing field");
460         return;
461     }
462 
463     mEnv->SetObjectField(obj, field, value);
464 }
465 
setStringField(jobject obj,const char * name,const char * value)466 jboolean JNIHelper::setStringField(jobject obj, const char *name, const char *value)
467 {
468     JNIObject<jstring> str(*this, mEnv->NewStringUTF(value));
469 
470     if (mEnv->ExceptionCheck()) {
471         mEnv->ExceptionDescribe();
472         mEnv->ExceptionClear();
473         return false;
474     }
475 
476     if (str == NULL) {
477         THROW(*this, "Error creating string");
478         return false;
479     }
480 
481     setObjectField(obj, name, "Ljava/lang/String;", str);
482     return true;
483 }
484 
reportEvent(jclass cls,const char * method,const char * signature,...)485 void JNIHelper::reportEvent(jclass cls, const char *method, const char *signature, ...)
486 {
487     va_list params;
488     va_start(params, signature);
489 
490     jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
491     if (methodID == 0) {
492         ALOGE("Error in getting method ID");
493         return;
494     }
495 
496     mEnv->CallStaticVoidMethodV(cls, methodID, params);
497     if (mEnv->ExceptionCheck()) {
498         mEnv->ExceptionDescribe();
499         mEnv->ExceptionClear();
500     }
501 
502     va_end(params);
503 }
504 
callStaticMethod(jclass cls,const char * method,const char * signature,...)505 jboolean JNIHelper::callStaticMethod(jclass cls, const char *method, const char *signature, ...)
506 {
507     va_list params;
508     va_start(params, signature);
509 
510     jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
511     if (methodID == 0) {
512         ALOGE("Error in getting method ID");
513         return false;
514     }
515 
516     jboolean result = mEnv->CallStaticBooleanMethodV(cls, methodID, params);
517     if (mEnv->ExceptionCheck()) {
518         mEnv->ExceptionDescribe();
519         mEnv->ExceptionClear();
520         return false;
521     }
522 
523     va_end(params);
524     return result;
525 }
526 
createObject(const char * className)527 JNIObject<jobject> JNIHelper::createObject(const char *className)
528 {
529     JNIObject<jclass> cls(*this, mEnv->FindClass(className));
530     if (cls == NULL) {
531         ALOGE("Error in finding class %s", className);
532         return JNIObject<jobject>(*this, NULL);
533     }
534 
535     jmethodID constructor = mEnv->GetMethodID(cls, "<init>", "()V");
536     if (constructor == 0) {
537         ALOGE("Error in constructor ID for %s", className);
538         return JNIObject<jobject>(*this, NULL);
539     }
540 
541     JNIObject<jobject> obj(*this, mEnv->NewObject(cls, constructor));
542     if (obj == NULL) {
543         ALOGE("Could not create new object of %s", className);
544         return JNIObject<jobject>(*this, NULL);
545     }
546 
547     return obj;
548 }
549 
createObjectArray(const char * className,int num)550 JNIObject<jobjectArray> JNIHelper::createObjectArray(const char *className, int num)
551 {
552     JNIObject<jclass> cls(*this, mEnv->FindClass(className));
553     if (cls == NULL) {
554         ALOGE("Error in finding class %s", className);
555         return JNIObject<jobjectArray>(*this, NULL);
556     }
557 
558     JNIObject<jobject> array(*this, mEnv->NewObjectArray(num, cls.get(), NULL));
559     if (array.get() == NULL) {
560         ALOGE("Error in creating array of class %s", className);
561         return JNIObject<jobjectArray>(*this, NULL);
562     }
563 
564     return JNIObject<jobjectArray>(*this, (jobjectArray)array.detach());
565 }
566 
getObjectArrayElement(jobjectArray array,int index)567 JNIObject<jobject> JNIHelper::getObjectArrayElement(jobjectArray array, int index)
568 {
569     return JNIObject<jobject>(*this, mEnv->GetObjectArrayElement(array, index));
570 }
571 
getObjectArrayElement(jobject array,int index)572 JNIObject<jobject> JNIHelper::getObjectArrayElement(jobject array, int index)
573 {
574     return getObjectArrayElement((jobjectArray)array, index);
575 }
576 
getArrayLength(jarray array)577 int JNIHelper::getArrayLength(jarray array) {
578     return mEnv->GetArrayLength(array);
579 }
580 
newObjectArray(int num,const char * className,jobject val)581 JNIObject<jobjectArray> JNIHelper::newObjectArray(int num, const char *className, jobject val) {
582     JNIObject<jclass> cls(*this, mEnv->FindClass(className));
583     if (cls == NULL) {
584         ALOGE("Error in finding class %s", className);
585         return JNIObject<jobjectArray>(*this, NULL);
586     }
587 
588     return JNIObject<jobjectArray>(*this, mEnv->NewObjectArray(num, cls, val));
589 }
590 
newByteArray(int num)591 JNIObject<jbyteArray> JNIHelper::newByteArray(int num) {
592     return JNIObject<jbyteArray>(*this, mEnv->NewByteArray(num));
593 }
594 
newIntArray(int num)595 JNIObject<jintArray> JNIHelper::newIntArray(int num) {
596     return JNIObject<jintArray>(*this, mEnv->NewIntArray(num));
597 }
598 
newLongArray(int num)599 JNIObject<jlongArray> JNIHelper::newLongArray(int num) {
600     return JNIObject<jlongArray>(*this, mEnv->NewLongArray(num));
601 }
602 
newStringUTF(const char * utf)603 JNIObject<jstring> JNIHelper::newStringUTF(const char *utf) {
604     return JNIObject<jstring>(*this, mEnv->NewStringUTF(utf));
605 }
606 
setObjectArrayElement(jobjectArray array,int index,jobject obj)607 void JNIHelper::setObjectArrayElement(jobjectArray array, int index, jobject obj) {
608     mEnv->SetObjectArrayElement(array, index, obj);
609 }
610 
setByteArrayRegion(jbyteArray array,int from,int to,jbyte * bytes)611 void JNIHelper::setByteArrayRegion(jbyteArray array, int from, int to, jbyte *bytes) {
612     mEnv->SetByteArrayRegion(array, from, to, bytes);
613 }
614 
setIntArrayRegion(jintArray array,int from,int to,jint * ints)615 void JNIHelper::setIntArrayRegion(jintArray array, int from, int to, jint *ints) {
616     mEnv->SetIntArrayRegion(array, from, to, ints);
617 }
618 
setLongArrayRegion(jlongArray array,int from,int to,jlong * longs)619 void JNIHelper::setLongArrayRegion(jlongArray array, int from, int to, jlong *longs) {
620     mEnv->SetLongArrayRegion(array, from, to, longs);
621 }
622 
623 }; // namespace android
624 
625 
626