• 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 #define LOG_TAG "GnssMeasCbJni"
18 
19 #include "GnssMeasurementCallback.h"
20 
21 namespace android::gnss {
22 
23 using binder::Status;
24 using hardware::gnss::CorrelationVector;
25 using hardware::gnss::ElapsedRealtime;
26 using hardware::gnss::GnssClock;
27 using hardware::gnss::GnssData;
28 using hardware::gnss::GnssMeasurement;
29 using hardware::gnss::SatellitePvt;
30 
31 jclass class_arrayList;
32 jclass class_clockInfo;
33 jclass class_correlationVectorBuilder;
34 jclass class_gnssMeasurementsEvent;
35 jclass class_gnssMeasurement;
36 jclass class_gnssClock;
37 jclass class_positionEcef;
38 jclass class_satellitePvtBuilder;
39 jclass class_velocityEcef;
40 
41 jmethodID method_arrayListAdd;
42 jmethodID method_arrayListCtor;
43 jmethodID method_correlationVectorBuilderBuild;
44 jmethodID method_correlationVectorBuilderCtor;
45 jmethodID method_correlationVectorBuilderSetFrequencyOffsetMetersPerSecond;
46 jmethodID method_correlationVectorBuilderSetMagnitude;
47 jmethodID method_correlationVectorBuilderSetSamplingStartMeters;
48 jmethodID method_correlationVectorBuilderSetSamplingWidthMeters;
49 jmethodID method_gnssMeasurementsEventCtor;
50 jmethodID method_gnssMeasurementsSetCorrelationVectors;
51 jmethodID method_gnssMeasurementsSetSatellitePvt;
52 jmethodID method_gnssClockCtor;
53 jmethodID method_gnssMeasurementCtor;
54 jmethodID method_reportMeasurementData;
55 jmethodID method_satellitePvtBuilderBuild;
56 jmethodID method_satellitePvtBuilderCtor;
57 jmethodID method_satellitePvtBuilderSetPositionEcef;
58 jmethodID method_satellitePvtBuilderSetVelocityEcef;
59 jmethodID method_satellitePvtBuilderSetClockInfo;
60 jmethodID method_satellitePvtBuilderSetIonoDelayMeters;
61 jmethodID method_satellitePvtBuilderSetTropoDelayMeters;
62 jmethodID method_positionEcef;
63 jmethodID method_velocityEcef;
64 jmethodID method_clockInfo;
65 
GnssMeasurement_class_init_once(JNIEnv * env,jclass & clazz)66 void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz) {
67     method_reportMeasurementData = env->GetMethodID(clazz, "reportMeasurementData",
68                                                     "(Landroid/location/GnssMeasurementsEvent;)V");
69     jclass gnssMeasurementsEventClass = env->FindClass("android/location/GnssMeasurementsEvent");
70     class_gnssMeasurementsEvent = (jclass)env->NewGlobalRef(gnssMeasurementsEventClass);
71     method_gnssMeasurementsEventCtor =
72             env->GetMethodID(class_gnssMeasurementsEvent, "<init>",
73                              "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
74 
75     jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
76     class_gnssMeasurement = (jclass)env->NewGlobalRef(gnssMeasurementClass);
77     method_gnssMeasurementCtor = env->GetMethodID(class_gnssMeasurement, "<init>", "()V");
78     method_gnssMeasurementsSetSatellitePvt =
79             env->GetMethodID(class_gnssMeasurement, "setSatellitePvt",
80                              "(Landroid/location/SatellitePvt;)V");
81     method_gnssMeasurementsSetCorrelationVectors =
82             env->GetMethodID(class_gnssMeasurement, "setCorrelationVectors",
83                              "(Ljava/util/Collection;)V");
84 
85     jclass gnssClockClass = env->FindClass("android/location/GnssClock");
86     class_gnssClock = (jclass)env->NewGlobalRef(gnssClockClass);
87     method_gnssClockCtor = env->GetMethodID(class_gnssClock, "<init>", "()V");
88 
89     jclass satellitePvtBuilder = env->FindClass("android/location/SatellitePvt$Builder");
90     class_satellitePvtBuilder = (jclass)env->NewGlobalRef(satellitePvtBuilder);
91     method_satellitePvtBuilderCtor = env->GetMethodID(class_satellitePvtBuilder, "<init>", "()V");
92     method_satellitePvtBuilderSetPositionEcef =
93             env->GetMethodID(class_satellitePvtBuilder, "setPositionEcef",
94                              "(Landroid/location/SatellitePvt$PositionEcef;)"
95                              "Landroid/location/SatellitePvt$Builder;");
96     method_satellitePvtBuilderSetVelocityEcef =
97             env->GetMethodID(class_satellitePvtBuilder, "setVelocityEcef",
98                              "(Landroid/location/SatellitePvt$VelocityEcef;)"
99                              "Landroid/location/SatellitePvt$Builder;");
100     method_satellitePvtBuilderSetClockInfo =
101             env->GetMethodID(class_satellitePvtBuilder, "setClockInfo",
102                              "(Landroid/location/SatellitePvt$ClockInfo;)"
103                              "Landroid/location/SatellitePvt$Builder;");
104     method_satellitePvtBuilderSetIonoDelayMeters =
105             env->GetMethodID(class_satellitePvtBuilder, "setIonoDelayMeters",
106                              "(D)Landroid/location/SatellitePvt$Builder;");
107     method_satellitePvtBuilderSetTropoDelayMeters =
108             env->GetMethodID(class_satellitePvtBuilder, "setTropoDelayMeters",
109                              "(D)Landroid/location/SatellitePvt$Builder;");
110     method_satellitePvtBuilderBuild = env->GetMethodID(class_satellitePvtBuilder, "build",
111                                                        "()Landroid/location/SatellitePvt;");
112 
113     jclass positionEcefClass = env->FindClass("android/location/SatellitePvt$PositionEcef");
114     class_positionEcef = (jclass)env->NewGlobalRef(positionEcefClass);
115     method_positionEcef = env->GetMethodID(class_positionEcef, "<init>", "(DDDD)V");
116 
117     jclass velocityEcefClass = env->FindClass("android/location/SatellitePvt$VelocityEcef");
118     class_velocityEcef = (jclass)env->NewGlobalRef(velocityEcefClass);
119     method_velocityEcef = env->GetMethodID(class_velocityEcef, "<init>", "(DDDD)V");
120 
121     jclass clockInfoClass = env->FindClass("android/location/SatellitePvt$ClockInfo");
122     class_clockInfo = (jclass)env->NewGlobalRef(clockInfoClass);
123     method_clockInfo = env->GetMethodID(class_clockInfo, "<init>", "(DDD)V");
124 
125     jclass correlationVectorBuilder = env->FindClass("android/location/CorrelationVector$Builder");
126     class_correlationVectorBuilder = (jclass)env->NewGlobalRef(correlationVectorBuilder);
127     method_correlationVectorBuilderCtor =
128             env->GetMethodID(class_correlationVectorBuilder, "<init>", "()V");
129     method_correlationVectorBuilderSetMagnitude =
130             env->GetMethodID(class_correlationVectorBuilder, "setMagnitude",
131                              "([I)Landroid/location/CorrelationVector$Builder;");
132     method_correlationVectorBuilderSetFrequencyOffsetMetersPerSecond =
133             env->GetMethodID(class_correlationVectorBuilder, "setFrequencyOffsetMetersPerSecond",
134                              "(D)Landroid/location/CorrelationVector$Builder;");
135     method_correlationVectorBuilderSetSamplingStartMeters =
136             env->GetMethodID(class_correlationVectorBuilder, "setSamplingStartMeters",
137                              "(D)Landroid/location/CorrelationVector$Builder;");
138     method_correlationVectorBuilderSetSamplingWidthMeters =
139             env->GetMethodID(class_correlationVectorBuilder, "setSamplingWidthMeters",
140                              "(D)Landroid/location/CorrelationVector$Builder;");
141     method_correlationVectorBuilderBuild =
142             env->GetMethodID(class_correlationVectorBuilder, "build",
143                              "()Landroid/location/CorrelationVector;");
144 
145     jclass arrayListClass = env->FindClass("java/util/ArrayList");
146     class_arrayList = (jclass)env->NewGlobalRef(arrayListClass);
147     method_arrayListCtor = env->GetMethodID(class_arrayList, "<init>", "()V");
148     method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z");
149 }
150 
setMeasurementData(JNIEnv * env,jobject & callbacksObj,jobject clock,jobjectArray measurementArray)151 void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock,
152                         jobjectArray measurementArray) {
153     jobject gnssMeasurementsEvent =
154             env->NewObject(class_gnssMeasurementsEvent, method_gnssMeasurementsEventCtor, clock,
155                            measurementArray);
156 
157     env->CallVoidMethod(callbacksObj, method_reportMeasurementData, gnssMeasurementsEvent);
158     checkAndClearExceptionFromCallback(env, __FUNCTION__);
159     env->DeleteLocalRef(gnssMeasurementsEvent);
160 }
161 
162 template <class T_Measurement, class T_Flags>
setMeasurementFields_V1_0(const T_Measurement & measurement,JavaObject & object)163 void setMeasurementFields_V1_0(const T_Measurement& measurement, JavaObject& object) {
164     uint32_t flags = static_cast<uint32_t>(measurement.flags);
165 
166     SET(Svid, static_cast<int32_t>(measurement.svid));
167     SET(TimeOffsetNanos, measurement.timeOffsetNs);
168     SET(State, static_cast<int32_t>(measurement.state));
169     SET(ReceivedSvTimeNanos, measurement.receivedSvTimeInNs);
170     SET(ReceivedSvTimeUncertaintyNanos, measurement.receivedSvTimeUncertaintyInNs);
171     SET(PseudorangeRateMetersPerSecond, measurement.pseudorangeRateMps);
172     SET(PseudorangeRateUncertaintyMetersPerSecond, measurement.pseudorangeRateUncertaintyMps);
173     SET(AccumulatedDeltaRangeState,
174         (static_cast<int32_t>(measurement.accumulatedDeltaRangeState) &
175          ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
176     SET(AccumulatedDeltaRangeMeters, measurement.accumulatedDeltaRangeM);
177     SET(AccumulatedDeltaRangeUncertaintyMeters, measurement.accumulatedDeltaRangeUncertaintyM);
178 
179     // Intentionally not copying deprecated fields of carrierCycles,
180     // carrierPhase, carrierPhaseUncertainty
181 
182     SET(MultipathIndicator, static_cast<int32_t>(measurement.multipathIndicator));
183 
184     if (flags & static_cast<uint32_t>(T_Flags::HAS_SNR)) {
185         SET(SnrInDb, measurement.snrDb);
186     }
187 
188     if (flags & static_cast<uint32_t>(T_Flags::HAS_AUTOMATIC_GAIN_CONTROL)) {
189         SET(AutomaticGainControlLevelInDb, measurement.agcLevelDb);
190     }
191 }
192 
193 template <class T_Measurement, class T_Flags>
setMeasurementFields_V2_1(const T_Measurement & measurement,JavaObject & object)194 void setMeasurementFields_V2_1(const T_Measurement& measurement, JavaObject& object) {
195     SET(BasebandCn0DbHz, measurement.basebandCN0DbHz);
196 
197     if (measurement.flags & T_Flags::HAS_FULL_ISB) {
198         SET(FullInterSignalBiasNanos, measurement.fullInterSignalBiasNs);
199     }
200 
201     if (measurement.flags & T_Flags::HAS_FULL_ISB_UNCERTAINTY) {
202         SET(FullInterSignalBiasUncertaintyNanos, measurement.fullInterSignalBiasUncertaintyNs);
203     }
204 
205     if (measurement.flags & T_Flags::HAS_SATELLITE_ISB) {
206         SET(SatelliteInterSignalBiasNanos, measurement.satelliteInterSignalBiasNs);
207     }
208 
209     if (measurement.flags & T_Flags::HAS_SATELLITE_ISB_UNCERTAINTY) {
210         SET(SatelliteInterSignalBiasUncertaintyNanos,
211             measurement.satelliteInterSignalBiasUncertaintyNs);
212     }
213 }
214 
215 template <class T_Clock, class T_Flags>
setClockFields_V1_0(const T_Clock & clock,JavaObject & object)216 void setClockFields_V1_0(const T_Clock& clock, JavaObject& object) {
217     uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags);
218     if (flags & static_cast<uint32_t>(T_Flags::HAS_LEAP_SECOND)) {
219         SET(LeapSecond, static_cast<int32_t>(clock.leapSecond));
220     }
221 
222     if (flags & static_cast<uint32_t>(T_Flags::HAS_TIME_UNCERTAINTY)) {
223         SET(TimeUncertaintyNanos, clock.timeUncertaintyNs);
224     }
225 
226     if (flags & static_cast<uint32_t>(T_Flags::HAS_FULL_BIAS)) {
227         SET(FullBiasNanos, clock.fullBiasNs);
228     }
229 
230     if (flags & static_cast<uint32_t>(T_Flags::HAS_BIAS)) {
231         SET(BiasNanos, clock.biasNs);
232     }
233 
234     if (flags & static_cast<uint32_t>(T_Flags::HAS_BIAS_UNCERTAINTY)) {
235         SET(BiasUncertaintyNanos, clock.biasUncertaintyNs);
236     }
237 
238     if (flags & static_cast<uint32_t>(T_Flags::HAS_DRIFT)) {
239         SET(DriftNanosPerSecond, clock.driftNsps);
240     }
241 
242     if (flags & static_cast<uint32_t>(T_Flags::HAS_DRIFT_UNCERTAINTY)) {
243         SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps);
244     }
245 
246     SET(TimeNanos, clock.timeNs);
247     SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount);
248 }
249 
250 template <class T_Clock, class T_Flags>
setClockFields_V2_1(const T_Clock & clock,JavaObject & object)251 void setClockFields_V2_1(const T_Clock& clock, JavaObject& object) {
252     JNIEnv* env = getJniEnv();
253     SET(ReferenceConstellationTypeForIsb,
254         static_cast<int32_t>(clock.referenceSignalTypeForIsb.constellation));
255     SET(ReferenceCarrierFrequencyHzForIsb, clock.referenceSignalTypeForIsb.carrierFrequencyHz);
256 
257     jstring referenceCodeTypeForIsb =
258             env->NewStringUTF(clock.referenceSignalTypeForIsb.codeType.c_str());
259     SET(ReferenceCodeTypeForIsb, referenceCodeTypeForIsb);
260     env->DeleteLocalRef(referenceCodeTypeForIsb);
261 }
262 
263 template <class T_ElapsedRealtime, class T_Flags>
setElapsedRealtimeFields(const T_ElapsedRealtime & elapsedRealtime,JavaObject & object)264 void setElapsedRealtimeFields(const T_ElapsedRealtime& elapsedRealtime, JavaObject& object) {
265     uint32_t flags = static_cast<uint32_t>(elapsedRealtime.flags);
266     if (flags & T_Flags::HAS_TIMESTAMP_NS) {
267         SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
268     }
269     if (flags & T_Flags::HAS_TIME_UNCERTAINTY_NS) {
270         SET(ElapsedRealtimeUncertaintyNanos,
271             static_cast<double>(elapsedRealtime.timeUncertaintyNs));
272     }
273 }
274 
275 // Implementation of GnssMeasurementCallbackAidl class.
276 
gnssMeasurementCb(const GnssData & data)277 Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& data) {
278     ALOGD("%s", __func__);
279     translateAndSetGnssData(data);
280     return Status::ok();
281 }
282 
translateAndSetGnssData(const GnssData & data)283 void GnssMeasurementCallbackAidl::translateAndSetGnssData(const GnssData& data) {
284     JNIEnv* env = getJniEnv();
285 
286     JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
287     translateGnssClock(env, data, gnssClockJavaObject);
288     jobject clock = gnssClockJavaObject.get();
289 
290     jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements);
291     setMeasurementData(env, mCallbacksObj, clock, measurementArray);
292 
293     env->DeleteLocalRef(clock);
294     env->DeleteLocalRef(measurementArray);
295 }
296 
translateSingleGnssMeasurement(JNIEnv * env,const GnssMeasurement & measurement,JavaObject & object)297 void GnssMeasurementCallbackAidl::translateSingleGnssMeasurement(JNIEnv* env,
298                                                                  const GnssMeasurement& measurement,
299                                                                  JavaObject& object) {
300     setMeasurementFields_V1_0<GnssMeasurement, GnssMeasurement>(measurement, object);
301     setMeasurementFields_V2_1<GnssMeasurement, GnssMeasurement>(measurement, object);
302 
303     SET(Cn0DbHz, measurement.antennaCN0DbHz);
304     SET(ConstellationType, static_cast<int32_t>(measurement.signalType.constellation));
305     // Half cycle state is reported in the AIDL version of GnssMeasurement
306     SET(AccumulatedDeltaRangeState,
307         (static_cast<int32_t>(measurement.accumulatedDeltaRangeState) |
308          ADR_STATE_HALF_CYCLE_REPORTED));
309 
310     if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_CARRIER_FREQUENCY)) {
311         SET(CarrierFrequencyHz, static_cast<float>(measurement.signalType.carrierFrequencyHz));
312     }
313 
314     if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_SATELLITE_PVT)) {
315         const SatellitePvt& satellitePvt = measurement.satellitePvt;
316         uint16_t satFlags = static_cast<uint16_t>(satellitePvt.flags);
317         jobject positionEcef = nullptr;
318         jobject velocityEcef = nullptr;
319         jobject clockInfo = nullptr;
320         jobject satellitePvtBuilderObject =
321                 env->NewObject(class_satellitePvtBuilder, method_satellitePvtBuilderCtor);
322 
323         if (satFlags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) {
324             positionEcef = env->NewObject(class_positionEcef, method_positionEcef,
325                                           satellitePvt.satPosEcef.posXMeters,
326                                           satellitePvt.satPosEcef.posYMeters,
327                                           satellitePvt.satPosEcef.posZMeters,
328                                           satellitePvt.satPosEcef.ureMeters);
329             velocityEcef =
330                     env->NewObject(class_velocityEcef, method_velocityEcef,
331                                    satellitePvt.satVelEcef.velXMps, satellitePvt.satVelEcef.velYMps,
332                                    satellitePvt.satVelEcef.velZMps,
333                                    satellitePvt.satVelEcef.ureRateMps);
334             clockInfo = env->NewObject(class_clockInfo, method_clockInfo,
335                                        satellitePvt.satClockInfo.satHardwareCodeBiasMeters,
336                                        satellitePvt.satClockInfo.satTimeCorrectionMeters,
337                                        satellitePvt.satClockInfo.satClkDriftMps);
338             env->CallObjectMethod(satellitePvtBuilderObject,
339                                   method_satellitePvtBuilderSetPositionEcef, positionEcef);
340             env->CallObjectMethod(satellitePvtBuilderObject,
341                                   method_satellitePvtBuilderSetVelocityEcef, velocityEcef);
342             env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderSetClockInfo,
343                                   clockInfo);
344         }
345 
346         if (satFlags & SatellitePvt::HAS_IONO) {
347             env->CallObjectMethod(satellitePvtBuilderObject,
348                                   method_satellitePvtBuilderSetIonoDelayMeters,
349                                   satellitePvt.ionoDelayMeters);
350         }
351 
352         if (satFlags & SatellitePvt::HAS_TROPO) {
353             env->CallObjectMethod(satellitePvtBuilderObject,
354                                   method_satellitePvtBuilderSetTropoDelayMeters,
355                                   satellitePvt.tropoDelayMeters);
356         }
357 
358         jobject satellitePvtObject =
359                 env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderBuild);
360         env->CallVoidMethod(object.get(), method_gnssMeasurementsSetSatellitePvt,
361                             satellitePvtObject);
362         env->DeleteLocalRef(positionEcef);
363         env->DeleteLocalRef(velocityEcef);
364         env->DeleteLocalRef(clockInfo);
365         env->DeleteLocalRef(satellitePvtBuilderObject);
366         env->DeleteLocalRef(satellitePvtObject);
367     }
368 
369     if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_CORRELATION_VECTOR)) {
370         jobject correlationVectorList = env->NewObject(class_arrayList, method_arrayListCtor);
371         for (uint16_t i = 0; i < measurement.correlationVectors.size(); ++i) {
372             const CorrelationVector& correlationVector = measurement.correlationVectors[i];
373             const std::vector<int32_t>& magnitudeVector = correlationVector.magnitude;
374 
375             jsize numMagnitude = magnitudeVector.size();
376             jintArray magnitudeArray = env->NewIntArray(numMagnitude);
377             env->SetIntArrayRegion(magnitudeArray, 0, numMagnitude,
378                                    reinterpret_cast<const jint*>(magnitudeVector.data()));
379 
380             jobject correlationVectorBuilderObject =
381                     env->NewObject(class_correlationVectorBuilder,
382                                    method_correlationVectorBuilderCtor);
383             env->CallObjectMethod(correlationVectorBuilderObject,
384                                   method_correlationVectorBuilderSetMagnitude, magnitudeArray);
385             env->CallObjectMethod(correlationVectorBuilderObject,
386                                   method_correlationVectorBuilderSetFrequencyOffsetMetersPerSecond,
387                                   correlationVector.frequencyOffsetMps);
388             env->CallObjectMethod(correlationVectorBuilderObject,
389                                   method_correlationVectorBuilderSetSamplingStartMeters,
390                                   correlationVector.samplingStartM);
391             env->CallObjectMethod(correlationVectorBuilderObject,
392                                   method_correlationVectorBuilderSetSamplingWidthMeters,
393                                   correlationVector.samplingWidthM);
394             jobject correlationVectorObject =
395                     env->CallObjectMethod(correlationVectorBuilderObject,
396                                           method_correlationVectorBuilderBuild);
397 
398             env->CallBooleanMethod(correlationVectorList, method_arrayListAdd,
399                                    correlationVectorObject);
400 
401             env->DeleteLocalRef(magnitudeArray);
402             env->DeleteLocalRef(correlationVectorBuilderObject);
403             env->DeleteLocalRef(correlationVectorObject);
404         }
405         env->CallVoidMethod(object.get(), method_gnssMeasurementsSetCorrelationVectors,
406                             correlationVectorList);
407         env->DeleteLocalRef(correlationVectorList);
408     }
409 
410     jstring codeType = env->NewStringUTF(measurement.signalType.codeType.c_str());
411     SET(CodeType, codeType);
412     env->DeleteLocalRef(codeType);
413 }
414 
translateAllGnssMeasurements(JNIEnv * env,const std::vector<GnssMeasurement> & measurements)415 jobjectArray GnssMeasurementCallbackAidl::translateAllGnssMeasurements(
416         JNIEnv* env, const std::vector<GnssMeasurement>& measurements) {
417     if (measurements.size() == 0) {
418         return nullptr;
419     }
420 
421     jobjectArray gnssMeasurementArray =
422             env->NewObjectArray(measurements.size(), class_gnssMeasurement,
423                                 nullptr /* initialElement */);
424 
425     for (uint16_t i = 0; i < measurements.size(); ++i) {
426         JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
427         translateSingleGnssMeasurement(env, measurements[i], object);
428         jobject gnssMeasurement = object.get();
429         env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
430         env->DeleteLocalRef(gnssMeasurement);
431     }
432 
433     return gnssMeasurementArray;
434 }
435 
translateGnssClock(JNIEnv * env,const GnssData & data,JavaObject & object)436 void GnssMeasurementCallbackAidl::translateGnssClock(JNIEnv* env, const GnssData& data,
437                                                      JavaObject& object) {
438     setElapsedRealtimeFields<ElapsedRealtime, ElapsedRealtime>(data.elapsedRealtime, object);
439     setClockFields_V1_0<GnssClock, GnssClock>(data.clock, object);
440     setClockFields_V2_1<GnssClock, GnssClock>(data.clock, object);
441 }
442 
443 // Implementation of GnssMeasurementCallbackHidl class.
444 
gnssMeasurementCb_2_1(const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData & data)445 hardware::Return<void> GnssMeasurementCallbackHidl::gnssMeasurementCb_2_1(
446         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) {
447     translateAndSetGnssData(data);
448     return hardware::Void();
449 }
450 
gnssMeasurementCb_2_0(const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData & data)451 hardware::Return<void> GnssMeasurementCallbackHidl::gnssMeasurementCb_2_0(
452         const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) {
453     translateAndSetGnssData(data);
454     return hardware::Void();
455 }
456 
gnssMeasurementCb(const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData & data)457 hardware::Return<void> GnssMeasurementCallbackHidl::gnssMeasurementCb(
458         const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) {
459     translateAndSetGnssData(data);
460     return hardware::Void();
461 }
462 
GnssMeasurementCb(const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData & data)463 hardware::Return<void> GnssMeasurementCallbackHidl::GnssMeasurementCb(
464         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) {
465     translateAndSetGnssData(data);
466     return hardware::Void();
467 }
468 
469 template <>
getMeasurementCount(const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData & data)470 size_t GnssMeasurementCallbackHidl::getMeasurementCount<
471         hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>(
472         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) {
473     return data.measurementCount;
474 }
475 
476 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
477 template <>
translateSingleGnssMeasurement(const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement & measurement,JavaObject & object)478 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
479         hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>(
480         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement& measurement,
481         JavaObject& object) {
482     setMeasurementFields_V1_0<hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement,
483                               GnssMeasurementFlags>(measurement, object);
484 
485     SET(ConstellationType, static_cast<int32_t>(measurement.constellation));
486     SET(Cn0DbHz, measurement.cN0DbHz);
487     if (measurement.flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
488         SET(CarrierFrequencyHz, measurement.carrierFrequencyHz);
489     }
490 }
491 
492 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
493 template <>
translateSingleGnssMeasurement(const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement & measurement_V1_1,JavaObject & object)494 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
495         hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>(
496         const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V1_1,
497         JavaObject& object) {
498     translateSingleGnssMeasurement(measurement_V1_1.v1_0, object);
499 
500     // Half cycle state is reported in HIDL v1.1 or newer.
501     SET(AccumulatedDeltaRangeState,
502         (static_cast<int32_t>(measurement_V1_1.accumulatedDeltaRangeState) |
503          ADR_STATE_HALF_CYCLE_REPORTED));
504 }
505 
506 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
507 template <>
translateSingleGnssMeasurement(const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement & measurement_V2_0,JavaObject & object)508 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
509         hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>(
510         const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_0,
511         JavaObject& object) {
512     JNIEnv* env = getJniEnv();
513     translateSingleGnssMeasurement(measurement_V2_0.v1_1, object);
514 
515     jstring codeType = env->NewStringUTF(measurement_V2_0.codeType.c_str());
516     SET(CodeType, codeType);
517 
518     // Overwrite with v2_0.state since V2_0.v1_1.v1_0.state is deprecated.
519     SET(State, static_cast<int32_t>(measurement_V2_0.state));
520 
521     // Overwrite with v2_0.constellation since V2_0.v1_1.v1_0.constellation is deprecated.
522     SET(ConstellationType, static_cast<int32_t>(measurement_V2_0.constellation));
523 
524     if (codeType) {
525         env->DeleteLocalRef(codeType);
526     }
527 }
528 
529 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
530 template <>
translateSingleGnssMeasurement(const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement & measurement_V2_1,JavaObject & object)531 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
532         hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>(
533         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_1,
534         JavaObject& object) {
535     translateSingleGnssMeasurement(measurement_V2_1.v2_0, object);
536 
537     setMeasurementFields_V2_1<hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement,
538                               GnssMeasurementFlags>(measurement_V2_1, object);
539 }
540 
541 template <>
translateGnssClock(const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock & clock,JavaObject & object)542 void GnssMeasurementCallbackHidl::translateGnssClock(
543         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock,
544         JavaObject& object) {
545     setClockFields_V1_0<hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock,
546                         GnssClockFlags>(clock, object);
547 }
548 
549 template <>
translateGnssClock(const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock & clock,JavaObject & object)550 void GnssMeasurementCallbackHidl::translateGnssClock(
551         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock,
552         JavaObject& object) {
553     setClockFields_V2_1<hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock,
554                         GnssClockFlags>(clock, object);
555     translateGnssClock(clock.v1_0, object);
556 }
557 
558 template <>
translateGnssClock(const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData & data,JavaObject & object)559 void GnssMeasurementCallbackHidl::translateGnssClock(
560         const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object) {
561     setElapsedRealtimeFields<hardware::gnss::V2_0::ElapsedRealtime,
562                              hardware::gnss::V2_0::ElapsedRealtimeFlags>(data.elapsedRealtime,
563                                                                          object);
564     translateGnssClock(data.clock, object);
565 }
566 
567 template <>
translateGnssClock(const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData & data,JavaObject & object)568 void GnssMeasurementCallbackHidl::translateGnssClock(
569         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data, JavaObject& object) {
570     auto elapsedRealtime = data.elapsedRealtime;
571     uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
572     if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
573         SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
574     }
575     if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
576         SET(ElapsedRealtimeUncertaintyNanos,
577             static_cast<double>(elapsedRealtime.timeUncertaintyNs));
578     }
579     translateGnssClock(data.clock, object);
580 }
581 
582 } // namespace android::gnss
583