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