• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 #include "JNIHelp.h"
24 #include "jni.h"
25 #include "hardware_legacy/power.h"
26 #include "utils/Log.h"
27 #include "utils/misc.h"
28 #include "android_runtime/AndroidRuntime.h"
29 #include "android_runtime/Log.h"
30 
31 #include <arpa/inet.h>
32 #include <limits>
33 #include <linux/in.h>
34 #include <linux/in6.h>
35 #include <pthread.h>
36 #include <string.h>
37 #include <cinttypes>
38 
39 static jobject mCallbacksObj = NULL;
40 
41 static jmethodID method_reportLocation;
42 static jmethodID method_reportStatus;
43 static jmethodID method_reportSvStatus;
44 static jmethodID method_reportAGpsStatus;
45 static jmethodID method_reportNmea;
46 static jmethodID method_setEngineCapabilities;
47 static jmethodID method_setGnssYearOfHardware;
48 static jmethodID method_xtraDownloadRequest;
49 static jmethodID method_reportNiNotification;
50 static jmethodID method_requestRefLocation;
51 static jmethodID method_requestSetID;
52 static jmethodID method_requestUtcTime;
53 static jmethodID method_reportGeofenceTransition;
54 static jmethodID method_reportGeofenceStatus;
55 static jmethodID method_reportGeofenceAddStatus;
56 static jmethodID method_reportGeofenceRemoveStatus;
57 static jmethodID method_reportGeofencePauseStatus;
58 static jmethodID method_reportGeofenceResumeStatus;
59 static jmethodID method_reportMeasurementData;
60 static jmethodID method_reportNavigationMessages;
61 static jmethodID method_reportLocationBatch;
62 
63 /*
64  * Save a pointer to JavaVm to attach/detach threads executing
65  * callback methods that need to make JNI calls.
66  */
67 static JavaVM* sJvm;
68 
69 using android::OK;
70 using android::sp;
71 using android::wp;
72 using android::status_t;
73 using android::String16;
74 
75 using android::hardware::Return;
76 using android::hardware::Void;
77 using android::hardware::hidl_vec;
78 using android::hardware::hidl_death_recipient;
79 using android::hidl::base::V1_0::IBase;
80 
81 using android::hardware::gnss::V1_0::IAGnss;
82 using android::hardware::gnss::V1_0::IAGnssCallback;
83 using android::hardware::gnss::V1_0::IAGnssCallback;
84 using android::hardware::gnss::V1_0::IAGnssRil;
85 using android::hardware::gnss::V1_0::IAGnssRilCallback;
86 using android::hardware::gnss::V1_0::IGnss;
87 using android::hardware::gnss::V1_0::IGnssBatching;
88 using android::hardware::gnss::V1_0::IGnssBatchingCallback;
89 using android::hardware::gnss::V1_0::IGnssCallback;
90 using android::hardware::gnss::V1_0::IGnssConfiguration;
91 using android::hardware::gnss::V1_0::IGnssDebug;
92 using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
93 using android::hardware::gnss::V1_0::IGnssGeofencing;
94 using android::hardware::gnss::V1_0::IGnssMeasurement;
95 using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
96 using android::hardware::gnss::V1_0::IGnssNavigationMessage;
97 using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
98 using android::hardware::gnss::V1_0::IGnssNi;
99 using android::hardware::gnss::V1_0::IGnssNiCallback;
100 using android::hardware::gnss::V1_0::IGnssXtra;
101 using android::hardware::gnss::V1_0::IGnssXtraCallback;
102 
103 struct GnssDeathRecipient : virtual public hidl_death_recipient
104 {
105     // hidl_death_recipient interface
serviceDiedGnssDeathRecipient106     virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
107       // TODO(gomo): implement a better death recovery mechanism without
108       // crashing system server process as described in go//treble-gnss-death
109       LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
110             " restarting system server");
111     }
112 };
113 
114 sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
115 sp<IGnss> gnssHal = nullptr;
116 sp<IGnssXtra> gnssXtraIface = nullptr;
117 sp<IAGnssRil> agnssRilIface = nullptr;
118 sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
119 sp<IAGnss> agnssIface = nullptr;
120 sp<IGnssBatching> gnssBatchingIface = nullptr;
121 sp<IGnssDebug> gnssDebugIface = nullptr;
122 sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
123 sp<IGnssNi> gnssNiIface = nullptr;
124 sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
125 sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
126 
127 #define WAKE_LOCK_NAME  "GPS"
128 
129 namespace android {
130 
131 template<class T>
132 class JavaMethodHelper {
133  public:
134     // Helper function to call setter on a Java object.
135     static void callJavaMethod(
136            JNIEnv* env,
137            jclass clazz,
138            jobject object,
139            const char* method_name,
140            T value);
141 
142  private:
143     static const char *const signature_;
144 };
145 
146 template<class T>
callJavaMethod(JNIEnv * env,jclass clazz,jobject object,const char * method_name,T value)147 void JavaMethodHelper<T>::callJavaMethod(
148         JNIEnv* env,
149         jclass clazz,
150         jobject object,
151         const char* method_name,
152         T value) {
153     jmethodID method = env->GetMethodID(clazz, method_name, signature_);
154     env->CallVoidMethod(object, method, value);
155 }
156 
157 class JavaObject {
158  public:
159     JavaObject(JNIEnv* env, const char* class_name);
160     JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
161     virtual ~JavaObject();
162 
163     template<class T>
164     void callSetter(const char* method_name, T value);
165     template<class T>
166     void callSetter(const char* method_name, T* value, size_t size);
167     jobject get();
168 
169  private:
170     JNIEnv* env_;
171     jclass clazz_;
172     jobject object_;
173 };
174 
JavaObject(JNIEnv * env,const char * class_name)175 JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
176     clazz_ = env_->FindClass(class_name);
177     jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
178     object_ = env_->NewObject(clazz_, ctor);
179 }
180 
JavaObject(JNIEnv * env,const char * class_name,const char * sz_arg_1)181 JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
182     clazz_ = env_->FindClass(class_name);
183     jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
184     object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
185 }
186 
~JavaObject()187 JavaObject::~JavaObject() {
188     env_->DeleteLocalRef(clazz_);
189 }
190 
191 template<class T>
callSetter(const char * method_name,T value)192 void JavaObject::callSetter(const char* method_name, T value) {
193     JavaMethodHelper<T>::callJavaMethod(
194             env_, clazz_, object_, method_name, value);
195 }
196 
197 template<>
callSetter(const char * method_name,uint8_t * value,size_t size)198 void JavaObject::callSetter(
199         const char* method_name, uint8_t* value, size_t size) {
200     jbyteArray array = env_->NewByteArray(size);
201     env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
202     jmethodID method = env_->GetMethodID(
203             clazz_,
204             method_name,
205             "([B)V");
206     env_->CallVoidMethod(object_, method, array);
207     env_->DeleteLocalRef(array);
208 }
209 
get()210 jobject JavaObject::get() {
211     return object_;
212 }
213 
214 // Define Java method signatures for all known types.
215 template<>
216 const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
217 template<>
218 const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
219 template<>
220 const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
221 template<>
222 const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
223 template<>
224 const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
225 template<>
226 const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
227 template<>
228 const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
229 template<>
230 const char *const JavaMethodHelper<float>::signature_ = "(F)V";
231 template<>
232 const char *const JavaMethodHelper<double>::signature_ = "(D)V";
233 template<>
234 const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
235 
236 #define SET(setter, value) object.callSetter("set" # setter, (value))
237 
boolToJbool(bool value)238 static inline jboolean boolToJbool(bool value) {
239     return value ? JNI_TRUE : JNI_FALSE;
240 }
241 
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)242 static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
243     if (env->ExceptionCheck()) {
244         ALOGE("An exception was thrown by callback '%s'.", methodName);
245         LOGE_EX(env);
246         env->ExceptionClear();
247     }
248 }
249 
250 class ScopedJniThreadAttach {
251 public:
ScopedJniThreadAttach()252     ScopedJniThreadAttach() {
253         /*
254          * attachResult will also be JNI_OK if the thead was already attached to
255          * JNI before the call to AttachCurrentThread().
256          */
257         jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
258         LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
259                             attachResult);
260     }
261 
~ScopedJniThreadAttach()262     ~ScopedJniThreadAttach() {
263         jint detachResult = sJvm->DetachCurrentThread();
264         /*
265          * Return if the thread was already detached. Log error for any other
266          * failure.
267          */
268         if (detachResult == JNI_EDETACHED) {
269             return;
270         }
271 
272         LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
273                             detachResult);
274     }
275 
getEnv()276     JNIEnv* getEnv() {
277         /*
278          * Checking validity of mEnv in case the thread was detached elsewhere.
279          */
280         LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
281         return mEnv;
282     }
283 
284 private:
285     JNIEnv* mEnv = nullptr;
286 };
287 
288 thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
289 
getJniEnv()290 static JNIEnv* getJniEnv() {
291     JNIEnv* env = AndroidRuntime::getJNIEnv();
292 
293     /*
294      * If env is nullptr, the thread is not already attached to
295      * JNI. It is attached below and the destructor for ScopedJniThreadAttach
296      * will detach it on thread exit.
297      */
298     if (env == nullptr) {
299         tJniThreadAttacher.reset(new ScopedJniThreadAttach());
300         env = tJniThreadAttacher->getEnv();
301     }
302 
303     return env;
304 }
305 
translateLocation(JNIEnv * env,const hardware::gnss::V1_0::GnssLocation & location)306 static jobject translateLocation(JNIEnv* env, const hardware::gnss::V1_0::GnssLocation& location) {
307     JavaObject object(env, "android/location/Location", "gps");
308 
309     uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
310     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) {
311         SET(Latitude, location.latitudeDegrees);
312         SET(Longitude, location.longitudeDegrees);
313     }
314     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) {
315         SET(Altitude, location.altitudeMeters);
316     }
317     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) {
318         SET(Speed, location.speedMetersPerSec);
319     }
320     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) {
321         SET(Bearing, location.bearingDegrees);
322     }
323     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
324         SET(Accuracy, location.horizontalAccuracyMeters);
325     }
326     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
327         SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
328     }
329     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
330         SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
331     }
332     if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
333         SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
334     }
335     SET(Time, location.timestamp);
336 
337     return object.get();
338 }
339 
340 /*
341  * GnssCallback class implements the callback methods for IGnss interface.
342  */
343 struct GnssCallback : public IGnssCallback {
344     Return<void> gnssLocationCb(
345           const android::hardware::gnss::V1_0::GnssLocation& location) override;
346     Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
347     Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
348     Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
349     Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
350     Return<void> gnssAcquireWakelockCb() override;
351     Return<void> gnssReleaseWakelockCb() override;
352     Return<void> gnssRequestTimeCb() override;
353     Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
354 
355     static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
356             android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
357     static size_t sGnssSvListSize;
358 
359     static const char* sNmeaString;
360     static size_t sNmeaStringLength;
361 };
362 
363 IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
364         android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
365 const char* GnssCallback::sNmeaString = nullptr;
366 size_t GnssCallback::sNmeaStringLength = 0;
367 size_t GnssCallback::sGnssSvListSize = 0;
368 
gnssLocationCb(const::android::hardware::gnss::V1_0::GnssLocation & location)369 Return<void> GnssCallback::gnssLocationCb(
370         const ::android::hardware::gnss::V1_0::GnssLocation& location) {
371     JNIEnv* env = getJniEnv();
372 
373     jobject jLocation = translateLocation(env, location);
374     bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
375             hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) != 0;
376 
377     env->CallVoidMethod(mCallbacksObj,
378                         method_reportLocation,
379                         boolToJbool(hasLatLong),
380                         jLocation);
381     checkAndClearExceptionFromCallback(env, __FUNCTION__);
382     return Void();
383 }
384 
gnssStatusCb(const IGnssCallback::GnssStatusValue status)385 Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
386     JNIEnv* env = getJniEnv();
387     env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
388     checkAndClearExceptionFromCallback(env, __FUNCTION__);
389     return Void();
390 }
391 
gnssSvStatusCb(const IGnssCallback::GnssSvStatus & svStatus)392 Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
393     JNIEnv* env = getJniEnv();
394 
395     sGnssSvListSize = svStatus.numSvs;
396     if (sGnssSvListSize > static_cast<uint32_t>(
397             android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
398         ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
399               static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
400         sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
401     }
402 
403     // Copy GNSS SV info into sGnssSvList, if any.
404     if (svStatus.numSvs > 0) {
405         memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
406     }
407 
408     env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
409     checkAndClearExceptionFromCallback(env, __FUNCTION__);
410     return Void();
411 }
412 
gnssNmeaCb(int64_t timestamp,const::android::hardware::hidl_string & nmea)413 Return<void> GnssCallback::gnssNmeaCb(
414     int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
415     JNIEnv* env = getJniEnv();
416     /*
417      * The Java code will call back to read these values.
418      * We do this to avoid creating unnecessary String objects.
419      */
420     sNmeaString = nmea.c_str();
421     sNmeaStringLength = nmea.size();
422 
423     env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
424     checkAndClearExceptionFromCallback(env, __FUNCTION__);
425     return Void();
426 }
427 
gnssSetCapabilitesCb(uint32_t capabilities)428 Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
429     ALOGD("%s: %du\n", __func__, capabilities);
430 
431     JNIEnv* env = getJniEnv();
432     env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
433     checkAndClearExceptionFromCallback(env, __FUNCTION__);
434     return Void();
435 }
436 
gnssAcquireWakelockCb()437 Return<void> GnssCallback::gnssAcquireWakelockCb() {
438     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
439     return Void();
440 }
441 
gnssReleaseWakelockCb()442 Return<void> GnssCallback::gnssReleaseWakelockCb() {
443     release_wake_lock(WAKE_LOCK_NAME);
444     return Void();
445 }
446 
gnssRequestTimeCb()447 Return<void> GnssCallback::gnssRequestTimeCb() {
448     JNIEnv* env = getJniEnv();
449     env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
450     checkAndClearExceptionFromCallback(env, __FUNCTION__);
451     return Void();
452 }
453 
gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo & info)454 Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
455     ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
456 
457     JNIEnv* env = getJniEnv();
458     env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
459                         info.yearOfHw);
460     checkAndClearExceptionFromCallback(env, __FUNCTION__);
461     return Void();
462 }
463 
464 class GnssXtraCallback : public IGnssXtraCallback {
465     Return<void> downloadRequestCb() override;
466 };
467 
468 /*
469  * GnssXtraCallback class implements the callback methods for the IGnssXtra
470  * interface.
471  */
downloadRequestCb()472 Return<void> GnssXtraCallback::downloadRequestCb() {
473     JNIEnv* env = getJniEnv();
474     env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
475     checkAndClearExceptionFromCallback(env, __FUNCTION__);
476     return Void();
477 }
478 
479 /*
480  * GnssGeofenceCallback class implements the callback methods for the
481  * IGnssGeofence interface.
482  */
483 struct GnssGeofenceCallback : public IGnssGeofenceCallback {
484     // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
485     Return<void> gnssGeofenceTransitionCb(
486             int32_t geofenceId,
487             const android::hardware::gnss::V1_0::GnssLocation& location,
488             GeofenceTransition transition,
489             hardware::gnss::V1_0::GnssUtcTime timestamp) override;
490     Return<void> gnssGeofenceStatusCb(
491             GeofenceAvailability status,
492             const android::hardware::gnss::V1_0::GnssLocation& location) override;
493     Return<void> gnssGeofenceAddCb(int32_t geofenceId,
494                                    GeofenceStatus status) override;
495     Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
496                                       GeofenceStatus status) override;
497     Return<void> gnssGeofencePauseCb(int32_t geofenceId,
498                                      GeofenceStatus status) override;
499     Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
500                                       GeofenceStatus status) override;
501 };
502 
gnssGeofenceTransitionCb(int32_t geofenceId,const android::hardware::gnss::V1_0::GnssLocation & location,GeofenceTransition transition,hardware::gnss::V1_0::GnssUtcTime timestamp)503 Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
504         int32_t geofenceId,
505         const android::hardware::gnss::V1_0::GnssLocation& location,
506         GeofenceTransition transition,
507         hardware::gnss::V1_0::GnssUtcTime timestamp) {
508     JNIEnv* env = getJniEnv();
509 
510     jobject jLocation = translateLocation(env, location);
511 
512     env->CallVoidMethod(mCallbacksObj,
513                         method_reportGeofenceTransition,
514                         geofenceId,
515                         jLocation,
516                         transition,
517                         timestamp);
518 
519     checkAndClearExceptionFromCallback(env, __FUNCTION__);
520     return Void();
521 }
522 
gnssGeofenceStatusCb(GeofenceAvailability status,const android::hardware::gnss::V1_0::GnssLocation & location)523 Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
524         GeofenceAvailability status,
525         const android::hardware::gnss::V1_0::GnssLocation& location) {
526     JNIEnv* env = getJniEnv();
527 
528     jobject jLocation = translateLocation(env, location);
529 
530     env->CallVoidMethod(mCallbacksObj,
531                         method_reportGeofenceStatus,
532                         status,
533                         jLocation);
534     checkAndClearExceptionFromCallback(env, __FUNCTION__);
535     return Void();
536 }
537 
gnssGeofenceAddCb(int32_t geofenceId,GeofenceStatus status)538 Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
539                                                     GeofenceStatus status) {
540     JNIEnv* env = getJniEnv();
541     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
542         ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
543     }
544 
545     env->CallVoidMethod(mCallbacksObj,
546                         method_reportGeofenceAddStatus,
547                         geofenceId,
548                         status);
549     checkAndClearExceptionFromCallback(env, __FUNCTION__);
550     return Void();
551 }
552 
gnssGeofenceRemoveCb(int32_t geofenceId,GeofenceStatus status)553 Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
554                                                        GeofenceStatus status) {
555     JNIEnv* env = getJniEnv();
556     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
557         ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
558     }
559 
560     env->CallVoidMethod(mCallbacksObj,
561                         method_reportGeofenceRemoveStatus,
562                         geofenceId, status);
563     checkAndClearExceptionFromCallback(env, __FUNCTION__);
564     return Void();
565 }
566 
gnssGeofencePauseCb(int32_t geofenceId,GeofenceStatus status)567 Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
568                                                       GeofenceStatus status) {
569     JNIEnv* env = getJniEnv();
570     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
571         ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
572     }
573 
574     env->CallVoidMethod(mCallbacksObj,
575                         method_reportGeofencePauseStatus,
576                         geofenceId, status);
577     checkAndClearExceptionFromCallback(env, __FUNCTION__);
578     return Void();
579 }
580 
gnssGeofenceResumeCb(int32_t geofenceId,GeofenceStatus status)581 Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
582                                                        GeofenceStatus status) {
583     JNIEnv* env = getJniEnv();
584     if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
585         ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
586     }
587 
588     env->CallVoidMethod(mCallbacksObj,
589                         method_reportGeofenceResumeStatus,
590                         geofenceId, status);
591     checkAndClearExceptionFromCallback(env, __FUNCTION__);
592     return Void();
593 }
594 
595 /*
596  * GnssNavigationMessageCallback interface implements the callback methods
597  * required by the IGnssNavigationMessage interface.
598  */
599 struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
600   /*
601    * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
602    * follow.
603    */
604   Return<void> gnssNavigationMessageCb(
605           const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
606 };
607 
gnssNavigationMessageCb(const IGnssNavigationMessageCallback::GnssNavigationMessage & message)608 Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
609         const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
610     JNIEnv* env = getJniEnv();
611 
612     size_t dataLength = message.data.size();
613 
614     std::vector<uint8_t> navigationData = message.data;
615     uint8_t* data = &(navigationData[0]);
616     if (dataLength == 0 || data == NULL) {
617       ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
618             dataLength);
619       return Void();
620     }
621 
622     JavaObject object(env, "android/location/GnssNavigationMessage");
623     SET(Type, static_cast<int32_t>(message.type));
624     SET(Svid, static_cast<int32_t>(message.svid));
625     SET(MessageId, static_cast<int32_t>(message.messageId));
626     SET(SubmessageId, static_cast<int32_t>(message.submessageId));
627     object.callSetter("setData", data, dataLength);
628     SET(Status, static_cast<int32_t>(message.status));
629 
630     jobject navigationMessage = object.get();
631     env->CallVoidMethod(mCallbacksObj,
632                         method_reportNavigationMessages,
633                         navigationMessage);
634     checkAndClearExceptionFromCallback(env, __FUNCTION__);
635     env->DeleteLocalRef(navigationMessage);
636     return Void();
637 }
638 
639 /*
640  * GnssMeasurementCallback implements the callback methods required for the
641  * GnssMeasurement interface.
642  */
643 struct GnssMeasurementCallback : public IGnssMeasurementCallback {
644     Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
645  private:
646     jobject translateGnssMeasurement(
647             JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
648     jobject translateGnssClock(
649             JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
650     jobjectArray translateGnssMeasurements(
651             JNIEnv* env,
652             const IGnssMeasurementCallback::GnssMeasurement* measurements,
653             size_t count);
654     void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
655 };
656 
657 
GnssMeasurementCb(const IGnssMeasurementCallback::GnssData & data)658 Return<void> GnssMeasurementCallback::GnssMeasurementCb(
659         const IGnssMeasurementCallback::GnssData& data) {
660     JNIEnv* env = getJniEnv();
661 
662     jobject clock;
663     jobjectArray measurementArray;
664 
665     clock = translateGnssClock(env, &data.clock);
666     measurementArray = translateGnssMeasurements(
667         env, data.measurements.data(), data.measurementCount);
668     setMeasurementData(env, clock, measurementArray);
669 
670     env->DeleteLocalRef(clock);
671     env->DeleteLocalRef(measurementArray);
672     return Void();
673 }
674 
translateGnssMeasurement(JNIEnv * env,const IGnssMeasurementCallback::GnssMeasurement * measurement)675 jobject GnssMeasurementCallback::translateGnssMeasurement(
676         JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
677     JavaObject object(env, "android/location/GnssMeasurement");
678 
679     uint32_t flags = static_cast<uint32_t>(measurement->flags);
680 
681     SET(Svid, static_cast<int32_t>(measurement->svid));
682     SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
683     SET(TimeOffsetNanos, measurement->timeOffsetNs);
684     SET(State, static_cast<int32_t>(measurement->state));
685     SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
686     SET(ReceivedSvTimeUncertaintyNanos,
687         measurement->receivedSvTimeUncertaintyInNs);
688     SET(Cn0DbHz, measurement->cN0DbHz);
689     SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
690     SET(PseudorangeRateUncertaintyMetersPerSecond,
691         measurement->pseudorangeRateUncertaintyMps);
692     SET(AccumulatedDeltaRangeState,
693         (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
694     SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
695     SET(AccumulatedDeltaRangeUncertaintyMeters,
696         measurement->accumulatedDeltaRangeUncertaintyM);
697 
698     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
699         SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
700     }
701 
702     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
703         SET(CarrierPhase, measurement->carrierPhase);
704     }
705 
706     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
707         SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
708     }
709 
710     SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
711 
712     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
713         SET(SnrInDb, measurement->snrDb);
714     }
715 
716     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
717         SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
718     }
719 
720     return object.get();
721 }
722 
translateGnssClock(JNIEnv * env,const IGnssMeasurementCallback::GnssClock * clock)723 jobject GnssMeasurementCallback::translateGnssClock(
724        JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
725     JavaObject object(env, "android/location/GnssClock");
726 
727     uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
728     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
729         SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
730     }
731 
732     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
733         SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
734     }
735 
736     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
737         SET(FullBiasNanos, clock->fullBiasNs);
738     }
739 
740     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
741         SET(BiasNanos, clock->biasNs);
742     }
743 
744     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
745         SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
746     }
747 
748     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
749         SET(DriftNanosPerSecond, clock->driftNsps);
750     }
751 
752     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
753         SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
754     }
755 
756     SET(TimeNanos, clock->timeNs);
757     SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
758 
759     return object.get();
760 }
761 
translateGnssMeasurements(JNIEnv * env,const IGnssMeasurementCallback::GnssMeasurement * measurements,size_t count)762 jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
763                                        const IGnssMeasurementCallback::GnssMeasurement*
764                                        measurements, size_t count) {
765     if (count == 0) {
766         return NULL;
767     }
768 
769     jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
770     jobjectArray gnssMeasurementArray = env->NewObjectArray(
771             count,
772             gnssMeasurementClass,
773             NULL /* initialElement */);
774 
775     for (uint16_t i = 0; i < count; ++i) {
776         jobject gnssMeasurement = translateGnssMeasurement(
777             env,
778             &measurements[i]);
779         env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
780         env->DeleteLocalRef(gnssMeasurement);
781     }
782 
783     env->DeleteLocalRef(gnssMeasurementClass);
784     return gnssMeasurementArray;
785 }
786 
setMeasurementData(JNIEnv * env,jobject clock,jobjectArray measurementArray)787 void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
788                              jobjectArray measurementArray) {
789     jclass gnssMeasurementsEventClass =
790             env->FindClass("android/location/GnssMeasurementsEvent");
791     jmethodID gnssMeasurementsEventCtor =
792             env->GetMethodID(
793                     gnssMeasurementsEventClass,
794                     "<init>",
795                     "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
796 
797     jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
798                                                    gnssMeasurementsEventCtor,
799                                                    clock,
800                                                    measurementArray);
801 
802     env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
803                       gnssMeasurementsEvent);
804     checkAndClearExceptionFromCallback(env, __FUNCTION__);
805     env->DeleteLocalRef(gnssMeasurementsEventClass);
806     env->DeleteLocalRef(gnssMeasurementsEvent);
807 }
808 
809 /*
810  * GnssNiCallback implements callback methods required by the IGnssNi interface.
811  */
812 struct GnssNiCallback : public IGnssNiCallback {
813     Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
814             override;
815 };
816 
niNotifyCb(const IGnssNiCallback::GnssNiNotification & notification)817 Return<void> GnssNiCallback::niNotifyCb(
818         const IGnssNiCallback::GnssNiNotification& notification) {
819     JNIEnv* env = getJniEnv();
820     jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
821     jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
822 
823     if (requestorId && text) {
824         env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
825                             notification.notificationId, notification.niType,
826                             notification.notifyFlags, notification.timeoutSec,
827                             notification.defaultResponse, requestorId, text,
828                             notification.requestorIdEncoding,
829                             notification.notificationIdEncoding);
830     } else {
831         ALOGE("%s: OOM Error\n", __func__);
832     }
833 
834     if (requestorId) {
835         env->DeleteLocalRef(requestorId);
836     }
837 
838     if (text) {
839         env->DeleteLocalRef(text);
840     }
841     checkAndClearExceptionFromCallback(env, __FUNCTION__);
842     return Void();
843 }
844 
845 /*
846  * AGnssCallback implements callback methods required by the IAGnss interface.
847  */
848 struct AGnssCallback : public IAGnssCallback {
849     // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
850     Return<void> agnssStatusIpV6Cb(
851       const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
852 
853     Return<void> agnssStatusIpV4Cb(
854       const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
855  private:
856     jbyteArray convertToIpV4(uint32_t ip);
857 };
858 
agnssStatusIpV6Cb(const IAGnssCallback::AGnssStatusIpV6 & agps_status)859 Return<void> AGnssCallback::agnssStatusIpV6Cb(
860         const IAGnssCallback::AGnssStatusIpV6& agps_status) {
861     JNIEnv* env = getJniEnv();
862     jbyteArray byteArray = NULL;
863     bool isSupported = false;
864 
865     byteArray = env->NewByteArray(16);
866     if (byteArray != NULL) {
867         env->SetByteArrayRegion(byteArray, 0, 16,
868                                 (const jbyte*)(agps_status.ipV6Addr.data()));
869         isSupported = true;
870     } else {
871         ALOGE("Unable to allocate byte array for IPv6 address.");
872     }
873 
874     IF_ALOGD() {
875         // log the IP for reference in case there is a bogus value pushed by HAL
876         char str[INET6_ADDRSTRLEN];
877         inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
878         ALOGD("AGPS IP is v6: %s", str);
879     }
880 
881     jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
882     ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
883     env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
884                         agps_status.type, agps_status.status, byteArray);
885 
886     checkAndClearExceptionFromCallback(env, __FUNCTION__);
887 
888     if (byteArray) {
889         env->DeleteLocalRef(byteArray);
890     }
891 
892     return Void();
893 }
894 
agnssStatusIpV4Cb(const IAGnssCallback::AGnssStatusIpV4 & agps_status)895 Return<void> AGnssCallback::agnssStatusIpV4Cb(
896         const IAGnssCallback::AGnssStatusIpV4& agps_status) {
897     JNIEnv* env = getJniEnv();
898     jbyteArray byteArray = NULL;
899 
900     uint32_t ipAddr = agps_status.ipV4Addr;
901     byteArray = convertToIpV4(ipAddr);
902 
903     IF_ALOGD() {
904         /*
905          * log the IP for reference in case there is a bogus value pushed by
906          * HAL.
907          */
908         char str[INET_ADDRSTRLEN];
909         inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
910         ALOGD("AGPS IP is v4: %s", str);
911     }
912 
913     jsize byteArrayLength =
914       byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
915     ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
916     env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
917                       agps_status.type, agps_status.status, byteArray);
918 
919     checkAndClearExceptionFromCallback(env, __FUNCTION__);
920 
921     if (byteArray) {
922         env->DeleteLocalRef(byteArray);
923     }
924     return Void();
925 }
926 
convertToIpV4(uint32_t ip)927 jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
928     if (INADDR_NONE == ip) {
929         return NULL;
930     }
931 
932     JNIEnv* env = getJniEnv();
933     jbyteArray byteArray = env->NewByteArray(4);
934     if (byteArray == NULL) {
935         ALOGE("Unable to allocate byte array for IPv4 address");
936         return NULL;
937     }
938 
939     jbyte ipv4[4];
940     ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
941     memcpy(ipv4, &ip, sizeof(ipv4));
942     env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
943     return byteArray;
944 }
945 
946 /*
947  * AGnssRilCallback implements the callback methods required by the AGnssRil
948  * interface.
949  */
950 struct AGnssRilCallback : IAGnssRilCallback {
951     Return<void> requestSetIdCb(uint32_t setIdFlag) override;
952     Return<void> requestRefLocCb() override;
953 };
954 
requestSetIdCb(uint32_t setIdFlag)955 Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
956     JNIEnv* env = getJniEnv();
957     env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
958     checkAndClearExceptionFromCallback(env, __FUNCTION__);
959     return Void();
960 }
961 
requestRefLocCb()962 Return<void> AGnssRilCallback::requestRefLocCb() {
963     JNIEnv* env = getJniEnv();
964     env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
965     checkAndClearExceptionFromCallback(env, __FUNCTION__);
966     return Void();
967 }
968 
969 /*
970  * GnssBatchingCallback interface implements the callback methods
971  * required by the IGnssBatching interface.
972  */
973 struct GnssBatchingCallback : public IGnssBatchingCallback {
974     /*
975     * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
976     * follow.
977     */
978     Return<void> gnssLocationBatchCb(
979         const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations)
980         override;
981 };
982 
gnssLocationBatchCb(const::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations)983 Return<void> GnssBatchingCallback::gnssLocationBatchCb(
984         const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations) {
985     JNIEnv* env = getJniEnv();
986 
987     jobjectArray jLocations = env->NewObjectArray(locations.size(),
988             env->FindClass("android/location/Location"), nullptr);
989 
990     for (uint16_t i = 0; i < locations.size(); ++i) {
991         jobject jLocation = translateLocation(env, locations[i]);
992         env->SetObjectArrayElement(jLocations, i, jLocation);
993         env->DeleteLocalRef(jLocation);
994     }
995 
996     env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
997     checkAndClearExceptionFromCallback(env, __FUNCTION__);
998 
999     env->DeleteLocalRef(jLocations);
1000 
1001     return Void();
1002 }
1003 
android_location_GnssLocationProvider_class_init_native(JNIEnv * env,jclass clazz)1004 static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
1005     method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1006             "(ZLandroid/location/Location;)V");
1007     method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1008     method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1009     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1010     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1011     method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1012     method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
1013     method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1014     method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1015             "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1016     method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1017     method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1018     method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1019     method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
1020             "(ILandroid/location/Location;IJ)V");
1021     method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
1022             "(ILandroid/location/Location;)V");
1023     method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1024             "(II)V");
1025     method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1026             "(II)V");
1027     method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1028             "(II)V");
1029     method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1030             "(II)V");
1031     method_reportMeasurementData = env->GetMethodID(
1032             clazz,
1033             "reportMeasurementData",
1034             "(Landroid/location/GnssMeasurementsEvent;)V");
1035     method_reportNavigationMessages = env->GetMethodID(
1036             clazz,
1037             "reportNavigationMessage",
1038             "(Landroid/location/GnssNavigationMessage;)V");
1039     method_reportLocationBatch = env->GetMethodID(
1040             clazz,
1041             "reportLocationBatch",
1042             "([Landroid/location/Location;)V");
1043 
1044     /*
1045      * Save a pointer to JVM.
1046      */
1047     jint jvmStatus = env->GetJavaVM(&sJvm);
1048     if (jvmStatus != JNI_OK) {
1049         LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1050     }
1051 
1052     // TODO(b/31632518)
1053     gnssHal = IGnss::getService();
1054     if (gnssHal != nullptr) {
1055       gnssHalDeathRecipient = new GnssDeathRecipient();
1056       hardware::Return<bool> linked = gnssHal->linkToDeath(
1057           gnssHalDeathRecipient, /*cookie*/ 0);
1058         if (!linked.isOk()) {
1059             ALOGE("Transaction error in linking to GnssHAL death: %s",
1060                     linked.description().c_str());
1061         } else if (!linked) {
1062             ALOGW("Unable to link to GnssHal death notifications");
1063         } else {
1064             ALOGD("Link to death notification successful");
1065         }
1066 
1067         auto gnssXtra = gnssHal->getExtensionXtra();
1068         if (!gnssXtra.isOk()) {
1069             ALOGD("Unable to get a handle to Xtra");
1070         } else {
1071             gnssXtraIface = gnssXtra;
1072         }
1073 
1074         auto gnssRil = gnssHal->getExtensionAGnssRil();
1075         if (!gnssRil.isOk()) {
1076             ALOGD("Unable to get a handle to AGnssRil");
1077         } else {
1078             agnssRilIface = gnssRil;
1079         }
1080 
1081         auto gnssAgnss = gnssHal->getExtensionAGnss();
1082         if (!gnssAgnss.isOk()) {
1083             ALOGD("Unable to get a handle to AGnss");
1084         } else {
1085             agnssIface = gnssAgnss;
1086         }
1087 
1088         auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1089         if (!gnssNavigationMessage.isOk()) {
1090             ALOGD("Unable to get a handle to GnssNavigationMessage");
1091         } else {
1092             gnssNavigationMessageIface = gnssNavigationMessage;
1093         }
1094 
1095         auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1096         if (!gnssMeasurement.isOk()) {
1097             ALOGD("Unable to get a handle to GnssMeasurement");
1098         } else {
1099             gnssMeasurementIface = gnssMeasurement;
1100         }
1101 
1102         auto gnssDebug = gnssHal->getExtensionGnssDebug();
1103         if (!gnssDebug.isOk()) {
1104             ALOGD("Unable to get a handle to GnssDebug");
1105         } else {
1106             gnssDebugIface = gnssDebug;
1107         }
1108 
1109         auto gnssNi = gnssHal->getExtensionGnssNi();
1110         if (!gnssNi.isOk()) {
1111             ALOGD("Unable to get a handle to GnssNi");
1112         } else {
1113             gnssNiIface = gnssNi;
1114         }
1115 
1116         auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1117         if (!gnssConfiguration.isOk()) {
1118             ALOGD("Unable to get a handle to GnssConfiguration");
1119         } else {
1120             gnssConfigurationIface = gnssConfiguration;
1121         }
1122 
1123         auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1124         if (!gnssGeofencing.isOk()) {
1125             ALOGD("Unable to get a handle to GnssGeofencing");
1126         } else {
1127             gnssGeofencingIface = gnssGeofencing;
1128         }
1129 
1130         auto gnssBatching = gnssHal->getExtensionGnssBatching();
1131         if (!gnssBatching.isOk()) {
1132             ALOGD("Unable to get a handle to gnssBatching");
1133         } else {
1134             gnssBatchingIface = gnssBatching;
1135         }
1136     } else {
1137       ALOGE("Unable to get GPS service\n");
1138     }
1139 }
1140 
android_location_GnssLocationProvider_is_supported(JNIEnv *,jclass)1141 static jboolean android_location_GnssLocationProvider_is_supported(
1142         JNIEnv* /* env */, jclass /* clazz */) {
1143     return (gnssHal != nullptr) ?  JNI_TRUE : JNI_FALSE;
1144 }
1145 
android_location_GnssLocationProvider_is_agps_ril_supported(JNIEnv *,jclass)1146 static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1147         JNIEnv* /* env */, jclass /* clazz */) {
1148     return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1149 }
1150 
android_location_gpsLocationProvider_is_gnss_configuration_supported(JNIEnv *,jclass)1151 static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1152         JNIEnv* /* env */, jclass /* jclazz */) {
1153     return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1154 }
1155 
android_location_GnssLocationProvider_init(JNIEnv * env,jobject obj)1156 static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1157     /*
1158      * This must be set before calling into the HAL library.
1159      */
1160     if (!mCallbacksObj)
1161         mCallbacksObj = env->NewGlobalRef(obj);
1162 
1163     sp<IGnssCallback> gnssCbIface = new GnssCallback();
1164     /*
1165      * Fail if the main interface fails to initialize
1166      */
1167     if (gnssHal == nullptr) {
1168         ALOGE("Unable to Initialize GNSS HAL\n");
1169         return JNI_FALSE;
1170     }
1171 
1172     auto result = gnssHal->setCallback(gnssCbIface);
1173     if (!result.isOk() || !result) {
1174         ALOGE("SetCallback for Gnss Interface fails\n");
1175         return JNI_FALSE;
1176     }
1177 
1178     sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1179     if (gnssXtraIface == nullptr) {
1180         ALOGE("Unable to initialize GNSS Xtra interface\n");
1181     } else {
1182         result = gnssXtraIface->setCallback(gnssXtraCbIface);
1183         if (!result.isOk() || !result) {
1184             gnssXtraIface = nullptr;
1185             ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1186         }
1187     }
1188 
1189     sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1190     if (agnssIface != nullptr) {
1191         agnssIface->setCallback(aGnssCbIface);
1192     } else {
1193         ALOGE("Unable to Initialize AGnss interface\n");
1194     }
1195 
1196     sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1197     if (gnssGeofencingIface != nullptr) {
1198       gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1199     } else {
1200         ALOGE("Unable to initialize GNSS Geofencing interface\n");
1201     }
1202 
1203     sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1204     if (gnssNiIface != nullptr) {
1205         gnssNiIface->setCallback(gnssNiCbIface);
1206     } else {
1207         ALOGE("Unable to initialize GNSS NI interface\n");
1208     }
1209 
1210     return JNI_TRUE;
1211 }
1212 
android_location_GnssLocationProvider_cleanup(JNIEnv *,jobject)1213 static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1214     if (gnssHal != nullptr) {
1215         gnssHal->cleanup();
1216     }
1217 }
1218 
android_location_GnssLocationProvider_set_position_mode(JNIEnv *,jobject,jint mode,jint recurrence,jint min_interval,jint preferred_accuracy,jint preferred_time)1219 static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1220         jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1221         jint preferred_time) {
1222     if (gnssHal != nullptr) {
1223         auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1224                                      static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1225                                      min_interval,
1226                                      preferred_accuracy,
1227                                      preferred_time);
1228         if (!result.isOk()) {
1229             ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1230             return JNI_FALSE;
1231         } else {
1232             return result;
1233         }
1234     } else {
1235         return JNI_FALSE;
1236     }
1237 }
1238 
android_location_GnssLocationProvider_start(JNIEnv *,jobject)1239 static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1240     if (gnssHal != nullptr) {
1241         auto result = gnssHal->start();
1242         if (!result.isOk()) {
1243             return JNI_FALSE;
1244         } else {
1245             return result;
1246         }
1247     } else {
1248         return JNI_FALSE;
1249     }
1250 }
1251 
android_location_GnssLocationProvider_stop(JNIEnv *,jobject)1252 static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1253     if (gnssHal != nullptr) {
1254         auto result = gnssHal->stop();
1255         if (!result.isOk()) {
1256             return JNI_FALSE;
1257         } else {
1258             return result;
1259         }
1260     } else {
1261         return JNI_FALSE;
1262     }
1263 }
android_location_GnssLocationProvider_delete_aiding_data(JNIEnv *,jobject,jint flags)1264 static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1265                                                                     jobject /* obj */,
1266                                                                     jint flags) {
1267     if (gnssHal != nullptr) {
1268         auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
1269         if (!result.isOk()) {
1270             ALOGE("Error in deleting aiding data");
1271         }
1272     }
1273 }
1274 
1275 /*
1276  * This enum is used by the read_sv_status method to combine the svid,
1277  * constellation and svFlag fields.
1278  */
1279 enum ShiftWidth: uint8_t {
1280     SVID_SHIFT_WIDTH = 8,
1281     CONSTELLATION_TYPE_SHIFT_WIDTH = 4
1282 };
1283 
android_location_GnssLocationProvider_read_sv_status(JNIEnv * env,jobject,jintArray svidWithFlagArray,jfloatArray cn0Array,jfloatArray elevArray,jfloatArray azumArray,jfloatArray carrierFreqArray)1284 static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1285         jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
1286         jfloatArray azumArray, jfloatArray carrierFreqArray) {
1287     /*
1288      * This method should only be called from within a call to reportSvStatus.
1289      */
1290     jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1291     jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1292     jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1293     jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
1294     jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
1295 
1296     /*
1297      * Read GNSS SV info.
1298      */
1299     for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1300         const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1301         svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1302             (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1303             static_cast<uint32_t>(info.svFlag);
1304         cn0s[i] = info.cN0Dbhz;
1305         elev[i] = info.elevationDegrees;
1306         azim[i] = info.azimuthDegrees;
1307         carrierFreq[i] = info.carrierFrequencyHz;
1308     }
1309 
1310     env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1311     env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1312     env->ReleaseFloatArrayElements(elevArray, elev, 0);
1313     env->ReleaseFloatArrayElements(azumArray, azim, 0);
1314     env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
1315     return static_cast<jint>(GnssCallback::sGnssSvListSize);
1316 }
1317 
android_location_GnssLocationProvider_agps_set_reference_location_cellid(JNIEnv *,jobject,jint type,jint mcc,jint mnc,jint lac,jint cid)1318 static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1319         JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1320     IAGnssRil::AGnssRefLocation location;
1321 
1322     if (agnssRilIface == nullptr) {
1323         ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1324         return;
1325     }
1326 
1327     switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1328         case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1329         case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1330           location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1331           location.cellID.mcc = mcc;
1332           location.cellID.mnc = mnc;
1333           location.cellID.lac = lac;
1334           location.cellID.cid = cid;
1335           break;
1336         default:
1337             ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1338             return;
1339             break;
1340     }
1341 
1342     agnssRilIface->setRefLocation(location);
1343 }
1344 
android_location_GnssLocationProvider_agps_set_id(JNIEnv * env,jobject,jint type,jstring setid_string)1345 static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1346                                                              jint type, jstring  setid_string) {
1347     if (agnssRilIface == nullptr) {
1348         ALOGE("no AGPS RIL interface in agps_set_id");
1349         return;
1350     }
1351 
1352     const char *setid = env->GetStringUTFChars(setid_string, NULL);
1353     agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1354     env->ReleaseStringUTFChars(setid_string, setid);
1355 }
1356 
android_location_GnssLocationProvider_read_nmea(JNIEnv * env,jobject,jbyteArray nmeaArray,jint buffer_size)1357 static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1358                                             jbyteArray nmeaArray, jint buffer_size) {
1359     // this should only be called from within a call to reportNmea
1360     jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1361     int length = GnssCallback::sNmeaStringLength;
1362     if (length > buffer_size)
1363         length = buffer_size;
1364     memcpy(nmea, GnssCallback::sNmeaString, length);
1365     env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1366     return (jint) length;
1367 }
1368 
android_location_GnssLocationProvider_inject_time(JNIEnv *,jobject,jlong time,jlong timeReference,jint uncertainty)1369 static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1370         jlong time, jlong timeReference, jint uncertainty) {
1371     if (gnssHal != nullptr) {
1372         auto result = gnssHal->injectTime(time, timeReference, uncertainty);
1373         if (!result.isOk() || !result) {
1374             ALOGE("%s: Gnss injectTime() failed", __func__);
1375         }
1376     }
1377 }
1378 
android_location_GnssLocationProvider_inject_location(JNIEnv *,jobject,jdouble latitude,jdouble longitude,jfloat accuracy)1379 static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1380         jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1381     if (gnssHal != nullptr) {
1382         auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
1383         if (!result.isOk() || !result) {
1384             ALOGE("%s: Gnss injectLocation() failed", __func__);
1385         }
1386     }
1387 }
1388 
android_location_GnssLocationProvider_supports_xtra(JNIEnv *,jobject)1389 static jboolean android_location_GnssLocationProvider_supports_xtra(
1390         JNIEnv* /* env */, jobject /* obj */) {
1391     return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1392 }
1393 
android_location_GnssLocationProvider_inject_xtra_data(JNIEnv * env,jobject,jbyteArray data,jint length)1394 static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1395         jbyteArray data, jint length) {
1396     if (gnssXtraIface == nullptr) {
1397         ALOGE("XTRA Interface not supported");
1398         return;
1399     }
1400 
1401     jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1402     gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1403     env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1404 }
1405 
android_location_GnssLocationProvider_agps_data_conn_open(JNIEnv * env,jobject,jstring apn,jint apnIpType)1406 static void android_location_GnssLocationProvider_agps_data_conn_open(
1407         JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1408     if (agnssIface == nullptr) {
1409         ALOGE("no AGPS interface in agps_data_conn_open");
1410         return;
1411     }
1412     if (apn == NULL) {
1413         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1414         return;
1415     }
1416 
1417     const char *apnStr = env->GetStringUTFChars(apn, NULL);
1418 
1419     auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
1420     if (!result.isOk() || !result){
1421         ALOGE("%s: Failed to set APN and its IP type", __func__);
1422     }
1423     env->ReleaseStringUTFChars(apn, apnStr);
1424 }
1425 
android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv *,jobject)1426 static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1427                                                                        jobject /* obj */) {
1428     if (agnssIface == nullptr) {
1429         ALOGE("%s: AGPS interface not supported", __func__);
1430         return;
1431     }
1432 
1433     auto result = agnssIface->dataConnClosed();
1434     if (!result.isOk() || !result) {
1435         ALOGE("%s: Failed to close AGnss data connection", __func__);
1436     }
1437 }
1438 
android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv *,jobject)1439 static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1440                                                                        jobject /* obj */) {
1441     if (agnssIface == nullptr) {
1442         ALOGE("%s: AGPS interface not supported", __func__);
1443         return;
1444     }
1445 
1446     auto result = agnssIface->dataConnFailed();
1447     if (!result.isOk() || !result) {
1448         ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1449     }
1450 }
1451 
android_location_GnssLocationProvider_set_agps_server(JNIEnv * env,jobject,jint type,jstring hostname,jint port)1452 static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1453         jint type, jstring hostname, jint port) {
1454     if (agnssIface == nullptr) {
1455         ALOGE("no AGPS interface in set_agps_server");
1456         return;
1457     }
1458 
1459     const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1460     auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1461                                        c_hostname,
1462                                        port);
1463     if (!result.isOk() || !result) {
1464         ALOGE("%s: Failed to set AGnss host name and port", __func__);
1465     }
1466 
1467     env->ReleaseStringUTFChars(hostname, c_hostname);
1468 }
1469 
android_location_GnssLocationProvider_send_ni_response(JNIEnv *,jobject,jint notifId,jint response)1470 static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1471       jobject /* obj */, jint notifId, jint response) {
1472     if (gnssNiIface == nullptr) {
1473         ALOGE("no NI interface in send_ni_response");
1474         return;
1475     }
1476 
1477     gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1478 }
1479 
android_location_GnssLocationProvider_get_internal_state(JNIEnv * env,jobject)1480 static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1481                                                                        jobject /* obj */) {
1482     jstring result = NULL;
1483     /*
1484      * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1485      */
1486 
1487     std::stringstream internalState;
1488 
1489     if (gnssDebugIface == nullptr) {
1490         internalState << "Gnss Debug Interface not available"  << std::endl;
1491     } else {
1492         IGnssDebug::DebugData data;
1493         gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1494             data = debugData;
1495         });
1496 
1497         internalState << "Gnss Location Data:: ";
1498         if (!data.position.valid) {
1499             internalState << "not valid";
1500         } else {
1501             internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
1502                           << ", LongitudeDegrees: " << data.position.longitudeDegrees
1503                           << ", altitudeMeters: " << data.position.altitudeMeters
1504                           << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1505                           << ", bearingDegrees: " << data.position.bearingDegrees
1506                           << ", horizontalAccuracyMeters: "
1507                           << data.position.horizontalAccuracyMeters
1508                           << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
1509                           << ", speedAccuracyMetersPerSecond: "
1510                           << data.position.speedAccuracyMetersPerSecond
1511                           << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
1512                           << ", ageSeconds: " << data.position.ageSeconds;
1513         }
1514         internalState << std::endl;
1515 
1516         internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1517                       << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1518                       << ", frequencyUncertaintyNsPerSec: "
1519                       << data.time.frequencyUncertaintyNsPerSec << std::endl;
1520 
1521         if (data.satelliteDataArray.size() != 0) {
1522             internalState << "Satellite Data for " << data.satelliteDataArray.size()
1523                           << " satellites:: " << std::endl;
1524         }
1525 
1526         internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1527                       << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1528                       << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1529                       << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
1530         for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1531             internalState << "svid: " << data.satelliteDataArray[i].svid
1532                           << ", constellation: "
1533                           << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1534                           << ", ephemerisType: "
1535                           << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1536                           << ", ephemerisSource: "
1537                           << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1538                           << ", ephemerisHealth: "
1539                           << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1540                           << ", serverPredictionIsAvailable: "
1541                           << data.satelliteDataArray[i].serverPredictionIsAvailable
1542                           << ", serverPredictionAgeSeconds: "
1543                           << data.satelliteDataArray[i].serverPredictionAgeSeconds
1544                           << ", ephemerisAgeSeconds: "
1545                           << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1546         }
1547     }
1548 
1549     result = env->NewStringUTF(internalState.str().c_str());
1550     return result;
1551 }
1552 
android_location_GnssLocationProvider_update_network_state(JNIEnv * env,jobject,jboolean connected,jint type,jboolean roaming,jboolean available,jstring extraInfo,jstring apn)1553 static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1554                                                                        jobject /* obj */,
1555                                                                        jboolean connected,
1556                                                                        jint type,
1557                                                                        jboolean roaming,
1558                                                                        jboolean available,
1559                                                                        jstring extraInfo,
1560                                                                        jstring apn) {
1561     if (agnssRilIface != nullptr) {
1562         auto result = agnssRilIface->updateNetworkState(connected,
1563                                                        static_cast<IAGnssRil::NetworkType>(type),
1564                                                        roaming);
1565         if (!result.isOk() || !result) {
1566             ALOGE("updateNetworkState failed");
1567         }
1568 
1569         const char *c_apn = env->GetStringUTFChars(apn, NULL);
1570         result = agnssRilIface->updateNetworkAvailability(available, c_apn);
1571         if (!result.isOk() || !result) {
1572             ALOGE("updateNetworkAvailability failed");
1573         }
1574 
1575         env->ReleaseStringUTFChars(apn, c_apn);
1576     } else {
1577         ALOGE("AGnssRilInterface does not exist");
1578     }
1579 }
1580 
android_location_GnssLocationProvider_is_geofence_supported(JNIEnv *,jobject)1581 static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1582         JNIEnv* /* env */, jobject /* obj */) {
1583     return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1584 }
1585 
android_location_GnssLocationProvider_add_geofence(JNIEnv *,jobject,jint geofenceId,jdouble latitude,jdouble longitude,jdouble radius,jint last_transition,jint monitor_transition,jint notification_responsiveness,jint unknown_timer)1586 static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1587         jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1588         jint last_transition, jint monitor_transition, jint notification_responsiveness,
1589         jint unknown_timer) {
1590     if (gnssGeofencingIface != nullptr) {
1591         auto result = gnssGeofencingIface->addGeofence(
1592                 geofenceId, latitude, longitude, radius,
1593                 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1594                 monitor_transition, notification_responsiveness, unknown_timer);
1595         return boolToJbool(result.isOk());
1596     } else {
1597         ALOGE("Geofence Interface not available");
1598     }
1599     return JNI_FALSE;
1600 }
1601 
android_location_GnssLocationProvider_remove_geofence(JNIEnv *,jobject,jint geofenceId)1602 static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1603         jobject /* obj */, jint geofenceId) {
1604     if (gnssGeofencingIface != nullptr) {
1605         auto result = gnssGeofencingIface->removeGeofence(geofenceId);
1606         return boolToJbool(result.isOk());
1607     } else {
1608         ALOGE("Geofence interface not available");
1609     }
1610     return JNI_FALSE;
1611 }
1612 
android_location_GnssLocationProvider_pause_geofence(JNIEnv *,jobject,jint geofenceId)1613 static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1614         jobject /* obj */, jint geofenceId) {
1615     if (gnssGeofencingIface != nullptr) {
1616         auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
1617         return boolToJbool(result.isOk());
1618     } else {
1619         ALOGE("Geofence interface not available");
1620     }
1621     return JNI_FALSE;
1622 }
1623 
android_location_GnssLocationProvider_resume_geofence(JNIEnv *,jobject,jint geofenceId,jint monitor_transition)1624 static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1625         jobject /* obj */, jint geofenceId, jint monitor_transition) {
1626     if (gnssGeofencingIface != nullptr) {
1627         auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
1628         return boolToJbool(result.isOk());
1629     } else {
1630         ALOGE("Geofence interface not available");
1631     }
1632     return JNI_FALSE;
1633 }
1634 
android_location_GnssLocationProvider_is_measurement_supported(JNIEnv * env,jclass clazz)1635 static jboolean android_location_GnssLocationProvider_is_measurement_supported(
1636     JNIEnv* env, jclass clazz) {
1637     if (gnssMeasurementIface != nullptr) {
1638         return JNI_TRUE;
1639     }
1640 
1641     return JNI_FALSE;
1642 }
1643 
android_location_GnssLocationProvider_start_measurement_collection(JNIEnv * env,jobject obj)1644 static jboolean android_location_GnssLocationProvider_start_measurement_collection(
1645         JNIEnv* env,
1646         jobject obj) {
1647     if (gnssMeasurementIface == nullptr) {
1648         ALOGE("GNSS Measurement interface is not available.");
1649         return JNI_FALSE;
1650     }
1651 
1652     sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1653     IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1654     if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1655         ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1656               static_cast<int32_t>(result));
1657         return JNI_FALSE;
1658     } else {
1659       ALOGD("gnss measurement infc has been enabled");
1660     }
1661 
1662     return JNI_TRUE;
1663 }
1664 
android_location_GnssLocationProvider_stop_measurement_collection(JNIEnv * env,jobject obj)1665 static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
1666         JNIEnv* env,
1667         jobject obj) {
1668     if (gnssMeasurementIface == nullptr) {
1669         ALOGE("Measurement interface not available");
1670         return JNI_FALSE;
1671     }
1672 
1673     auto result = gnssMeasurementIface->close();
1674     return boolToJbool(result.isOk());
1675 }
1676 
android_location_GnssLocationProvider_is_navigation_message_supported(JNIEnv * env,jclass clazz)1677 static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
1678         JNIEnv* env,
1679         jclass clazz) {
1680     if (gnssNavigationMessageIface != nullptr) {
1681         return JNI_TRUE;
1682     }
1683     return JNI_FALSE;
1684 }
1685 
android_location_GnssLocationProvider_start_navigation_message_collection(JNIEnv * env,jobject obj)1686 static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
1687         JNIEnv* env,
1688         jobject obj) {
1689     if (gnssNavigationMessageIface == nullptr) {
1690         ALOGE("Navigation Message interface is not available.");
1691         return JNI_FALSE;
1692     }
1693 
1694     sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1695             new GnssNavigationMessageCallback();
1696     IGnssNavigationMessage::GnssNavigationMessageStatus result =
1697             gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1698 
1699     if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1700         ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
1701         return JNI_FALSE;
1702     }
1703 
1704     return JNI_TRUE;
1705 }
1706 
android_location_GnssLocationProvider_stop_navigation_message_collection(JNIEnv * env,jobject obj)1707 static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
1708         JNIEnv* env,
1709         jobject obj) {
1710     if (gnssNavigationMessageIface == nullptr) {
1711         ALOGE("Navigation Message interface is not available.");
1712         return JNI_FALSE;
1713     }
1714 
1715     auto result = gnssNavigationMessageIface->close();
1716     return boolToJbool(result.isOk());
1717 }
1718 
android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv *,jobject,jint emergencySuplPdn)1719 static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1720                                                                     jobject,
1721                                                                     jint emergencySuplPdn) {
1722     if (gnssConfigurationIface == nullptr) {
1723         ALOGE("no GNSS configuration interface available");
1724         return JNI_FALSE;
1725     }
1726 
1727     auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
1728     if (result.isOk()) {
1729         return result;
1730     } else {
1731         return JNI_FALSE;
1732     }
1733 }
1734 
android_location_GnssLocationProvider_set_supl_version(JNIEnv *,jobject,jint version)1735 static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1736                                                                     jobject,
1737                                                                     jint version) {
1738     if (gnssConfigurationIface == nullptr) {
1739         ALOGE("no GNSS configuration interface available");
1740         return JNI_FALSE;
1741     }
1742     auto result = gnssConfigurationIface->setSuplVersion(version);
1743     if (result.isOk()) {
1744         return result;
1745     } else {
1746         return JNI_FALSE;
1747     }
1748 }
1749 
android_location_GnssLocationProvider_set_supl_es(JNIEnv *,jobject,jint suplEs)1750 static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1751                                                                     jobject,
1752                                                                     jint suplEs) {
1753     if (gnssConfigurationIface == nullptr) {
1754         ALOGE("no GNSS configuration interface available");
1755         return JNI_FALSE;
1756     }
1757 
1758     auto result = gnssConfigurationIface->setSuplEs(suplEs);
1759     if (result.isOk()) {
1760         return result;
1761     } else {
1762         return JNI_FALSE;
1763     }
1764 }
1765 
android_location_GnssLocationProvider_set_supl_mode(JNIEnv *,jobject,jint mode)1766 static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1767                                                                     jobject,
1768                                                                     jint mode) {
1769     if (gnssConfigurationIface == nullptr) {
1770         ALOGE("no GNSS configuration interface available");
1771         return JNI_FALSE;
1772     }
1773 
1774     auto result = gnssConfigurationIface->setSuplMode(mode);
1775     if (result.isOk()) {
1776         return result;
1777     } else {
1778         return JNI_FALSE;
1779     }
1780 }
1781 
android_location_GnssLocationProvider_set_gps_lock(JNIEnv *,jobject,jint gpsLock)1782 static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1783                                                                    jobject,
1784                                                                    jint gpsLock) {
1785     if (gnssConfigurationIface == nullptr) {
1786         ALOGE("no GNSS configuration interface available");
1787         return JNI_FALSE;
1788     }
1789 
1790     auto result = gnssConfigurationIface->setGpsLock(gpsLock);
1791     if (result.isOk()) {
1792         return result;
1793     } else {
1794         return JNI_FALSE;
1795     }
1796 }
1797 
android_location_GnssLocationProvider_set_lpp_profile(JNIEnv *,jobject,jint lppProfile)1798 static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1799                                                                    jobject,
1800                                                                    jint lppProfile) {
1801     if (gnssConfigurationIface == nullptr) {
1802         ALOGE("no GNSS configuration interface available");
1803         return JNI_FALSE;
1804     }
1805 
1806     auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1807 
1808     if (result.isOk()) {
1809         return result;
1810     } else {
1811         return JNI_FALSE;
1812     }
1813 }
1814 
android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv *,jobject,jint gnssPosProtocol)1815 static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1816                                                                    jobject,
1817                                                                    jint gnssPosProtocol) {
1818     if (gnssConfigurationIface == nullptr) {
1819         ALOGE("no GNSS configuration interface available");
1820         return JNI_FALSE;
1821     }
1822 
1823     auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
1824     if (result.isOk()) {
1825         return result;
1826     } else {
1827         return JNI_FALSE;
1828     }
1829 }
1830 
android_location_GnssLocationProvider_get_batch_size(JNIEnv *,jclass)1831 static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1832     if (gnssBatchingIface == nullptr) {
1833         return 0; // batching not supported, size = 0
1834     }
1835     auto result = gnssBatchingIface->getBatchSize();
1836     if (result.isOk()) {
1837         return static_cast<jint>(result);
1838     } else {
1839         return 0; // failure in binder, don't support batching
1840     }
1841 }
1842 
android_location_GnssLocationProvider_init_batching(JNIEnv *,jclass)1843 static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1844     if (gnssBatchingIface == nullptr) {
1845         return JNI_FALSE; // batching not supported
1846     }
1847     sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1848 
1849     return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1850 }
1851 
android_location_GnssLocationProvider_cleanup_batching(JNIEnv *,jclass)1852 static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1853     if (gnssBatchingIface == nullptr) {
1854         return; // batching not supported
1855     }
1856     gnssBatchingIface->cleanup();
1857 }
1858 
android_location_GnssLocationProvider_start_batch(JNIEnv *,jclass,jlong periodNanos,jboolean wakeOnFifoFull)1859 static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1860         jlong periodNanos, jboolean wakeOnFifoFull) {
1861     if (gnssBatchingIface == nullptr) {
1862         return JNI_FALSE; // batching not supported
1863     }
1864 
1865     IGnssBatching::Options options;
1866     options.periodNanos = periodNanos;
1867     if (wakeOnFifoFull) {
1868         options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1869     } else {
1870         options.flags = 0;
1871     }
1872 
1873     return static_cast<jboolean>(gnssBatchingIface->start(options));
1874 }
1875 
android_location_GnssLocationProvider_flush_batch(JNIEnv *,jclass)1876 static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1877     if (gnssBatchingIface == nullptr) {
1878         return; // batching not supported
1879     }
1880 
1881     gnssBatchingIface->flush();
1882 }
1883 
android_location_GnssLocationProvider_stop_batch(JNIEnv *,jclass)1884 static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1885     if (gnssBatchingIface == nullptr) {
1886         return JNI_FALSE; // batching not supported
1887     }
1888 
1889     return gnssBatchingIface->stop();
1890 }
1891 
1892 static const JNINativeMethod sMethods[] = {
1893      /* name, signature, funcPtr */
1894     {"class_init_native", "()V", reinterpret_cast<void *>(
1895             android_location_GnssLocationProvider_class_init_native)},
1896     {"native_is_supported", "()Z", reinterpret_cast<void *>(
1897             android_location_GnssLocationProvider_is_supported)},
1898     {"native_is_agps_ril_supported", "()Z",
1899             reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
1900     {"native_is_gnss_configuration_supported", "()Z",
1901             reinterpret_cast<void *>(
1902                     android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1903     {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1904     {"native_cleanup", "()V", reinterpret_cast<void *>(
1905             android_location_GnssLocationProvider_cleanup)},
1906     {"native_set_position_mode",
1907             "(IIIII)Z",
1908             reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1909     {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1910     {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
1911     {"native_delete_aiding_data",
1912             "(I)V",
1913             reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
1914     {"native_read_sv_status",
1915             "([I[F[F[F[F)I",
1916             reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1917     {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1918             android_location_GnssLocationProvider_read_nmea)},
1919     {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1920             android_location_GnssLocationProvider_inject_time)},
1921     {"native_inject_location",
1922             "(DDF)V",
1923             reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1924     {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1925             android_location_GnssLocationProvider_supports_xtra)},
1926     {"native_inject_xtra_data",
1927             "([BI)V",
1928             reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
1929     {"native_agps_data_conn_open",
1930             "(Ljava/lang/String;I)V",
1931             reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
1932     {"native_agps_data_conn_closed",
1933             "()V",
1934             reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
1935     {"native_agps_data_conn_failed",
1936             "()V",
1937             reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
1938     {"native_agps_set_id",
1939             "(ILjava/lang/String;)V",
1940             reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
1941     {"native_agps_set_ref_location_cellid",
1942             "(IIIII)V",
1943             reinterpret_cast<void *>(
1944                     android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
1945     {"native_set_agps_server",
1946             "(ILjava/lang/String;I)V",
1947             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
1948     {"native_send_ni_response",
1949             "(II)V",
1950             reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
1951     {"native_get_internal_state",
1952             "()Ljava/lang/String;",
1953             reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
1954     {"native_update_network_state",
1955             "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
1956             reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
1957     {"native_is_geofence_supported",
1958             "()Z",
1959             reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
1960     {"native_add_geofence",
1961             "(IDDDIIII)Z",
1962             reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
1963     {"native_remove_geofence",
1964             "(I)Z",
1965             reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1966     {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1967             android_location_GnssLocationProvider_pause_geofence)},
1968     {"native_resume_geofence",
1969             "(II)Z",
1970             reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
1971     {"native_is_measurement_supported",
1972             "()Z",
1973             reinterpret_cast<void *>(
1974                     android_location_GnssLocationProvider_is_measurement_supported)},
1975     {"native_start_measurement_collection",
1976             "()Z",
1977             reinterpret_cast<void *>(
1978                     android_location_GnssLocationProvider_start_measurement_collection)},
1979     {"native_stop_measurement_collection",
1980             "()Z",
1981             reinterpret_cast<void *>(
1982                     android_location_GnssLocationProvider_stop_measurement_collection)},
1983     {"native_is_navigation_message_supported",
1984             "()Z",
1985             reinterpret_cast<void *>(
1986                     android_location_GnssLocationProvider_is_navigation_message_supported)},
1987     {"native_start_navigation_message_collection",
1988             "()Z",
1989             reinterpret_cast<void *>(
1990                     android_location_GnssLocationProvider_start_navigation_message_collection)},
1991     {"native_stop_navigation_message_collection",
1992             "()Z",
1993             reinterpret_cast<void *>(
1994                     android_location_GnssLocationProvider_stop_navigation_message_collection)},
1995     {"native_set_supl_es",
1996             "(I)Z",
1997             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1998     {"native_set_supl_version",
1999             "(I)Z",
2000             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2001     {"native_set_supl_mode",
2002             "(I)Z",
2003             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2004     {"native_set_lpp_profile",
2005             "(I)Z",
2006             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2007     {"native_set_gnss_pos_protocol_select",
2008             "(I)Z",
2009             reinterpret_cast<void *>(
2010                     android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2011     {"native_set_gps_lock",
2012             "(I)Z",
2013             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2014     {"native_set_emergency_supl_pdn",
2015             "(I)Z",
2016             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
2017     {"native_get_batch_size",
2018             "()I",
2019             reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2020     {"native_init_batching",
2021             "()Z",
2022             reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2023     {"native_start_batch",
2024             "(JZ)Z",
2025             reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2026     {"native_flush_batch",
2027             "()V",
2028             reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2029     {"native_stop_batch",
2030             "()Z",
2031             reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2032     {"native_init_batching",
2033             "()Z",
2034             reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2035     {"native_cleanup_batching",
2036             "()V",
2037             reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
2038 };
2039 
register_android_server_location_GnssLocationProvider(JNIEnv * env)2040 int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
2041     return jniRegisterNativeMethods(
2042             env,
2043             "com/android/server/location/GnssLocationProvider",
2044             sMethods,
2045             NELEM(sMethods));
2046 }
2047 
2048 } /* namespace android */
2049