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