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 
19 namespace android {
20 
21 /* JNI Helpers for wifi_hal to WifiNative bridge implementation */
22 
23 class JNIHelper;
24 
25 template<typename T>
26 class JNIObject {
27 protected:
28     JNIHelper &mHelper;
29     T mObj;
30 public:
31     JNIObject(JNIHelper &helper, T obj);
32     JNIObject(const JNIObject<T>& rhs);
33     virtual ~JNIObject();
getHelper()34     JNIHelper& getHelper() const {
35         return mHelper;
36     }
get()37     T get() const {
38         return mObj;
39     }
T()40     operator T() const {
41         return mObj;
42     }
isNull()43     bool isNull() const {
44         return mObj == NULL;
45     }
46     void release();
detach()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     }
print()59     void print() {
60         ALOGD("holding %p", mObj);
61     }
62 
63 private:
64     template<typename T2>
65     JNIObject(const JNIObject<T2>& rhs);  // NOLINT(implicit)
66 };
67 
68 class JNIHelper {
69     JavaVM *mVM;
70     JNIEnv *mEnv;
71 
72 public :
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 
81 private:
82     /* Jni wrappers */
83     friend class JNIObject<jbyteArray>;
84     jobject newLocalRef(jobject obj);
85     void deleteLocalRef(jobject obj);
86 };
87 
88 template<typename T>
JNIObject(JNIHelper & helper,T obj)89 JNIObject<T>::JNIObject(JNIHelper &helper, T obj)
90       : mHelper(helper), mObj(obj)
91 { }
92 
93 template<typename T>
JNIObject(const JNIObject<T> & rhs)94 JNIObject<T>::JNIObject(const JNIObject<T>& rhs)
95       : mHelper(rhs.mHelper), mObj(NULL)
96 {
97       mObj = (T)mHelper.newLocalRef(rhs.mObj);
98 }
99 
100 template<typename T>
~JNIObject()101 JNIObject<T>::~JNIObject() {
102       release();
103 }
104 
105 template<typename T>
release()106 void JNIObject<T>::release()
107 {
108       if (mObj != NULL) {
109           mHelper.deleteLocalRef(mObj);
110           mObj = NULL;
111       }
112 }
113 
114 template<typename T>
clone()115 T JNIObject<T>::clone()
116 {
117       return mHelper.newLocalRef(mObj);
118 }
119 }
120 
121 #define THROW(env, message)      (env).throwException(message, __LINE__)
122