1/*
2 * Copyright 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <jni.h>
18
19namespace android {
20
21/* JNI Helpers for wifi_hal to WifiNative bridge implementation */
22
23class JNIHelper;
24
25template<typename T>
26class JNIObject {
27protected:
28    JNIHelper &mHelper;
29    T mObj;
30public:
31    JNIObject(JNIHelper &helper, T obj);
32    JNIObject(const JNIObject<T>& rhs);
33    virtual ~JNIObject();
34    JNIHelper& getHelper() const {
35        return mHelper;
36    }
37    T get() const {
38        return mObj;
39    }
40    operator T() const {
41        return mObj;
42    }
43    bool isNull() const {
44        return mObj == NULL;
45    }
46    void release();
47    T detach() {
48        T tObj = mObj;
49        mObj = NULL;
50        return tObj;
51    }
52    T clone();
53    JNIObject<T>& operator = (const JNIObject<T>& rhs) {
54        release();
55        mHelper = rhs.mHelper;
56        mObj = rhs.mObj;
57        return *this;
58    }
59    void print() {
60        ALOGD("holding %p", mObj);
61    }
62
63private:
64    template<typename T2>
65    JNIObject(const JNIObject<T2>& rhs);  // NOLINT(implicit)
66};
67
68class JNIHelper {
69    JavaVM *mVM;
70    JNIEnv *mEnv;
71
72public :
73    explicit JNIHelper(JavaVM *vm);
74    explicit JNIHelper(JNIEnv *env);
75    ~JNIHelper();
76
77    /* helpers to deal with static members */
78    JNIObject<jbyteArray> newByteArray(int num);
79    void setByteArrayRegion(jbyteArray array, int from, int to, const jbyte *bytes);
80
81private:
82    /* Jni wrappers */
83    friend class JNIObject<jbyteArray>;
84    jobject newLocalRef(jobject obj);
85    void deleteLocalRef(jobject obj);
86};
87
88template<typename T>
89JNIObject<T>::JNIObject(JNIHelper &helper, T obj)
90      : mHelper(helper), mObj(obj)
91{ }
92
93template<typename T>
94JNIObject<T>::JNIObject(const JNIObject<T>& rhs)
95      : mHelper(rhs.mHelper), mObj(NULL)
96{
97      mObj = (T)mHelper.newLocalRef(rhs.mObj);
98}
99
100template<typename T>
101JNIObject<T>::~JNIObject() {
102      release();
103}
104
105template<typename T>
106void JNIObject<T>::release()
107{
108      if (mObj != NULL) {
109          mHelper.deleteLocalRef(mObj);
110          mObj = NULL;
111      }
112}
113
114template<typename T>
115T JNIObject<T>::clone()
116{
117      return mHelper.newLocalRef(mObj);
118}
119}
120
121#define THROW(env, message)      (env).throwException(message, __LINE__)
122