C++程序  |  179行  |  6.12 KB

/*
 * Copyright 2016, 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.
 */

namespace android {

/* JNI Helpers for wifi_hal to WifiNative bridge implementation */

class JNIHelper;

template<typename T>
class JNIObject {
protected:
    JNIHelper &mHelper;
    T mObj;
public:
    JNIObject(JNIHelper &helper, T obj);
    JNIObject(const JNIObject<T>& rhs);
    virtual ~JNIObject();
    JNIHelper& getHelper() const {
        return mHelper;
    }
    T get() const {
        return mObj;
    }
    operator T() const {
        return mObj;
    }
    bool isNull() const {
        return mObj == NULL;
    }
    void release();
    T detach() {
        T tObj = mObj;
        mObj = NULL;
        return tObj;
    }
    T clone();
    JNIObject<T>& operator = (const JNIObject<T>& rhs) {
        release();
        mHelper = rhs.mHelper;
        mObj = rhs.mObj;
        return *this;
    }
    void print() {
        ALOGD("holding %p", mObj);
    }

private:
    template<typename T2>
    JNIObject(const JNIObject<T2>& rhs);
};

class JNIHelper {
    JavaVM *mVM;
    JNIEnv *mEnv;

public :
    JNIHelper(JavaVM *vm);
    JNIHelper(JNIEnv *env);
    ~JNIHelper();

    void throwException(const char *message, int line);

    /* helpers to deal with members */
    jboolean getBoolField(jobject obj, const char *name);
    jint getIntField(jobject obj, const char *name);
    jlong getLongField(jobject obj, const char *name);
    JNIObject<jstring> getStringField(jobject obj, const char *name);
    bool getStringFieldValue(jobject obj, const char *name, char *buf, int size);
    JNIObject<jobject> getObjectField(jobject obj, const char *name, const char *type);
    JNIObject<jobjectArray> getArrayField(jobject obj, const char *name, const char *type);
    void getByteArrayField(jobject obj, const char *name, byte* buf, int size);
    jlong getLongArrayField(jobject obj, const char *name, int index);
    JNIObject<jobject> getObjectArrayField(
            jobject obj, const char *name, const char *type, int index);
    void setIntField(jobject obj, const char *name, jint value);
    void setByteField(jobject obj, const char *name, jbyte value);
    jbyte getByteField(jobject obj, const char *name);
    void setBooleanField(jobject obj, const char *name, jboolean value);
    void setLongField(jobject obj, const char *name, jlong value);
    void setLongArrayField(jobject obj, const char *name, jlongArray value);
    void setLongArrayElement(jobject obj, const char *name, int index, jlong value);
    jboolean setStringField(jobject obj, const char *name, const char *value);
    void reportEvent(jclass cls, const char *method, const char *signature, ...);
    JNIObject<jobject> createObject(const char *className);
    JNIObject<jobject> createObjectWithArgs(const char *className, const char *signature, ...);
    JNIObject<jobjectArray> createObjectArray(const char *className, int size);
    void setObjectField(jobject obj, const char *name, const char *type, jobject value);
    void callMethod(jobject obj, const char *method, const char *signature, ...);

    /* helpers to deal with static members */
    jlong getStaticLongField(jobject obj, const char *name);
    jlong getStaticLongField(jclass cls, const char *name);
    void setStaticLongField(jobject obj, const char *name, jlong value);
    void setStaticLongField(jclass cls, const char *name, jlong value);
    jlong getStaticLongArrayField(jobject obj, const char *name, int index);
    jlong getStaticLongArrayField(jclass cls, const char *name, int index);
    void setStaticLongArrayField(jobject obj, const char *name, jlongArray value);
    void setStaticLongArrayField(jclass obj, const char *name, jlongArray value);
    jboolean callStaticMethod(jclass cls, const char *method, const char *signature, ...);

    JNIObject<jobject> getObjectArrayElement(jobjectArray array, int index);
    JNIObject<jobject> getObjectArrayElement(jobject array, int index);
    int getArrayLength(jarray array);
    JNIObject<jobjectArray> newObjectArray(int num, const char *className, jobject val);
    JNIObject<jbyteArray> newByteArray(int num);
    JNIObject<jintArray> newIntArray(int num);
    JNIObject<jlongArray> newLongArray(int num);
    JNIObject<jstring> newStringUTF(const char *utf);
    void setObjectArrayElement(jobjectArray array, int index, jobject obj);
    void setByteArrayRegion(jbyteArray array, int from, int to, const jbyte *bytes);
    void setIntArrayRegion(jintArray array, int from, int to, const jint *ints);
    void setLongArrayRegion(jlongArray array, int from, int to, const jlong *longs);

    jobject newGlobalRef(jobject obj);
    void deleteGlobalRef(jobject obj);

private:
    /* Jni wrappers */
    friend class JNIObject<jobject>;
    friend class JNIObject<jstring>;
    friend class JNIObject<jobjectArray>;
    friend class JNIObject<jclass>;
    friend class JNIObject<jlongArray>;
    friend class JNIObject<jbyteArray>;
    friend class JNIObject<jintArray>;
    jobject newLocalRef(jobject obj);
    void deleteLocalRef(jobject obj);
};

template<typename T>
JNIObject<T>::JNIObject(JNIHelper &helper, T obj)
    : mHelper(helper), mObj(obj)
{ }

template<typename T>
JNIObject<T>::JNIObject(const JNIObject<T>& rhs)
    : mHelper(rhs.mHelper), mObj(NULL)
{
    mObj = (T)mHelper.newLocalRef(rhs.mObj);
}

template<typename T>
JNIObject<T>::~JNIObject() {
    release();
}

template<typename T>
void JNIObject<T>::release()
{
    if (mObj != NULL) {
        mHelper.deleteLocalRef(mObj);
        mObj = NULL;
    }
}

template<typename T>
T JNIObject<T>::clone()
{
    return mHelper.newLocalRef(mObj);
}

}

#define THROW(env, message)      (env).throwException(message, __LINE__)