C++程序  |  424行  |  10.96 KB

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