/* * 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 #include #include #include #include #include "wifi.h" #include "wifi_hal.h" #include "jni_helper.h" namespace android { /* JNI Helpers for wifi_hal implementation */ JNIHelper::JNIHelper(JavaVM *vm) { vm->AttachCurrentThread(&mEnv, NULL); mVM = vm; } JNIHelper::JNIHelper(JNIEnv *env) { mVM = NULL; mEnv = env; } JNIHelper::~JNIHelper() { if (mVM != NULL) { // mVM->DetachCurrentThread(); /* 'attempting to detach while still running code' */ mVM = NULL; /* not really required; but may help debugging */ mEnv = NULL; /* not really required; but may help debugging */ } } jobject JNIHelper::newGlobalRef(jobject obj) { return mEnv->NewGlobalRef(obj); } void JNIHelper::deleteGlobalRef(jobject obj) { mEnv->DeleteGlobalRef(obj); } jobject JNIHelper::newLocalRef(jobject obj) { return mEnv->NewLocalRef(obj); } void JNIHelper::deleteLocalRef(jobject obj) { mEnv->DeleteLocalRef(obj); } void JNIHelper::throwException(const char *message, int line) { ALOGE("error at line %d: %s", line, message); const char *className = "java/lang/Exception"; jclass exClass = mEnv->FindClass(className ); if ( exClass == NULL ) { ALOGE("Could not find exception class to throw error"); ALOGE("error at line %d: %s", line, message); return; } mEnv->ThrowNew(exClass, message); } jboolean JNIHelper::getBoolField(jobject obj, const char *name) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, "Z"); if (field == 0) { THROW(*this, "Error in accessing field"); return 0; } return mEnv->GetBooleanField(obj, field); } jint JNIHelper::getIntField(jobject obj, const char *name) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, "I"); if (field == 0) { THROW(*this, "Error in accessing field"); return 0; } return mEnv->GetIntField(obj, field); } jbyte JNIHelper::getByteField(jobject obj, const char *name) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, "B"); if (field == 0) { THROW(*this, "Error in accessing field"); return 0; } return mEnv->GetByteField(obj, field); } jlong JNIHelper::getLongField(jobject obj, const char *name) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, "J"); if (field == 0) { THROW(*this, "Error in accessing field"); return 0; } return mEnv->GetLongField(obj, field); } JNIObject JNIHelper::getStringField(jobject obj, const char *name) { JNIObject m = getObjectField(obj, name, "Ljava/lang/String;"); if (m == NULL) { THROW(*this, "Error in accessing field"); return JNIObject(*this, NULL); } return JNIObject(*this, (jstring)m.detach()); } bool JNIHelper::getStringFieldValue(jobject obj, const char *name, char *buf, int size) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, "Ljava/lang/String;"); if (field == 0) { THROW(*this, "Error in accessing field"); return 0; } JNIObject value(*this, mEnv->GetObjectField(obj, field)); JNIObject string(*this, (jstring)value.clone()); ScopedUtfChars chars(mEnv, string); const char *utf = chars.c_str(); if (utf == NULL) { THROW(*this, "Error in accessing value"); return false; } if (*utf != 0 && size < 1) { return false; } strncpy(buf, utf, size); if (size > 0) { buf[size - 1] = 0; } return true; } jlong JNIHelper::getStaticLongField(jobject obj, const char *name) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); return getStaticLongField(cls, name); } jlong JNIHelper::getStaticLongField(jclass cls, const char *name) { jfieldID field = mEnv->GetStaticFieldID(cls, name, "J"); if (field == 0) { THROW(*this, "Error in accessing field"); return 0; } //ALOGE("getStaticLongField %s %p", name, cls); return mEnv->GetStaticLongField(cls, field); } JNIObject JNIHelper::getObjectField(jobject obj, const char *name, const char *type) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, type); if (field == 0) { THROW(*this, "Error in accessing field"); return JNIObject(*this, NULL); } return JNIObject(*this, mEnv->GetObjectField(obj, field)); } JNIObject JNIHelper::getArrayField(jobject obj, const char *name, const char *type) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, type); if (field == 0) { THROW(*this, "Error in accessing field"); return JNIObject(*this, NULL); } return JNIObject(*this, (jobjectArray)mEnv->GetObjectField(obj, field)); } jlong JNIHelper::getLongArrayField(jobject obj, const char *name, int index) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, "[J"); if (field == 0) { THROW(*this, "Error in accessing field definition"); return 0; } JNIObject array(*this, (jlongArray)mEnv->GetObjectField(obj, field)); if (array == NULL) { THROW(*this, "Error in accessing array"); return 0; } jlong *elem = mEnv->GetLongArrayElements(array, 0); if (elem == NULL) { THROW(*this, "Error in accessing index element"); return 0; } jlong value = elem[index]; mEnv->ReleaseLongArrayElements(array, elem, 0); return value; } jlong JNIHelper::getStaticLongArrayField(jobject obj, const char *name, int index) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); return getStaticLongArrayField(cls, name, index); } jlong JNIHelper::getStaticLongArrayField(jclass cls, const char *name, int index) { jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J"); if (field == 0) { THROW(*this, "Error in accessing field definition"); return 0; } JNIObject array(*this, (jlongArray)mEnv->GetStaticObjectField(cls, field)); jlong *elem = mEnv->GetLongArrayElements(array, 0); if (elem == NULL) { THROW(*this, "Error in accessing index element"); return 0; } jlong value = elem[index]; mEnv->ReleaseLongArrayElements(array, elem, 0); return value; } JNIObject JNIHelper::getObjectArrayField(jobject obj, const char *name, const char *type, int index) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); jfieldID field = mEnv->GetFieldID(cls, name, type); if (field == 0) { THROW(*this, "Error in accessing field definition"); return JNIObject(*this, NULL); } JNIObject array(*this, (jobjectArray)mEnv->GetObjectField(obj, field)); JNIObject elem(*this, mEnv->GetObjectArrayElement(array, index)); if (elem.isNull()) { THROW(*this, "Error in accessing index element"); return JNIObject(*this, NULL); } return elem; } void JNIHelper::setIntField(jobject obj, const char *name, jint value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing class"); return; } jfieldID field = mEnv->GetFieldID(cls, name, "I"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetIntField(obj, field, value); } void JNIHelper::setByteField(jobject obj, const char *name, jbyte value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing class"); return; } jfieldID field = mEnv->GetFieldID(cls, name, "B"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetByteField(obj, field, value); } void JNIHelper::setBooleanField(jobject obj, const char *name, jboolean value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing class"); return; } jfieldID field = mEnv->GetFieldID(cls, name, "Z"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetBooleanField(obj, field, value); } void JNIHelper::setLongField(jobject obj, const char *name, jlong value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing class"); return; } jfieldID field = mEnv->GetFieldID(cls, name, "J"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetLongField(obj, field, value); } void JNIHelper::setStaticLongField(jobject obj, const char *name, jlong value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing class"); return; } setStaticLongField(cls, name, value); } void JNIHelper::setStaticLongField(jclass cls, const char *name, jlong value) { jfieldID field = mEnv->GetStaticFieldID(cls, name, "J"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetStaticLongField(cls, field, value); } void JNIHelper::setLongArrayField(jobject obj, const char *name, jlongArray value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing field"); return; } jfieldID field = mEnv->GetFieldID(cls, name, "[J"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetObjectField(obj, field, value); } void JNIHelper::setStaticLongArrayField(jobject obj, const char *name, jlongArray value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing field"); return; } setStaticLongArrayField(cls, name, value); } void JNIHelper::setStaticLongArrayField(jclass cls, const char *name, jlongArray value) { jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetStaticObjectField(cls, field, value); ALOGD("array field set"); } void JNIHelper::setLongArrayElement(jobject obj, const char *name, int index, jlong value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing field"); return; } jfieldID field = mEnv->GetFieldID(cls, name, "[J"); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } JNIObject array(*this, (jlongArray)mEnv->GetObjectField(obj, field)); if (array == NULL) { THROW(*this, "Error in accessing array"); return; } jlong *elem = mEnv->GetLongArrayElements(array, NULL); if (elem == NULL) { THROW(*this, "Error in accessing index element"); return; } elem[index] = value; mEnv->ReleaseLongArrayElements(array, elem, 0); } void JNIHelper::setObjectField(jobject obj, const char *name, const char *type, jobject value) { JNIObject cls(*this, mEnv->GetObjectClass(obj)); if (cls == NULL) { THROW(*this, "Error in accessing class"); return; } jfieldID field = mEnv->GetFieldID(cls, name, type); if (field == NULL) { THROW(*this, "Error in accessing field"); return; } mEnv->SetObjectField(obj, field, value); } jboolean JNIHelper::setStringField(jobject obj, const char *name, const char *value) { JNIObject str(*this, mEnv->NewStringUTF(value)); if (mEnv->ExceptionCheck()) { mEnv->ExceptionDescribe(); mEnv->ExceptionClear(); return false; } if (str == NULL) { THROW(*this, "Error creating string"); return false; } setObjectField(obj, name, "Ljava/lang/String;", str); return true; } void JNIHelper::reportEvent(jclass cls, const char *method, const char *signature, ...) { va_list params; va_start(params, signature); jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature); if (methodID == 0) { ALOGE("Error in getting method ID"); return; } mEnv->CallStaticVoidMethodV(cls, methodID, params); if (mEnv->ExceptionCheck()) { mEnv->ExceptionDescribe(); mEnv->ExceptionClear(); } va_end(params); } jboolean JNIHelper::callStaticMethod(jclass cls, const char *method, const char *signature, ...) { va_list params; va_start(params, signature); jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature); if (methodID == 0) { ALOGE("Error in getting method ID"); return false; } jboolean result = mEnv->CallStaticBooleanMethodV(cls, methodID, params); if (mEnv->ExceptionCheck()) { mEnv->ExceptionDescribe(); mEnv->ExceptionClear(); return false; } va_end(params); return result; } JNIObject JNIHelper::createObject(const char *className) { JNIObject cls(*this, mEnv->FindClass(className)); if (cls == NULL) { ALOGE("Error in finding class %s", className); return JNIObject(*this, NULL); } jmethodID constructor = mEnv->GetMethodID(cls, "", "()V"); if (constructor == 0) { ALOGE("Error in constructor ID for %s", className); return JNIObject(*this, NULL); } JNIObject obj(*this, mEnv->NewObject(cls, constructor)); if (obj == NULL) { ALOGE("Could not create new object of %s", className); return JNIObject(*this, NULL); } return obj; } JNIObject JNIHelper::createObjectArray(const char *className, int num) { JNIObject cls(*this, mEnv->FindClass(className)); if (cls == NULL) { ALOGE("Error in finding class %s", className); return JNIObject(*this, NULL); } JNIObject array(*this, mEnv->NewObjectArray(num, cls.get(), NULL)); if (array.get() == NULL) { ALOGE("Error in creating array of class %s", className); return JNIObject(*this, NULL); } return JNIObject(*this, (jobjectArray)array.detach()); } JNIObject JNIHelper::getObjectArrayElement(jobjectArray array, int index) { return JNIObject(*this, mEnv->GetObjectArrayElement(array, index)); } JNIObject JNIHelper::getObjectArrayElement(jobject array, int index) { return getObjectArrayElement((jobjectArray)array, index); } int JNIHelper::getArrayLength(jarray array) { return mEnv->GetArrayLength(array); } JNIObject JNIHelper::newObjectArray(int num, const char *className, jobject val) { JNIObject cls(*this, mEnv->FindClass(className)); if (cls == NULL) { ALOGE("Error in finding class %s", className); return JNIObject(*this, NULL); } return JNIObject(*this, mEnv->NewObjectArray(num, cls, val)); } JNIObject JNIHelper::newByteArray(int num) { return JNIObject(*this, mEnv->NewByteArray(num)); } JNIObject JNIHelper::newIntArray(int num) { return JNIObject(*this, mEnv->NewIntArray(num)); } JNIObject JNIHelper::newLongArray(int num) { return JNIObject(*this, mEnv->NewLongArray(num)); } JNIObject JNIHelper::newStringUTF(const char *utf) { return JNIObject(*this, mEnv->NewStringUTF(utf)); } void JNIHelper::setObjectArrayElement(jobjectArray array, int index, jobject obj) { mEnv->SetObjectArrayElement(array, index, obj); } void JNIHelper::setByteArrayRegion(jbyteArray array, int from, int to, jbyte *bytes) { mEnv->SetByteArrayRegion(array, from, to, bytes); } void JNIHelper::setIntArrayRegion(jintArray array, int from, int to, jint *ints) { mEnv->SetIntArrayRegion(array, from, to, ints); } void JNIHelper::setLongArrayRegion(jlongArray array, int from, int to, jlong *longs) { mEnv->SetLongArrayRegion(array, from, to, longs); } }; // namespace android