1 /*
2  * Copyright (C) 2008 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 "GnssLocationProvider"
18 
19 #define LOG_NDEBUG 0
20 
21 #include <android/hardware/gnss/1.0/IGnss.h>
22 #include <android/hardware/gnss/1.1/IGnss.h>
23 #include <android/hardware/gnss/2.0/IGnss.h>
24 
25 #include <android/hardware/gnss/1.0/IGnssMeasurement.h>
26 #include <android/hardware/gnss/1.1/IGnssMeasurement.h>
27 #include <android/hardware/gnss/2.0/IGnssMeasurement.h>
28 #include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
29 #include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
30 #include <nativehelper/JNIHelp.h>
31 #include "jni.h"
32 #include "hardware_legacy/power.h"
33 #include "utils/Log.h"
34 #include "utils/misc.h"
35 #include "android_runtime/AndroidRuntime.h"
36 #include "android_runtime/Log.h"
37 
38 #include <arpa/inet.h>
39 #include <cinttypes>
40 #include <iomanip>
41 #include <limits>
42 #include <linux/in.h>
43 #include <linux/in6.h>
44 #include <pthread.h>
45 #include <string.h>
46 #include <utils/SystemClock.h>
47 
48 static jclass class_gnssMeasurementsEvent;
49 static jclass class_gnssMeasurement;
50 static jclass class_location;
51 static jclass class_gnssNavigationMessage;
52 static jclass class_gnssClock;
53 static jclass class_gnssConfiguration_halInterfaceVersion;
54 
55 static jobject mCallbacksObj = nullptr;
56 
57 static jmethodID method_reportLocation;
58 static jmethodID method_reportStatus;
59 static jmethodID method_reportSvStatus;
60 static jmethodID method_reportAGpsStatus;
61 static jmethodID method_reportNmea;
62 static jmethodID method_setTopHalCapabilities;
63 static jmethodID method_setGnssYearOfHardware;
64 static jmethodID method_setGnssHardwareModelName;
65 static jmethodID method_psdsDownloadRequest;
66 static jmethodID method_reportNiNotification;
67 static jmethodID method_requestLocation;
68 static jmethodID method_requestRefLocation;
69 static jmethodID method_requestSetID;
70 static jmethodID method_requestUtcTime;
71 static jmethodID method_reportGeofenceTransition;
72 static jmethodID method_reportGeofenceStatus;
73 static jmethodID method_reportGeofenceAddStatus;
74 static jmethodID method_reportGeofenceRemoveStatus;
75 static jmethodID method_reportGeofencePauseStatus;
76 static jmethodID method_reportGeofenceResumeStatus;
77 static jmethodID method_reportMeasurementData;
78 static jmethodID method_reportNavigationMessages;
79 static jmethodID method_reportLocationBatch;
80 static jmethodID method_reportGnssServiceDied;
81 static jmethodID method_setSubHalMeasurementCorrectionsCapabilities;
82 static jmethodID method_correctionsGetLatitudeDegrees;
83 static jmethodID method_correctionsGetLongitudeDegrees;
84 static jmethodID method_correctionsGetAltitudeMeters;
85 static jmethodID method_correctionsGetHorPosUncMeters;
86 static jmethodID method_correctionsGetVerPosUncMeters;
87 static jmethodID method_correctionsGetToaGpsNanosecondsOfWeek;
88 static jmethodID method_correctionsGetSingleSatCorrectionList;
89 static jmethodID method_listSize;
90 static jmethodID method_correctionListGet;
91 static jmethodID method_correctionSatFlags;
92 static jmethodID method_correctionSatConstType;
93 static jmethodID method_correctionSatId;
94 static jmethodID method_correctionSatCarrierFreq;
95 static jmethodID method_correctionSatIsLosProb;
96 static jmethodID method_correctionSatEpl;
97 static jmethodID method_correctionSatEplUnc;
98 static jmethodID method_correctionSatRefPlane;
99 static jmethodID method_correctionPlaneLatDeg;
100 static jmethodID method_correctionPlaneLngDeg;
101 static jmethodID method_correctionPlaneAltDeg;
102 static jmethodID method_correctionPlaneAzimDeg;
103 static jmethodID method_reportNfwNotification;
104 static jmethodID method_isInEmergencySession;
105 static jmethodID method_gnssMeasurementsEventCtor;
106 static jmethodID method_locationCtor;
107 static jmethodID method_gnssNavigationMessageCtor;
108 static jmethodID method_gnssClockCtor;
109 static jmethodID method_gnssMeasurementCtor;
110 static jmethodID method_halInterfaceVersionCtor;
111 
112 /*
113  * Save a pointer to JavaVm to attach/detach threads executing
114  * callback methods that need to make JNI calls.
115  */
116 static JavaVM* sJvm;
117 
118 using android::OK;
119 using android::sp;
120 using android::wp;
121 using android::status_t;
122 using android::String16;
123 
124 using android::hardware::Return;
125 using android::hardware::Void;
126 using android::hardware::hidl_vec;
127 using android::hardware::hidl_string;
128 using android::hardware::hidl_death_recipient;
129 
130 using android::hardware::gnss::V1_0::GnssConstellationType;
131 using android::hardware::gnss::V1_0::GnssLocationFlags;
132 using android::hardware::gnss::V1_0::IAGnssRilCallback;
133 using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
134 using android::hardware::gnss::V1_0::IGnssGeofencing;
135 using android::hardware::gnss::V1_0::IGnssNavigationMessage;
136 using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
137 using android::hardware::gnss::V1_0::IGnssNi;
138 using android::hardware::gnss::V1_0::IGnssNiCallback;
139 using android::hardware::gnss::V1_0::IGnssXtra;
140 using android::hardware::gnss::V1_0::IGnssXtraCallback;
141 
142 using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
143 using android::hardware::gnss::V2_0::IGnssCallback;
144 
145 using android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
146 using android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
147 using android::hardware::gnss::measurement_corrections::V1_0::ReflectingPlane;
148 
149 using android::hidl::base::V1_0::IBase;
150 
151 using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
152 using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
153 using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
154 using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
155 using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
156 using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback;
157 using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
158 using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
159 using IGnssConfiguration_V2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
160 using IGnssDebug_V1_0 = android::hardware::gnss::V1_0::IGnssDebug;
161 using IGnssDebug_V2_0 = android::hardware::gnss::V2_0::IGnssDebug;
162 using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
163 using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
164 using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
165 using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
166 using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
167 using IGnssMeasurementCallback_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
168 using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil;
169 using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil;
170 using IAGnss_V1_0 = android::hardware::gnss::V1_0::IAGnss;
171 using IAGnss_V2_0 = android::hardware::gnss::V2_0::IAGnss;
172 using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback;
173 using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
174 using IGnssBatching_V1_0 = android::hardware::gnss::V1_0::IGnssBatching;
175 using IGnssBatching_V2_0 = android::hardware::gnss::V2_0::IGnssBatching;
176 using IGnssBatchingCallback_V1_0 = android::hardware::gnss::V1_0::IGnssBatchingCallback;
177 using IGnssBatchingCallback_V2_0 = android::hardware::gnss::V2_0::IGnssBatchingCallback;
178 
179 using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
180 using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
181 using android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
182 
183 using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
184 using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
185 
186 struct GnssDeathRecipient : virtual public hidl_death_recipient
187 {
188     // hidl_death_recipient interface
serviceDiedGnssDeathRecipient189     virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
190         ALOGE("IGNSS hidl service failed, trying to recover...");
191 
192         JNIEnv* env = android::AndroidRuntime::getJNIEnv();
193         env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
194     }
195 };
196 
197 // Must match the value from GnssMeasurement.java
198 static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
199 
200 sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
201 sp<IGnss_V1_0> gnssHal = nullptr;
202 sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
203 sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
204 sp<IGnssXtra> gnssXtraIface = nullptr;
205 sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
206 sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
207 sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
208 sp<IAGnss_V1_0> agnssIface = nullptr;
209 sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
210 sp<IGnssBatching_V1_0> gnssBatchingIface = nullptr;
211 sp<IGnssBatching_V2_0> gnssBatchingIface_V2_0 = nullptr;
212 sp<IGnssDebug_V1_0> gnssDebugIface = nullptr;
213 sp<IGnssDebug_V2_0> gnssDebugIface_V2_0 = nullptr;
214 sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
215 sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
216 sp<IGnssConfiguration_V2_0> gnssConfigurationIface_V2_0 = nullptr;
217 sp<IGnssNi> gnssNiIface = nullptr;
218 sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
219 sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
220 sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
221 sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
222 sp<IMeasurementCorrections> gnssCorrectionsIface = nullptr;
223 sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
224 
225 #define WAKE_LOCK_NAME  "GPS"
226 
227 namespace android {
228 
229 namespace {
230 
231 // Returns true if location has lat/long information.
hasLatLong(const GnssLocation_V1_0 & location)232 bool hasLatLong(const GnssLocation_V1_0& location) {
233     return (static_cast<uint32_t>(location.gnssLocationFlags) &
234             GnssLocationFlags::HAS_LAT_LONG) != 0;
235 }
236 
237 // Returns true if location has lat/long information.
hasLatLong(const GnssLocation_V2_0 & location)238 bool hasLatLong(const GnssLocation_V2_0& location) {
239     return hasLatLong(location.v1_0);
240 }
241 
242 }  // namespace
243 template<class T>
244 class JavaMethodHelper {
245  public:
246     // Helper function to call setter on a Java object.
247     static void callJavaMethod(
248            JNIEnv* env,
249            jclass clazz,
250            jobject object,
251            const char* method_name,
252            T value);
253 
254  private:
255     static const char* const signature_;
256 };
257 
258 template<class T>
callJavaMethod(JNIEnv * env,jclass clazz,jobject object,const char * method_name,T value)259 void JavaMethodHelper<T>::callJavaMethod(
260         JNIEnv* env,
261         jclass clazz,
262         jobject object,
263         const char* method_name,
264         T value) {
265     jmethodID method = env->GetMethodID(clazz, method_name, signature_);
266     env->CallVoidMethod(object, method, value);
267 }
268 
269 class JavaObject {
270  public:
271     JavaObject(JNIEnv* env, jclass clazz, jmethodID defaultCtor);
272     JavaObject(JNIEnv* env, jclass clazz, jmethodID stringCtor, const char * sz_arg_1);
273     JavaObject(JNIEnv* env, jclass clazz, jobject object);
274 
275     virtual ~JavaObject() = default;
276 
277     template<class T>
278     void callSetter(const char* method_name, T value);
279     template<class T>
280     void callSetter(const char* method_name, T* value, size_t size);
281     jobject get();
282 
283  private:
284     JNIEnv* env_;
285     jclass clazz_;
286     jobject object_;
287 };
288 
JavaObject(JNIEnv * env,jclass clazz,jmethodID defaultCtor)289 JavaObject::JavaObject(JNIEnv* env, jclass clazz, jmethodID defaultCtor) : env_(env),
290         clazz_(clazz) {
291     object_ = env_->NewObject(clazz_, defaultCtor);
292 }
293 
294 
JavaObject(JNIEnv * env,jclass clazz,jmethodID stringCtor,const char * sz_arg_1)295 JavaObject::JavaObject(JNIEnv* env, jclass clazz, jmethodID stringCtor, const char * sz_arg_1)
296         : env_(env), clazz_(clazz) {
297     object_ = env_->NewObject(clazz_, stringCtor, env->NewStringUTF(sz_arg_1));
298 }
299 
300 
JavaObject(JNIEnv * env,jclass clazz,jobject object)301 JavaObject::JavaObject(JNIEnv* env, jclass clazz, jobject object)
302     : env_(env), clazz_(clazz), object_(object) {
303 }
304 
305 template<class T>
callSetter(const char * method_name,T value)306 void JavaObject::callSetter(const char* method_name, T value) {
307     JavaMethodHelper<T>::callJavaMethod(
308             env_, clazz_, object_, method_name, value);
309 }
310 
311 template<>
callSetter(const char * method_name,uint8_t * value,size_t size)312 void JavaObject::callSetter(
313         const char* method_name, uint8_t* value, size_t size) {
314     jbyteArray array = env_->NewByteArray(size);
315     env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
316     jmethodID method = env_->GetMethodID(
317             clazz_,
318             method_name,
319             "([B)V");
320     env_->CallVoidMethod(object_, method, array);
321     env_->DeleteLocalRef(array);
322 }
323 
get()324 jobject JavaObject::get() {
325     return object_;
326 }
327 
328 // Define Java method signatures for all known types.
329 template<>
330 const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
331 template<>
332 const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
333 template<>
334 const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
335 template<>
336 const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
337 template<>
338 const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
339 template<>
340 const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
341 template<>
342 const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
343 template<>
344 const char *const JavaMethodHelper<uint64_t>::signature_ = "(J)V";
345 template<>
346 const char *const JavaMethodHelper<float>::signature_ = "(F)V";
347 template<>
348 const char *const JavaMethodHelper<double>::signature_ = "(D)V";
349 template<>
350 const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
351 template<>
352 const char *const JavaMethodHelper<jstring>::signature_ = "(Ljava/lang/String;)V";
353 
354 #define SET(setter, value) object.callSetter("set" # setter, (value))
355 
boolToJbool(bool value)356 static inline jboolean boolToJbool(bool value) {
357     return value ? JNI_TRUE : JNI_FALSE;
358 }
359 
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)360 static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
361     if (env->ExceptionCheck()) {
362         ALOGE("An exception was thrown by callback '%s'.", methodName);
363         LOGE_EX(env);
364         env->ExceptionClear();
365     }
366 }
367 
createHalInterfaceVersionJavaObject(JNIEnv * env,jint major,jint minor)368 static jobject createHalInterfaceVersionJavaObject(JNIEnv* env, jint major, jint minor) {
369     jobject version = env->NewObject(class_gnssConfiguration_halInterfaceVersion,
370             method_halInterfaceVersionCtor, major, minor);
371     return version;
372 }
373 
374 struct ScopedJniString {
ScopedJniStringandroid::ScopedJniString375     ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) {
376         mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr);
377     }
378 
~ScopedJniStringandroid::ScopedJniString379     ~ScopedJniString() {
380         if (mNativeString != nullptr) {
381             mEnv->ReleaseStringUTFChars(mJavaString, mNativeString);
382         }
383     }
384 
c_strandroid::ScopedJniString385     const char* c_str() const {
386         return mNativeString;
387     }
388 
operator hidl_stringandroid::ScopedJniString389     operator hidl_string() const {
390         return hidl_string(mNativeString);
391     }
392 
393 private:
394     ScopedJniString(const ScopedJniString&) = delete;
395     ScopedJniString& operator=(const ScopedJniString&) = delete;
396 
397     JNIEnv* mEnv;
398     jstring mJavaString;
399     const char* mNativeString;
400 };
401 
402 class ScopedJniThreadAttach {
403 public:
ScopedJniThreadAttach()404     ScopedJniThreadAttach() {
405         /*
406          * attachResult will also be JNI_OK if the thead was already attached to
407          * JNI before the call to AttachCurrentThread().
408          */
409         jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
410         LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
411                             attachResult);
412     }
413 
~ScopedJniThreadAttach()414     ~ScopedJniThreadAttach() {
415         jint detachResult = sJvm->DetachCurrentThread();
416         /*
417          * Return if the thread was already detached. Log error for any other
418          * failure.
419          */
420         if (detachResult == JNI_EDETACHED) {
421             return;
422         }
423 
424         LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
425                             detachResult);
426     }
427 
getEnv()428     JNIEnv* getEnv() {
429         /*
430          * Checking validity of mEnv in case the thread was detached elsewhere.
431          */
432         LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
433         return mEnv;
434     }
435 
436 private:
437     JNIEnv* mEnv = nullptr;
438 };
439 
440 thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
441 
getJniEnv()442 static JNIEnv* getJniEnv() {
443     JNIEnv* env = AndroidRuntime::getJNIEnv();
444 
445     /*
446      * If env is nullptr, the thread is not already attached to
447      * JNI. It is attached below and the destructor for ScopedJniThreadAttach
448      * will detach it on thread exit.
449      */
450     if (env == nullptr) {
451         tJniThreadAttacher.reset(new ScopedJniThreadAttach());
452         env = tJniThreadAttacher->getEnv();
453     }
454 
455     return env;
456 }
457 
translateGnssLocation(JNIEnv * env,const GnssLocation_V1_0 & location)458 static jobject translateGnssLocation(JNIEnv* env,
459                                      const GnssLocation_V1_0& location) {
460     JavaObject object(env, class_location, method_locationCtor, "gps");
461 
462     uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
463     if (flags & GnssLocationFlags::HAS_LAT_LONG) {
464         SET(Latitude, location.latitudeDegrees);
465         SET(Longitude, location.longitudeDegrees);
466     }
467     if (flags & GnssLocationFlags::HAS_ALTITUDE) {
468         SET(Altitude, location.altitudeMeters);
469     }
470     if (flags & GnssLocationFlags::HAS_SPEED) {
471         SET(Speed, location.speedMetersPerSec);
472     }
473     if (flags & GnssLocationFlags::HAS_BEARING) {
474         SET(Bearing, location.bearingDegrees);
475     }
476     if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
477         SET(Accuracy, location.horizontalAccuracyMeters);
478     }
479     if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
480         SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
481     }
482     if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
483         SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
484     }
485     if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
486         SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
487     }
488     SET(Time, location.timestamp);
489     SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
490 
491     return object.get();
492 }
493 
translateGnssLocation(JNIEnv * env,const GnssLocation_V2_0 & location)494 static jobject translateGnssLocation(JNIEnv* env,
495                                      const GnssLocation_V2_0& location) {
496     JavaObject object(env, class_location, translateGnssLocation(env, location.v1_0));
497 
498     const uint16_t flags = static_cast<uint16_t>(location.elapsedRealtime.flags);
499 
500     // Overwrite ElapsedRealtimeNanos when available from HAL.
501     if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
502         SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
503     }
504 
505     if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
506         SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
507     }
508 
509     return object.get();
510 }
511 
createGnssLocation_V1_0(jint gnssLocationFlags,jdouble latitudeDegrees,jdouble longitudeDegrees,jdouble altitudeMeters,jfloat speedMetersPerSec,jfloat bearingDegrees,jfloat horizontalAccuracyMeters,jfloat verticalAccuracyMeters,jfloat speedAccuracyMetersPerSecond,jfloat bearingAccuracyDegrees,jlong timestamp)512 static GnssLocation_V1_0 createGnssLocation_V1_0(
513         jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
514         jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
515         jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
516         jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
517         jlong timestamp) {
518     GnssLocation_V1_0 location;
519     location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
520     location.latitudeDegrees = static_cast<double>(latitudeDegrees);
521     location.longitudeDegrees = static_cast<double>(longitudeDegrees);
522     location.altitudeMeters = static_cast<double>(altitudeMeters);
523     location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
524     location.bearingDegrees = static_cast<float>(bearingDegrees);
525     location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
526     location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
527     location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
528     location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
529     location.timestamp = static_cast<uint64_t>(timestamp);
530 
531     return location;
532 }
533 
createGnssLocation_V2_0(jint gnssLocationFlags,jdouble latitudeDegrees,jdouble longitudeDegrees,jdouble altitudeMeters,jfloat speedMetersPerSec,jfloat bearingDegrees,jfloat horizontalAccuracyMeters,jfloat verticalAccuracyMeters,jfloat speedAccuracyMetersPerSecond,jfloat bearingAccuracyDegrees,jlong timestamp,jint elapsedRealtimeFlags,jlong elapsedRealtimeNanos,jdouble elapsedRealtimeUncertaintyNanos)534 static GnssLocation_V2_0 createGnssLocation_V2_0(
535         jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
536         jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
537         jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
538         jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
539         jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
540         jdouble elapsedRealtimeUncertaintyNanos) {
541     GnssLocation_V2_0 location;
542     location.v1_0 = createGnssLocation_V1_0(
543             gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
544             speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
545             verticalAccuracyMeters, speedAccuracyMetersPerSecond,
546             bearingAccuracyDegrees, timestamp);
547 
548     location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
549     location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
550     location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
551 
552     return location;
553 }
554 
555 /*
556  * GnssCallback class implements the callback methods for IGnss interface.
557  */
558 struct GnssCallback : public IGnssCallback {
559     Return<void> gnssLocationCb(const GnssLocation_V1_0& location) override;
560     Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
gnssSvStatusCbandroid::GnssCallback561     Return<void> gnssSvStatusCb(const IGnssCallback_V1_0::GnssSvStatus& svStatus) override {
562         return gnssSvStatusCbImpl(svStatus);
563     }
564     Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
565     Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
566     Return<void> gnssAcquireWakelockCb() override;
567     Return<void> gnssReleaseWakelockCb() override;
568     Return<void> gnssRequestTimeCb() override;
569     Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
570 
571     Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
572 
573     // New in 1.1
574     Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
575 
576     // New in 2.0
577     Return<void> gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool isUserEmergency)
578             override;
579     Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
580     Return<void> gnssLocationCb_2_0(const GnssLocation_V2_0& location) override;
gnssSvStatusCb_2_0android::GnssCallback581     Return<void> gnssSvStatusCb_2_0(const hidl_vec<IGnssCallback::GnssSvInfo>& svInfoList) override {
582         return gnssSvStatusCbImpl(svInfoList);
583     }
584 
585     Return<void> gnssSetCapabilitesCbImpl(uint32_t capabilities, bool hasSubHalCapabilityFlags);
586 
587     // TODO: Reconsider allocation cost vs threadsafety on these statics
588     static const char* sNmeaString;
589     static size_t sNmeaStringLength;
590 private:
591     template<class T>
592     Return<void> gnssLocationCbImpl(const T& location);
593 
594     template<class T>
595     Return<void> gnssSvStatusCbImpl(const T& svStatus);
596 
getGnssSvInfoListSizeandroid::GnssCallback597     uint32_t getGnssSvInfoListSize(const IGnssCallback_V1_0::GnssSvStatus& svStatus) {
598         return svStatus.numSvs;
599     }
600 
getGnssSvInfoListSizeandroid::GnssCallback601     uint32_t getGnssSvInfoListSize(const hidl_vec<IGnssCallback::GnssSvInfo>& svInfoList) {
602         return svInfoList.size();
603     }
604 
getGnssSvInfoOfIndexandroid::GnssCallback605     const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
606             const IGnssCallback_V1_0::GnssSvStatus& svStatus, size_t i) {
607         return svStatus.gnssSvList.data()[i];
608     }
609 
getGnssSvInfoOfIndexandroid::GnssCallback610     const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
611             const hidl_vec<IGnssCallback::GnssSvInfo>& svInfoList, size_t i) {
612         return svInfoList[i].v1_0;
613     }
614 
getConstellationTypeandroid::GnssCallback615     uint32_t getConstellationType(const IGnssCallback_V1_0::GnssSvStatus& svStatus, size_t i) {
616         return static_cast<uint32_t>(svStatus.gnssSvList.data()[i].constellation);
617     }
618 
getConstellationTypeandroid::GnssCallback619     uint32_t getConstellationType(const hidl_vec<IGnssCallback::GnssSvInfo>& svInfoList, size_t i) {
620         return static_cast<uint32_t>(svInfoList[i].constellation);
621     }
622 };
623 
gnssNameCb(const android::hardware::hidl_string & name)624 Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
625     ALOGD("%s: name=%s\n", __func__, name.c_str());
626 
627     JNIEnv* env = getJniEnv();
628     jstring jstringName = env->NewStringUTF(name.c_str());
629     env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
630     checkAndClearExceptionFromCallback(env, __FUNCTION__);
631 
632     return Void();
633 }
634 
635 const char* GnssCallback::sNmeaString = nullptr;
636 size_t GnssCallback::sNmeaStringLength = 0;
637 
638 template<class T>
gnssLocationCbImpl(const T & location)639 Return<void> GnssCallback::gnssLocationCbImpl(const T& location) {
640     JNIEnv* env = getJniEnv();
641 
642     jobject jLocation = translateGnssLocation(env, location);
643 
644     env->CallVoidMethod(mCallbacksObj,
645                         method_reportLocation,
646                         boolToJbool(hasLatLong(location)),
647                         jLocation);
648     checkAndClearExceptionFromCallback(env, __FUNCTION__);
649     env->DeleteLocalRef(jLocation);
650     return Void();
651 }
652 
gnssLocationCb(const GnssLocation_V1_0 & location)653 Return<void> GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) {
654     return gnssLocationCbImpl<GnssLocation_V1_0>(location);
655 }
656 
657 Return<void>
gnssLocationCb_2_0(const GnssLocation_V2_0 & location)658 GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
659     return gnssLocationCbImpl<GnssLocation_V2_0>(location);
660 }
661 
gnssStatusCb(const IGnssCallback::GnssStatusValue status)662 Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
663     JNIEnv* env = getJniEnv();
664     env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
665     checkAndClearExceptionFromCallback(env, __FUNCTION__);
666     return Void();
667 }
668 
669 template<class T>
gnssSvStatusCbImpl(const T & svStatus)670 Return<void> GnssCallback::gnssSvStatusCbImpl(const T& svStatus) {
671     JNIEnv* env = getJniEnv();
672 
673     uint32_t listSize = getGnssSvInfoListSize(svStatus);
674     if (listSize > static_cast<uint32_t>(
675             android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
676         ALOGD("Too many satellites %u. Clamps to %u.", listSize,
677               static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
678         listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
679     }
680 
681     jintArray svidWithFlagArray = env->NewIntArray(listSize);
682     jfloatArray cn0Array = env->NewFloatArray(listSize);
683     jfloatArray elevArray = env->NewFloatArray(listSize);
684     jfloatArray azimArray = env->NewFloatArray(listSize);
685     jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
686 
687     jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
688     jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
689     jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
690     jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
691     jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
692 
693     /*
694      * Read GNSS SV info.
695      */
696     for (size_t i = 0; i < listSize; ++i) {
697         enum ShiftWidth: uint8_t {
698             SVID_SHIFT_WIDTH = 8,
699             CONSTELLATION_TYPE_SHIFT_WIDTH = 4
700         };
701 
702         const IGnssCallback_V1_0::GnssSvInfo& info = getGnssSvInfoOfIndex(svStatus, i);
703         svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
704             (getConstellationType(svStatus, i) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
705             static_cast<uint32_t>(info.svFlag);
706         cn0s[i] = info.cN0Dbhz;
707         elev[i] = info.elevationDegrees;
708         azim[i] = info.azimuthDegrees;
709         carrierFreq[i] = info.carrierFrequencyHz;
710     }
711 
712     env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
713     env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
714     env->ReleaseFloatArrayElements(elevArray, elev, 0);
715     env->ReleaseFloatArrayElements(azimArray, azim, 0);
716     env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
717 
718     env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
719             static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
720             carrierFreqArray);
721 
722     checkAndClearExceptionFromCallback(env, __FUNCTION__);
723     return Void();
724 }
725 
gnssNmeaCb(int64_t timestamp,const::android::hardware::hidl_string & nmea)726 Return<void> GnssCallback::gnssNmeaCb(
727     int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
728     JNIEnv* env = getJniEnv();
729     /*
730      * The Java code will call back to read these values.
731      * We do this to avoid creating unnecessary String objects.
732      */
733     sNmeaString = nmea.c_str();
734     sNmeaStringLength = nmea.size();
735 
736     env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
737     checkAndClearExceptionFromCallback(env, __FUNCTION__);
738     return Void();
739 }
740 
gnssSetCapabilitesCb(uint32_t capabilities)741 Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
742     ALOGD("%s: %du\n", __func__, capabilities);
743 
744     JNIEnv* env = getJniEnv();
745     env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities);
746     checkAndClearExceptionFromCallback(env, __FUNCTION__);
747     return Void();
748 }
749 
gnssSetCapabilitiesCb_2_0(uint32_t capabilities)750 Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
751     return GnssCallback::gnssSetCapabilitesCb(capabilities);
752 }
753 
gnssAcquireWakelockCb()754 Return<void> GnssCallback::gnssAcquireWakelockCb() {
755     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
756     return Void();
757 }
758 
gnssReleaseWakelockCb()759 Return<void> GnssCallback::gnssReleaseWakelockCb() {
760     release_wake_lock(WAKE_LOCK_NAME);
761     return Void();
762 }
763 
gnssRequestTimeCb()764 Return<void> GnssCallback::gnssRequestTimeCb() {
765     JNIEnv* env = getJniEnv();
766     env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
767     checkAndClearExceptionFromCallback(env, __FUNCTION__);
768     return Void();
769 }
770 
gnssRequestLocationCb(const bool independentFromGnss)771 Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
772     return GnssCallback::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */
773             false);
774 }
775 
gnssRequestLocationCb_2_0(const bool independentFromGnss,const bool isUserEmergency)776 Return<void> GnssCallback::gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool
777         isUserEmergency) {
778     JNIEnv* env = getJniEnv();
779     env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
780             boolToJbool(isUserEmergency));
781     checkAndClearExceptionFromCallback(env, __FUNCTION__);
782     return Void();
783 }
784 
gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo & info)785 Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
786     ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
787 
788     JNIEnv* env = getJniEnv();
789     env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
790                         info.yearOfHw);
791     checkAndClearExceptionFromCallback(env, __FUNCTION__);
792     return Void();
793 }
794 
795 class GnssXtraCallback : public IGnssXtraCallback {
796     Return<void> downloadRequestCb() override;
797 };
798 
799 /*
800  * GnssXtraCallback class implements the callback methods for the IGnssXtra
801  * interface.
802  */
downloadRequestCb()803 Return<void> GnssXtraCallback::downloadRequestCb() {
804     JNIEnv* env = getJniEnv();
805     env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest);
806     checkAndClearExceptionFromCallback(env, __FUNCTION__);
807     return Void();
808 }
809 
810 /*
811  * GnssGeofenceCallback class implements the callback methods for the
812  * IGnssGeofence interface.
813  */
814 struct GnssGeofenceCallback : public IGnssGeofenceCallback {
815     // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
816     Return<void> gnssGeofenceTransitionCb(
817             int32_t geofenceId,
818             const GnssLocation_V1_0& location,
819             GeofenceTransition transition,
820             hardware::gnss::V1_0::GnssUtcTime timestamp) override;
821     Return<void>
822     gnssGeofenceStatusCb(
823             GeofenceAvailability status,
824             const GnssLocation_V1_0& location) override;
825     Return<void> gnssGeofenceAddCb(int32_t geofenceId,
826                                    GeofenceStatus status) override;
827     Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
828                                       GeofenceStatus status) override;
829     Return<void> gnssGeofencePauseCb(int32_t geofenceId,
830                                      GeofenceStatus status) override;
831     Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
832                                       GeofenceStatus status) override;
833 };
834 
gnssGeofenceTransitionCb(int32_t geofenceId,const GnssLocation_V1_0 & location,GeofenceTransition transition,hardware::gnss::V1_0::GnssUtcTime timestamp)835 Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
836         int32_t geofenceId, const GnssLocation_V1_0& location,
837         GeofenceTransition transition,
838         hardware::gnss::V1_0::GnssUtcTime timestamp) {
839     JNIEnv* env = getJniEnv();
840 
841     jobject jLocation = translateGnssLocation(env, location);
842 
843     env->CallVoidMethod(mCallbacksObj,
844                         method_reportGeofenceTransition,
845                         geofenceId,
846                         jLocation,
847                         transition,
848                         timestamp);
849 
850     checkAndClearExceptionFromCallback(env, __FUNCTION__);
851     env->DeleteLocalRef(jLocation);
852     return Void();
853 }
854 
855 Return<void>
gnssGeofenceStatusCb(GeofenceAvailability status,const GnssLocation_V1_0 & location)856 GnssGeofenceCallback::gnssGeofenceStatusCb(GeofenceAvailability status,
857                                            const GnssLocation_V1_0& location) {
858     JNIEnv* env = getJniEnv();
859 
860     jobject jLocation = translateGnssLocation(env, location);
861 
862     env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
863                         jLocation);
864     checkAndClearExceptionFromCallback(env, __FUNCTION__);
865     env->DeleteLocalRef(jLocation);
866     return Void();
867 }
868 
gnssGeofenceAddCb(int32_t geofenceId,GeofenceStatus status)869 Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
870                                                     GeofenceStatus status) {
871     JNIEnv* env = getJniEnv();
872     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
873         ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
874     }
875 
876     env->CallVoidMethod(mCallbacksObj,
877                         method_reportGeofenceAddStatus,
878                         geofenceId,
879                         status);
880     checkAndClearExceptionFromCallback(env, __FUNCTION__);
881     return Void();
882 }
883 
gnssGeofenceRemoveCb(int32_t geofenceId,GeofenceStatus status)884 Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
885                                                        GeofenceStatus status) {
886     JNIEnv* env = getJniEnv();
887     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
888         ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
889     }
890 
891     env->CallVoidMethod(mCallbacksObj,
892                         method_reportGeofenceRemoveStatus,
893                         geofenceId, status);
894     checkAndClearExceptionFromCallback(env, __FUNCTION__);
895     return Void();
896 }
897 
gnssGeofencePauseCb(int32_t geofenceId,GeofenceStatus status)898 Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
899                                                       GeofenceStatus status) {
900     JNIEnv* env = getJniEnv();
901     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
902         ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
903     }
904 
905     env->CallVoidMethod(mCallbacksObj,
906                         method_reportGeofencePauseStatus,
907                         geofenceId, status);
908     checkAndClearExceptionFromCallback(env, __FUNCTION__);
909     return Void();
910 }
911 
gnssGeofenceResumeCb(int32_t geofenceId,GeofenceStatus status)912 Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
913                                                        GeofenceStatus status) {
914     JNIEnv* env = getJniEnv();
915     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
916         ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
917     }
918 
919     env->CallVoidMethod(mCallbacksObj,
920                         method_reportGeofenceResumeStatus,
921                         geofenceId, status);
922     checkAndClearExceptionFromCallback(env, __FUNCTION__);
923     return Void();
924 }
925 
926 /*
927  * GnssNavigationMessageCallback interface implements the callback methods
928  * required by the IGnssNavigationMessage interface.
929  */
930 struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
931   /*
932    * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
933    * follow.
934    */
935   Return<void> gnssNavigationMessageCb(
936           const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
937 };
938 
gnssNavigationMessageCb(const IGnssNavigationMessageCallback::GnssNavigationMessage & message)939 Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
940         const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
941     JNIEnv* env = getJniEnv();
942 
943     size_t dataLength = message.data.size();
944 
945     std::vector<uint8_t> navigationData = message.data;
946     uint8_t* data = &(navigationData[0]);
947     if (dataLength == 0 || data == nullptr) {
948       ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
949             dataLength);
950       return Void();
951     }
952 
953     JavaObject object(env, class_gnssNavigationMessage, method_gnssNavigationMessageCtor);
954     SET(Type, static_cast<int32_t>(message.type));
955     SET(Svid, static_cast<int32_t>(message.svid));
956     SET(MessageId, static_cast<int32_t>(message.messageId));
957     SET(SubmessageId, static_cast<int32_t>(message.submessageId));
958     object.callSetter("setData", data, dataLength);
959     SET(Status, static_cast<int32_t>(message.status));
960 
961     jobject navigationMessage = object.get();
962     env->CallVoidMethod(mCallbacksObj,
963                         method_reportNavigationMessages,
964                         navigationMessage);
965     checkAndClearExceptionFromCallback(env, __FUNCTION__);
966     env->DeleteLocalRef(navigationMessage);
967     return Void();
968 }
969 
970 /*
971  * GnssMeasurementCallback implements the callback methods required for the
972  * GnssMeasurement interface.
973  */
974 struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_0 {
975     Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_V2_0::GnssData& data)
976             override;
977     Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
978     Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
979  private:
980     template<class T>
981     void translateSingleGnssMeasurement(const T* measurement, JavaObject& object);
982 
983     template<class T>
984     jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
985 
986     template<class T>
987     void translateAndSetGnssData(const T& data);
988 
989     template<class T>
990     size_t getMeasurementCount(const T& data);
991 
992     template<class T>
993     void translateGnssClock(JavaObject& object, const T& data);
994 
995     void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
996 };
997 
gnssMeasurementCb_2_0(const IGnssMeasurementCallback_V2_0::GnssData & data)998 Return<void> GnssMeasurementCallback::gnssMeasurementCb_2_0(
999         const IGnssMeasurementCallback_V2_0::GnssData& data) {
1000     translateAndSetGnssData(data);
1001     return Void();
1002 }
1003 
gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData & data)1004 Return<void> GnssMeasurementCallback::gnssMeasurementCb(
1005         const IGnssMeasurementCallback_V1_1::GnssData& data) {
1006     translateAndSetGnssData(data);
1007     return Void();
1008 }
1009 
GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData & data)1010 Return<void> GnssMeasurementCallback::GnssMeasurementCb(
1011         const IGnssMeasurementCallback_V1_0::GnssData& data) {
1012     translateAndSetGnssData(data);
1013     return Void();
1014 }
1015 
1016 template<class T>
translateAndSetGnssData(const T & data)1017 void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
1018     JNIEnv* env = getJniEnv();
1019 
1020     JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
1021     translateGnssClock(gnssClockJavaObject, data);
1022     jobject clock = gnssClockJavaObject.get();
1023 
1024     size_t count = getMeasurementCount(data);
1025     jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
1026     setMeasurementData(env, clock, measurementArray);
1027 
1028     env->DeleteLocalRef(clock);
1029     env->DeleteLocalRef(measurementArray);
1030 }
1031 
1032 template<>
getMeasurementCount(const IGnssMeasurementCallback_V1_0::GnssData & data)1033 size_t GnssMeasurementCallback::getMeasurementCount<IGnssMeasurementCallback_V1_0::GnssData>
1034         (const IGnssMeasurementCallback_V1_0::GnssData& data) {
1035     return data.measurementCount;
1036 }
1037 
1038 template<class T>
getMeasurementCount(const T & data)1039 size_t GnssMeasurementCallback::getMeasurementCount(const T& data) {
1040     return data.measurements.size();
1041 }
1042 
1043 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1044 template<>
translateSingleGnssMeasurement(const IGnssMeasurementCallback_V1_0::GnssMeasurement * measurement,JavaObject & object)1045 void GnssMeasurementCallback::translateSingleGnssMeasurement
1046         <IGnssMeasurementCallback_V1_0::GnssMeasurement>(
1047         const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
1048         JavaObject& object) {
1049     uint32_t flags = static_cast<uint32_t>(measurement->flags);
1050 
1051     SET(Svid, static_cast<int32_t>(measurement->svid));
1052     SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
1053     SET(TimeOffsetNanos, measurement->timeOffsetNs);
1054     SET(State, static_cast<int32_t>(measurement->state));
1055     SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
1056     SET(ReceivedSvTimeUncertaintyNanos,
1057         measurement->receivedSvTimeUncertaintyInNs);
1058     SET(Cn0DbHz, measurement->cN0DbHz);
1059     SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
1060     SET(PseudorangeRateUncertaintyMetersPerSecond,
1061         measurement->pseudorangeRateUncertaintyMps);
1062     SET(AccumulatedDeltaRangeState,
1063         (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
1064         ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
1065     SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
1066     SET(AccumulatedDeltaRangeUncertaintyMeters,
1067         measurement->accumulatedDeltaRangeUncertaintyM);
1068 
1069     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
1070         SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
1071     }
1072 
1073     // Intentionally not copying deprecated fields of carrierCycles,
1074     // carrierPhase, carrierPhaseUncertainty
1075 
1076     SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
1077 
1078     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
1079         SET(SnrInDb, measurement->snrDb);
1080     }
1081 
1082     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
1083         SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
1084     }
1085 }
1086 
1087 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1088 template<>
translateSingleGnssMeasurement(const IGnssMeasurementCallback_V1_1::GnssMeasurement * measurement_V1_1,JavaObject & object)1089 void GnssMeasurementCallback::translateSingleGnssMeasurement
1090         <IGnssMeasurementCallback_V1_1::GnssMeasurement>(
1091         const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurement_V1_1,
1092         JavaObject& object) {
1093     translateSingleGnssMeasurement(&(measurement_V1_1->v1_0), object);
1094 
1095     // Set the V1_1 flag, and mark that new field has valid information for Java Layer
1096     SET(AccumulatedDeltaRangeState,
1097             (static_cast<int32_t>(measurement_V1_1->accumulatedDeltaRangeState) |
1098             ADR_STATE_HALF_CYCLE_REPORTED));
1099 }
1100 
1101 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1102 template<>
translateSingleGnssMeasurement(const IGnssMeasurementCallback_V2_0::GnssMeasurement * measurement_V2_0,JavaObject & object)1103 void GnssMeasurementCallback::translateSingleGnssMeasurement
1104         <IGnssMeasurementCallback_V2_0::GnssMeasurement>(
1105         const IGnssMeasurementCallback_V2_0::GnssMeasurement* measurement_V2_0,
1106         JavaObject& object) {
1107     JNIEnv* env = getJniEnv();
1108     translateSingleGnssMeasurement(&(measurement_V2_0->v1_1), object);
1109 
1110     SET(CodeType, env->NewStringUTF(measurement_V2_0->codeType.c_str()));
1111 
1112     // Overwrite with v2_0.state since v2_0->v1_1->v1_0.state is deprecated.
1113     SET(State, static_cast<int32_t>(measurement_V2_0->state));
1114 
1115     // Overwrite with v2_0.constellation since v2_0->v1_1->v1_0.constellation is deprecated.
1116     SET(ConstellationType, static_cast<int32_t>(measurement_V2_0->constellation));
1117 }
1118 
1119 template<class T>
translateGnssClock(JavaObject & object,const T & data)1120 void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) {
1121     translateGnssClock(object, data.clock);
1122 }
1123 
1124 template<>
translateGnssClock(JavaObject & object,const IGnssMeasurementCallback_V1_0::GnssClock & clock)1125 void GnssMeasurementCallback::translateGnssClock(
1126        JavaObject& object, const IGnssMeasurementCallback_V1_0::GnssClock& clock) {
1127     uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags);
1128     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
1129         SET(LeapSecond, static_cast<int32_t>(clock.leapSecond));
1130     }
1131 
1132     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
1133         SET(TimeUncertaintyNanos, clock.timeUncertaintyNs);
1134     }
1135 
1136     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
1137         SET(FullBiasNanos, clock.fullBiasNs);
1138     }
1139 
1140     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
1141         SET(BiasNanos, clock.biasNs);
1142     }
1143 
1144     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
1145         SET(BiasUncertaintyNanos, clock.biasUncertaintyNs);
1146     }
1147 
1148     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
1149         SET(DriftNanosPerSecond, clock.driftNsps);
1150     }
1151 
1152     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
1153         SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps);
1154     }
1155 
1156     SET(TimeNanos, clock.timeNs);
1157     SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount);
1158 }
1159 
1160 template<>
translateGnssClock(JavaObject & object,const IGnssMeasurementCallback_V2_0::GnssData & data)1161 void GnssMeasurementCallback::translateGnssClock(
1162        JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) {
1163     auto elapsedRealtime = data.elapsedRealtime;
1164     uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
1165     if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
1166         SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
1167     }
1168     if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
1169         SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(elapsedRealtime.timeUncertaintyNs));
1170     }
1171     translateGnssClock(object, data.clock);
1172 }
1173 
1174 template<class T>
translateAllGnssMeasurements(JNIEnv * env,const T * measurements,size_t count)1175 jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,
1176         const T* measurements,
1177         size_t count) {
1178     if (count == 0) {
1179         return nullptr;
1180     }
1181 
1182     jobjectArray gnssMeasurementArray = env->NewObjectArray(
1183             count,
1184             class_gnssMeasurement,
1185             nullptr /* initialElement */);
1186 
1187     for (uint16_t i = 0; i < count; ++i) {
1188         JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
1189         translateSingleGnssMeasurement(&(measurements[i]), object);
1190         env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
1191     }
1192 
1193     return gnssMeasurementArray;
1194 }
1195 
setMeasurementData(JNIEnv * env,jobject clock,jobjectArray measurementArray)1196 void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
1197                              jobjectArray measurementArray) {
1198     jobject gnssMeasurementsEvent = env->NewObject(class_gnssMeasurementsEvent,
1199                                                    method_gnssMeasurementsEventCtor,
1200                                                    clock,
1201                                                    measurementArray);
1202 
1203     env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
1204                       gnssMeasurementsEvent);
1205     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1206     env->DeleteLocalRef(gnssMeasurementsEvent);
1207 }
1208 
1209 /*
1210  * MeasurementCorrectionsCallback implements callback methods of interface
1211  * IMeasurementCorrectionsCallback.hal.
1212  */
1213 struct MeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
1214     Return<void> setCapabilitiesCb(uint32_t capabilities) override;
1215 };
1216 
setCapabilitiesCb(uint32_t capabilities)1217 Return<void> MeasurementCorrectionsCallback::setCapabilitiesCb(uint32_t capabilities) {
1218     ALOGD("%s: %du\n", __func__, capabilities);
1219     JNIEnv* env = getJniEnv();
1220     env->CallVoidMethod(mCallbacksObj, method_setSubHalMeasurementCorrectionsCapabilities,
1221                         capabilities);
1222     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1223     return Void();
1224 }
1225 
1226 /*
1227  * GnssNiCallback implements callback methods required by the IGnssNi interface.
1228  */
1229 struct GnssNiCallback : public IGnssNiCallback {
1230     Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
1231             override;
1232 };
1233 
niNotifyCb(const IGnssNiCallback::GnssNiNotification & notification)1234 Return<void> GnssNiCallback::niNotifyCb(
1235         const IGnssNiCallback::GnssNiNotification& notification) {
1236     JNIEnv* env = getJniEnv();
1237     jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1238     jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
1239 
1240     if (requestorId && text) {
1241         env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
1242                             notification.notificationId, notification.niType,
1243                             notification.notifyFlags, notification.timeoutSec,
1244                             notification.defaultResponse, requestorId, text,
1245                             notification.requestorIdEncoding,
1246                             notification.notificationIdEncoding);
1247     } else {
1248         ALOGE("%s: OOM Error\n", __func__);
1249     }
1250 
1251     if (requestorId) {
1252         env->DeleteLocalRef(requestorId);
1253     }
1254 
1255     if (text) {
1256         env->DeleteLocalRef(text);
1257     }
1258     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1259     return Void();
1260 }
1261 
1262 /*
1263  * GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal.
1264  */
1265 struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback {
1266     Return<void> nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification)
1267             override;
1268     Return<bool> isInEmergencySession() override;
1269 };
1270 
nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification & notification)1271 Return<void> GnssVisibilityControlCallback::nfwNotifyCb(
1272         const IGnssVisibilityControlCallback::NfwNotification& notification) {
1273     JNIEnv* env = getJniEnv();
1274     jstring proxyAppPackageName = env->NewStringUTF(notification.proxyAppPackageName.c_str());
1275     jstring otherProtocolStackName = env->NewStringUTF(notification.otherProtocolStackName.c_str());
1276     jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1277 
1278     if (proxyAppPackageName && otherProtocolStackName && requestorId) {
1279         env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
1280                             notification.protocolStack, otherProtocolStackName,
1281                             notification.requestor, requestorId, notification.responseType,
1282                             notification.inEmergencyMode, notification.isCachedLocation);
1283     } else {
1284         ALOGE("%s: OOM Error\n", __func__);
1285     }
1286 
1287     if (requestorId) {
1288         env->DeleteLocalRef(requestorId);
1289     }
1290 
1291     if (otherProtocolStackName) {
1292         env->DeleteLocalRef(otherProtocolStackName);
1293     }
1294 
1295     if (proxyAppPackageName) {
1296         env->DeleteLocalRef(proxyAppPackageName);
1297     }
1298 
1299     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1300     return Void();
1301 }
1302 
isInEmergencySession()1303 Return<bool> GnssVisibilityControlCallback::isInEmergencySession() {
1304     JNIEnv* env = getJniEnv();
1305     auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession);
1306     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1307     return result;
1308 }
1309 
1310 /*
1311  * AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface.
1312  */
1313 struct AGnssCallback_V1_0 : public IAGnssCallback_V1_0 {
1314     // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
1315     Return<void> agnssStatusIpV6Cb(
1316       const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) override;
1317 
1318     Return<void> agnssStatusIpV4Cb(
1319       const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) override;
1320  private:
1321     jbyteArray convertToIpV4(uint32_t ip);
1322 };
1323 
agnssStatusIpV6Cb(const IAGnssCallback_V1_0::AGnssStatusIpV6 & agps_status)1324 Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb(
1325         const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) {
1326     JNIEnv* env = getJniEnv();
1327     jbyteArray byteArray = nullptr;
1328 
1329     byteArray = env->NewByteArray(16);
1330     if (byteArray != nullptr) {
1331         env->SetByteArrayRegion(byteArray, 0, 16,
1332                                 (const jbyte*)(agps_status.ipV6Addr.data()));
1333     } else {
1334         ALOGE("Unable to allocate byte array for IPv6 address.");
1335     }
1336 
1337     IF_ALOGD() {
1338         // log the IP for reference in case there is a bogus value pushed by HAL
1339         char str[INET6_ADDRSTRLEN];
1340         inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1341         ALOGD("AGPS IP is v6: %s", str);
1342     }
1343 
1344     jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
1345     ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1346     env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1347                         agps_status.type, agps_status.status, byteArray);
1348 
1349     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1350 
1351     if (byteArray) {
1352         env->DeleteLocalRef(byteArray);
1353     }
1354 
1355     return Void();
1356 }
1357 
agnssStatusIpV4Cb(const IAGnssCallback_V1_0::AGnssStatusIpV4 & agps_status)1358 Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb(
1359         const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) {
1360     JNIEnv* env = getJniEnv();
1361     jbyteArray byteArray = nullptr;
1362 
1363     uint32_t ipAddr = agps_status.ipV4Addr;
1364     byteArray = convertToIpV4(ipAddr);
1365 
1366     IF_ALOGD() {
1367         /*
1368          * log the IP for reference in case there is a bogus value pushed by
1369          * HAL.
1370          */
1371         char str[INET_ADDRSTRLEN];
1372         inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1373         ALOGD("AGPS IP is v4: %s", str);
1374     }
1375 
1376     jsize byteArrayLength =
1377       byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
1378     ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1379     env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1380                       agps_status.type, agps_status.status, byteArray);
1381 
1382     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1383 
1384     if (byteArray) {
1385         env->DeleteLocalRef(byteArray);
1386     }
1387     return Void();
1388 }
1389 
convertToIpV4(uint32_t ip)1390 jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) {
1391     if (INADDR_NONE == ip) {
1392         return nullptr;
1393     }
1394 
1395     JNIEnv* env = getJniEnv();
1396     jbyteArray byteArray = env->NewByteArray(4);
1397     if (byteArray == nullptr) {
1398         ALOGE("Unable to allocate byte array for IPv4 address");
1399         return nullptr;
1400     }
1401 
1402     jbyte ipv4[4];
1403     ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1404     memcpy(ipv4, &ip, sizeof(ipv4));
1405     env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1406     return byteArray;
1407 }
1408 
1409 /*
1410  * AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface.
1411  */
1412 struct AGnssCallback_V2_0 : public IAGnssCallback_V2_0 {
1413     // Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow.
1414     Return<void> agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1415         IAGnssCallback_V2_0::AGnssStatusValue status) override;
1416 };
1417 
agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,IAGnssCallback_V2_0::AGnssStatusValue status)1418 Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1419         IAGnssCallback_V2_0::AGnssStatusValue status) {
1420     JNIEnv* env = getJniEnv();
1421     env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr);
1422     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1423     return Void();
1424 }
1425 
1426 /*
1427  * AGnssRilCallback implements the callback methods required by the AGnssRil
1428  * interface.
1429  */
1430 struct AGnssRilCallback : IAGnssRilCallback {
1431     Return<void> requestSetIdCb(uint32_t setIdFlag) override;
1432     Return<void> requestRefLocCb() override;
1433 };
1434 
requestSetIdCb(uint32_t setIdFlag)1435 Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
1436     JNIEnv* env = getJniEnv();
1437     env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1438     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1439     return Void();
1440 }
1441 
requestRefLocCb()1442 Return<void> AGnssRilCallback::requestRefLocCb() {
1443     JNIEnv* env = getJniEnv();
1444     env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1445     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1446     return Void();
1447 }
1448 
1449 struct GnssBatchingCallbackUtil {
1450     template<class T>
1451     static Return<void> gnssLocationBatchCbImpl(const hidl_vec<T>& locations);
1452 private:
1453     GnssBatchingCallbackUtil() = delete;
1454 };
1455 
1456 template<class T>
gnssLocationBatchCbImpl(const hidl_vec<T> & locations)1457 Return<void> GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(const hidl_vec<T>& locations) {
1458     JNIEnv* env = getJniEnv();
1459 
1460     jobjectArray jLocations = env->NewObjectArray(locations.size(), class_location, nullptr);
1461 
1462     for (uint16_t i = 0; i < locations.size(); ++i) {
1463         jobject jLocation = translateGnssLocation(env, locations[i]);
1464         env->SetObjectArrayElement(jLocations, i, jLocation);
1465         env->DeleteLocalRef(jLocation);
1466     }
1467 
1468     env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1469     checkAndClearExceptionFromCallback(env, __FUNCTION__);
1470 
1471     env->DeleteLocalRef(jLocations);
1472 
1473     return Void();
1474 }
1475 
1476 /*
1477  * GnssBatchingCallback_V1_0 class implements the callback methods required by the
1478  * IGnssBatching 1.0 interface.
1479  */
1480 struct GnssBatchingCallback_V1_0 : public IGnssBatchingCallback_V1_0 {
1481     /** Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback follow. */
gnssLocationBatchCbandroid::GnssBatchingCallback_V1_01482     Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V1_0>& locations) override {
1483         return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
1484     }
1485 };
1486 
1487 /*
1488  * GnssBatchingCallback_V2_0 class implements the callback methods required by the
1489  * IGnssBatching 2.0 interface.
1490  */
1491 struct GnssBatchingCallback_V2_0 : public IGnssBatchingCallback_V2_0 {
1492     /** Methods from ::android::hardware::gps::V2_0::IGnssBatchingCallback follow. */
gnssLocationBatchCbandroid::GnssBatchingCallback_V2_01493     Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V2_0>& locations) override {
1494         return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
1495     }
1496 };
1497 
1498 /* Initializes the GNSS service handle. */
android_location_GnssLocationProvider_set_gps_service_handle()1499 static void android_location_GnssLocationProvider_set_gps_service_handle() {
1500     gnssHal_V2_0 = IGnss_V2_0::getService();
1501     if (gnssHal_V2_0 != nullptr) {
1502         gnssHal = gnssHal_V2_0;
1503         gnssHal_V1_1 = gnssHal_V2_0;
1504         return;
1505     }
1506 
1507     ALOGD("gnssHal 2.0 was null, trying 1.1");
1508     gnssHal_V1_1 = IGnss_V1_1::getService();
1509     if (gnssHal_V1_1 != nullptr) {
1510         gnssHal = gnssHal_V1_1;
1511         return;
1512     }
1513 
1514     ALOGD("gnssHal 1.1 was null, trying 1.0");
1515     gnssHal = IGnss_V1_0::getService();
1516 }
1517 
1518 /* One time initialization at system boot */
android_location_GnssLocationProvider_class_init_native(JNIEnv * env,jclass clazz)1519 static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
1520     // Initialize the top level gnss HAL handle.
1521     android_location_GnssLocationProvider_set_gps_service_handle();
1522 
1523     // Cache methodIDs and class IDs.
1524     method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1525             "(ZLandroid/location/Location;)V");
1526     method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1527     method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
1528     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1529     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1530     method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");
1531     method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
1532     method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1533             "(Ljava/lang/String;)V");
1534     method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "()V");
1535     method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1536             "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1537     method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
1538     method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1539     method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1540     method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1541     method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
1542             "(ILandroid/location/Location;IJ)V");
1543     method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
1544             "(ILandroid/location/Location;)V");
1545     method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1546             "(II)V");
1547     method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1548             "(II)V");
1549     method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1550             "(II)V");
1551     method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1552             "(II)V");
1553     method_reportMeasurementData = env->GetMethodID(
1554             clazz,
1555             "reportMeasurementData",
1556             "(Landroid/location/GnssMeasurementsEvent;)V");
1557     method_reportNavigationMessages = env->GetMethodID(
1558             clazz,
1559             "reportNavigationMessage",
1560             "(Landroid/location/GnssNavigationMessage;)V");
1561     method_reportLocationBatch = env->GetMethodID(
1562             clazz,
1563             "reportLocationBatch",
1564             "([Landroid/location/Location;)V");
1565     method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
1566     method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
1567             "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
1568     method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
1569 
1570     method_setSubHalMeasurementCorrectionsCapabilities = env->GetMethodID(clazz,
1571             "setSubHalMeasurementCorrectionsCapabilities", "(I)V");
1572 
1573     jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
1574     method_correctionsGetLatitudeDegrees = env->GetMethodID(
1575             measCorrClass,"getLatitudeDegrees", "()D");
1576     method_correctionsGetLongitudeDegrees = env->GetMethodID(
1577             measCorrClass, "getLongitudeDegrees", "()D");
1578     method_correctionsGetAltitudeMeters = env->GetMethodID(
1579             measCorrClass, "getAltitudeMeters", "()D");
1580     method_correctionsGetHorPosUncMeters = env->GetMethodID(
1581             measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
1582     method_correctionsGetVerPosUncMeters = env->GetMethodID(
1583             measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
1584     method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
1585             measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");
1586 
1587     method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
1588             measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava/util/List;");
1589 
1590     jclass corrListClass = env->FindClass("java/util/List");
1591     method_listSize = env->GetMethodID(corrListClass, "size", "()I");
1592     method_correctionListGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;");
1593 
1594     jclass singleSatCorrClass = env->FindClass("android/location/GnssSingleSatCorrection");
1595     method_correctionSatFlags = env->GetMethodID(
1596             singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
1597     method_correctionSatConstType = env->GetMethodID(
1598             singleSatCorrClass, "getConstellationType", "()I");
1599     method_correctionSatId= env->GetMethodID(
1600             singleSatCorrClass, "getSatelliteId", "()I");
1601     method_correctionSatCarrierFreq = env->GetMethodID(
1602             singleSatCorrClass, "getCarrierFrequencyHz", "()F");
1603     method_correctionSatIsLosProb = env->GetMethodID(
1604             singleSatCorrClass,"getProbabilityLineOfSight", "()F");
1605     method_correctionSatEpl = env->GetMethodID(
1606             singleSatCorrClass, "getExcessPathLengthMeters", "()F");
1607     method_correctionSatEplUnc = env->GetMethodID(
1608             singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
1609     method_correctionSatRefPlane = env->GetMethodID(
1610             singleSatCorrClass, "getReflectingPlane", "()Landroid/location/GnssReflectingPlane;");
1611 
1612     jclass refPlaneClass = env->FindClass("android/location/GnssReflectingPlane");
1613     method_correctionPlaneLatDeg = env->GetMethodID(refPlaneClass, "getLatitudeDegrees", "()D");
1614     method_correctionPlaneLngDeg = env->GetMethodID(refPlaneClass, "getLongitudeDegrees", "()D");
1615     method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D");
1616     method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D");
1617 
1618     jclass gnssMeasurementsEventClass = env->FindClass("android/location/GnssMeasurementsEvent");
1619     class_gnssMeasurementsEvent= (jclass) env->NewGlobalRef(gnssMeasurementsEventClass);
1620     method_gnssMeasurementsEventCtor = env->GetMethodID(
1621                     class_gnssMeasurementsEvent,
1622                     "<init>",
1623                     "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
1624 
1625     jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
1626     class_gnssMeasurement = (jclass) env->NewGlobalRef(gnssMeasurementClass);
1627     method_gnssMeasurementCtor = env->GetMethodID(class_gnssMeasurement, "<init>", "()V");
1628 
1629     jclass locationClass = env->FindClass("android/location/Location");
1630     class_location = (jclass) env->NewGlobalRef(locationClass);
1631     method_locationCtor = env->GetMethodID(class_location, "<init>", "(Ljava/lang/String;)V");
1632 
1633     jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
1634     class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass);
1635     method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "<init>", "()V");
1636 
1637     jclass gnssClockClass = env->FindClass("android/location/GnssClock");
1638     class_gnssClock = (jclass) env->NewGlobalRef(gnssClockClass);
1639     method_gnssClockCtor = env->GetMethodID(class_gnssClock, "<init>", "()V");
1640 
1641     jclass gnssConfiguration_halInterfaceVersionClass =
1642             env->FindClass("com/android/server/location/GnssConfiguration$HalInterfaceVersion");
1643     class_gnssConfiguration_halInterfaceVersion =
1644             (jclass) env->NewGlobalRef(gnssConfiguration_halInterfaceVersionClass);
1645     method_halInterfaceVersionCtor =
1646             env->GetMethodID(class_gnssConfiguration_halInterfaceVersion, "<init>", "(II)V");
1647 }
1648 
1649 /* Initialization needed at system boot and whenever GNSS service dies. */
android_location_GnssLocationProvider_init_once(JNIEnv * env,jclass clazz,jboolean reinitializeGnssServiceHandle)1650 static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz,
1651         jboolean reinitializeGnssServiceHandle) {
1652     /*
1653      * Save a pointer to JVM.
1654      */
1655     jint jvmStatus = env->GetJavaVM(&sJvm);
1656     if (jvmStatus != JNI_OK) {
1657         LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1658     }
1659 
1660     if (reinitializeGnssServiceHandle) {
1661         android_location_GnssLocationProvider_set_gps_service_handle();
1662     }
1663 
1664     if (gnssHal == nullptr) {
1665         ALOGE("Unable to get GPS service\n");
1666         return;
1667     }
1668 
1669     gnssHalDeathRecipient = new GnssDeathRecipient();
1670     hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
1671     if (!linked.isOk()) {
1672         ALOGE("Transaction error in linking to GnssHAL death: %s",
1673                 linked.description().c_str());
1674     } else if (!linked) {
1675         ALOGW("Unable to link to GnssHal death notifications");
1676     } else {
1677         ALOGD("Link to death notification successful");
1678     }
1679 
1680     auto gnssXtra = gnssHal->getExtensionXtra();
1681     if (!gnssXtra.isOk()) {
1682         ALOGD("Unable to get a handle to Xtra");
1683     } else {
1684         gnssXtraIface = gnssXtra;
1685     }
1686 
1687     if (gnssHal_V2_0 != nullptr) {
1688         auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
1689         if (!agnssRil_V2_0.isOk()) {
1690             ALOGD("Unable to get a handle to AGnssRil_V2_0");
1691         } else {
1692             agnssRilIface_V2_0 = agnssRil_V2_0;
1693             agnssRilIface = agnssRilIface_V2_0;
1694         }
1695     } else {
1696         auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
1697         if (!agnssRil_V1_0.isOk()) {
1698             ALOGD("Unable to get a handle to AGnssRil");
1699         } else {
1700             agnssRilIface = agnssRil_V1_0;
1701         }
1702     }
1703 
1704     if (gnssHal_V2_0 != nullptr) {
1705         auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
1706         if (!agnss_V2_0.isOk()) {
1707             ALOGD("Unable to get a handle to AGnss_V2_0");
1708         } else {
1709             agnssIface_V2_0 = agnss_V2_0;
1710         }
1711     } else {
1712         auto agnss_V1_0 = gnssHal->getExtensionAGnss();
1713         if (!agnss_V1_0.isOk()) {
1714             ALOGD("Unable to get a handle to AGnss");
1715         } else {
1716             agnssIface = agnss_V1_0;
1717         }
1718     }
1719 
1720     auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1721     if (!gnssNavigationMessage.isOk()) {
1722         ALOGD("Unable to get a handle to GnssNavigationMessage");
1723     } else {
1724         gnssNavigationMessageIface = gnssNavigationMessage;
1725     }
1726 
1727     // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means,
1728     // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement
1729     // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
1730     // 1.0@IGnss is paired with 1.0@IGnssMeasurement
1731     gnssMeasurementIface = nullptr;
1732     if (gnssHal_V2_0 != nullptr) {
1733         auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
1734         if (!gnssMeasurement.isOk()) {
1735             ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
1736         } else {
1737             gnssMeasurementIface_V2_0 = gnssMeasurement;
1738             gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
1739             gnssMeasurementIface = gnssMeasurementIface_V2_0;
1740         }
1741     }
1742     if (gnssHal_V1_1 != nullptr && gnssMeasurementIface == nullptr) {
1743          auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1744          if (!gnssMeasurement.isOk()) {
1745              ALOGD("Unable to get a handle to GnssMeasurement_V1_1");
1746          } else {
1747              gnssMeasurementIface_V1_1 = gnssMeasurement;
1748              gnssMeasurementIface = gnssMeasurementIface_V1_1;
1749          }
1750     }
1751     if (gnssMeasurementIface == nullptr) {
1752          auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1753          if (!gnssMeasurement.isOk()) {
1754              ALOGD("Unable to get a handle to GnssMeasurement");
1755          } else {
1756              gnssMeasurementIface = gnssMeasurement;
1757          }
1758     }
1759 
1760     if (gnssHal_V2_0 != nullptr) {
1761         auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
1762         if (!gnssCorrections.isOk()) {
1763             ALOGD("Unable to get a handle to GnssMeasurementCorrections interface");
1764         } else {
1765             gnssCorrectionsIface = gnssCorrections;
1766         }
1767     }
1768 
1769     // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means,
1770     // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug
1771     // 1.0@IGnss is paired with 1.0@IGnssDebug
1772     gnssDebugIface = nullptr;
1773     if (gnssHal_V2_0 != nullptr) {
1774         auto gnssDebug = gnssHal_V2_0->getExtensionGnssDebug_2_0();
1775         if (!gnssDebug.isOk()) {
1776             ALOGD("Unable to get a handle to GnssDebug_V2_0");
1777         } else {
1778             gnssDebugIface_V2_0 = gnssDebug;
1779             gnssDebugIface = gnssDebugIface_V2_0;
1780         }
1781     }
1782     if (gnssDebugIface == nullptr) {
1783         auto gnssDebug = gnssHal->getExtensionGnssDebug();
1784         if (!gnssDebug.isOk()) {
1785             ALOGD("Unable to get a handle to GnssDebug");
1786         } else {
1787             gnssDebugIface = gnssDebug;
1788         }
1789     }
1790 
1791     auto gnssNi = gnssHal->getExtensionGnssNi();
1792     if (!gnssNi.isOk()) {
1793         ALOGD("Unable to get a handle to GnssNi");
1794     } else {
1795         gnssNiIface = gnssNi;
1796     }
1797 
1798     if (gnssHal_V2_0 != nullptr) {
1799         auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0();
1800         if (!gnssConfiguration.isOk()) {
1801             ALOGD("Unable to get a handle to GnssConfiguration_V2_0");
1802         } else {
1803             gnssConfigurationIface_V2_0 = gnssConfiguration;
1804             gnssConfigurationIface_V1_1 = gnssConfigurationIface_V2_0;
1805             gnssConfigurationIface = gnssConfigurationIface_V2_0;
1806         }
1807     } else if (gnssHal_V1_1 != nullptr) {
1808         auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1809         if (!gnssConfiguration.isOk()) {
1810             ALOGD("Unable to get a handle to GnssConfiguration_V1_1");
1811         } else {
1812             gnssConfigurationIface_V1_1 = gnssConfiguration;
1813             gnssConfigurationIface = gnssConfigurationIface_V1_1;
1814         }
1815     } else {
1816         auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1817         if (!gnssConfiguration_V1_0.isOk()) {
1818             ALOGD("Unable to get a handle to GnssConfiguration");
1819         } else {
1820             gnssConfigurationIface = gnssConfiguration_V1_0;
1821         }
1822     }
1823 
1824     auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1825     if (!gnssGeofencing.isOk()) {
1826         ALOGD("Unable to get a handle to GnssGeofencing");
1827     } else {
1828         gnssGeofencingIface = gnssGeofencing;
1829     }
1830 
1831     // If IGnssBatching.hal@2.0 is not supported, use IGnssBatching.hal@1.0
1832     if (gnssHal_V2_0 != nullptr) {
1833         auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0();
1834         if (!gnssBatching_V2_0.isOk()) {
1835             ALOGD("Unable to get a handle to GnssBatching_V2_0");
1836         } else {
1837             gnssBatchingIface_V2_0 = gnssBatching_V2_0;
1838         }
1839     }
1840     if (gnssBatchingIface_V2_0 == nullptr ) {
1841         auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching();
1842         if (!gnssBatching_V1_0.isOk()) {
1843             ALOGD("Unable to get a handle to GnssBatching");
1844         } else {
1845             gnssBatchingIface = gnssBatching_V1_0;
1846         }
1847     }
1848 
1849     if (gnssHal_V2_0 != nullptr) {
1850         auto gnssVisibilityControl = gnssHal_V2_0->getExtensionVisibilityControl();
1851         if (!gnssVisibilityControl.isOk()) {
1852             ALOGD("Unable to get a handle to GnssVisibilityControl interface");
1853         } else {
1854             gnssVisibilityControlIface = gnssVisibilityControl;
1855         }
1856     }
1857 }
1858 
android_location_GnssLocationProvider_is_supported(JNIEnv *,jclass)1859 static jboolean android_location_GnssLocationProvider_is_supported(
1860         JNIEnv* /* env */, jclass /* clazz */) {
1861     return (gnssHal != nullptr) ?  JNI_TRUE : JNI_FALSE;
1862 }
1863 
android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(JNIEnv *,jclass)1864 static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
1865         JNIEnv* /* env */, jclass /* clazz */) {
1866     return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1867 }
1868 
android_location_GnssConfiguration_get_gnss_configuration_version(JNIEnv * env,jclass)1869 static jobject android_location_GnssConfiguration_get_gnss_configuration_version(
1870         JNIEnv* env, jclass /* jclazz */) {
1871     jint major, minor;
1872     if (gnssConfigurationIface_V2_0 != nullptr) {
1873         major = 2;
1874         minor = 0;
1875     } else if (gnssConfigurationIface_V1_1 != nullptr) {
1876         major = 1;
1877         minor = 1;
1878     } else if (gnssConfigurationIface != nullptr) {
1879         major = 1;
1880         minor = 0;
1881     } else {
1882         return nullptr;
1883     }
1884 
1885     return createHalInterfaceVersionJavaObject(env, major, minor);
1886 }
1887 
1888 /* Initialization needed each time the GPS service is shutdown. */
android_location_GnssLocationProvider_init(JNIEnv * env,jobject obj)1889 static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1890     /*
1891      * This must be set before calling into the HAL library.
1892      */
1893     if (!mCallbacksObj)
1894         mCallbacksObj = env->NewGlobalRef(obj);
1895 
1896     /*
1897      * Fail if the main interface fails to initialize
1898      */
1899     if (gnssHal == nullptr) {
1900         ALOGE("Unable to initialize GNSS HAL.");
1901         return JNI_FALSE;
1902     }
1903 
1904     Return<bool> result = false;
1905 
1906     // Set top level IGnss.hal callback.
1907     sp<IGnssCallback> gnssCbIface = new GnssCallback();
1908     if (gnssHal_V2_0 != nullptr) {
1909         result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
1910     } else if (gnssHal_V1_1 != nullptr) {
1911         result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
1912     } else {
1913         result = gnssHal->setCallback(gnssCbIface);
1914     }
1915 
1916     if (!result.isOk() || !result) {
1917         ALOGE("SetCallback for IGnss interface failed.");
1918         return JNI_FALSE;
1919     }
1920 
1921     // Set IGnssXtra.hal callback.
1922     if (gnssXtraIface == nullptr) {
1923         ALOGI("Unable to initialize IGnssXtra interface.");
1924     } else {
1925         sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1926         result = gnssXtraIface->setCallback(gnssXtraCbIface);
1927         if (!result.isOk() || !result) {
1928             gnssXtraIface = nullptr;
1929             ALOGI("SetCallback for IGnssXtra interface failed.");
1930         }
1931     }
1932 
1933     // Set IAGnss.hal callback.
1934     Return<void> agnssStatus;
1935     if (agnssIface_V2_0 != nullptr) {
1936         sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
1937         agnssStatus = agnssIface_V2_0->setCallback(aGnssCbIface);
1938     } else if (agnssIface != nullptr) {
1939         sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
1940         agnssStatus = agnssIface->setCallback(aGnssCbIface);
1941     } else {
1942         ALOGI("Unable to initialize IAGnss interface.");
1943     }
1944 
1945     if (!agnssStatus.isOk()) {
1946         ALOGI("SetCallback for IAGnss interface failed.");
1947     }
1948 
1949     // Set IGnssGeofencing.hal callback.
1950     sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1951     if (gnssGeofencingIface != nullptr) {
1952         auto status = gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1953         if (!status.isOk()) {
1954             ALOGI("SetCallback for IGnssGeofencing interface failed.");
1955         }
1956     } else {
1957         ALOGI("Unable to initialize IGnssGeofencing interface.");
1958     }
1959 
1960     // Set IGnssNi.hal callback.
1961     sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1962     if (gnssNiIface != nullptr) {
1963         auto status = gnssNiIface->setCallback(gnssNiCbIface);
1964         if (!status.isOk()) {
1965             ALOGI("SetCallback for IGnssNi interface failed.");
1966         }
1967     } else {
1968         ALOGI("Unable to initialize IGnssNi interface.");
1969     }
1970 
1971     // Set IAGnssRil.hal callback.
1972     sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1973     if (agnssRilIface != nullptr) {
1974         auto status = agnssRilIface->setCallback(aGnssRilCbIface);
1975         if (!status.isOk()) {
1976             ALOGI("SetCallback for IAGnssRil interface failed.");
1977         }
1978     } else {
1979         ALOGI("Unable to initialize IAGnssRil interface.");
1980     }
1981 
1982     // Set IGnssVisibilityControl.hal callback.
1983     if (gnssVisibilityControlIface != nullptr) {
1984         sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
1985                 new GnssVisibilityControlCallback();
1986         result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
1987         if (!result.isOk() || !result) {
1988             ALOGI("SetCallback for IGnssVisibilityControl interface failed.");
1989         }
1990     }
1991 
1992     // Set IMeasurementCorrections.hal callback.
1993     if (gnssCorrectionsIface != nullptr) {
1994         sp<IMeasurementCorrectionsCallback> gnssCorrectionsIfaceCbIface =
1995                 new MeasurementCorrectionsCallback();
1996         result = gnssCorrectionsIface->setCallback(gnssCorrectionsIfaceCbIface);
1997         if (!result.isOk() || !result) {
1998             ALOGI("SetCallback for IMeasurementCorrections interface failed.");
1999         }
2000     }
2001 
2002     return JNI_TRUE;
2003 }
2004 
android_location_GnssLocationProvider_cleanup(JNIEnv *,jobject)2005 static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
2006     if (gnssHal != nullptr) {
2007         gnssHal->cleanup();
2008     }
2009 }
2010 
android_location_GnssLocationProvider_set_position_mode(JNIEnv *,jobject,jint mode,jint recurrence,jint min_interval,jint preferred_accuracy,jint preferred_time,jboolean low_power_mode)2011 static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
2012         jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
2013         jint preferred_time, jboolean low_power_mode) {
2014     Return<bool> result = false;
2015     if (gnssHal_V1_1 != nullptr) {
2016          result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
2017                  static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
2018                  min_interval,
2019                  preferred_accuracy,
2020                  preferred_time,
2021                  low_power_mode);
2022      } else if (gnssHal != nullptr) {
2023          result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
2024                  static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
2025                  min_interval,
2026                  preferred_accuracy,
2027                  preferred_time);
2028     }
2029     if (!result.isOk()) {
2030        ALOGE("%s: GNSS setPositionMode failed\n", __func__);
2031        return JNI_FALSE;
2032     } else {
2033        return result;
2034     }
2035 }
2036 
android_location_GnssLocationProvider_start(JNIEnv *,jobject)2037 static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
2038     if (gnssHal != nullptr) {
2039         auto result = gnssHal->start();
2040         if (!result.isOk()) {
2041             return JNI_FALSE;
2042         } else {
2043             return result;
2044         }
2045     } else {
2046         return JNI_FALSE;
2047     }
2048 }
2049 
android_location_GnssLocationProvider_stop(JNIEnv *,jobject)2050 static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
2051     if (gnssHal != nullptr) {
2052         auto result = gnssHal->stop();
2053         if (!result.isOk()) {
2054             return JNI_FALSE;
2055         } else {
2056             return result;
2057         }
2058     } else {
2059         return JNI_FALSE;
2060     }
2061 }
android_location_GnssLocationProvider_delete_aiding_data(JNIEnv *,jobject,jint flags)2062 static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
2063                                                                     jobject /* obj */,
2064                                                                     jint flags) {
2065     if (gnssHal != nullptr) {
2066         auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
2067         if (!result.isOk()) {
2068             ALOGE("Error in deleting aiding data");
2069         }
2070     }
2071 }
2072 
android_location_GnssLocationProvider_agps_set_reference_location_cellid(JNIEnv *,jobject,jint type,jint mcc,jint mnc,jint lac,jint cid)2073 static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
2074         JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
2075     IAGnssRil_V1_0::AGnssRefLocation location;
2076 
2077     if (agnssRilIface == nullptr) {
2078         ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
2079         return;
2080     }
2081 
2082     switch (static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type)) {
2083         case IAGnssRil_V1_0::AGnssRefLocationType::GSM_CELLID:
2084         case IAGnssRil_V1_0::AGnssRefLocationType::UMTS_CELLID:
2085           location.type = static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type);
2086           location.cellID.mcc = mcc;
2087           location.cellID.mnc = mnc;
2088           location.cellID.lac = lac;
2089           location.cellID.cid = cid;
2090           break;
2091         default:
2092             ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
2093             return;
2094             break;
2095     }
2096 
2097     agnssRilIface->setRefLocation(location);
2098 }
2099 
android_location_GnssLocationProvider_agps_set_id(JNIEnv * env,jobject,jint type,jstring setid_string)2100 static void android_location_GnssLocationProvider_agps_set_id(JNIEnv* env, jobject /* obj */,
2101                                                              jint type, jstring  setid_string) {
2102     if (agnssRilIface == nullptr) {
2103         ALOGE("no AGPS RIL interface in agps_set_id");
2104         return;
2105     }
2106 
2107     ScopedJniString jniSetId{env, setid_string};
2108     agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId);
2109 }
2110 
android_location_GnssLocationProvider_read_nmea(JNIEnv * env,jobject,jbyteArray nmeaArray,jint buffer_size)2111 static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
2112                                             jbyteArray nmeaArray, jint buffer_size) {
2113     // this should only be called from within a call to reportNmea
2114     jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
2115     int length = GnssCallback::sNmeaStringLength;
2116     if (length > buffer_size)
2117         length = buffer_size;
2118     memcpy(nmea, GnssCallback::sNmeaString, length);
2119     env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
2120     return (jint) length;
2121 }
2122 
android_location_GnssLocationProvider_inject_time(JNIEnv *,jobject,jlong time,jlong timeReference,jint uncertainty)2123 static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
2124         jlong time, jlong timeReference, jint uncertainty) {
2125     if (gnssHal != nullptr) {
2126         auto result = gnssHal->injectTime(time, timeReference, uncertainty);
2127         if (!result.isOk() || !result) {
2128             ALOGE("%s: Gnss injectTime() failed", __func__);
2129         }
2130     }
2131 }
2132 
android_location_GnssLocationProvider_inject_best_location(JNIEnv *,jobject,jint gnssLocationFlags,jdouble latitudeDegrees,jdouble longitudeDegrees,jdouble altitudeMeters,jfloat speedMetersPerSec,jfloat bearingDegrees,jfloat horizontalAccuracyMeters,jfloat verticalAccuracyMeters,jfloat speedAccuracyMetersPerSecond,jfloat bearingAccuracyDegrees,jlong timestamp,jint elapsedRealtimeFlags,jlong elapsedRealtimeNanos,jdouble elapsedRealtimeUncertaintyNanos)2133 static void android_location_GnssLocationProvider_inject_best_location(
2134         JNIEnv*,
2135         jobject,
2136         jint gnssLocationFlags,
2137         jdouble latitudeDegrees,
2138         jdouble longitudeDegrees,
2139         jdouble altitudeMeters,
2140         jfloat speedMetersPerSec,
2141         jfloat bearingDegrees,
2142         jfloat horizontalAccuracyMeters,
2143         jfloat verticalAccuracyMeters,
2144         jfloat speedAccuracyMetersPerSecond,
2145         jfloat bearingAccuracyDegrees,
2146         jlong timestamp,
2147         jint elapsedRealtimeFlags,
2148         jlong elapsedRealtimeNanos,
2149         jdouble elapsedRealtimeUncertaintyNanos) {
2150     if (gnssHal_V2_0 != nullptr) {
2151         GnssLocation_V2_0 location = createGnssLocation_V2_0(
2152                 gnssLocationFlags,
2153                 latitudeDegrees,
2154                 longitudeDegrees,
2155                 altitudeMeters,
2156                 speedMetersPerSec,
2157                 bearingDegrees,
2158                 horizontalAccuracyMeters,
2159                 verticalAccuracyMeters,
2160                 speedAccuracyMetersPerSecond,
2161                 bearingAccuracyDegrees,
2162                 timestamp,
2163                 elapsedRealtimeFlags,
2164                 elapsedRealtimeNanos,
2165                 elapsedRealtimeUncertaintyNanos);
2166         auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
2167 
2168         if (!result.isOk() || !result) {
2169             ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
2170         }
2171         return;
2172     }
2173 
2174     if (gnssHal_V1_1 != nullptr) {
2175         GnssLocation_V1_0 location = createGnssLocation_V1_0(
2176                 gnssLocationFlags,
2177                 latitudeDegrees,
2178                 longitudeDegrees,
2179                 altitudeMeters,
2180                 speedMetersPerSec,
2181                 bearingDegrees,
2182                 horizontalAccuracyMeters,
2183                 verticalAccuracyMeters,
2184                 speedAccuracyMetersPerSecond,
2185                 bearingAccuracyDegrees,
2186                 timestamp);
2187         auto result = gnssHal_V1_1->injectBestLocation(location);
2188 
2189         if (!result.isOk() || !result) {
2190             ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
2191         }
2192         return;
2193     }
2194 
2195     ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
2196 }
2197 
android_location_GnssLocationProvider_inject_location(JNIEnv *,jobject,jdouble latitude,jdouble longitude,jfloat accuracy)2198 static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
2199         jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
2200     if (gnssHal != nullptr) {
2201         auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
2202         if (!result.isOk() || !result) {
2203             ALOGE("%s: Gnss injectLocation() failed", __func__);
2204         }
2205     }
2206 }
2207 
android_location_GnssLocationProvider_supports_psds(JNIEnv *,jobject)2208 static jboolean android_location_GnssLocationProvider_supports_psds(
2209         JNIEnv* /* env */, jobject /* obj */) {
2210     return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2211 }
2212 
android_location_GnssLocationProvider_inject_psds_data(JNIEnv * env,jobject,jbyteArray data,jint length)2213 static void android_location_GnssLocationProvider_inject_psds_data(JNIEnv* env, jobject /* obj */,
2214         jbyteArray data, jint length) {
2215     if (gnssXtraIface == nullptr) {
2216         ALOGE("XTRA Interface not supported");
2217         return;
2218     }
2219 
2220     jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
2221     gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
2222     env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
2223 }
2224 
2225 struct AGnssDispatcher {
2226     static void dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, jint apnIpType);
2227     static void dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, jlong networkHandle,
2228             jstring apn, jint apnIpType);
2229 
2230     template <class T>
2231     static void dataConnClosed(sp<T> agnssIface);
2232 
2233     template <class T>
2234     static void dataConnFailed(sp<T> agnssIface);
2235 
2236     template <class T, class U>
2237     static void setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, jint port);
2238 
2239 private:
2240     AGnssDispatcher() = delete;
2241 };
2242 
dataConnOpen(sp<IAGnss_V1_0> agnssIface,JNIEnv * env,jstring apn,jint apnIpType)2243 void AGnssDispatcher::dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn,
2244         jint apnIpType) {
2245     ScopedJniString jniApn{env, apn};
2246     auto result = agnssIface->dataConnOpen(jniApn,
2247             static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
2248     if (!result.isOk() || !result){
2249         ALOGE("%s: Failed to set APN and its IP type", __func__);
2250     }
2251 }
2252 
dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0,JNIEnv * env,jlong networkHandle,jstring apn,jint apnIpType)2253 void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env,
2254         jlong networkHandle, jstring apn, jint apnIpType) {
2255     ScopedJniString jniApn{env, apn};
2256     auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
2257             static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
2258     if (!result.isOk() || !result){
2259         ALOGE("%s: Failed to set APN and its IP type", __func__);
2260     }
2261 }
2262 
2263 template<class T>
dataConnClosed(sp<T> agnssIface)2264 void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) {
2265     auto result = agnssIface->dataConnClosed();
2266     if (!result.isOk() || !result) {
2267         ALOGE("%s: Failed to close AGnss data connection", __func__);
2268     }
2269 }
2270 
2271 template<class T>
dataConnFailed(sp<T> agnssIface)2272 void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) {
2273     auto result = agnssIface->dataConnFailed();
2274     if (!result.isOk() || !result) {
2275         ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
2276     }
2277 }
2278 
2279 template <class T, class U>
setServer(sp<T> agnssIface,JNIEnv * env,jint type,jstring hostname,jint port)2280 void AGnssDispatcher::setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname,
2281         jint port) {
2282     ScopedJniString jniHostName{env, hostname};
2283     auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type),
2284             jniHostName, port);
2285     if (!result.isOk() || !result) {
2286         ALOGE("%s: Failed to set AGnss host name and port", __func__);
2287     }
2288 }
2289 
android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(JNIEnv * env,jobject,jlong networkHandle,jstring apn,jint apnIpType)2290 static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
2291         JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
2292     if (apn == nullptr) {
2293         jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
2294         return;
2295     }
2296 
2297     if (agnssIface_V2_0 != nullptr) {
2298         AGnssDispatcher::dataConnOpen(agnssIface_V2_0, env, networkHandle, apn, apnIpType);
2299     } else if (agnssIface != nullptr) {
2300         AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType);
2301     } else {
2302         ALOGE("%s: AGPS interface not supported", __func__);
2303         return;
2304     }
2305 }
2306 
android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv *,jobject)2307 static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
2308                                                                        jobject /* obj */) {
2309     if (agnssIface_V2_0 != nullptr) {
2310         AGnssDispatcher::dataConnClosed(agnssIface_V2_0);
2311     } else if (agnssIface != nullptr) {
2312         AGnssDispatcher::dataConnClosed(agnssIface);
2313     } else {
2314         ALOGE("%s: AGPS interface not supported", __func__);
2315         return;
2316     }
2317 }
2318 
android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv *,jobject)2319 static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
2320                                                                        jobject /* obj */) {
2321     if (agnssIface_V2_0 != nullptr) {
2322         AGnssDispatcher::dataConnFailed(agnssIface_V2_0);
2323     } else if (agnssIface != nullptr) {
2324         AGnssDispatcher::dataConnFailed(agnssIface);
2325     } else {
2326         ALOGE("%s: AGPS interface not supported", __func__);
2327         return;
2328     }
2329 }
2330 
android_location_GnssLocationProvider_set_agps_server(JNIEnv * env,jobject,jint type,jstring hostname,jint port)2331 static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
2332         jint type, jstring hostname, jint port) {
2333     if (agnssIface_V2_0 != nullptr) {
2334         AGnssDispatcher::setServer<IAGnss_V2_0, IAGnssCallback_V2_0>(agnssIface_V2_0, env, type,
2335                 hostname, port);
2336     } else if (agnssIface != nullptr) {
2337         AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type,
2338                 hostname, port);
2339     } else {
2340         ALOGE("%s: AGPS interface not supported", __func__);
2341         return;
2342     }
2343 }
2344 
android_location_GnssLocationProvider_send_ni_response(JNIEnv *,jobject,jint notifId,jint response)2345 static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
2346       jobject /* obj */, jint notifId, jint response) {
2347     if (gnssNiIface == nullptr) {
2348         ALOGE("no NI interface in send_ni_response");
2349         return;
2350     }
2351 
2352     gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
2353 }
2354 
getSatelliteData(const hidl_vec<IGnssDebug_V1_0::SatelliteData> & satelliteDataArray,size_t i)2355 const IGnssDebug_V1_0::SatelliteData& getSatelliteData(const hidl_vec<IGnssDebug_V1_0::SatelliteData>& satelliteDataArray, size_t i) {
2356     return satelliteDataArray[i];
2357 }
2358 
getSatelliteData(const hidl_vec<IGnssDebug_V2_0::SatelliteData> & satelliteDataArray,size_t i)2359 const IGnssDebug_V1_0::SatelliteData& getSatelliteData(const hidl_vec<IGnssDebug_V2_0::SatelliteData>& satelliteDataArray, size_t i) {
2360     return satelliteDataArray[i].v1_0;
2361 }
2362 
2363 template<class T>
getConstellationType(const hidl_vec<T> & satelliteDataArray,size_t i)2364 uint32_t getConstellationType(const hidl_vec<T>& satelliteDataArray, size_t i) {
2365     return static_cast<uint32_t>(satelliteDataArray[i].constellation);
2366 }
2367 
2368 template<class T>
parseDebugData(JNIEnv * env,std::stringstream & internalState,const T & data)2369 static jstring parseDebugData(JNIEnv* env, std::stringstream& internalState, const T& data) {
2370     internalState << "Gnss Location Data:: ";
2371     if (!data.position.valid) {
2372         internalState << "not valid";
2373     } else {
2374         internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
2375                       << ", LongitudeDegrees: " << data.position.longitudeDegrees
2376                       << ", altitudeMeters: " << data.position.altitudeMeters
2377                       << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
2378                       << ", bearingDegrees: " << data.position.bearingDegrees
2379                       << ", horizontalAccuracyMeters: "
2380                       << data.position.horizontalAccuracyMeters
2381                       << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
2382                       << ", speedAccuracyMetersPerSecond: "
2383                       << data.position.speedAccuracyMetersPerSecond
2384                       << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
2385                       << ", ageSeconds: " << data.position.ageSeconds;
2386     }
2387     internalState << std::endl;
2388 
2389     internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
2390                   << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
2391                   << ", frequencyUncertaintyNsPerSec: "
2392                   << data.time.frequencyUncertaintyNsPerSec << std::endl;
2393 
2394     if (data.satelliteDataArray.size() != 0) {
2395         internalState << "Satellite Data for " << data.satelliteDataArray.size()
2396                       << " satellites:: " << std::endl;
2397     }
2398 
2399     internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL, 7=IRNSS; "
2400                   << "ephType: 0=Eph, 1=Alm, 2=Unk; "
2401                   << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
2402                   << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
2403     for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
2404         IGnssDebug_V1_0::SatelliteData satelliteData =
2405                 getSatelliteData(data.satelliteDataArray, i);
2406         internalState << "constell: "
2407                       << getConstellationType(data.satelliteDataArray, i)
2408                       << ", svid: " << std::setw(3) << satelliteData.svid
2409                       << ", serverPredAvail: "
2410                       << satelliteData.serverPredictionIsAvailable
2411                       << ", serverPredAgeSec: " << std::setw(7)
2412                       << satelliteData.serverPredictionAgeSeconds
2413                       << ", ephType: "
2414                       << static_cast<uint32_t>(satelliteData.ephemerisType)
2415                       << ", ephSource: "
2416                       << static_cast<uint32_t>(satelliteData.ephemerisSource)
2417                       << ", ephHealth: "
2418                       << static_cast<uint32_t>(satelliteData.ephemerisHealth)
2419                       << ", ephAgeSec: " << std::setw(7)
2420                       << satelliteData.ephemerisAgeSeconds << std::endl;
2421     }
2422     return (jstring) env->NewStringUTF(internalState.str().c_str());
2423 }
2424 
android_location_GnssLocationProvider_get_internal_state(JNIEnv * env,jobject)2425 static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
2426                                                                        jobject /* obj */) {
2427     jstring result = nullptr;
2428     /*
2429      * TODO: Create a jobject to represent GnssDebug.
2430      */
2431 
2432     std::stringstream internalState;
2433 
2434     if (gnssDebugIface == nullptr) {
2435         internalState << "Gnss Debug Interface not available"  << std::endl;
2436     } else if (gnssDebugIface_V2_0 != nullptr) {
2437         IGnssDebug_V2_0::DebugData data;
2438         gnssDebugIface_V2_0->getDebugData_2_0([&data](const IGnssDebug_V2_0::DebugData& debugData) {
2439             data = debugData;
2440         });
2441         result = parseDebugData(env, internalState, data);
2442     } else {
2443         IGnssDebug_V1_0::DebugData data;
2444         gnssDebugIface->getDebugData([&data](const IGnssDebug_V1_0::DebugData& debugData) {
2445             data = debugData;
2446         });
2447         result = parseDebugData(env, internalState, data);
2448     }
2449     return result;
2450 }
2451 
android_location_GnssLocationProvider_is_gnss_visibility_control_supported(JNIEnv *,jclass)2452 static jboolean android_location_GnssLocationProvider_is_gnss_visibility_control_supported(
2453         JNIEnv* /* env */, jclass /* clazz */) {
2454     return (gnssVisibilityControlIface != nullptr) ?  JNI_TRUE : JNI_FALSE;
2455 }
2456 
android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv * env,jobject,jboolean connected,jint type,jboolean roaming,jboolean available,jstring apn,jlong networkHandle,jshort capabilities)2457 static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
2458                                                                        jobject /* obj */,
2459                                                                        jboolean connected,
2460                                                                        jint type,
2461                                                                        jboolean roaming,
2462                                                                        jboolean available,
2463                                                                        jstring apn,
2464                                                                        jlong networkHandle,
2465                                                                        jshort capabilities) {
2466     if (agnssRilIface_V2_0 != nullptr) {
2467         ScopedJniString jniApn{env, apn};
2468         IAGnssRil_V2_0::NetworkAttributes networkAttributes = {
2469             .networkHandle = static_cast<uint64_t>(networkHandle),
2470             .isConnected = static_cast<bool>(connected),
2471             .capabilities = static_cast<uint16_t>(capabilities),
2472             .apn = jniApn
2473         };
2474 
2475         auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes);
2476         if (!result.isOk() || !result) {
2477             ALOGE("updateNetworkState_2_0 failed");
2478         }
2479     } else if (agnssRilIface != nullptr) {
2480         ScopedJniString jniApn{env, apn};
2481         hidl_string hidlApn{jniApn};
2482         auto result = agnssRilIface->updateNetworkState(connected,
2483                 static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming);
2484         if (!result.isOk() || !result) {
2485             ALOGE("updateNetworkState failed");
2486         }
2487 
2488         if (!hidlApn.empty()) {
2489             result = agnssRilIface->updateNetworkAvailability(available, hidlApn);
2490             if (!result.isOk() || !result) {
2491                 ALOGE("updateNetworkAvailability failed");
2492             }
2493         }
2494     } else {
2495         ALOGE("AGnssRilInterface does not exist");
2496     }
2497 }
2498 
android_location_GnssGeofenceProvider_is_geofence_supported(JNIEnv *,jobject)2499 static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
2500         JNIEnv* /* env */, jobject /* obj */) {
2501     return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2502 }
2503 
android_location_GnssGeofenceProvider_add_geofence(JNIEnv *,jobject,jint geofenceId,jdouble latitude,jdouble longitude,jdouble radius,jint last_transition,jint monitor_transition,jint notification_responsiveness,jint unknown_timer)2504 static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
2505         jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
2506         jint last_transition, jint monitor_transition, jint notification_responsiveness,
2507         jint unknown_timer) {
2508     if (gnssGeofencingIface != nullptr) {
2509         auto result = gnssGeofencingIface->addGeofence(
2510                 geofenceId, latitude, longitude, radius,
2511                 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
2512                 monitor_transition, notification_responsiveness, unknown_timer);
2513         return boolToJbool(result.isOk());
2514     } else {
2515         ALOGE("Geofence Interface not available");
2516     }
2517     return JNI_FALSE;
2518 }
2519 
android_location_GnssGeofenceProvider_remove_geofence(JNIEnv *,jobject,jint geofenceId)2520 static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
2521         jobject /* obj */, jint geofenceId) {
2522     if (gnssGeofencingIface != nullptr) {
2523         auto result = gnssGeofencingIface->removeGeofence(geofenceId);
2524         return boolToJbool(result.isOk());
2525     } else {
2526         ALOGE("Geofence interface not available");
2527     }
2528     return JNI_FALSE;
2529 }
2530 
android_location_GnssGeofenceProvider_pause_geofence(JNIEnv *,jobject,jint geofenceId)2531 static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
2532         jobject /* obj */, jint geofenceId) {
2533     if (gnssGeofencingIface != nullptr) {
2534         auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
2535         return boolToJbool(result.isOk());
2536     } else {
2537         ALOGE("Geofence interface not available");
2538     }
2539     return JNI_FALSE;
2540 }
2541 
android_location_GnssGeofenceProvider_resume_geofence(JNIEnv *,jobject,jint geofenceId,jint monitor_transition)2542 static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
2543         jobject /* obj */, jint geofenceId, jint monitor_transition) {
2544     if (gnssGeofencingIface != nullptr) {
2545         auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
2546         return boolToJbool(result.isOk());
2547     } else {
2548         ALOGE("Geofence interface not available");
2549     }
2550     return JNI_FALSE;
2551 }
2552 
android_location_GnssMeasurementsProvider_is_measurement_supported(JNIEnv * env,jclass clazz)2553 static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
2554     JNIEnv* env, jclass clazz) {
2555     if (gnssMeasurementIface != nullptr) {
2556         return JNI_TRUE;
2557     }
2558 
2559     return JNI_FALSE;
2560 }
2561 
android_location_GnssMeasurementsProvider_start_measurement_collection(JNIEnv *,jobject,jboolean enableFullTracking)2562 static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
2563         JNIEnv* /* env */,
2564         jobject /* obj */,
2565         jboolean enableFullTracking) {
2566     if (gnssMeasurementIface == nullptr) {
2567         ALOGE("GNSS Measurement interface is not available.");
2568         return JNI_FALSE;
2569     }
2570 
2571     sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
2572     IGnssMeasurement_V1_0::GnssMeasurementStatus result =
2573             IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;
2574     if (gnssMeasurementIface_V2_0 != nullptr) {
2575         result = gnssMeasurementIface_V2_0->setCallback_2_0(cbIface, enableFullTracking);
2576     } else if (gnssMeasurementIface_V1_1 != nullptr) {
2577         result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface, enableFullTracking);
2578     } else {
2579         if (enableFullTracking == JNI_TRUE) {
2580             // full tracking mode not supported in 1.0 HAL
2581             return JNI_FALSE;
2582         }
2583         result = gnssMeasurementIface->setCallback(cbIface);
2584     }
2585 
2586     if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
2587         ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
2588               static_cast<int32_t>(result));
2589         return JNI_FALSE;
2590     } else {
2591         ALOGD("gnss measurement infc has been enabled");
2592     }
2593 
2594     return JNI_TRUE;
2595 }
2596 
android_location_GnssMeasurementsProvider_stop_measurement_collection(JNIEnv * env,jobject obj)2597 static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
2598         JNIEnv* env,
2599         jobject obj) {
2600     if (gnssMeasurementIface == nullptr) {
2601         ALOGE("Measurement interface not available");
2602         return JNI_FALSE;
2603     }
2604 
2605     auto result = gnssMeasurementIface->close();
2606     return boolToJbool(result.isOk());
2607 }
2608 
2609 static jboolean
android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported(JNIEnv * env,jclass clazz)2610     android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported(
2611     JNIEnv* env, jclass clazz) {
2612     if (gnssCorrectionsIface != nullptr) {
2613         return JNI_TRUE;
2614     }
2615 
2616     return JNI_FALSE;
2617 }
2618 
2619 static jboolean
android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections(JNIEnv * env,jobject obj,jobject correctionsObj)2620     android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections(
2621         JNIEnv* env,
2622         jobject obj /* clazz*/,
2623         jobject correctionsObj) {
2624 
2625     if (gnssCorrectionsIface == nullptr) {
2626         ALOGW("Trying to inject GNSS measurement corrections on a chipset that does not"
2627             " support them.");
2628         return JNI_FALSE;
2629     }
2630 
2631     jdouble latitudeDegreesCorr = env->CallDoubleMethod(
2632         correctionsObj, method_correctionsGetLatitudeDegrees);
2633     jdouble longitudeDegreesCorr = env->CallDoubleMethod(
2634         correctionsObj, method_correctionsGetLongitudeDegrees);
2635     jdouble altitudeDegreesCorr = env->CallDoubleMethod(
2636         correctionsObj, method_correctionsGetAltitudeMeters);
2637     jdouble horizontalPositionUncertaintyMeters = env->CallDoubleMethod(
2638         correctionsObj, method_correctionsGetHorPosUncMeters);
2639     jdouble verticalPositionUncertaintyMeters = env->CallDoubleMethod(
2640             correctionsObj, method_correctionsGetVerPosUncMeters);
2641     jlong toaGpsNanosOfWeek = env->CallLongMethod(
2642         correctionsObj, method_correctionsGetToaGpsNanosecondsOfWeek);
2643     jobject singleSatCorrectionList = env->CallObjectMethod(correctionsObj,
2644         method_correctionsGetSingleSatCorrectionList);
2645 
2646     auto len = (singleSatCorrectionList == nullptr)
2647         ? 0
2648         : env->CallIntMethod(singleSatCorrectionList, method_listSize);
2649     if (len == 0) {
2650         ALOGI("Empty correction list injected....Returning with no HAL injection");
2651         return JNI_TRUE;
2652     }
2653     hidl_vec<SingleSatCorrection> list(len);
2654 
2655     for (uint16_t i = 0; i < len; ++i) {
2656         jobject singleSatCorrectionObj = env->CallObjectMethod(
2657             singleSatCorrectionList, method_correctionListGet, i);
2658 
2659         jint correctionFlags =
2660             env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags);
2661         jint constType = env->CallIntMethod(singleSatCorrectionObj,
2662             method_correctionSatConstType);
2663         jint satId =
2664             env->CallIntMethod(singleSatCorrectionObj, method_correctionSatId);
2665         jfloat carrierFreqHz = env->CallFloatMethod(
2666             singleSatCorrectionObj, method_correctionSatCarrierFreq);
2667         jfloat probSatIsLos = env->CallFloatMethod(singleSatCorrectionObj,
2668             method_correctionSatIsLosProb);
2669         jfloat eplMeters =
2670             env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl);
2671         jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj,
2672             method_correctionSatEplUnc);
2673         uint16_t corrFlags = static_cast<uint16_t>(correctionFlags);
2674         jobject reflectingPlaneObj;
2675         bool has_ref_plane = (corrFlags & GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE) != 0;
2676         if (has_ref_plane) {
2677             reflectingPlaneObj = env->CallObjectMethod(
2678                 singleSatCorrectionObj, method_correctionSatRefPlane);
2679         }
2680 
2681         ReflectingPlane reflectingPlane;
2682         if (has_ref_plane) {
2683             jdouble latitudeDegreesRefPlane = env->CallDoubleMethod(
2684                 reflectingPlaneObj, method_correctionPlaneLatDeg);
2685             jdouble longitudeDegreesRefPlane = env->CallDoubleMethod(
2686                 reflectingPlaneObj, method_correctionPlaneLngDeg);
2687             jdouble altitudeDegreesRefPlane = env->CallDoubleMethod(
2688                 reflectingPlaneObj, method_correctionPlaneAltDeg);
2689             jdouble azimuthDegreeRefPlane = env->CallDoubleMethod(
2690                 reflectingPlaneObj, method_correctionPlaneAzimDeg);
2691             reflectingPlane = {
2692                 .latitudeDegrees = latitudeDegreesRefPlane,
2693                 .longitudeDegrees = longitudeDegreesRefPlane,
2694                 .altitudeMeters = altitudeDegreesRefPlane,
2695                 .azimuthDegrees = azimuthDegreeRefPlane,
2696             };
2697         }
2698 
2699         SingleSatCorrection singleSatCorrection = {
2700             .singleSatCorrectionFlags = corrFlags,
2701             .constellation = static_cast<GnssConstellationType>(constType),
2702             .svid = static_cast<uint16_t>(satId),
2703             .carrierFrequencyHz = carrierFreqHz,
2704             .probSatIsLos = probSatIsLos,
2705             .excessPathLengthMeters = eplMeters,
2706             .excessPathLengthUncertaintyMeters = eplUncMeters,
2707             .reflectingPlane = reflectingPlane,
2708         };
2709         list[i] = singleSatCorrection;
2710     }
2711     MeasurementCorrections measurementCorrections = {
2712         .latitudeDegrees = latitudeDegreesCorr,
2713         .longitudeDegrees = longitudeDegreesCorr,
2714         .altitudeMeters = altitudeDegreesCorr,
2715         .horizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters,
2716         .verticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters,
2717         .toaGpsNanosecondsOfWeek = static_cast<uint64_t>(toaGpsNanosOfWeek),
2718         .satCorrections = list,
2719     };
2720 
2721     gnssCorrectionsIface->setCorrections(measurementCorrections);
2722     return JNI_TRUE;
2723 }
2724 
android_location_GnssNavigationMessageProvider_is_navigation_message_supported(JNIEnv * env,jclass clazz)2725 static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
2726         JNIEnv* env,
2727         jclass clazz) {
2728     if (gnssNavigationMessageIface != nullptr) {
2729         return JNI_TRUE;
2730     }
2731     return JNI_FALSE;
2732 }
2733 
android_location_GnssNavigationMessageProvider_start_navigation_message_collection(JNIEnv * env,jobject obj)2734 static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
2735         JNIEnv* env,
2736         jobject obj) {
2737     if (gnssNavigationMessageIface == nullptr) {
2738         ALOGE("Navigation Message interface is not available.");
2739         return JNI_FALSE;
2740     }
2741 
2742     sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
2743             new GnssNavigationMessageCallback();
2744     IGnssNavigationMessage::GnssNavigationMessageStatus result =
2745             gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
2746 
2747     if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
2748         ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
2749         return JNI_FALSE;
2750     }
2751 
2752     return JNI_TRUE;
2753 }
2754 
android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(JNIEnv * env,jobject obj)2755 static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
2756         JNIEnv* env,
2757         jobject obj) {
2758     if (gnssNavigationMessageIface == nullptr) {
2759         ALOGE("Navigation Message interface is not available.");
2760         return JNI_FALSE;
2761     }
2762 
2763     auto result = gnssNavigationMessageIface->close();
2764     return boolToJbool(result.isOk());
2765 }
2766 
android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv *,jobject,jint emergencySuplPdn)2767 static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*,
2768                                                                           jobject,
2769                                                                           jint emergencySuplPdn) {
2770     if (gnssConfigurationIface == nullptr) {
2771         ALOGE("no GNSS configuration interface available");
2772         return JNI_FALSE;
2773     }
2774 
2775     auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
2776     if (result.isOk()) {
2777         return result;
2778     } else {
2779         return JNI_FALSE;
2780     }
2781 }
2782 
android_location_GnssConfiguration_set_supl_version(JNIEnv *,jobject,jint version)2783 static jboolean android_location_GnssConfiguration_set_supl_version(JNIEnv*,
2784                                                                     jobject,
2785                                                                     jint version) {
2786     if (gnssConfigurationIface == nullptr) {
2787         ALOGE("no GNSS configuration interface available");
2788         return JNI_FALSE;
2789     }
2790     auto result = gnssConfigurationIface->setSuplVersion(version);
2791     if (result.isOk()) {
2792         return result;
2793     } else {
2794         return JNI_FALSE;
2795     }
2796 }
2797 
android_location_GnssConfiguration_set_supl_es(JNIEnv *,jobject,jint suplEs)2798 static jboolean android_location_GnssConfiguration_set_supl_es(JNIEnv*,
2799                                                                jobject,
2800                                                                jint suplEs) {
2801     if (gnssConfigurationIface_V2_0 != nullptr) {
2802         ALOGI("Config parameter SUPL_ES is deprecated in IGnssConfiguration.hal version 2.0.");
2803         return JNI_FALSE;
2804     }
2805 
2806     if (gnssConfigurationIface == nullptr) {
2807         ALOGE("no GNSS configuration interface available");
2808         return JNI_FALSE;
2809     }
2810 
2811     auto result = gnssConfigurationIface->setSuplEs(suplEs);
2812     if (result.isOk()) {
2813         return result;
2814     } else {
2815         return JNI_FALSE;
2816     }
2817 }
2818 
android_location_GnssConfiguration_set_supl_mode(JNIEnv *,jobject,jint mode)2819 static jboolean android_location_GnssConfiguration_set_supl_mode(JNIEnv*,
2820                                                                  jobject,
2821                                                                  jint mode) {
2822     if (gnssConfigurationIface == nullptr) {
2823         ALOGE("no GNSS configuration interface available");
2824         return JNI_FALSE;
2825     }
2826 
2827     auto result = gnssConfigurationIface->setSuplMode(mode);
2828     if (result.isOk()) {
2829         return result;
2830     } else {
2831         return JNI_FALSE;
2832     }
2833 }
2834 
android_location_GnssConfiguration_set_gps_lock(JNIEnv *,jobject,jint gpsLock)2835 static jboolean android_location_GnssConfiguration_set_gps_lock(JNIEnv*,
2836                                                                 jobject,
2837                                                                 jint gpsLock) {
2838     if (gnssConfigurationIface_V2_0 != nullptr) {
2839         ALOGI("Config parameter GPS_LOCK is deprecated in IGnssConfiguration.hal version 2.0.");
2840         return JNI_FALSE;
2841     }
2842 
2843     if (gnssConfigurationIface == nullptr) {
2844         ALOGE("no GNSS configuration interface available");
2845         return JNI_FALSE;
2846     }
2847 
2848     auto result = gnssConfigurationIface->setGpsLock(gpsLock);
2849     if (result.isOk()) {
2850         return result;
2851     } else {
2852         return JNI_FALSE;
2853     }
2854 }
2855 
android_location_GnssConfiguration_set_lpp_profile(JNIEnv *,jobject,jint lppProfile)2856 static jboolean android_location_GnssConfiguration_set_lpp_profile(JNIEnv*,
2857                                                                    jobject,
2858                                                                    jint lppProfile) {
2859     if (gnssConfigurationIface == nullptr) {
2860         ALOGE("no GNSS configuration interface available");
2861         return JNI_FALSE;
2862     }
2863 
2864     auto result = gnssConfigurationIface->setLppProfile(lppProfile);
2865 
2866     if (result.isOk()) {
2867         return result;
2868     } else {
2869         return JNI_FALSE;
2870     }
2871 }
2872 
android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv *,jobject,jint gnssPosProtocol)2873 static jboolean android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv*,
2874                                                                             jobject,
2875                                                                             jint gnssPosProtocol) {
2876     if (gnssConfigurationIface == nullptr) {
2877         ALOGE("no GNSS configuration interface available");
2878         return JNI_FALSE;
2879     }
2880 
2881     auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
2882     if (result.isOk()) {
2883         return result;
2884     } else {
2885         return JNI_FALSE;
2886     }
2887 }
2888 
android_location_GnssConfiguration_set_satellite_blacklist(JNIEnv * env,jobject,jintArray constellations,jintArray sv_ids)2889 static jboolean android_location_GnssConfiguration_set_satellite_blacklist(
2890         JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2891     if (gnssConfigurationIface_V1_1 == nullptr) {
2892         ALOGI("No GNSS Satellite Blacklist interface available");
2893         return JNI_FALSE;
2894     }
2895 
2896     jint *constellation_array = env->GetIntArrayElements(constellations, 0);
2897     if (nullptr == constellation_array) {
2898         ALOGI("GetIntArrayElements returns nullptr.");
2899         return JNI_FALSE;
2900     }
2901     jsize length = env->GetArrayLength(constellations);
2902 
2903     jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
2904     if (nullptr == sv_id_array) {
2905         ALOGI("GetIntArrayElements returns nullptr.");
2906         return JNI_FALSE;
2907     }
2908 
2909     if (length != env->GetArrayLength(sv_ids)) {
2910         ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2911         return JNI_FALSE;
2912     }
2913 
2914     hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2915     sources.resize(length);
2916 
2917     for (int i = 0; i < length; i++) {
2918         sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2919         sources[i].svid = sv_id_array[i];
2920     }
2921 
2922     auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2923     if (result.isOk()) {
2924         return result;
2925     } else {
2926         return JNI_FALSE;
2927     }
2928 }
2929 
android_location_GnssConfiguration_set_es_extension_sec(JNIEnv *,jobject,jint emergencyExtensionSeconds)2930 static jboolean android_location_GnssConfiguration_set_es_extension_sec(
2931         JNIEnv*, jobject, jint emergencyExtensionSeconds) {
2932     if (gnssConfigurationIface == nullptr) {
2933         ALOGE("no GNSS configuration interface available");
2934         return JNI_FALSE;
2935     }
2936 
2937     if (gnssConfigurationIface_V2_0 == nullptr) {
2938         ALOGI("Config parameter ES_EXTENSION_SEC is not supported in IGnssConfiguration.hal"
2939                 " versions earlier than 2.0.");
2940         return JNI_FALSE;
2941     }
2942 
2943     auto result = gnssConfigurationIface_V2_0->setEsExtensionSec(emergencyExtensionSeconds);
2944     if (result.isOk()) {
2945         return result;
2946     } else {
2947         return JNI_FALSE;
2948     }
2949 }
2950 
android_location_GnssBatchingProvider_get_batch_size(JNIEnv *,jclass)2951 static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
2952     if (gnssBatchingIface == nullptr) {
2953         return 0; // batching not supported, size = 0
2954     }
2955     auto result = gnssBatchingIface->getBatchSize();
2956     if (result.isOk()) {
2957         return static_cast<jint>(result);
2958     } else {
2959         return 0; // failure in binder, don't support batching
2960     }
2961 }
2962 
android_location_GnssBatchingProvider_init_batching(JNIEnv *,jclass)2963 static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
2964     if (gnssBatchingIface_V2_0 != nullptr) {
2965         sp<IGnssBatchingCallback_V2_0> gnssBatchingCbIface_V2_0 = new GnssBatchingCallback_V2_0();
2966         return static_cast<jboolean>(gnssBatchingIface_V2_0->init_2_0(gnssBatchingCbIface_V2_0));
2967     } else if (gnssBatchingIface != nullptr) {
2968         sp<IGnssBatchingCallback_V1_0> gnssBatchingCbIface_V1_0 = new GnssBatchingCallback_V1_0();
2969         return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface_V1_0));
2970     } else {
2971         return JNI_FALSE; // batching not supported
2972     }
2973 }
2974 
android_location_GnssBatchingProvider_cleanup_batching(JNIEnv *,jclass)2975 static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
2976     if (gnssBatchingIface == nullptr) {
2977         return; // batching not supported
2978     }
2979     gnssBatchingIface->cleanup();
2980 }
2981 
android_location_GnssBatchingProvider_start_batch(JNIEnv *,jclass,jlong periodNanos,jboolean wakeOnFifoFull)2982 static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
2983         jlong periodNanos, jboolean wakeOnFifoFull) {
2984     if (gnssBatchingIface == nullptr) {
2985         return JNI_FALSE; // batching not supported
2986     }
2987 
2988     IGnssBatching_V1_0::Options options;
2989     options.periodNanos = periodNanos;
2990     if (wakeOnFifoFull) {
2991         options.flags = static_cast<uint8_t>(IGnssBatching_V1_0::Flag::WAKEUP_ON_FIFO_FULL);
2992     } else {
2993         options.flags = 0;
2994     }
2995 
2996     return static_cast<jboolean>(gnssBatchingIface->start(options));
2997 }
2998 
android_location_GnssBatchingProvider_flush_batch(JNIEnv *,jclass)2999 static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
3000     if (gnssBatchingIface == nullptr) {
3001         return; // batching not supported
3002     }
3003 
3004     gnssBatchingIface->flush();
3005 }
3006 
android_location_GnssBatchingProvider_stop_batch(JNIEnv *,jclass)3007 static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
3008     if (gnssBatchingIface == nullptr) {
3009         return JNI_FALSE; // batching not supported
3010     }
3011 
3012     return gnssBatchingIface->stop();
3013 }
3014 
android_location_GnssVisibilityControl_enable_nfw_location_access(JNIEnv * env,jobject,jobjectArray proxyApps)3015 static jboolean android_location_GnssVisibilityControl_enable_nfw_location_access(
3016         JNIEnv* env, jobject, jobjectArray proxyApps) {
3017     if (gnssVisibilityControlIface == nullptr) {
3018         ALOGI("No GNSS Visibility Control interface available");
3019         return JNI_FALSE;
3020     }
3021 
3022     const jsize length = env->GetArrayLength(proxyApps);
3023     hidl_vec<hidl_string> hidlProxyApps(length);
3024     for (int i = 0; i < length; ++i) {
3025         jstring proxyApp = (jstring) (env->GetObjectArrayElement(proxyApps, i));
3026         ScopedJniString jniProxyApp(env, proxyApp);
3027         hidlProxyApps[i] = jniProxyApp;
3028     }
3029 
3030     auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps);
3031     if (result.isOk()) {
3032         return result;
3033     } else {
3034         return JNI_FALSE;
3035     }
3036 }
3037 
3038 static const JNINativeMethod sMethods[] = {
3039      /* name, signature, funcPtr */
3040     {"class_init_native", "()V", reinterpret_cast<void *>(
3041             android_location_GnssLocationProvider_class_init_native)},
3042     {"native_is_supported", "()Z", reinterpret_cast<void *>(
3043             android_location_GnssLocationProvider_is_supported)},
3044     {"native_init_once", "(Z)V", reinterpret_cast<void *>(
3045             android_location_GnssLocationProvider_init_once)},
3046     {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
3047     {"native_cleanup", "()V", reinterpret_cast<void *>(
3048             android_location_GnssLocationProvider_cleanup)},
3049     {"native_set_position_mode", "(IIIIIZ)Z", reinterpret_cast<void *>(
3050             android_location_GnssLocationProvider_set_position_mode)},
3051     {"native_start", "()Z", reinterpret_cast<void *>(
3052             android_location_GnssLocationProvider_start)},
3053     {"native_stop", "()Z", reinterpret_cast<void *>(
3054             android_location_GnssLocationProvider_stop)},
3055     {"native_delete_aiding_data", "(I)V", reinterpret_cast<void *>(
3056             android_location_GnssLocationProvider_delete_aiding_data)},
3057     {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
3058             android_location_GnssLocationProvider_read_nmea)},
3059     {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
3060             android_location_GnssLocationProvider_inject_time)},
3061     {"native_inject_best_location", "(IDDDFFFFFFJIJD)V", reinterpret_cast<void *>(
3062             android_location_GnssLocationProvider_inject_best_location)},
3063     {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
3064             android_location_GnssLocationProvider_inject_location)},
3065     {"native_supports_psds", "()Z", reinterpret_cast<void *>(
3066             android_location_GnssLocationProvider_supports_psds)},
3067     {"native_inject_psds_data", "([BI)V", reinterpret_cast<void *>(
3068             android_location_GnssLocationProvider_inject_psds_data)},
3069     {"native_agps_set_id", "(ILjava/lang/String;)V", reinterpret_cast<void *>(
3070             android_location_GnssLocationProvider_agps_set_id)},
3071     {"native_agps_set_ref_location_cellid", "(IIIII)V", reinterpret_cast<void *>(
3072             android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
3073     {"native_set_agps_server", "(ILjava/lang/String;I)V", reinterpret_cast<void *>(
3074             android_location_GnssLocationProvider_set_agps_server)},
3075     {"native_send_ni_response", "(II)V", reinterpret_cast<void *>(
3076             android_location_GnssLocationProvider_send_ni_response)},
3077     {"native_get_internal_state", "()Ljava/lang/String;", reinterpret_cast<void *>(
3078             android_location_GnssLocationProvider_get_internal_state)},
3079     {"native_is_gnss_visibility_control_supported", "()Z", reinterpret_cast<void *>(
3080             android_location_GnssLocationProvider_is_gnss_visibility_control_supported)},
3081 };
3082 
3083 static const JNINativeMethod sMethodsBatching[] = {
3084      /* name, signature, funcPtr */
3085     {"native_get_batch_size",
3086             "()I",
3087             reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
3088     {"native_start_batch",
3089             "(JZ)Z",
3090             reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
3091     {"native_flush_batch",
3092             "()V",
3093             reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
3094     {"native_stop_batch",
3095             "()Z",
3096             reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
3097     {"native_init_batching",
3098             "()Z",
3099             reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
3100     {"native_cleanup_batching",
3101             "()V",
3102             reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
3103 };
3104 
3105 static const JNINativeMethod sGeofenceMethods[] = {
3106      /* name, signature, funcPtr */
3107     {"native_is_geofence_supported",
3108             "()Z",
3109             reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
3110     {"native_add_geofence",
3111             "(IDDDIIII)Z",
3112             reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
3113     {"native_remove_geofence",
3114             "(I)Z",
3115             reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
3116     {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
3117             android_location_GnssGeofenceProvider_pause_geofence)},
3118     {"native_resume_geofence",
3119             "(II)Z",
3120             reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
3121 };
3122 
3123 static const JNINativeMethod sMeasurementMethods[] = {
3124     /* name, signature, funcPtr */
3125     {"native_is_measurement_supported", "()Z",
3126             reinterpret_cast<void*>(
3127             android_location_GnssMeasurementsProvider_is_measurement_supported)},
3128     {"native_start_measurement_collection", "(Z)Z",
3129             reinterpret_cast<void*>(
3130             android_location_GnssMeasurementsProvider_start_measurement_collection)},
3131     {"native_stop_measurement_collection", "()Z",
3132             reinterpret_cast<void*>(
3133             android_location_GnssMeasurementsProvider_stop_measurement_collection)},
3134 };
3135 
3136 static const JNINativeMethod sMeasurementCorrectionsMethods[] = {
3137     /* name, signature, funcPtr */
3138     {"native_is_measurement_corrections_supported", "()Z",
3139             reinterpret_cast<void*>(
3140             android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported)},
3141     {"native_inject_gnss_measurement_corrections",
3142             "(Landroid/location/GnssMeasurementCorrections;)Z",
3143             reinterpret_cast<void*>(
3144             android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections)},
3145 };
3146 
3147 static const JNINativeMethod sNavigationMessageMethods[] = {
3148      /* name, signature, funcPtr */
3149     {"native_is_navigation_message_supported",
3150             "()Z",
3151             reinterpret_cast<void *>(
3152                     android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
3153     {"native_start_navigation_message_collection",
3154             "()Z",
3155             reinterpret_cast<void *>(
3156                     android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
3157     {"native_stop_navigation_message_collection",
3158             "()Z",
3159             reinterpret_cast<void *>(
3160                     android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
3161 };
3162 
3163 static const JNINativeMethod sNetworkConnectivityMethods[] = {
3164      /* name, signature, funcPtr */
3165     {"native_is_agps_ril_supported", "()Z",
3166             reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
3167     {"native_update_network_state",
3168             "(ZIZZLjava/lang/String;JS)V",
3169             reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
3170     {"native_agps_data_conn_open",
3171             "(JLjava/lang/String;I)V",
3172             reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
3173     {"native_agps_data_conn_closed",
3174             "()V",
3175             reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
3176     {"native_agps_data_conn_failed",
3177             "()V",
3178             reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
3179 };
3180 
3181 static const JNINativeMethod sConfigurationMethods[] = {
3182      /* name, signature, funcPtr */
3183     {"native_get_gnss_configuration_version",
3184             "()Lcom/android/server/location/GnssConfiguration$HalInterfaceVersion;",
3185             reinterpret_cast<void *>(
3186                     android_location_GnssConfiguration_get_gnss_configuration_version)},
3187     {"native_set_supl_es",
3188             "(I)Z",
3189             reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_es)},
3190     {"native_set_supl_version",
3191             "(I)Z",
3192             reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_version)},
3193     {"native_set_supl_mode",
3194             "(I)Z",
3195             reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_mode)},
3196     {"native_set_lpp_profile",
3197             "(I)Z",
3198             reinterpret_cast<void *>(android_location_GnssConfiguration_set_lpp_profile)},
3199     {"native_set_gnss_pos_protocol_select",
3200             "(I)Z",
3201             reinterpret_cast<void *>(
3202                     android_location_GnssConfiguration_set_gnss_pos_protocol_select)},
3203     {"native_set_gps_lock",
3204             "(I)Z",
3205             reinterpret_cast<void *>(android_location_GnssConfiguration_set_gps_lock)},
3206     {"native_set_emergency_supl_pdn",
3207             "(I)Z",
3208             reinterpret_cast<void *>(android_location_GnssConfiguration_set_emergency_supl_pdn)},
3209     {"native_set_satellite_blacklist",
3210             "([I[I)Z",
3211             reinterpret_cast<void *>(android_location_GnssConfiguration_set_satellite_blacklist)},
3212     {"native_set_es_extension_sec",
3213             "(I)Z",
3214             reinterpret_cast<void *>(android_location_GnssConfiguration_set_es_extension_sec)},
3215 };
3216 
3217 static const JNINativeMethod sVisibilityControlMethods[] = {
3218      /* name, signature, funcPtr */
3219     {"native_enable_nfw_location_access",
3220             "([Ljava/lang/String;)Z",
3221             reinterpret_cast<void *>(
3222                     android_location_GnssVisibilityControl_enable_nfw_location_access)},
3223 };
3224 
register_android_server_location_GnssLocationProvider(JNIEnv * env)3225 int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
3226     jniRegisterNativeMethods(
3227             env,
3228             "com/android/server/location/GnssBatchingProvider",
3229             sMethodsBatching,
3230             NELEM(sMethodsBatching));
3231     jniRegisterNativeMethods(
3232             env,
3233             "com/android/server/location/GnssGeofenceProvider",
3234             sGeofenceMethods,
3235             NELEM(sGeofenceMethods));
3236     jniRegisterNativeMethods(
3237             env,
3238             "com/android/server/location/GnssMeasurementsProvider",
3239             sMeasurementMethods,
3240             NELEM(sMeasurementMethods));
3241     jniRegisterNativeMethods(
3242             env,
3243             "com/android/server/location/GnssMeasurementCorrectionsProvider",
3244             sMeasurementCorrectionsMethods,
3245             NELEM(sMeasurementCorrectionsMethods));
3246     jniRegisterNativeMethods(
3247             env,
3248             "com/android/server/location/GnssNavigationMessageProvider",
3249             sNavigationMessageMethods,
3250             NELEM(sNavigationMessageMethods));
3251     jniRegisterNativeMethods(
3252             env,
3253             "com/android/server/location/GnssNetworkConnectivityHandler",
3254             sNetworkConnectivityMethods,
3255             NELEM(sNetworkConnectivityMethods));
3256     jniRegisterNativeMethods(
3257             env,
3258             "com/android/server/location/GnssConfiguration",
3259             sConfigurationMethods,
3260             NELEM(sConfigurationMethods));
3261     jniRegisterNativeMethods(
3262             env,
3263             "com/android/server/location/GnssVisibilityControl",
3264             sVisibilityControlMethods,
3265             NELEM(sVisibilityControlMethods));
3266     return jniRegisterNativeMethods(
3267             env,
3268             "com/android/server/location/GnssLocationProvider",
3269             sMethods,
3270             NELEM(sMethods));
3271 }
3272 
3273 } /* namespace android */
3274