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
41 } // anonymous namespace
42
43 extern jobject mCallbacksObj;
44
45 jboolean checkHidlReturn(hardware::Return<bool>& result, const char* errorMessage);
46
47 jboolean checkAidlStatus(const android::binder::Status& status, const char* errorMessage);
48
49 void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
50
51 template <class T>
logHidlError(hardware::Return<T> & result,const char * errorMessage)52 void logHidlError(hardware::Return<T>& result, const char* errorMessage) {
53 ALOGE("%s HIDL transport error: %s", errorMessage, result.description().c_str());
54 }
55
56 template <class T>
checkHidlReturn(hardware::Return<T> & result,const char * errorMessage)57 jboolean checkHidlReturn(hardware::Return<T>& result, const char* errorMessage) {
58 if (!result.isOk()) {
59 logHidlError(result, errorMessage);
60 return JNI_FALSE;
61 } else {
62 return JNI_TRUE;
63 }
64 }
65
66 template <class T>
checkHidlReturn(hardware::Return<sp<T>> & result,const char * errorMessage)67 jboolean checkHidlReturn(hardware::Return<sp<T>>& result, const char* errorMessage) {
68 if (!result.isOk()) {
69 logHidlError(result, errorMessage);
70 return JNI_FALSE;
71 } else if ((sp<T>)result == nullptr) {
72 return JNI_FALSE;
73 } else {
74 return JNI_TRUE;
75 }
76 }
77
78 template <class T>
79 class JavaMethodHelper {
80 public:
81 // Helper function to call setter on a Java object.
82 static void callJavaMethod(JNIEnv* env, jclass clazz, jobject object, const char* method_name,
83 T value);
84
85 private:
86 static const char* const signature_;
87 };
88
89 // Define Java method signatures for all known types.
90 template <>
91 const char* const JavaMethodHelper<uint8_t>::signature_;
92 template <>
93 const char* const JavaMethodHelper<int8_t>::signature_;
94 template <>
95 const char* const JavaMethodHelper<int16_t>::signature_;
96 template <>
97 const char* const JavaMethodHelper<uint16_t>::signature_;
98 template <>
99 const char* const JavaMethodHelper<int32_t>::signature_;
100 template <>
101 const char* const JavaMethodHelper<uint32_t>::signature_;
102 template <>
103 const char* const JavaMethodHelper<int64_t>::signature_;
104 template <>
105 const char* const JavaMethodHelper<uint64_t>::signature_;
106 template <>
107 const char* const JavaMethodHelper<float>::signature_;
108 template <>
109 const char* const JavaMethodHelper<double>::signature_;
110 template <>
111 const char* const JavaMethodHelper<bool>::signature_;
112 template <>
113 const char* const JavaMethodHelper<jstring>::signature_;
114 template <>
115 const char* const JavaMethodHelper<jdoubleArray>::signature_;
116
117 template <class T>
callJavaMethod(JNIEnv * env,jclass clazz,jobject object,const char * method_name,T value)118 void JavaMethodHelper<T>::callJavaMethod(JNIEnv* env, jclass clazz, jobject object,
119 const char* method_name, T value) {
120 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
121 env->CallVoidMethod(object, method, value);
122 }
123
124 class JavaObject {
125 public:
126 JavaObject(JNIEnv* env, jclass clazz, jmethodID defaultCtor);
127 JavaObject(JNIEnv* env, jclass clazz, jmethodID stringCtor, const char* sz_arg_1);
128 JavaObject(JNIEnv* env, jclass clazz, jobject object);
129
130 virtual ~JavaObject() = default;
131
132 template <class T>
133 void callSetter(const char* method_name, T value);
134 template <class T>
135 void callSetter(const char* method_name, T* value, size_t size);
get()136 jobject get() { return object_; }
137
138 private:
139 JNIEnv* env_;
140 jclass clazz_;
141 jobject object_;
142 };
143
144 template <class T>
callSetter(const char * method_name,T value)145 void JavaObject::callSetter(const char* method_name, T value) {
146 JavaMethodHelper<T>::callJavaMethod(env_, clazz_, object_, method_name, value);
147 }
148
149 #define SET(setter, value) object.callSetter("set" #setter, (value))
150
151 class ScopedJniThreadAttach {
152 public:
153 static JavaVM* sJvm;
154
ScopedJniThreadAttach()155 ScopedJniThreadAttach() {
156 /*
157 * attachResult will also be JNI_OK if the thead was already attached to
158 * JNI before the call to AttachCurrentThread().
159 */
160 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
161 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
162 attachResult);
163 }
164
~ScopedJniThreadAttach()165 ~ScopedJniThreadAttach() {
166 jint detachResult = sJvm->DetachCurrentThread();
167 /*
168 * Return if the thread was already detached. Log error for any other
169 * failure.
170 */
171 if (detachResult == JNI_EDETACHED) {
172 return;
173 }
174
175 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
176 detachResult);
177 }
178
getEnv()179 JNIEnv* getEnv() {
180 /*
181 * Checking validity of mEnv in case the thread was detached elsewhere.
182 */
183 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
184 return mEnv;
185 }
186
187 private:
188 JNIEnv* mEnv = nullptr;
189 };
190
191 JNIEnv* getJniEnv();
192
193 } // namespace android
194
195 #endif // _ANDROID_SERVER_GNSS_UTILS_H
196