summaryrefslogtreecommitdiffstats
path: root/service/jni/jni_helper.h
blob: 834b0ac5f7704712bd19f647d943aacb2e084200 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

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);
    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<jobjectArray> createObjectArray(const char *className, int size);
    void setObjectField(jobject obj, const char *name, const char *type, jobject value);

    /* 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, jbyte *bytes);
    void setIntArrayRegion(jintArray array, int from, int to, jint *ints);
    void setLongArrayRegion(jlongArray array, int from, int to, 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__)