• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #ifndef _ANDROID_SERVER_GNSS_UTILS_H
18 #define _ANDROID_SERVER_GNSS_UTILS_H
19 
20 #pragma once
21 
22 #ifndef LOG_TAG
23 #error LOG_TAG must be defined before including this file.
24 #endif
25 
26 #include <android/hardware/gnss/1.0/IGnss.h>
27 #include <android/hardware/gnss/BnGnss.h>
28 #include <log/log.h>
29 #include <nativehelper/JNIHelp.h>
30 #include "android_runtime/AndroidRuntime.h"
31 #include "android_runtime/Log.h"
32 #include "jni.h"
33 
34 namespace android {
35 
36 namespace {
37 
38 // Must match the value from GnssMeasurement.java
39 const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1 << 4);
40 extern jmethodID method_locationCtor;
41 
42 } // anonymous namespace
43 
44 extern jclass class_location;
45 extern jobject mCallbacksObj;
46 
47 namespace gnss {
48 void Utils_class_init_once(JNIEnv* env);
49 } // namespace gnss
50 
51 jobject& getCallbacksObj();
52 
53 jboolean checkHidlReturn(hardware::Return<bool>& result, const char* errorMessage);
54 
55 jboolean checkAidlStatus(const android::binder::Status& status, const char* errorMessage);
56 
57 void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
58 
59 void callObjectMethodIgnoringResult(JNIEnv* env, jobject obj, jmethodID mid, ...);
60 
61 template <class T>
logHidlError(hardware::Return<T> & result,const char * errorMessage)62 void logHidlError(hardware::Return<T>& result, const char* errorMessage) {
63     ALOGE("%s HIDL transport error: %s", errorMessage, result.description().c_str());
64 }
65 
66 template <class T>
checkHidlReturn(hardware::Return<T> & result,const char * errorMessage)67 jboolean checkHidlReturn(hardware::Return<T>& result, const char* errorMessage) {
68     if (!result.isOk()) {
69         logHidlError(result, errorMessage);
70         return JNI_FALSE;
71     } else {
72         return JNI_TRUE;
73     }
74 }
75 
76 template <class T>
checkHidlReturn(hardware::Return<sp<T>> & result,const char * errorMessage)77 jboolean checkHidlReturn(hardware::Return<sp<T>>& result, const char* errorMessage) {
78     if (!result.isOk()) {
79         logHidlError(result, errorMessage);
80         return JNI_FALSE;
81     } else if ((sp<T>)result == nullptr) {
82         return JNI_FALSE;
83     } else {
84         return JNI_TRUE;
85     }
86 }
87 
88 template <class T>
89 class JavaMethodHelper {
90 public:
91     // Helper function to call setter on a Java object.
92     static void callJavaMethod(JNIEnv* env, jclass clazz, jobject object, const char* method_name,
93                                T value);
94 
95 private:
96     static const char* const signature_;
97 };
98 
99 // Define Java method signatures for all known types.
100 template <>
101 const char* const JavaMethodHelper<uint8_t>::signature_;
102 template <>
103 const char* const JavaMethodHelper<int8_t>::signature_;
104 template <>
105 const char* const JavaMethodHelper<int16_t>::signature_;
106 template <>
107 const char* const JavaMethodHelper<uint16_t>::signature_;
108 template <>
109 const char* const JavaMethodHelper<int32_t>::signature_;
110 template <>
111 const char* const JavaMethodHelper<uint32_t>::signature_;
112 template <>
113 const char* const JavaMethodHelper<int64_t>::signature_;
114 template <>
115 const char* const JavaMethodHelper<uint64_t>::signature_;
116 template <>
117 const char* const JavaMethodHelper<float>::signature_;
118 template <>
119 const char* const JavaMethodHelper<double>::signature_;
120 template <>
121 const char* const JavaMethodHelper<bool>::signature_;
122 template <>
123 const char* const JavaMethodHelper<jstring>::signature_;
124 template <>
125 const char* const JavaMethodHelper<jdoubleArray>::signature_;
126 
127 template <class T>
callJavaMethod(JNIEnv * env,jclass clazz,jobject object,const char * method_name,T value)128 void JavaMethodHelper<T>::callJavaMethod(JNIEnv* env, jclass clazz, jobject object,
129                                          const char* method_name, T value) {
130     jmethodID method = env->GetMethodID(clazz, method_name, signature_);
131     env->CallVoidMethod(object, method, value);
132 }
133 
134 class JavaObject {
135 public:
136     JavaObject(JNIEnv* env, jclass clazz, jmethodID defaultCtor);
137     JavaObject(JNIEnv* env, jclass clazz, jmethodID stringCtor, const char* sz_arg_1);
138     JavaObject(JNIEnv* env, jclass clazz, jobject object);
139 
140     virtual ~JavaObject() = default;
141 
142     template <class T>
143     void callSetter(const char* method_name, T value);
144     template <class T>
145     void callSetter(const char* method_name, T* value, size_t size);
get()146     jobject get() { return object_; }
147 
148 private:
149     JNIEnv* env_;
150     jclass clazz_;
151     jobject object_;
152 };
153 
154 template <class T>
callSetter(const char * method_name,T value)155 void JavaObject::callSetter(const char* method_name, T value) {
156     JavaMethodHelper<T>::callJavaMethod(env_, clazz_, object_, method_name, value);
157 }
158 
159 #define SET(setter, value) object.callSetter("set" #setter, (value))
160 
161 class ScopedJniThreadAttach {
162 public:
163     static JavaVM* sJvm;
164 
ScopedJniThreadAttach()165     ScopedJniThreadAttach() {
166         /*
167          * attachResult will also be JNI_OK if the thead was already attached to
168          * JNI before the call to AttachCurrentThread().
169          */
170         jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
171         LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
172                             attachResult);
173     }
174 
~ScopedJniThreadAttach()175     ~ScopedJniThreadAttach() {
176         jint detachResult = sJvm->DetachCurrentThread();
177         /*
178          * Return if the thread was already detached. Log error for any other
179          * failure.
180          */
181         if (detachResult == JNI_EDETACHED) {
182             return;
183         }
184 
185         LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
186                             detachResult);
187     }
188 
getEnv()189     JNIEnv* getEnv() {
190         /*
191          * Checking validity of mEnv in case the thread was detached elsewhere.
192          */
193         LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
194         return mEnv;
195     }
196 
197 private:
198     JNIEnv* mEnv = nullptr;
199 };
200 
201 struct ScopedJniString {
ScopedJniStringScopedJniString202     ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) {
203         mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr);
204     }
205 
~ScopedJniStringScopedJniString206     ~ScopedJniString() {
207         if (mNativeString != nullptr) {
208             mEnv->ReleaseStringUTFChars(mJavaString, mNativeString);
209         }
210     }
211 
c_strScopedJniString212     const char* c_str() const { return mNativeString; }
213 
hidl_stringScopedJniString214     operator hardware::hidl_string() const { return hardware::hidl_string(mNativeString); }
215 
216 private:
217     ScopedJniString(const ScopedJniString&) = delete;
218     ScopedJniString& operator=(const ScopedJniString&) = delete;
219 
220     JNIEnv* mEnv;
221     jstring mJavaString;
222     const char* mNativeString;
223 };
224 
225 JNIEnv* getJniEnv();
226 
227 template <class T>
228 jobject translateGnssLocation(JNIEnv* env, const T& location);
229 
230 } // namespace android
231 
232 #endif // _ANDROID_SERVER_GNSS_UTILS_H
233