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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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