Home | History | Annotate | Download | only in jni
      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 
     43 static jobject mCallbacksObj = NULL;
     44 
     45 static jmethodID method_reportLocation;
     46 static jmethodID method_reportStatus;
     47 static jmethodID method_reportSvStatus;
     48 static jmethodID method_reportAGpsStatus;
     49 static jmethodID method_reportNmea;
     50 static jmethodID method_setEngineCapabilities;
     51 static jmethodID method_setGnssYearOfHardware;
     52 static jmethodID method_setGnssHardwareModelName;
     53 static jmethodID method_xtraDownloadRequest;
     54 static jmethodID method_reportNiNotification;
     55 static jmethodID method_requestLocation;
     56 static jmethodID method_requestRefLocation;
     57 static jmethodID method_requestSetID;
     58 static jmethodID method_requestUtcTime;
     59 static jmethodID method_reportGeofenceTransition;
     60 static jmethodID method_reportGeofenceStatus;
     61 static jmethodID method_reportGeofenceAddStatus;
     62 static jmethodID method_reportGeofenceRemoveStatus;
     63 static jmethodID method_reportGeofencePauseStatus;
     64 static jmethodID method_reportGeofenceResumeStatus;
     65 static jmethodID method_reportMeasurementData;
     66 static jmethodID method_reportNavigationMessages;
     67 static jmethodID method_reportLocationBatch;
     68 static 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  */
     74 static JavaVM* sJvm;
     75 
     76 using android::OK;
     77 using android::sp;
     78 using android::wp;
     79 using android::status_t;
     80 using android::String16;
     81 
     82 using android::hardware::Return;
     83 using android::hardware::Void;
     84 using android::hardware::hidl_vec;
     85 using android::hardware::hidl_death_recipient;
     86 using android::hardware::gnss::V1_0::GnssConstellationType;
     87 using android::hardware::gnss::V1_0::GnssLocation;
     88 using android::hardware::gnss::V1_0::GnssLocationFlags;
     89 
     90 using android::hardware::gnss::V1_0::IAGnss;
     91 using android::hardware::gnss::V1_0::IAGnssCallback;
     92 using android::hardware::gnss::V1_0::IAGnssCallback;
     93 using android::hardware::gnss::V1_0::IAGnssRil;
     94 using android::hardware::gnss::V1_0::IAGnssRilCallback;
     95 using android::hardware::gnss::V1_0::IGnssBatching;
     96 using android::hardware::gnss::V1_0::IGnssBatchingCallback;
     97 using android::hardware::gnss::V1_0::IGnssDebug;
     98 using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
     99 using android::hardware::gnss::V1_0::IGnssGeofencing;
    100 using android::hardware::gnss::V1_0::IGnssNavigationMessage;
    101 using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
    102 using android::hardware::gnss::V1_0::IGnssNi;
    103 using android::hardware::gnss::V1_0::IGnssNiCallback;
    104 using android::hardware::gnss::V1_0::IGnssXtra;
    105 using android::hardware::gnss::V1_0::IGnssXtraCallback;
    106 
    107 using android::hardware::gnss::V1_1::IGnssCallback;
    108 
    109 using android::hidl::base::V1_0::IBase;
    110 
    111 using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
    112 using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
    113 using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
    114 using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
    115 using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
    116 using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
    117 using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
    118 using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
    119 
    120 
    121 struct 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
    133 static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
    134 
    135 sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
    136 sp<IGnss_V1_0> gnssHal = nullptr;
    137 sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
    138 sp<IGnssXtra> gnssXtraIface = nullptr;
    139 sp<IAGnssRil> agnssRilIface = nullptr;
    140 sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
    141 sp<IAGnss> agnssIface = nullptr;
    142 sp<IGnssBatching> gnssBatchingIface = nullptr;
    143 sp<IGnssDebug> gnssDebugIface = nullptr;
    144 sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
    145 sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
    146 sp<IGnssNi> gnssNiIface = nullptr;
    147 sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
    148 sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
    149 sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
    150 
    151 #define WAKE_LOCK_NAME  "GPS"
    152 
    153 namespace android {
    154 
    155 template<class T>
    156 class 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 
    170 template<class T>
    171 void 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 
    181 class 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 
    199 JavaObject::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 
    205 JavaObject::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 
    211 JavaObject::~JavaObject() {
    212     env_->DeleteLocalRef(clazz_);
    213 }
    214 
    215 template<class T>
    216 void JavaObject::callSetter(const char* method_name, T value) {
    217     JavaMethodHelper<T>::callJavaMethod(
    218             env_, clazz_, object_, method_name, value);
    219 }
    220 
    221 template<>
    222 void 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 
    234 jobject JavaObject::get() {
    235     return object_;
    236 }
    237 
    238 // Define Java method signatures for all known types.
    239 template<>
    240 const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
    241 template<>
    242 const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
    243 template<>
    244 const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
    245 template<>
    246 const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
    247 template<>
    248 const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
    249 template<>
    250 const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
    251 template<>
    252 const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
    253 template<>
    254 const char *const JavaMethodHelper<float>::signature_ = "(F)V";
    255 template<>
    256 const char *const JavaMethodHelper<double>::signature_ = "(D)V";
    257 template<>
    258 const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
    259 
    260 #define SET(setter, value) object.callSetter("set" # setter, (value))
    261 
    262 static inline jboolean boolToJbool(bool value) {
    263     return value ? JNI_TRUE : JNI_FALSE;
    264 }
    265 
    266 static 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 
    274 class ScopedJniThreadAttach {
    275 public:
    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 
    308 private:
    309     JNIEnv* mEnv = nullptr;
    310 };
    311 
    312 thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
    313 
    314 static 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 
    330 static 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 
    364 static 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  */
    395 struct 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 
    415 Return<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 
    426 const char* GnssCallback::sNmeaString = nullptr;
    427 size_t GnssCallback::sNmeaStringLength = 0;
    428 
    429 Return<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 
    445 Return<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 
    452 Return<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 
    508 Return<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 
    523 Return<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 
    532 Return<void> GnssCallback::gnssAcquireWakelockCb() {
    533     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
    534     return Void();
    535 }
    536 
    537 Return<void> GnssCallback::gnssReleaseWakelockCb() {
    538     release_wake_lock(WAKE_LOCK_NAME);
    539     return Void();
    540 }
    541 
    542 Return<void> GnssCallback::gnssRequestTimeCb() {
    543     JNIEnv* env = getJniEnv();
    544     env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
    545     checkAndClearExceptionFromCallback(env, __FUNCTION__);
    546     return Void();
    547 }
    548 
    549 Return<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 
    556 Return<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 
    566 class GnssXtraCallback : public IGnssXtraCallback {
    567     Return<void> downloadRequestCb() override;
    568 };
    569 
    570 /*
    571  * GnssXtraCallback class implements the callback methods for the IGnssXtra
    572  * interface.
    573  */
    574 Return<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  */
    585 struct 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 
    605 Return<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 
    626 Return<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 
    642 Return<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 
    657 Return<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 
    671 Return<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 
    685 Return<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  */
    703 struct 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 
    712 Return<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  */
    747 struct 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 
    765 Return<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 
    783 Return<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");
    801 void 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 
    842 jobject 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 
    881 jobjectArray 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 
    915 void 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  */
    940 struct GnssNiCallback : public IGnssNiCallback {
    941     Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
    942             override;
    943 };
    944 
    945 Return<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  */
    976 struct 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 
    987 Return<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 
   1023 Return<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 
   1055 jbyteArray 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  */
   1078 struct AGnssRilCallback : IAGnssRilCallback {
   1079     Return<void> requestSetIdCb(uint32_t setIdFlag) override;
   1080     Return<void> requestRefLocCb() override;
   1081 };
   1082 
   1083 Return<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 
   1090 Return<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  */
   1101 struct 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 
   1110 Return<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 
   1130 static 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 
   1140 static 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 
   1299 static jboolean android_location_GnssLocationProvider_is_supported(
   1300         JNIEnv* /* env */, jclass /* clazz */) {
   1301     return (gnssHal != nullptr) ?  JNI_TRUE : JNI_FALSE;
   1302 }
   1303 
   1304 static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
   1305         JNIEnv* /* env */, jclass /* clazz */) {
   1306     return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
   1307 }
   1308 
   1309 static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
   1310         JNIEnv* /* env */, jclass /* jclazz */) {
   1311     return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
   1312 }
   1313 
   1314 static 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 
   1384 static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
   1385     if (gnssHal != nullptr) {
   1386         gnssHal->cleanup();
   1387     }
   1388 }
   1389 
   1390 static 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 
   1416 static 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 
   1429 static 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 }
   1441 static 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 
   1452 static 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 
   1479 static 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 
   1491 static 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 
   1503 static 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 
   1513 static 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 
   1549 static 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 
   1559 static jboolean android_location_GnssLocationProvider_supports_xtra(
   1560         JNIEnv* /* env */, jobject /* obj */) {
   1561     return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
   1562 }
   1563 
   1564 static 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 
   1576 static 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 
   1596 static 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 
   1609 static 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 
   1622 static 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 
   1640 static 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 
   1650 static 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 
   1723 static 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 
   1751 static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
   1752         JNIEnv* /* env */, jobject /* obj */) {
   1753     return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
   1754 }
   1755 
   1756 static 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 
   1772 static 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 
   1783 static 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 
   1794 static 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 
   1805 static 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 
   1814 static 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 
   1848 static 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 
   1860 static 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 
   1869 static 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 
   1890 static 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 
   1902 static 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 
   1918 static 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 
   1933 static 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 
   1949 static 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 
   1965 static 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 
   1981 static 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 
   1998 static 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 
   2014 static 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 
   2056 static 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 
   2068 static 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 
   2077 static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
   2078     if (gnssBatchingIface == nullptr) {
   2079         return; // batching not supported
   2080     }
   2081     gnssBatchingIface->cleanup();
   2082 }
   2083 
   2084 static 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 
   2101 static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
   2102     if (gnssBatchingIface == nullptr) {
   2103         return; // batching not supported
   2104     }
   2105 
   2106     gnssBatchingIface->flush();
   2107 }
   2108 
   2109 static 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 
   2117 static 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 
   2211 static 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 
   2233 static 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 
   2251 static 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 
   2267 static 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 
   2283 int 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