1 /*
2 * Copyright (C) 2021 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 // Define LOG_TAG before <log/log.h> to overwrite the default value.
18 #define LOG_TAG "GnssAntInfoCbJni"
19
20 #include "GnssAntennaInfoCallback.h"
21 #include "Utils.h"
22
23 namespace android::gnss {
24
25 using android::hardware::hidl_vec;
26 using android::hardware::Return;
27 using android::hardware::Void;
28 using binder::Status;
29
30 using IGnssAntennaInfoCallbackAidl = android::hardware::gnss::IGnssAntennaInfoCallback;
31 using IGnssAntennaInfoCallback_V2_1 = android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
32
33 namespace {
34 jclass class_gnssAntennaInfoBuilder;
35 jclass class_phaseCenterOffset;
36 jclass class_sphericalCorrections;
37 jclass class_arrayList;
38 jclass class_doubleArray;
39
40 jmethodID method_reportAntennaInfo;
41 jmethodID method_gnssAntennaInfoBuilderCtor;
42 jmethodID method_phaseCenterOffsetCtor;
43 jmethodID method_sphericalCorrectionsCtor;
44 jmethodID method_arrayListCtor;
45 jmethodID method_arrayListAdd;
46 jmethodID method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz;
47 jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterOffset;
48 jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections;
49 jmethodID method_gnssAntennaInfoBuilderSetSignalGainCorrections;
50 jmethodID method_gnssAntennaInfoBuilderBuild;
51 } // anonymous namespace
52
GnssAntennaInfo_class_init_once(JNIEnv * env,jclass & clazz)53 void GnssAntennaInfo_class_init_once(JNIEnv* env, jclass& clazz) {
54 method_reportAntennaInfo = env->GetMethodID(clazz, "reportAntennaInfo", "(Ljava/util/List;)V");
55 jclass gnssAntennaInfoBuilder = env->FindClass("android/location/GnssAntennaInfo$Builder");
56 class_gnssAntennaInfoBuilder = (jclass)env->NewGlobalRef(gnssAntennaInfoBuilder);
57 method_gnssAntennaInfoBuilderCtor =
58 env->GetMethodID(class_gnssAntennaInfoBuilder, "<init>", "()V");
59 method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz =
60 env->GetMethodID(class_gnssAntennaInfoBuilder, "setCarrierFrequencyMHz",
61 "(D)Landroid/location/GnssAntennaInfo$Builder;");
62 method_gnssAntennaInfoBuilderSetPhaseCenterOffset =
63 env->GetMethodID(class_gnssAntennaInfoBuilder, "setPhaseCenterOffset",
64 "(Landroid/location/GnssAntennaInfo$PhaseCenterOffset;)"
65 "Landroid/location/GnssAntennaInfo$Builder;");
66 method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections =
67 env->GetMethodID(class_gnssAntennaInfoBuilder, "setPhaseCenterVariationCorrections",
68 "(Landroid/location/GnssAntennaInfo$SphericalCorrections;)"
69 "Landroid/location/GnssAntennaInfo$Builder;");
70 method_gnssAntennaInfoBuilderSetSignalGainCorrections =
71 env->GetMethodID(class_gnssAntennaInfoBuilder, "setSignalGainCorrections",
72 "(Landroid/location/GnssAntennaInfo$SphericalCorrections;)"
73 "Landroid/location/GnssAntennaInfo$Builder;");
74 method_gnssAntennaInfoBuilderBuild = env->GetMethodID(class_gnssAntennaInfoBuilder, "build",
75 "()Landroid/location/GnssAntennaInfo;");
76
77 jclass phaseCenterOffsetClass =
78 env->FindClass("android/location/GnssAntennaInfo$PhaseCenterOffset");
79 class_phaseCenterOffset = (jclass)env->NewGlobalRef(phaseCenterOffsetClass);
80 method_phaseCenterOffsetCtor = env->GetMethodID(class_phaseCenterOffset, "<init>", "(DDDDDD)V");
81
82 jclass sphericalCorrectionsClass =
83 env->FindClass("android/location/GnssAntennaInfo$SphericalCorrections");
84 class_sphericalCorrections = (jclass)env->NewGlobalRef(sphericalCorrectionsClass);
85 method_sphericalCorrectionsCtor =
86 env->GetMethodID(class_sphericalCorrections, "<init>", "([[D[[D)V");
87
88 jclass arrayListClass = env->FindClass("java/util/ArrayList");
89 class_arrayList = (jclass)env->NewGlobalRef(arrayListClass);
90 method_arrayListCtor = env->GetMethodID(class_arrayList, "<init>", "()V");
91 method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z");
92
93 jclass doubleArrayClass = env->FindClass("[D");
94 class_doubleArray = (jclass)env->NewGlobalRef(doubleArrayClass);
95 }
96
gnssAntennaInfoCb(const std::vector<IGnssAntennaInfoCallbackAidl::GnssAntennaInfo> & gnssAntennaInfos)97 binder::Status GnssAntennaInfoCallbackAidl::gnssAntennaInfoCb(
98 const std::vector<IGnssAntennaInfoCallbackAidl::GnssAntennaInfo>& gnssAntennaInfos) {
99 GnssAntennaInfoCallbackUtil::translateAndReportGnssAntennaInfo(gnssAntennaInfos);
100 return Status::ok();
101 }
102
gnssAntennaInfoCb(const hidl_vec<IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo> & gnssAntennaInfos)103 Return<void> GnssAntennaInfoCallback_V2_1::gnssAntennaInfoCb(
104 const hidl_vec<IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo>& gnssAntennaInfos) {
105 GnssAntennaInfoCallbackUtil::translateAndReportGnssAntennaInfo(gnssAntennaInfos);
106 return Void();
107 }
108
109 template <template <class...> class T_vector, class T_info>
translate2dDoubleArray(JNIEnv * env,const T_vector<T_info> & array)110 jobjectArray GnssAntennaInfoCallbackUtil::translate2dDoubleArray(JNIEnv* env,
111 const T_vector<T_info>& array) {
112 jsize numRows = array.size();
113 if (numRows == 0) {
114 // Empty array
115 return NULL;
116 }
117 jsize numCols = array[0].row.size();
118 if (numCols <= 1) {
119 // phi angle separation is computed as 180.0 / (numColumns - 1), so can't be < 2.
120 return NULL;
121 }
122
123 // Allocate array of double arrays
124 jobjectArray returnArray = env->NewObjectArray(numRows, class_doubleArray, NULL);
125
126 // Create each double array
127 for (uint8_t i = 0; i < numRows; i++) {
128 jdoubleArray doubleArray = env->NewDoubleArray(numCols);
129 env->SetDoubleArrayRegion(doubleArray, (jsize)0, numCols, array[i].row.data());
130 env->SetObjectArrayElement(returnArray, (jsize)i, doubleArray);
131 env->DeleteLocalRef(doubleArray);
132 }
133 return returnArray;
134 }
135
136 template <template <class...> class T_vector, class T_info>
translateAllGnssAntennaInfos(JNIEnv * env,const T_vector<T_info> & gnssAntennaInfos)137 jobject GnssAntennaInfoCallbackUtil::translateAllGnssAntennaInfos(
138 JNIEnv* env, const T_vector<T_info>& gnssAntennaInfos) {
139 jobject arrayList = env->NewObject(class_arrayList,
140 method_arrayListCtor); // Create new ArrayList instance
141
142 for (auto gnssAntennaInfo : gnssAntennaInfos) {
143 jobject gnssAntennaInfoObject = translateSingleGnssAntennaInfo(env, gnssAntennaInfo);
144
145 env->CallBooleanMethod(arrayList, method_arrayListAdd,
146 gnssAntennaInfoObject); // Add the antennaInfo to the ArrayList
147
148 // Delete Local Refs
149 env->DeleteLocalRef(gnssAntennaInfoObject);
150 }
151 return arrayList;
152 }
153
154 template <class T>
translatePhaseCenterOffset(JNIEnv * env,const T & gnssAntennaInfo)155 jobject GnssAntennaInfoCallbackUtil::translatePhaseCenterOffset(JNIEnv* env,
156 const T& gnssAntennaInfo) {
157 jobject phaseCenterOffset =
158 env->NewObject(class_phaseCenterOffset, method_phaseCenterOffsetCtor,
159 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.x,
160 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.xUncertainty,
161 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.y,
162 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.yUncertainty,
163 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.z,
164 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.zUncertainty);
165
166 return phaseCenterOffset;
167 }
168
169 template <>
translatePhaseCenterVariationCorrections(JNIEnv * env,const IGnssAntennaInfoCallbackAidl::GnssAntennaInfo & gnssAntennaInfo)170 jobject GnssAntennaInfoCallbackUtil::translatePhaseCenterVariationCorrections(
171 JNIEnv* env, const IGnssAntennaInfoCallbackAidl::GnssAntennaInfo& gnssAntennaInfo) {
172 if (gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters.empty() ||
173 gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.empty()) {
174 return NULL;
175 }
176
177 jobjectArray phaseCenterVariationCorrectionsArray =
178 translate2dDoubleArray(env, gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters);
179 jobjectArray phaseCenterVariationCorrectionsUncertaintiesArray =
180 translate2dDoubleArray(env,
181 gnssAntennaInfo
182 .phaseCenterVariationCorrectionUncertaintyMillimeters);
183
184 if (phaseCenterVariationCorrectionsArray == NULL ||
185 phaseCenterVariationCorrectionsUncertaintiesArray == NULL) {
186 env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
187 env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
188 return NULL;
189 }
190
191 jobject phaseCenterVariationCorrections =
192 env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
193 phaseCenterVariationCorrectionsArray,
194 phaseCenterVariationCorrectionsUncertaintiesArray);
195
196 env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
197 env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
198
199 return phaseCenterVariationCorrections;
200 }
201
202 template <>
translatePhaseCenterVariationCorrections(JNIEnv * env,const IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo & gnssAntennaInfo)203 jobject GnssAntennaInfoCallbackUtil::translatePhaseCenterVariationCorrections(
204 JNIEnv* env, const IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo& gnssAntennaInfo) {
205 if (gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters == NULL ||
206 gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters == NULL) {
207 return NULL;
208 }
209
210 jobjectArray phaseCenterVariationCorrectionsArray =
211 translate2dDoubleArray(env, gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters);
212 jobjectArray phaseCenterVariationCorrectionsUncertaintiesArray =
213 translate2dDoubleArray(env,
214 gnssAntennaInfo
215 .phaseCenterVariationCorrectionUncertaintyMillimeters);
216
217 if (phaseCenterVariationCorrectionsArray == NULL ||
218 phaseCenterVariationCorrectionsUncertaintiesArray == NULL) {
219 env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
220 env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
221 return NULL;
222 }
223
224 jobject phaseCenterVariationCorrections =
225 env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
226 phaseCenterVariationCorrectionsArray,
227 phaseCenterVariationCorrectionsUncertaintiesArray);
228
229 env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
230 env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
231
232 return phaseCenterVariationCorrections;
233 }
234
235 template <>
translateSignalGainCorrections(JNIEnv * env,const IGnssAntennaInfoCallbackAidl::GnssAntennaInfo & gnssAntennaInfo)236 jobject GnssAntennaInfoCallbackUtil::translateSignalGainCorrections(
237 JNIEnv* env, const IGnssAntennaInfoCallbackAidl::GnssAntennaInfo& gnssAntennaInfo) {
238 if (gnssAntennaInfo.signalGainCorrectionDbi.empty() ||
239 gnssAntennaInfo.signalGainCorrectionUncertaintyDbi.empty()) {
240 return NULL;
241 }
242 jobjectArray signalGainCorrectionsArray =
243 translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionDbi);
244 jobjectArray signalGainCorrectionsUncertaintiesArray =
245 translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionUncertaintyDbi);
246
247 if (signalGainCorrectionsArray == NULL || signalGainCorrectionsUncertaintiesArray == NULL) {
248 env->DeleteLocalRef(signalGainCorrectionsArray);
249 env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
250 return NULL;
251 }
252
253 jobject signalGainCorrections =
254 env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
255 signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray);
256
257 env->DeleteLocalRef(signalGainCorrectionsArray);
258 env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
259
260 return signalGainCorrections;
261 }
262
263 template <>
translateSignalGainCorrections(JNIEnv * env,const IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo & gnssAntennaInfo)264 jobject GnssAntennaInfoCallbackUtil::translateSignalGainCorrections(
265 JNIEnv* env, const IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo& gnssAntennaInfo) {
266 if (gnssAntennaInfo.signalGainCorrectionDbi == NULL ||
267 gnssAntennaInfo.signalGainCorrectionUncertaintyDbi == NULL) {
268 return NULL;
269 }
270 jobjectArray signalGainCorrectionsArray =
271 translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionDbi);
272 jobjectArray signalGainCorrectionsUncertaintiesArray =
273 translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionUncertaintyDbi);
274
275 if (signalGainCorrectionsArray == NULL || signalGainCorrectionsUncertaintiesArray == NULL) {
276 env->DeleteLocalRef(signalGainCorrectionsArray);
277 env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
278 return NULL;
279 }
280
281 jobject signalGainCorrections =
282 env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
283 signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray);
284
285 env->DeleteLocalRef(signalGainCorrectionsArray);
286 env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
287
288 return signalGainCorrections;
289 }
290
291 template <class T>
translateSingleGnssAntennaInfo(JNIEnv * env,const T & gnssAntennaInfo)292 jobject GnssAntennaInfoCallbackUtil::translateSingleGnssAntennaInfo(JNIEnv* env,
293 const T& gnssAntennaInfo) {
294 jobject phaseCenterOffset = translatePhaseCenterOffset(env, gnssAntennaInfo);
295
296 // Nullable
297 jobject phaseCenterVariationCorrections =
298 translatePhaseCenterVariationCorrections(env, gnssAntennaInfo);
299
300 // Nullable
301 jobject signalGainCorrections = translateSignalGainCorrections(env, gnssAntennaInfo);
302
303 // Get builder
304 jobject gnssAntennaInfoBuilderObject =
305 env->NewObject(class_gnssAntennaInfoBuilder, method_gnssAntennaInfoBuilderCtor);
306
307 // Set fields
308 callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
309 method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz,
310 getCarrierFrequencyMHz(gnssAntennaInfo));
311 callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
312 method_gnssAntennaInfoBuilderSetPhaseCenterOffset,
313 phaseCenterOffset);
314 callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
315 method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections,
316 phaseCenterVariationCorrections);
317 callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
318 method_gnssAntennaInfoBuilderSetSignalGainCorrections,
319 signalGainCorrections);
320
321 // build
322 jobject gnssAntennaInfoObject =
323 env->CallObjectMethod(gnssAntennaInfoBuilderObject, method_gnssAntennaInfoBuilderBuild);
324
325 // Delete Local Refs
326 env->DeleteLocalRef(phaseCenterOffset);
327 env->DeleteLocalRef(phaseCenterVariationCorrections);
328 env->DeleteLocalRef(signalGainCorrections);
329
330 return gnssAntennaInfoObject;
331 }
332
333 template <template <class...> class T_vector, class T_info>
translateAndReportGnssAntennaInfo(const T_vector<T_info> & gnssAntennaInfos)334 void GnssAntennaInfoCallbackUtil::translateAndReportGnssAntennaInfo(
335 const T_vector<T_info>& gnssAntennaInfos) {
336 JNIEnv* env = getJniEnv();
337
338 jobject arrayList = translateAllGnssAntennaInfos(env, gnssAntennaInfos);
339
340 reportAntennaInfo(env, arrayList);
341
342 env->DeleteLocalRef(arrayList);
343 }
344
reportAntennaInfo(JNIEnv * env,const jobject antennaInfosArray)345 void GnssAntennaInfoCallbackUtil::reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray) {
346 env->CallVoidMethod(mCallbacksObj, method_reportAntennaInfo, antennaInfosArray);
347 checkAndClearExceptionFromCallback(env, __FUNCTION__);
348 }
349
350 } // namespace android::gnss
351