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
throwException(JNIEnv * env,const char * message,int line)34 void throwException( JNIEnv *env, const char *message, int line )
35 {
36 ALOGE("error at line %d: %s", line, message);
37
38 const char *className = "java/lang/Exception";
39
40 jclass exClass = (env)->FindClass(className );
41 if ( exClass == NULL ) {
42 ALOGE("Could not find exception class to throw error");
43 ALOGE("error at line %d: %s", line, message);
44 return;
45 }
46
47 (env)->ThrowNew(exClass, message);
48 }
49
getBoolField(JNIEnv * env,jobject obj,const char * name)50 jboolean getBoolField(JNIEnv *env, jobject obj, const char *name)
51 {
52 jclass cls = (env)->GetObjectClass(obj);
53 jfieldID field = (env)->GetFieldID(cls, name, "Z");
54 if (field == 0) {
55 THROW(env, "Error in accessing field");
56 return 0;
57 }
58
59 jboolean value = (env)->GetBooleanField(obj, field);
60 env->DeleteLocalRef(cls);
61 return value;
62 }
63
getIntField(JNIEnv * env,jobject obj,const char * name)64 jint getIntField(JNIEnv *env, jobject obj, const char *name)
65 {
66 jclass cls = (env)->GetObjectClass(obj);
67 jfieldID field = (env)->GetFieldID(cls, name, "I");
68 if (field == 0) {
69 THROW(env, "Error in accessing field");
70 return 0;
71 }
72
73 jint value = (env)->GetIntField(obj, field);
74 env->DeleteLocalRef(cls);
75 return value;
76 }
77
getLongField(JNIEnv * env,jobject obj,const char * name)78 jlong getLongField(JNIEnv *env, jobject obj, const char *name)
79 {
80 jclass cls = (env)->GetObjectClass(obj);
81 jfieldID field = (env)->GetFieldID(cls, name, "J");
82 if (field == 0) {
83 THROW(env, "Error in accessing field");
84 return 0;
85 }
86
87 jlong value = (env)->GetLongField(obj, field);
88 env->DeleteLocalRef(cls);
89 return value;
90 }
91
getStaticLongField(JNIEnv * env,jobject obj,const char * name)92 jlong getStaticLongField(JNIEnv *env, jobject obj, const char *name)
93 {
94 jclass cls = (env)->GetObjectClass(obj);
95 jlong result = getStaticLongField(env, cls, name);
96 env->DeleteLocalRef(cls);
97 return result;
98 }
99
getStaticLongField(JNIEnv * env,jclass cls,const char * name)100 jlong getStaticLongField(JNIEnv *env, jclass cls, const char *name)
101 {
102 jfieldID field = (env)->GetStaticFieldID(cls, name, "J");
103 if (field == 0) {
104 THROW(env, "Error in accessing field");
105 return 0;
106 }
107 ALOGE("getStaticLongField %s %p", name, cls);
108
109 return (env)->GetStaticLongField(cls, field);
110 }
111
getObjectField(JNIEnv * env,jobject obj,const char * name,const char * type)112 jobject getObjectField(JNIEnv *env, jobject obj, const char *name, const char *type)
113 {
114 jclass cls = (env)->GetObjectClass(obj);
115 jfieldID field = (env)->GetFieldID(cls, name, type);
116 if (field == 0) {
117 THROW(env, "Error in accessing field");
118 return 0;
119 }
120
121 jobject value = (env)->GetObjectField(obj, field);
122 env->DeleteLocalRef(cls);
123 return value;
124 }
125
getLongArrayField(JNIEnv * env,jobject obj,const char * name,int index)126 jlong getLongArrayField(JNIEnv *env, jobject obj, const char *name, int index)
127 {
128 jclass cls = (env)->GetObjectClass(obj);
129 jfieldID field = (env)->GetFieldID(cls, name, "[J");
130 if (field == 0) {
131 THROW(env, "Error in accessing field definition");
132 return 0;
133 }
134
135 jlongArray array = (jlongArray)(env)->GetObjectField(obj, field);
136 if (array == NULL) {
137 THROW(env, "Error in accessing array");
138 return 0;
139 }
140
141 jlong *elem = (env)->GetLongArrayElements(array, 0);
142 if (elem == NULL) {
143 THROW(env, "Error in accessing index element");
144 return 0;
145 }
146
147 jlong value = elem[index];
148 (env)->ReleaseLongArrayElements(array, elem, 0);
149
150 env->DeleteLocalRef(array);
151 env->DeleteLocalRef(cls);
152
153 return value;
154 }
155
getStaticLongArrayField(JNIEnv * env,jobject obj,const char * name,int index)156 jlong getStaticLongArrayField(JNIEnv *env, jobject obj, const char *name, int index)
157 {
158 jclass cls = (env)->GetObjectClass(obj);
159 jlong result = getStaticLongArrayField(env, cls, name, index);
160 env->DeleteLocalRef(cls);
161 return result;
162 }
163
getStaticLongArrayField(JNIEnv * env,jclass cls,const char * name,int index)164 jlong getStaticLongArrayField(JNIEnv *env, jclass cls, const char *name, int index)
165 {
166 jfieldID field = (env)->GetStaticFieldID(cls, name, "[J");
167 if (field == 0) {
168 THROW(env, "Error in accessing field definition");
169 return 0;
170 }
171
172 jlongArray array = (jlongArray)(env)->GetStaticObjectField(cls, field);
173 jlong *elem = (env)->GetLongArrayElements(array, 0);
174 if (elem == NULL) {
175 THROW(env, "Error in accessing index element");
176 return 0;
177 }
178
179 jlong value = elem[index];
180 (env)->ReleaseLongArrayElements(array, elem, 0);
181
182 env->DeleteLocalRef(array);
183 return value;
184 }
185
getObjectArrayField(JNIEnv * env,jobject obj,const char * name,const char * type,int index)186 jobject getObjectArrayField(JNIEnv *env, jobject obj, const char *name, const char *type, int index)
187 {
188 jclass cls = (env)->GetObjectClass(obj);
189 jfieldID field = (env)->GetFieldID(cls, name, type);
190 if (field == 0) {
191 THROW(env, "Error in accessing field definition");
192 return 0;
193 }
194
195 jobjectArray array = (jobjectArray)(env)->GetObjectField(obj, field);
196 jobject elem = (env)->GetObjectArrayElement(array, index);
197 if (elem == NULL) {
198 THROW(env, "Error in accessing index element");
199 return 0;
200 }
201
202 env->DeleteLocalRef(array);
203 env->DeleteLocalRef(cls);
204 return elem;
205 }
206
setIntField(JNIEnv * env,jobject obj,const char * name,jint value)207 void setIntField(JNIEnv *env, jobject obj, const char *name, jint value)
208 {
209 jclass cls = (env)->GetObjectClass(obj);
210 if (cls == NULL) {
211 THROW(env, "Error in accessing class");
212 return;
213 }
214
215 jfieldID field = (env)->GetFieldID(cls, name, "I");
216 if (field == NULL) {
217 THROW(env, "Error in accessing field");
218 return;
219 }
220
221 (env)->SetIntField(obj, field, value);
222 env->DeleteLocalRef(cls);
223 }
224
setLongField(JNIEnv * env,jobject obj,const char * name,jlong value)225 void setLongField(JNIEnv *env, jobject obj, const char *name, jlong value)
226 {
227 jclass cls = (env)->GetObjectClass(obj);
228 if (cls == NULL) {
229 THROW(env, "Error in accessing class");
230 return;
231 }
232
233 jfieldID field = (env)->GetFieldID(cls, name, "J");
234 if (field == NULL) {
235 THROW(env, "Error in accessing field");
236 return;
237 }
238
239 (env)->SetLongField(obj, field, value);
240 env->DeleteLocalRef(cls);
241 }
242
setStaticLongField(JNIEnv * env,jobject obj,const char * name,jlong value)243 void setStaticLongField(JNIEnv *env, jobject obj, const char *name, jlong value)
244 {
245 jclass cls = (env)->GetObjectClass(obj);
246 if (cls == NULL) {
247 THROW(env, "Error in accessing class");
248 return;
249 }
250
251 setStaticLongField(env, cls, name, value);
252 env->DeleteLocalRef(cls);
253 }
254
setStaticLongField(JNIEnv * env,jclass cls,const char * name,jlong value)255 void setStaticLongField(JNIEnv *env, jclass cls, const char *name, jlong value)
256 {
257 jfieldID field = (env)->GetStaticFieldID(cls, name, "J");
258 if (field == NULL) {
259 THROW(env, "Error in accessing field");
260 return;
261 }
262
263 (env)->SetStaticLongField(cls, field, value);
264 }
265
setLongArrayField(JNIEnv * env,jobject obj,const char * name,jlongArray value)266 void setLongArrayField(JNIEnv *env, jobject obj, const char *name, jlongArray value)
267 {
268 jclass cls = (env)->GetObjectClass(obj);
269 if (cls == NULL) {
270 THROW(env, "Error in accessing field");
271 return;
272 } else {
273 ALOGD("cls = %p", cls);
274 }
275
276 jfieldID field = (env)->GetFieldID(cls, name, "[J");
277 if (field == NULL) {
278 THROW(env, "Error in accessing field");
279 return;
280 }
281
282 (env)->SetObjectField(obj, field, value);
283 ALOGD("array field set");
284
285 env->DeleteLocalRef(cls);
286 }
287
setStaticLongArrayField(JNIEnv * env,jobject obj,const char * name,jlongArray value)288 void setStaticLongArrayField(JNIEnv *env, jobject obj, const char *name, jlongArray value)
289 {
290 jclass cls = (env)->GetObjectClass(obj);
291 if (cls == NULL) {
292 THROW(env, "Error in accessing field");
293 return;
294 } else {
295 ALOGD("cls = %p", cls);
296 }
297
298 setStaticLongArrayField(env, cls, name, value);
299 env->DeleteLocalRef(cls);
300 }
301
setStaticLongArrayField(JNIEnv * env,jclass cls,const char * name,jlongArray value)302 void setStaticLongArrayField(JNIEnv *env, jclass cls, const char *name, jlongArray value)
303 {
304 jfieldID field = (env)->GetStaticFieldID(cls, name, "[J");
305 if (field == NULL) {
306 THROW(env, "Error in accessing field");
307 return;
308 }
309
310 (env)->SetStaticObjectField(cls, field, value);
311 ALOGD("array field set");
312 }
313
setLongArrayElement(JNIEnv * env,jobject obj,const char * name,int index,jlong value)314 void setLongArrayElement(JNIEnv *env, jobject obj, const char *name, int index, jlong value)
315 {
316 jclass cls = (env)->GetObjectClass(obj);
317 if (cls == NULL) {
318 THROW(env, "Error in accessing field");
319 return;
320 } else {
321 ALOGD("cls = %p", cls);
322 }
323
324 jfieldID field = (env)->GetFieldID(cls, name, "[J");
325 if (field == NULL) {
326 THROW(env, "Error in accessing field");
327 return;
328 } else {
329 ALOGD("field = %p", field);
330 }
331
332 jlongArray array = (jlongArray)(env)->GetObjectField(obj, field);
333 if (array == NULL) {
334 THROW(env, "Error in accessing array");
335 return;
336 } else {
337 ALOGD("array = %p", array);
338 }
339
340 jlong *elem = (env)->GetLongArrayElements(array, NULL);
341 if (elem == NULL) {
342 THROW(env, "Error in accessing index element");
343 return;
344 }
345
346 elem[index] = value;
347 env->ReleaseLongArrayElements(array, elem, 0);
348 env->DeleteLocalRef(array);
349 env->DeleteLocalRef(cls);
350 }
351
setObjectField(JNIEnv * env,jobject obj,const char * name,const char * type,jobject value)352 void setObjectField(JNIEnv *env, jobject obj, const char *name, const char *type, jobject value)
353 {
354 jclass cls = (env)->GetObjectClass(obj);
355 if (cls == NULL) {
356 THROW(env, "Error in accessing class");
357 return;
358 }
359
360 jfieldID field = (env)->GetFieldID(cls, name, type);
361 if (field == NULL) {
362 THROW(env, "Error in accessing field");
363 return;
364 }
365
366 (env)->SetObjectField(obj, field, value);
367 env->DeleteLocalRef(cls);
368 }
369
setStringField(JNIEnv * env,jobject obj,const char * name,const char * value)370 void setStringField(JNIEnv *env, jobject obj, const char *name, const char *value)
371 {
372 jstring str = env->NewStringUTF(value);
373
374 if (str == NULL) {
375 THROW(env, "Error in accessing class");
376 return;
377 }
378
379 setObjectField(env, obj, name, "Ljava/lang/String;", str);
380 env->DeleteLocalRef(str);
381 }
382
reportEvent(JNIEnv * env,jclass cls,const char * method,const char * signature,...)383 void reportEvent(JNIEnv *env, jclass cls, const char *method, const char *signature, ...)
384 {
385 va_list params;
386 va_start(params, signature);
387
388 jmethodID methodID = env->GetStaticMethodID(cls, method, signature);
389 if (method == NULL) {
390 ALOGE("Error in getting method ID");
391 return;
392 }
393
394 env->CallStaticVoidMethodV(cls, methodID, params);
395 va_end(params);
396 }
397
createObject(JNIEnv * env,const char * className)398 jobject createObject(JNIEnv *env, const char *className)
399 {
400 jclass cls = env->FindClass(className);
401 if (cls == NULL) {
402 ALOGE("Error in finding class");
403 return NULL;
404 }
405
406 jmethodID constructor = env->GetMethodID(cls, "<init>", "()V");
407 if (constructor == NULL) {
408 ALOGE("Error in constructor ID");
409 return NULL;
410 }
411 jobject obj = env->NewObject(cls, constructor);
412 if (constructor == NULL) {
413 ALOGE("Could not create new object of %s", className);
414 return NULL;
415 }
416
417 env->DeleteLocalRef(cls);
418 return obj;
419 }
420
421 }; // namespace android
422
423
424