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