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