| /* |
| * Copyright 2008, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "wifi" |
| |
| #include "jni.h" |
| #include <ScopedUtfChars.h> |
| #include <utils/misc.h> |
| #include <android_runtime/AndroidRuntime.h> |
| #include <utils/Log.h> |
| #include <utils/String16.h> |
| |
| #include "wifi.h" |
| #include "wifi_hal.h" |
| #include "jni_helper.h" |
| |
| namespace android { |
| |
| /* JNI Helpers for wifi_hal implementation */ |
| |
| void throwException( JNIEnv *env, const char *message, int line ) |
| { |
| ALOGE("error at line %d: %s", line, message); |
| |
| const char *className = "java/lang/Exception"; |
| |
| jclass exClass = (env)->FindClass(className ); |
| if ( exClass == NULL ) { |
| ALOGE("Could not find exception class to throw error"); |
| ALOGE("error at line %d: %s", line, message); |
| return; |
| } |
| |
| (env)->ThrowNew(exClass, message); |
| } |
| |
| jboolean getBoolField(JNIEnv *env, jobject obj, const char *name) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jfieldID field = (env)->GetFieldID(cls, name, "Z"); |
| if (field == 0) { |
| THROW(env, "Error in accessing field"); |
| return 0; |
| } |
| |
| jboolean value = (env)->GetBooleanField(obj, field); |
| env->DeleteLocalRef(cls); |
| return value; |
| } |
| |
| jint getIntField(JNIEnv *env, jobject obj, const char *name) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jfieldID field = (env)->GetFieldID(cls, name, "I"); |
| if (field == 0) { |
| THROW(env, "Error in accessing field"); |
| return 0; |
| } |
| |
| jint value = (env)->GetIntField(obj, field); |
| env->DeleteLocalRef(cls); |
| return value; |
| } |
| |
| jlong getLongField(JNIEnv *env, jobject obj, const char *name) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jfieldID field = (env)->GetFieldID(cls, name, "J"); |
| if (field == 0) { |
| THROW(env, "Error in accessing field"); |
| return 0; |
| } |
| |
| jlong value = (env)->GetLongField(obj, field); |
| env->DeleteLocalRef(cls); |
| return value; |
| } |
| |
| jlong getStaticLongField(JNIEnv *env, jobject obj, const char *name) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jlong result = getStaticLongField(env, cls, name); |
| env->DeleteLocalRef(cls); |
| return result; |
| } |
| |
| jlong getStaticLongField(JNIEnv *env, jclass cls, const char *name) |
| { |
| jfieldID field = (env)->GetStaticFieldID(cls, name, "J"); |
| if (field == 0) { |
| THROW(env, "Error in accessing field"); |
| return 0; |
| } |
| ALOGE("getStaticLongField %s %p", name, cls); |
| |
| return (env)->GetStaticLongField(cls, field); |
| } |
| |
| jobject getObjectField(JNIEnv *env, jobject obj, const char *name, const char *type) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jfieldID field = (env)->GetFieldID(cls, name, type); |
| if (field == 0) { |
| THROW(env, "Error in accessing field"); |
| return 0; |
| } |
| |
| jobject value = (env)->GetObjectField(obj, field); |
| env->DeleteLocalRef(cls); |
| return value; |
| } |
| |
| jlong getLongArrayField(JNIEnv *env, jobject obj, const char *name, int index) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jfieldID field = (env)->GetFieldID(cls, name, "[J"); |
| if (field == 0) { |
| THROW(env, "Error in accessing field definition"); |
| return 0; |
| } |
| |
| jlongArray array = (jlongArray)(env)->GetObjectField(obj, field); |
| if (array == NULL) { |
| THROW(env, "Error in accessing array"); |
| return 0; |
| } |
| |
| jlong *elem = (env)->GetLongArrayElements(array, 0); |
| if (elem == NULL) { |
| THROW(env, "Error in accessing index element"); |
| return 0; |
| } |
| |
| jlong value = elem[index]; |
| (env)->ReleaseLongArrayElements(array, elem, 0); |
| |
| env->DeleteLocalRef(array); |
| env->DeleteLocalRef(cls); |
| |
| return value; |
| } |
| |
| jlong getStaticLongArrayField(JNIEnv *env, jobject obj, const char *name, int index) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jlong result = getStaticLongArrayField(env, cls, name, index); |
| env->DeleteLocalRef(cls); |
| return result; |
| } |
| |
| jlong getStaticLongArrayField(JNIEnv *env, jclass cls, const char *name, int index) |
| { |
| jfieldID field = (env)->GetStaticFieldID(cls, name, "[J"); |
| if (field == 0) { |
| THROW(env, "Error in accessing field definition"); |
| return 0; |
| } |
| |
| jlongArray array = (jlongArray)(env)->GetStaticObjectField(cls, field); |
| jlong *elem = (env)->GetLongArrayElements(array, 0); |
| if (elem == NULL) { |
| THROW(env, "Error in accessing index element"); |
| return 0; |
| } |
| |
| jlong value = elem[index]; |
| (env)->ReleaseLongArrayElements(array, elem, 0); |
| |
| env->DeleteLocalRef(array); |
| return value; |
| } |
| |
| jobject getObjectArrayField(JNIEnv *env, jobject obj, const char *name, const char *type, int index) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| jfieldID field = (env)->GetFieldID(cls, name, type); |
| if (field == 0) { |
| THROW(env, "Error in accessing field definition"); |
| return 0; |
| } |
| |
| jobjectArray array = (jobjectArray)(env)->GetObjectField(obj, field); |
| jobject elem = (env)->GetObjectArrayElement(array, index); |
| if (elem == NULL) { |
| THROW(env, "Error in accessing index element"); |
| return 0; |
| } |
| |
| env->DeleteLocalRef(array); |
| env->DeleteLocalRef(cls); |
| return elem; |
| } |
| |
| void setIntField(JNIEnv *env, jobject obj, const char *name, jint value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing class"); |
| return; |
| } |
| |
| jfieldID field = (env)->GetFieldID(cls, name, "I"); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } |
| |
| (env)->SetIntField(obj, field, value); |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setLongField(JNIEnv *env, jobject obj, const char *name, jlong value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing class"); |
| return; |
| } |
| |
| jfieldID field = (env)->GetFieldID(cls, name, "J"); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } |
| |
| (env)->SetLongField(obj, field, value); |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setStaticLongField(JNIEnv *env, jobject obj, const char *name, jlong value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing class"); |
| return; |
| } |
| |
| setStaticLongField(env, cls, name, value); |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setStaticLongField(JNIEnv *env, jclass cls, const char *name, jlong value) |
| { |
| jfieldID field = (env)->GetStaticFieldID(cls, name, "J"); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } |
| |
| (env)->SetStaticLongField(cls, field, value); |
| } |
| |
| void setLongArrayField(JNIEnv *env, jobject obj, const char *name, jlongArray value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } else { |
| ALOGD("cls = %p", cls); |
| } |
| |
| jfieldID field = (env)->GetFieldID(cls, name, "[J"); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } |
| |
| (env)->SetObjectField(obj, field, value); |
| ALOGD("array field set"); |
| |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setStaticLongArrayField(JNIEnv *env, jobject obj, const char *name, jlongArray value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } else { |
| ALOGD("cls = %p", cls); |
| } |
| |
| setStaticLongArrayField(env, cls, name, value); |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setStaticLongArrayField(JNIEnv *env, jclass cls, const char *name, jlongArray value) |
| { |
| jfieldID field = (env)->GetStaticFieldID(cls, name, "[J"); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } |
| |
| (env)->SetStaticObjectField(cls, field, value); |
| ALOGD("array field set"); |
| } |
| |
| void setLongArrayElement(JNIEnv *env, jobject obj, const char *name, int index, jlong value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } else { |
| ALOGD("cls = %p", cls); |
| } |
| |
| jfieldID field = (env)->GetFieldID(cls, name, "[J"); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } else { |
| ALOGD("field = %p", field); |
| } |
| |
| jlongArray array = (jlongArray)(env)->GetObjectField(obj, field); |
| if (array == NULL) { |
| THROW(env, "Error in accessing array"); |
| return; |
| } else { |
| ALOGD("array = %p", array); |
| } |
| |
| jlong *elem = (env)->GetLongArrayElements(array, NULL); |
| if (elem == NULL) { |
| THROW(env, "Error in accessing index element"); |
| return; |
| } |
| |
| elem[index] = value; |
| env->ReleaseLongArrayElements(array, elem, 0); |
| env->DeleteLocalRef(array); |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setObjectField(JNIEnv *env, jobject obj, const char *name, const char *type, jobject value) |
| { |
| jclass cls = (env)->GetObjectClass(obj); |
| if (cls == NULL) { |
| THROW(env, "Error in accessing class"); |
| return; |
| } |
| |
| jfieldID field = (env)->GetFieldID(cls, name, type); |
| if (field == NULL) { |
| THROW(env, "Error in accessing field"); |
| return; |
| } |
| |
| (env)->SetObjectField(obj, field, value); |
| env->DeleteLocalRef(cls); |
| } |
| |
| void setStringField(JNIEnv *env, jobject obj, const char *name, const char *value) |
| { |
| jstring str = env->NewStringUTF(value); |
| |
| if (str == NULL) { |
| THROW(env, "Error in accessing class"); |
| return; |
| } |
| |
| setObjectField(env, obj, name, "Ljava/lang/String;", str); |
| env->DeleteLocalRef(str); |
| } |
| |
| void reportEvent(JNIEnv *env, jclass cls, const char *method, const char *signature, ...) |
| { |
| va_list params; |
| va_start(params, signature); |
| |
| jmethodID methodID = env->GetStaticMethodID(cls, method, signature); |
| if (method == NULL) { |
| ALOGE("Error in getting method ID"); |
| return; |
| } |
| |
| env->CallStaticVoidMethodV(cls, methodID, params); |
| va_end(params); |
| } |
| |
| jobject createObject(JNIEnv *env, const char *className) |
| { |
| jclass cls = env->FindClass(className); |
| if (cls == NULL) { |
| ALOGE("Error in finding class"); |
| return NULL; |
| } |
| |
| jmethodID constructor = env->GetMethodID(cls, "<init>", "()V"); |
| if (constructor == NULL) { |
| ALOGE("Error in constructor ID"); |
| return NULL; |
| } |
| jobject obj = env->NewObject(cls, constructor); |
| if (constructor == NULL) { |
| ALOGE("Could not create new object of %s", className); |
| return NULL; |
| } |
| |
| env->DeleteLocalRef(cls); |
| return obj; |
| } |
| |
| }; // namespace android |
| |
| |