diff options
4 files changed, 1291 insertions, 1284 deletions
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 93e86afe2589..4c39c308ef87 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -131,14 +131,11 @@ public class GpsNetInitiatedHandler { public String text; public int requestorIdEncoding; public int textEncoding; - public Bundle extras; }; public static class GpsNiResponse { /* User response, one of the values in GpsUserResponseType */ int userResponse; - /* Optional extra data to pass with the user response */ - Bundle extras; }; private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 45f54a9f8828..54366e6c587c 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -95,7 +95,8 @@ import java.util.Arrays; import java.util.Date; import java.util.Map.Entry; import java.util.Properties; - +import java.util.Map; +import java.util.HashMap; import libcore.io.IoUtils; /** @@ -211,24 +212,18 @@ public class GnssLocationProvider implements LocationProviderInterface { private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2; - // Request ref location - private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1; - private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2; + //TODO(b/33112647): Create gps_debug.conf with commented career parameters. + private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf"; // ref. location info private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1; private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2; - private static final int AGPS_REG_LOCATION_TYPE_MAC = 3; // set id info private static final int AGPS_SETID_TYPE_NONE = 0; private static final int AGPS_SETID_TYPE_IMSI = 1; private static final int AGPS_SETID_TYPE_MSISDN = 2; - private static final String PROPERTIES_FILE_PREFIX = "/etc/gps"; - private static final String PROPERTIES_FILE_SUFFIX = ".conf"; - private static final String DEFAULT_PROPERTIES_FILE = PROPERTIES_FILE_PREFIX + PROPERTIES_FILE_SUFFIX; - private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L; private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L; @@ -501,10 +496,6 @@ public class GnssLocationProvider implements LocationProviderInterface { startNavigating(false); } else if (action.equals(ALARM_TIMEOUT)) { hibernate(); - } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { - checkSmsSuplInit(intent); - } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { - checkWapSuplInit(intent); } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action) || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action) || Intent.ACTION_SCREEN_OFF.equals(action) @@ -557,31 +548,6 @@ public class GnssLocationProvider implements LocationProviderInterface { } } - private void checkSmsSuplInit(Intent intent) { - SmsMessage[] messages = Intents.getMessagesFromIntent(intent); - if (messages == null) { - Log.e(TAG, "Message does not exist in the intent."); - return; - } - - for (SmsMessage message : messages) { - if (message != null && message.mWrappedSmsMessage != null) { - byte[] suplInit = message.getUserData(); - if (suplInit != null) { - native_agps_ni_message(suplInit, suplInit.length); - } - } - } - } - - private void checkWapSuplInit(Intent intent) { - byte[] suplInit = intent.getByteArrayExtra("data"); - if (suplInit == null) { - return; - } - native_agps_ni_message(suplInit,suplInit.length); - } - private void updateLowPowerMode() { // Disable GPS if we are in device idle mode. boolean disableGps = mPowerManager.isDeviceIdleMode(); @@ -602,23 +568,14 @@ public class GnssLocationProvider implements LocationProviderInterface { return native_is_supported(); } + interface SetCarrierProperty { + public boolean set(int value); + } + private void reloadGpsProperties(Context context, Properties properties) { if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size()); loadPropertiesFromResource(context, properties); - boolean isPropertiesLoadedFromFile = false; - final String gpsHardware = SystemProperties.get("ro.hardware.gps"); - - if (!TextUtils.isEmpty(gpsHardware)) { - final String propFilename = - PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX; - isPropertiesLoadedFromFile = - loadPropertiesFromFile(propFilename, properties); - } - if (!isPropertiesLoadedFromFile) { - loadPropertiesFromFile(DEFAULT_PROPERTIES_FILE, properties); - } - if (DEBUG) Log.d(TAG, "GPS properties reloaded, size = " + properties.size()); String lpp_prof = SystemProperties.get(LPP_PROFILE); if (!TextUtils.isEmpty(lpp_prof)) { // override default value of this if lpp_prof is not empty @@ -636,16 +593,37 @@ public class GnssLocationProvider implements LocationProviderInterface { Log.e(TAG, "unable to parse C2K_PORT: " + portString); } } - + /* + * Allow carrier properties to be loaded from a debug configuration file. + */ + loadPropertiesFromFile(DEBUG_PROPERTIES_FILE, properties); if (native_is_gnss_configuration_supported()) { - try { - // Convert properties to string contents and send it to HAL. - ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); - properties.store(baos, null); - native_configuration_update(baos.toString()); - if (DEBUG) Log.d(TAG, "final config = " + baos.toString()); - } catch (IOException ex) { - Log.e(TAG, "failed to dump properties contents"); + Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() { + { + put("SUPL_VER", (val) -> native_set_supl_version(val)); + put("SUPL_MODE", (val) -> native_set_supl_mode(val)); + put("SUPL_ES", (val) -> native_set_supl_es(val)); + put("LPP_PROFILE", (val) -> native_set_lpp_profile(val)); + put("A_GLONASS_POS_PROTOCOL_SELECT", (val) -> native_set_gnss_pos_protocol_select(val)); + put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", (val) -> native_set_emergency_supl_pdn(val)); + put("GPS_LOCK", (val) -> native_set_gps_lock(val)); + } + }; + + for(Entry<String, SetCarrierProperty> entry : map.entrySet()) { + String propertyName = entry.getKey(); + String propertyValueString = properties.getProperty(propertyName); + if (propertyValueString != null) { + try { + int propertyValueInt = Integer.decode(propertyValueString); + boolean result = entry.getValue().set(propertyValueInt); + if (result == false) { + Log.e(TAG, "Unable to set " + propertyName); + } + } catch (NumberFormatException e) { + Log.e(TAG, "unable to parse propertyName: " + propertyValueString); + } + } } } else if (DEBUG) { Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not" @@ -692,7 +670,7 @@ public class GnssLocationProvider implements LocationProviderInterface { } } catch (IOException e) { - Log.w(TAG, "Could not open GPS configuration file " + filename); + Log.v(TAG, "Could not open GPS configuration file " + filename); return false; } return true; @@ -1973,8 +1951,7 @@ public class GnssLocationProvider implements LocationProviderInterface { String requestorId, String text, int requestorIdEncoding, - int textEncoding, - String extras // Encoded extra data + int textEncoding ) { Log.i(TAG, "reportNiNotification: entered"); @@ -2003,28 +1980,6 @@ public class GnssLocationProvider implements LocationProviderInterface { notification.requestorIdEncoding = requestorIdEncoding; notification.textEncoding = textEncoding; - // Process extras, assuming the format is - // one of more lines of "key = value" - Bundle bundle = new Bundle(); - - if (extras == null) extras = ""; - Properties extraProp = new Properties(); - - try { - extraProp.load(new StringReader(extras)); - } - catch (IOException e) - { - Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); - } - - for (Entry<Object, Object> ent : extraProp.entrySet()) - { - bundle.putString((String) ent.getKey(), (String) ent.getValue()); - } - - notification.extras = bundle; - mNIHandler.handleNiNotification(notification); } @@ -2075,7 +2030,7 @@ public class GnssLocationProvider implements LocationProviderInterface { * Called from native code to request reference location info */ - private void requestRefLocation(int flags) { + private void requestRefLocation() { TelephonyManager phone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); final int phoneType = phone.getPhoneType(); @@ -2547,5 +2502,12 @@ public class GnssLocationProvider implements LocationProviderInterface { private native boolean native_stop_navigation_message_collection(); // GNSS Configuration - private static native void native_configuration_update(String configData); + private static native boolean native_set_supl_version(int version); + private static native boolean native_set_supl_mode(int mode); + private static native boolean native_set_supl_es(int es); + private static native boolean native_set_lpp_profile(int lppProfile); + private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect); + private static native boolean native_set_gps_lock(int gpsLock); + private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); + } diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index ac0e622f9664..50a6095912e2 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -73,6 +73,7 @@ LOCAL_SHARED_LIBRARIES += \ libhwbinder \ libutils \ android.hardware.audio.common@2.0 \ + android.hardware.gnss@1.0 \ android.hardware.light@2.0 \ android.hardware.power@1.0 \ android.hardware.thermal@1.0 \ diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 25e819c2c1dc..b0a4297da86e 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -18,10 +18,13 @@ #define LOG_NDEBUG 0 +#include <android/hardware/gnss/1.0/IGnss.h> + +#include <hwbinder/IPCThreadState.h> +#include <hwbinder/ProcessState.h> + #include "JNIHelp.h" #include "jni.h" -#include "hardware/hardware.h" -#include "hardware/gps_internal.h" #include "hardware_legacy/power.h" #include "utils/Log.h" #include "utils/misc.h" @@ -34,6 +37,7 @@ #include <linux/in6.h> #include <pthread.h> #include <string.h> +#include <cinttypes> static jobject mCallbacksObj = NULL; @@ -58,48 +62,157 @@ static jmethodID method_reportGeofenceResumeStatus; static jmethodID method_reportMeasurementData; static jmethodID method_reportNavigationMessages; -static const GpsInterface* sGpsInterface = NULL; -static const GpsXtraInterface* sGpsXtraInterface = NULL; -static const AGpsInterface* sAGpsInterface = NULL; -static const GpsNiInterface* sGpsNiInterface = NULL; -static const GpsDebugInterface* sGpsDebugInterface = NULL; -static const AGpsRilInterface* sAGpsRilInterface = NULL; -static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL; -static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL; -static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL; -static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL; - -#define GPS_MAX_SATELLITE_COUNT 32 -#define GNSS_MAX_SATELLITE_COUNT 64 - -// Let these through, with ID remapped down to 1, 2... by offset -#define GLONASS_SVID_OFFSET 64 -#define GLONASS_SVID_COUNT 24 -#define BEIDOU_SVID_OFFSET 200 -#define BEIDOU_SVID_COUNT 35 - -// Let these through, with ID remapped up (33->120 ... 64->151, etc.) -#define SBAS_SVID_MIN 33 -#define SBAS_SVID_MAX 64 -#define SBAS_SVID_ADD 87 - -// Let these through, with no ID remapping -#define QZSS_SVID_MIN 193 -#define QZSS_SVID_MAX 200 - -#define SVID_SHIFT_WIDTH 7 -#define CONSTELLATION_TYPE_SHIFT_WIDTH 3 - -// temporary storage for GPS callbacks -static GnssSvInfo sGnssSvList[GNSS_MAX_SATELLITE_COUNT]; -static size_t sGnssSvListSize; -static const char* sNmeaString; -static int sNmeaStringLength; +using android::OK; +using android::sp; +using android::status_t; +using android::String16; + +using android::hardware::IPCThreadState; +using android::hardware::ProcessState; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::hidl_vec; + +using android::hardware::gnss::V1_0::IAGnss; +using android::hardware::gnss::V1_0::IAGnssCallback; +using android::hardware::gnss::V1_0::IAGnssCallback; +using android::hardware::gnss::V1_0::IAGnssRil; +using android::hardware::gnss::V1_0::IAGnssRilCallback; +using android::hardware::gnss::V1_0::IGnss; +using android::hardware::gnss::V1_0::IGnssCallback; +using android::hardware::gnss::V1_0::IGnssConfiguration; +using android::hardware::gnss::V1_0::IGnssDebug; +using android::hardware::gnss::V1_0::IGnssGeofenceCallback; +using android::hardware::gnss::V1_0::IGnssGeofencing; +using android::hardware::gnss::V1_0::IGnssMeasurement; +using android::hardware::gnss::V1_0::IGnssMeasurementCallback; +using android::hardware::gnss::V1_0::IGnssNavigationMessage; +using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback; +using android::hardware::gnss::V1_0::IGnssNi; +using android::hardware::gnss::V1_0::IGnssNiCallback; +using android::hardware::gnss::V1_0::IGnssXtra; +using android::hardware::gnss::V1_0::IGnssXtraCallback; + + +sp<IGnss> gnssHal = nullptr; +sp<IGnssXtra> gnssXtraIface = nullptr; +sp<IAGnssRil> agnssRilIface = nullptr; +sp<IGnssGeofencing> gnssGeofencingIface = nullptr; +sp<IAGnss> agnssIface = nullptr; +sp<IGnssDebug> gnssDebugIface = nullptr; +sp<IGnssConfiguration> gnssConfigurationIface = nullptr; +sp<IGnssNi> gnssNiIface = nullptr; +sp<IGnssMeasurement> gnssMeasurementIface = nullptr; +sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr; #define WAKE_LOCK_NAME "GPS" namespace android { +template<class T> +class JavaMethodHelper { + public: + // Helper function to call setter on a Java object. + static void callJavaMethod( + JNIEnv* env, + jclass clazz, + jobject object, + const char* method_name, + T value); + + private: + static const char *const signature_; +}; + +template<class T> +void JavaMethodHelper<T>::callJavaMethod( + JNIEnv* env, + jclass clazz, + jobject object, + const char* method_name, + T value) { + jmethodID method = env->GetMethodID(clazz, method_name, signature_); + env->CallVoidMethod(object, method, value); +} + +class JavaObject { + public: + JavaObject(JNIEnv* env, const char* class_name); + virtual ~JavaObject(); + + template<class T> + void callSetter(const char* method_name, T value); + template<class T> + void callSetter(const char* method_name, T* value, size_t size); + jobject get(); + + private: + JNIEnv* env_; + jclass clazz_; + jobject object_; +}; + +JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) { + clazz_ = env_->FindClass(class_name); + jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V"); + object_ = env_->NewObject(clazz_, ctor); +} + +JavaObject::~JavaObject() { + env_->DeleteLocalRef(clazz_); +} + +template<class T> +void JavaObject::callSetter(const char* method_name, T value) { + JavaMethodHelper<T>::callJavaMethod( + env_, clazz_, object_, method_name, value); +} + +template<> +void JavaObject::callSetter( + const char* method_name, uint8_t* value, size_t size) { + jbyteArray array = env_->NewByteArray(size); + env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value)); + jmethodID method = env_->GetMethodID( + clazz_, + method_name, + "([B)V"); + env_->CallVoidMethod(object_, method, array); + env_->DeleteLocalRef(array); +} + +jobject JavaObject::get() { + return object_; +} + +// Define Java method signatures for all known types. +template<> +const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V"; +template<> +const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V"; +template<> +const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V"; +template<> +const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V"; +template<> +const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V"; +template<> +const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V"; +template<> +const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V"; +template<> +const char *const JavaMethodHelper<float>::signature_ = "(F)V"; +template<> +const char *const JavaMethodHelper<double>::signature_ = "(D)V"; +template<> +const char *const JavaMethodHelper<bool>::signature_ = "(Z)V"; + +#define SET(setter, value) object.callSetter("set" # setter, (value)) + +static inline jboolean boolToJbool(bool value) { + return value ? JNI_TRUE : JNI_FALSE; +} + static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { ALOGE("An exception was thrown by callback '%s'.", methodName); @@ -108,458 +221,641 @@ static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa } } -static void location_callback(GpsLocation* location) -{ - JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags, - (jdouble)location->latitude, (jdouble)location->longitude, - (jdouble)location->altitude, - (jfloat)location->speed, (jfloat)location->bearing, - (jfloat)location->accuracy, (jlong)location->timestamp); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} +/* + * GnssCallback class implements the callback methods for IGnss interface. + */ +struct GnssCallback : public IGnssCallback { + Return<void> gnssLocationCb( + const android::hardware::gnss::V1_0::GnssLocation& location) override; + Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override; + Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override; + Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override; + Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override; + Return<void> gnssAcquireWakelockCb() override; + Return<void> gnssReleaseWakelockCb() override; + Return<void> gnssRequestTimeCb() override; + Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override; + + static GnssSvInfo sGnssSvList[static_cast<uint32_t>( + android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)]; + static size_t sGnssSvListSize; + + static const char* sNmeaString; + static size_t sNmeaStringLength; +}; -static void status_callback(GpsStatus* status) -{ +IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>( + android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)]; +const char* GnssCallback::sNmeaString = nullptr; +size_t GnssCallback::sNmeaStringLength = 0; +size_t GnssCallback::sGnssSvListSize = 0; + +Return<void> GnssCallback::gnssLocationCb( + const ::android::hardware::gnss::V1_0::GnssLocation& location) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mCallbacksObj, method_reportStatus, status->status); + env->CallVoidMethod(mCallbacksObj, + method_reportLocation, + location.gnssLocationFlags, + static_cast<jdouble>(location.latitudeDegrees), + static_cast<jdouble>(location.longitudeDegrees), + static_cast<jdouble>(location.altitudeMeters), + static_cast<jfloat>(location.speedMetersPerSec), + static_cast<jfloat>(location.bearingDegrees), + static_cast<jfloat>(location.accuracyMeters), + static_cast<jlong>(location.timestamp)); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static void sv_status_callback(GpsSvStatus* sv_status) -{ +Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - size_t status_size = sv_status->size; - // Some drives doesn't set the size field correctly. Assume GpsSvStatus_v1 - // if it doesn't provide a valid size. - if (status_size == 0) { - ALOGW("Invalid size of GpsSvStatus found: %zd.", status_size); - } - sGnssSvListSize = sv_status->num_svs; - // Clamp the list size. Legacy GpsSvStatus has only 32 elements in sv_list. - if (sGnssSvListSize > GPS_MAX_SATELLITE_COUNT) { - ALOGW("Too many satellites %zd. Clamps to %d.", - sGnssSvListSize, - GPS_MAX_SATELLITE_COUNT); - sGnssSvListSize = GPS_MAX_SATELLITE_COUNT; - } - uint32_t ephemeris_mask = sv_status->ephemeris_mask; - uint32_t almanac_mask = sv_status->almanac_mask; - uint32_t used_in_fix_mask = sv_status->used_in_fix_mask; - for (size_t i = 0; i < sGnssSvListSize; i++) { - GnssSvInfo& info = sGnssSvList[i]; - info.svid = sv_status->sv_list[i].prn; - // Defacto mapping from the overused API that was designed for GPS-only - if (info.svid >=1 && info.svid <= 32) { - info.constellation = GNSS_CONSTELLATION_GPS; - } else if (info.svid > GLONASS_SVID_OFFSET && - info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) { - info.constellation = GNSS_CONSTELLATION_GLONASS; - info.svid -= GLONASS_SVID_OFFSET; - } else if (info.svid > BEIDOU_SVID_OFFSET && - info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) { - info.constellation = GNSS_CONSTELLATION_BEIDOU; - info.svid -= BEIDOU_SVID_OFFSET; - } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) { - info.constellation = GNSS_CONSTELLATION_SBAS; - info.svid += SBAS_SVID_ADD; - } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) { - info.constellation = GNSS_CONSTELLATION_QZSS; - } else { - ALOGD("Unknown constellation type with Svid = %d.", info.svid); - info.constellation = GNSS_CONSTELLATION_UNKNOWN; - } - info.c_n0_dbhz = sv_status->sv_list[i].snr; - info.elevation = sv_status->sv_list[i].elevation; - info.azimuth = sv_status->sv_list[i].azimuth; - info.flags = GNSS_SV_FLAGS_NONE; - // Only GPS info is valid for these fields, as these masks are just 32 bits, by GPS prn - if (info.constellation == GNSS_CONSTELLATION_GPS) { - int32_t this_svid_mask = (1 << (info.svid - 1)); - if ((ephemeris_mask & this_svid_mask) != 0) { - info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA; - } - if ((almanac_mask & this_svid_mask) != 0) { - info.flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA; - } - if ((used_in_fix_mask & this_svid_mask) != 0) { - info.flags |= GNSS_SV_FLAGS_USED_IN_FIX; - } - } - } - env->CallVoidMethod(mCallbacksObj, method_reportSvStatus); + env->CallVoidMethod(mCallbacksObj, method_reportStatus, status); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static void gnss_sv_status_callback(GnssSvStatus* sv_status) { +Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - size_t status_size = sv_status->size; - // Check the size, and reject the object that has invalid size. - if (status_size != sizeof(GnssSvStatus)) { - ALOGE("Invalid size of GnssSvStatus found: %zd.", status_size); - return; - } - sGnssSvListSize = sv_status->num_svs; - // Clamp the list size - if (sGnssSvListSize > GNSS_MAX_SATELLITE_COUNT) { - ALOGD("Too many satellites %zd. Clamps to %d.", - sGnssSvListSize, - GNSS_MAX_SATELLITE_COUNT); - sGnssSvListSize = GNSS_MAX_SATELLITE_COUNT; + + sGnssSvListSize = svStatus.numSvs; + if (sGnssSvListSize > static_cast<uint32_t>( + android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) { + ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize, + static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)); + sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT); } + // Copy GNSS SV info into sGnssSvList, if any. - if (sGnssSvListSize > 0) { - memcpy(sGnssSvList, - sv_status->gnss_sv_list, - sizeof(GnssSvInfo) * sGnssSvListSize); + if (svStatus.numSvs > 0) { + memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize); } + env->CallVoidMethod(mCallbacksObj, method_reportSvStatus); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) -{ +Return<void> GnssCallback::gnssNmeaCb( + int64_t timestamp, const ::android::hardware::hidl_string& nmea) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - // The Java code will call back to read these values - // We do this to avoid creating unnecessary String objects - sNmeaString = nmea; - sNmeaStringLength = length; + /* + * The Java code will call back to read these values. + * We do this to avoid creating unnecessary String objects. + */ + sNmeaString = nmea.c_str(); + sNmeaStringLength = nmea.size(); + env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static void set_system_info_callback(const GnssSystemInfo* info) { - ALOGD("set_system_info_callback: year_of_hw=%d\n", info->year_of_hw); - JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, - info->year_of_hw); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} +Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) { + ALOGD("%s: %du\n", __func__, capabilities); -static void set_capabilities_callback(uint32_t capabilities) -{ - ALOGD("set_capabilities_callback: %du\n", capabilities); JNIEnv* env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static void acquire_wakelock_callback() -{ +Return<void> GnssCallback::gnssAcquireWakelockCb() { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); + return Void(); } -static void release_wakelock_callback() -{ +Return<void> GnssCallback::gnssReleaseWakelockCb() { release_wake_lock(WAKE_LOCK_NAME); + return Void(); } -static void request_utc_time_callback() -{ +Return<void> GnssCallback::gnssRequestTimeCb() { JNIEnv* env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(mCallbacksObj, method_requestUtcTime); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) { + ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw); + + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, + info.yearOfHw); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) -{ - return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg); -} - -GpsCallbacks sGpsCallbacks = { - sizeof(GpsCallbacks), - location_callback, - status_callback, - sv_status_callback, - nmea_callback, - set_capabilities_callback, - acquire_wakelock_callback, - release_wakelock_callback, - create_thread_callback, - request_utc_time_callback, - set_system_info_callback, - gnss_sv_status_callback, +class GnssXtraCallback : public IGnssXtraCallback { + Return<void> downloadRequestCb() override; }; -static void xtra_download_request_callback() -{ +/* + * GnssXtraCallback class implements the callback methods for the IGnssXtra + * interface. + */ +Return<void> GnssXtraCallback::downloadRequestCb() { JNIEnv* env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest); checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -GpsXtraCallbacks sGpsXtraCallbacks = { - xtra_download_request_callback, - create_thread_callback, +/* + * GnssGeofenceCallback class implements the callback methods for the + * IGnssGeofence interface. + */ +struct GnssGeofenceCallback : public IGnssGeofenceCallback { + // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow. + Return<void> gnssGeofenceTransitionCb( + int32_t geofenceId, + const android::hardware::gnss::V1_0::GnssLocation& location, + GeofenceTransition transition, + hardware::gnss::V1_0::GnssUtcTime timestamp) override; + Return<void> gnssGeofenceStatusCb( + GeofenceAvailability status, + const android::hardware::gnss::V1_0::GnssLocation& location) override; + Return<void> gnssGeofenceAddCb(int32_t geofenceId, + GeofenceStatus status) override; + Return<void> gnssGeofenceRemoveCb(int32_t geofenceId, + GeofenceStatus status) override; + Return<void> gnssGeofencePauseCb(int32_t geofenceId, + GeofenceStatus status) override; + Return<void> gnssGeofenceResumeCb(int32_t geofenceId, + GeofenceStatus status) override; }; -static jbyteArray convert_to_ipv4(uint32_t ip, bool net_order) -{ - if (INADDR_NONE == ip) { - return NULL; - } +Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb( + int32_t geofenceId, + const android::hardware::gnss::V1_0::GnssLocation& location, + GeofenceTransition transition, + hardware::gnss::V1_0::GnssUtcTime timestamp) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + + env->CallVoidMethod(mCallbacksObj, + method_reportGeofenceTransition, + geofenceId, + location.gnssLocationFlags, + static_cast<jdouble>(location.latitudeDegrees), + static_cast<jdouble>(location.longitudeDegrees), + static_cast<jdouble>(location.altitudeMeters), + static_cast<jfloat>(location.speedMetersPerSec), + static_cast<jfloat>(location.bearingDegrees), + static_cast<jfloat>(location.accuracyMeters), + static_cast<jlong>(location.timestamp), + transition, + timestamp); + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} +Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb( + GeofenceAvailability status, + const android::hardware::gnss::V1_0::GnssLocation& location) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - jbyteArray byteArray = env->NewByteArray(4); - if (byteArray == NULL) { - ALOGE("Unable to allocate byte array for IPv4 address"); - return NULL; - } + env->CallVoidMethod(mCallbacksObj, + method_reportGeofenceStatus, + status, + location.gnssLocationFlags, + static_cast<jdouble>(location.latitudeDegrees), + static_cast<jdouble>(location.longitudeDegrees), + static_cast<jdouble>(location.altitudeMeters), + static_cast<jfloat>(location.speedMetersPerSec), + static_cast<jfloat>(location.bearingDegrees), + static_cast<jfloat>(location.accuracyMeters), + static_cast<jlong>(location.timestamp)); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} - jbyte ipv4[4]; - if (net_order) { - ALOGV("Converting IPv4 address(net_order) %x", ip); - memcpy(ipv4, &ip, sizeof(ipv4)); - } else { - ALOGV("Converting IPv4 address(host_order) %x", ip); - //endianess transparent conversion from int to char[] - ipv4[0] = (jbyte) (ip & 0xFF); - ipv4[1] = (jbyte)((ip>>8) & 0xFF); - ipv4[2] = (jbyte)((ip>>16) & 0xFF); - ipv4[3] = (jbyte) (ip>>24); +Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId, + GeofenceStatus status) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) { + ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status); } - env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*) ipv4); - return byteArray; + env->CallVoidMethod(mCallbacksObj, + method_reportGeofenceAddStatus, + geofenceId, + status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -static void agps_status_callback(AGpsStatus* agps_status) -{ +Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId, + GeofenceStatus status) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - jbyteArray byteArray = NULL; - bool isSupported = false; - - size_t status_size = agps_status->size; - if (status_size == sizeof(AGpsStatus)) { - ALOGV("AGpsStatus is V3: %zd", status_size); - switch (agps_status->addr.ss_family) - { - case AF_INET: - { - struct sockaddr_in *in = (struct sockaddr_in*)&(agps_status->addr); - uint32_t ipAddr = *(uint32_t*)&(in->sin_addr); - byteArray = convert_to_ipv4(ipAddr, true /* net_order */); - if (ipAddr == INADDR_NONE || byteArray != NULL) { - isSupported = true; - } - IF_ALOGD() { - // log the IP for reference in case there is a bogus value pushed by HAL - char str[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &(in->sin_addr), str, INET_ADDRSTRLEN); - ALOGD("AGPS IP is v4: %s", str); - } - } - break; - case AF_INET6: - { - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(agps_status->addr); - byteArray = env->NewByteArray(16); - if (byteArray != NULL) { - env->SetByteArrayRegion(byteArray, 0, 16, (const jbyte *)&(in6->sin6_addr)); - isSupported = true; - } else { - ALOGE("Unable to allocate byte array for IPv6 address."); - } - IF_ALOGD() { - // log the IP for reference in case there is a bogus value pushed by HAL - char str[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &(in6->sin6_addr), str, INET6_ADDRSTRLEN); - ALOGD("AGPS IP is v6: %s", str); - } - } - break; - default: - ALOGE("Invalid ss_family found: %d", agps_status->addr.ss_family); - break; - } - } else if (status_size >= sizeof(AGpsStatus_v2)) { - ALOGV("AGpsStatus is V2+: %zd", status_size); - // for back-compatibility reasons we check in v2 that the data structure size is greater or - // equal to the declared size in gps.h - uint32_t ipaddr = agps_status->ipaddr; - ALOGV("AGPS IP is v4: %x", ipaddr); - byteArray = convert_to_ipv4(ipaddr, false /* net_order */); - if (ipaddr == INADDR_NONE || byteArray != NULL) { - isSupported = true; - } - } else if (status_size >= sizeof(AGpsStatus_v1)) { - ALOGV("AGpsStatus is V1+: %zd", status_size); - // because we have to check for >= with regards to v2, we also need to relax the check here - // and only make sure that the size is at least what we expect - isSupported = true; - } else { - ALOGE("Invalid size of AGpsStatus found: %zd.", status_size); + if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) { + ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status); } - if (isSupported) { - jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0; - ALOGV("Passing AGPS IP addr: size %d", byteArrayLength); - env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, agps_status->type, - agps_status->status, byteArray); + env->CallVoidMethod(mCallbacksObj, + method_reportGeofenceRemoveStatus, + geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} - checkAndClearExceptionFromCallback(env, __FUNCTION__); - } else { - ALOGD("Skipping calling method_reportAGpsStatus."); +Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId, + GeofenceStatus status) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) { + ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status); } - if (byteArray) { - env->DeleteLocalRef(byteArray); + env->CallVoidMethod(mCallbacksObj, + method_reportGeofencePauseStatus, + geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId, + GeofenceStatus status) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) { + ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status); } + + env->CallVoidMethod(mCallbacksObj, + method_reportGeofenceResumeStatus, + geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); } -AGpsCallbacks sAGpsCallbacks = { - agps_status_callback, - create_thread_callback, +/* + * GnssNavigationMessageCallback interface implements the callback methods + * required by the IGnssNavigationMessage interface. + */ +struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback { + /* + * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback + * follow. + */ + Return<void> gnssNavigationMessageCb( + const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override; }; -static void gps_ni_notify_callback(GpsNiNotification *notification) -{ - ALOGD("gps_ni_notify_callback\n"); +Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb( + const IGnssNavigationMessageCallback::GnssNavigationMessage& message) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - jstring requestor_id = env->NewStringUTF(notification->requestor_id); - jstring text = env->NewStringUTF(notification->text); - jstring extras = env->NewStringUTF(notification->extras); - if (requestor_id && text && extras) { - env->CallVoidMethod(mCallbacksObj, method_reportNiNotification, - notification->notification_id, notification->ni_type, - notification->notify_flags, notification->timeout, - notification->default_response, requestor_id, text, - notification->requestor_id_encoding, - notification->text_encoding, extras); - } else { - ALOGE("out of memory in gps_ni_notify_callback\n"); + size_t dataLength = message.data.size(); + + std::vector<uint8_t> navigationData = message.data; + uint8_t* data = &(navigationData[0]); + if (dataLength == 0 || data == NULL) { + ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, + dataLength); + return Void(); } - if (requestor_id) - env->DeleteLocalRef(requestor_id); - if (text) - env->DeleteLocalRef(text); - if (extras) - env->DeleteLocalRef(extras); - checkAndClearExceptionFromCallback(env, __FUNCTION__); + JavaObject object(env, "android/location/GnssNavigationMessage"); + SET(Type, static_cast<int32_t>(message.type)); + SET(Svid, static_cast<int32_t>(message.svid)); + SET(MessageId, static_cast<int32_t>(message.messageId)); + SET(SubmessageId, static_cast<int32_t>(message.submessageId)); + object.callSetter("setData", data, dataLength); + SET(Status, static_cast<int32_t>(message.status)); + + jobject navigationMessage = object.get(); + env->CallVoidMethod(mCallbacksObj, + method_reportNavigationMessages, + navigationMessage); + env->DeleteLocalRef(navigationMessage); + return Void(); } -GpsNiCallbacks sGpsNiCallbacks = { - gps_ni_notify_callback, - create_thread_callback, +/* + * GnssMeasurementCallback implements the callback methods required for the + * GnssMeasurement interface. + */ +struct GnssMeasurementCallback : public IGnssMeasurementCallback { + Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data); + private: + jobject translateGnssMeasurement( + JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement); + jobject translateGnssClock( + JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock); + jobjectArray translateGnssMeasurements( + JNIEnv* env, + const IGnssMeasurementCallback::GnssMeasurement* measurements, + size_t count); + void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray); }; -static void agps_request_set_id(uint32_t flags) -{ + +Return<void> GnssMeasurementCallback::GnssMeasurementCb( + const IGnssMeasurementCallback::GnssData& data) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags); - checkAndClearExceptionFromCallback(env, __FUNCTION__); + + jobject clock; + jobjectArray measurementArray; + + clock = translateGnssClock(env, &data.clock); + measurementArray = translateGnssMeasurements( + env, data.measurements.data(), data.measurementCount); + setMeasurementData(env, clock, measurementArray); + + env->DeleteLocalRef(clock); + env->DeleteLocalRef(measurementArray); + return Void(); } -static void agps_request_ref_location(uint32_t flags) -{ - JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags); - checkAndClearExceptionFromCallback(env, __FUNCTION__); +jobject GnssMeasurementCallback::translateGnssMeasurement( + JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) { + JavaObject object(env, "android/location/GnssMeasurement"); + + uint32_t flags = static_cast<uint32_t>(measurement->flags); + + SET(Svid, static_cast<int32_t>(measurement->svid)); + SET(ConstellationType, static_cast<int32_t>(measurement->constellation)); + SET(TimeOffsetNanos, measurement->timeOffsetNs); + SET(State, static_cast<int32_t>(measurement->state)); + SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs); + SET(ReceivedSvTimeUncertaintyNanos, + measurement->receivedSvTimeUncertaintyInNs); + SET(Cn0DbHz, measurement->cN0DbHz); + SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps); + SET(PseudorangeRateUncertaintyMetersPerSecond, + measurement->pseudorangeRateUncertaintyMps); + SET(AccumulatedDeltaRangeState, + (static_cast<int32_t>(measurement->accumulatedDeltaRangeState))); + SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM); + SET(AccumulatedDeltaRangeUncertaintyMeters, + measurement->accumulatedDeltaRangeUncertaintyM); + + if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) { + SET(CarrierFrequencyHz, measurement->carrierFrequencyHz); + } + + if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) { + SET(CarrierPhase, measurement->carrierPhase); + } + + if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) { + SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty); + } + + SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator)); + + if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) { + SET(SnrInDb, measurement->snrDb); + } + + return object.get(); } -AGpsRilCallbacks sAGpsRilCallbacks = { - agps_request_set_id, - agps_request_ref_location, - create_thread_callback, -}; +jobject GnssMeasurementCallback::translateGnssClock( + JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) { + JavaObject object(env, "android/location/GnssClock"); -static void gps_geofence_transition_callback(int32_t geofence_id, GpsLocation* location, - int32_t transition, GpsUtcTime timestamp) -{ - JNIEnv* env = AndroidRuntime::getJNIEnv(); + uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags); + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) { + SET(LeapSecond, static_cast<int32_t>(clock->leapSecond)); + } + + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) { + SET(TimeUncertaintyNanos, clock->timeUncertaintyNs); + } + + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) { + SET(FullBiasNanos, clock->fullBiasNs); + } + + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) { + SET(BiasNanos, clock->biasNs); + } + + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) { + SET(BiasUncertaintyNanos, clock->biasUncertaintyNs); + } + + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) { + SET(DriftNanosPerSecond, clock->driftNsps); + } + + if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) { + SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps); + } + + SET(TimeNanos, clock->timeNs); + SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount); + + return object.get(); +} + +jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env, + const IGnssMeasurementCallback::GnssMeasurement* + measurements, size_t count) { + if (count == 0) { + return NULL; + } + + jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement"); + jobjectArray gnssMeasurementArray = env->NewObjectArray( + count, + gnssMeasurementClass, + NULL /* initialElement */); - env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofence_id, - location->flags, (jdouble)location->latitude, (jdouble)location->longitude, - (jdouble)location->altitude, - (jfloat)location->speed, (jfloat)location->bearing, - (jfloat)location->accuracy, (jlong)location->timestamp, - transition, timestamp); + for (uint16_t i = 0; i < count; ++i) { + jobject gnssMeasurement = translateGnssMeasurement( + env, + &measurements[i]); + env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement); + env->DeleteLocalRef(gnssMeasurement); + } + + env->DeleteLocalRef(gnssMeasurementClass); + return gnssMeasurementArray; +} + +void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock, + jobjectArray measurementArray) { + jclass gnssMeasurementsEventClass = + env->FindClass("android/location/GnssMeasurementsEvent"); + jmethodID gnssMeasurementsEventCtor = + env->GetMethodID( + gnssMeasurementsEventClass, + "<init>", + "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V"); + + jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass, + gnssMeasurementsEventCtor, + clock, + measurementArray); + + env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, + gnssMeasurementsEvent); checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(gnssMeasurementsEventClass); + env->DeleteLocalRef(gnssMeasurementsEvent); +} + +/* + * GnssNiCallback implements callback methods required by the IGnssNi interface. + */ +struct GnssNiCallback : public IGnssNiCallback { + Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification) + override; }; -static void gps_geofence_status_callback(int32_t status, GpsLocation* location) -{ +Return<void> GnssNiCallback::niNotifyCb( + const IGnssNiCallback::GnssNiNotification& notification) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - jint flags = 0; - jdouble latitude = 0; - jdouble longitude = 0; - jdouble altitude = 0; - jfloat speed = 0; - jfloat bearing = 0; - jfloat accuracy = 0; - jlong timestamp = 0; - if (location != NULL) { - flags = location->flags; - latitude = location->latitude; - longitude = location->longitude; - altitude = location->altitude; - speed = location->speed; - bearing = location->bearing; - accuracy = location->accuracy; - timestamp = location->timestamp; - } - - env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status, - flags, latitude, longitude, altitude, speed, bearing, accuracy, timestamp); + jstring requestorId = env->NewStringUTF(notification.requestorId.c_str()); + jstring text = env->NewStringUTF(notification.notificationMessage.c_str()); + + if (requestorId && text) { + env->CallVoidMethod(mCallbacksObj, method_reportNiNotification, + notification.notificationId, notification.niType, + notification.notifyFlags, notification.timeoutSec, + notification.defaultResponse, requestorId, text, + notification.requestorIdEncoding, + notification.notificationIdEncoding); + } else { + ALOGE("%s: OOM Error\n", __func__); + } + + if (requestorId) { + env->DeleteLocalRef(requestorId); + } + + if (text) { + env->DeleteLocalRef(text); + } checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +/* + * AGnssCallback implements callback methods required by the IAGnss interface. + */ +struct AGnssCallback : public IAGnssCallback { + // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow. + Return<void> agnssStatusIpV6Cb( + const IAGnssCallback::AGnssStatusIpV6& agps_status) override; + + Return<void> agnssStatusIpV4Cb( + const IAGnssCallback::AGnssStatusIpV4& agps_status) override; + private: + jbyteArray convertToIpV4(uint32_t ip); }; -static void gps_geofence_add_callback(int32_t geofence_id, int32_t status) -{ +Return<void> AGnssCallback::agnssStatusIpV6Cb( + const IAGnssCallback::AGnssStatusIpV6& agps_status) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (status != GPS_GEOFENCE_OPERATION_SUCCESS) { - ALOGE("Error in geofence_add_callback: %d\n", status); + jbyteArray byteArray = NULL; + bool isSupported = false; + + byteArray = env->NewByteArray(16); + if (byteArray != NULL) { + env->SetByteArrayRegion(byteArray, 0, 16, + (const jbyte*)(agps_status.ipV6Addr.data())); + isSupported = true; + } else { + ALOGE("Unable to allocate byte array for IPv6 address."); + } + + IF_ALOGD() { + // log the IP for reference in case there is a bogus value pushed by HAL + char str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN); + ALOGD("AGPS IP is v6: %s", str); } - env->CallVoidMethod(mCallbacksObj, method_reportGeofenceAddStatus, geofence_id, status); + + jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0; + ALOGV("Passing AGPS IP addr: size %d", byteArrayLength); + env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, + agps_status.type, agps_status.status, byteArray); + checkAndClearExceptionFromCallback(env, __FUNCTION__); -}; -static void gps_geofence_remove_callback(int32_t geofence_id, int32_t status) -{ + if (byteArray) { + env->DeleteLocalRef(byteArray); + } + + return Void(); +} + +Return<void> AGnssCallback::agnssStatusIpV4Cb( + const IAGnssCallback::AGnssStatusIpV4& agps_status) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (status != GPS_GEOFENCE_OPERATION_SUCCESS) { - ALOGE("Error in geofence_remove_callback: %d\n", status); + jbyteArray byteArray = NULL; + + uint32_t ipAddr = agps_status.ipV4Addr; + byteArray = convertToIpV4(ipAddr); + + IF_ALOGD() { + /* + * log the IP for reference in case there is a bogus value pushed by + * HAL. + */ + char str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN); + ALOGD("AGPS IP is v4: %s", str); } - env->CallVoidMethod(mCallbacksObj, method_reportGeofenceRemoveStatus, geofence_id, status); + + jsize byteArrayLength = + byteArray != NULL ? env->GetArrayLength(byteArray) : 0; + ALOGV("Passing AGPS IP addr: size %d", byteArrayLength); + env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, + agps_status.type, agps_status.status, byteArray); + checkAndClearExceptionFromCallback(env, __FUNCTION__); -}; -static void gps_geofence_resume_callback(int32_t geofence_id, int32_t status) -{ + if (byteArray) { + env->DeleteLocalRef(byteArray); + } + return Void(); +} + +jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) { + if (INADDR_NONE == ip) { + return NULL; + } + JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (status != GPS_GEOFENCE_OPERATION_SUCCESS) { - ALOGE("Error in geofence_resume_callback: %d\n", status); + jbyteArray byteArray = env->NewByteArray(4); + if (byteArray == NULL) { + ALOGE("Unable to allocate byte array for IPv4 address"); + return NULL; } - env->CallVoidMethod(mCallbacksObj, method_reportGeofenceResumeStatus, geofence_id, status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); + + jbyte ipv4[4]; + ALOGV("Converting IPv4 address byte array (net_order) %x", ip); + memcpy(ipv4, &ip, sizeof(ipv4)); + env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4); + return byteArray; +} + +/* + * AGnssRilCallback implements the callback methods required by the AGnssRil + * interface. + */ +struct AGnssRilCallback : IAGnssRilCallback { + Return<void> requestSetIdCb(IAGnssRilCallback::ID setIdFlag) override; + Return<void> requestRefLocCb() override; }; -static void gps_geofence_pause_callback(int32_t geofence_id, int32_t status) -{ +Return<void> AGnssRilCallback::requestSetIdCb(IAGnssRilCallback::ID setIdFlag) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (status != GPS_GEOFENCE_OPERATION_SUCCESS) { - ALOGE("Error in geofence_pause_callback: %d\n", status); - } - env->CallVoidMethod(mCallbacksObj, method_reportGeofencePauseStatus, geofence_id, status); + env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag); checkAndClearExceptionFromCallback(env, __FUNCTION__); -}; + return Void(); +} -GpsGeofenceCallbacks sGpsGeofenceCallbacks = { - gps_geofence_transition_callback, - gps_geofence_status_callback, - gps_geofence_add_callback, - gps_geofence_remove_callback, - gps_geofence_pause_callback, - gps_geofence_resume_callback, - create_thread_callback, -}; +Return<void> AGnssRilCallback::requestRefLocCb() { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestRefLocation); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { - int err; - hw_module_t* module; - method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); @@ -569,21 +865,21 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", - "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V"); - method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V"); - method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V"); - method_requestUtcTime = env->GetMethodID(clazz,"requestUtcTime","()V"); - method_reportGeofenceTransition = env->GetMethodID(clazz,"reportGeofenceTransition", + "(IIIIILjava/lang/String;Ljava/lang/String;II)V"); + method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V"); + method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); + method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); + method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition", "(IIDDDFFFJIJ)V"); - method_reportGeofenceStatus = env->GetMethodID(clazz,"reportGeofenceStatus", + method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus", "(IIDDDFFFJ)V"); - method_reportGeofenceAddStatus = env->GetMethodID(clazz,"reportGeofenceAddStatus", + method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus", "(II)V"); - method_reportGeofenceRemoveStatus = env->GetMethodID(clazz,"reportGeofenceRemoveStatus", + method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus", "(II)V"); - method_reportGeofenceResumeStatus = env->GetMethodID(clazz,"reportGeofenceResumeStatus", + method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus", "(II)V"); - method_reportGeofencePauseStatus = env->GetMethodID(clazz,"reportGeofencePauseStatus", + method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus", "(II)V"); method_reportMeasurementData = env->GetMethodID( clazz, @@ -594,274 +890,350 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, "reportNavigationMessage", "(Landroid/location/GnssNavigationMessage;)V"); - err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); - if (err == 0) { - hw_device_t* device; - err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); - if (err == 0) { - gps_device_t* gps_device = (gps_device_t *)device; - sGpsInterface = gps_device->get_gps_interface(gps_device); + // TODO(b/31632518) + gnssHal = IGnss::getService("gnss"); + if (gnssHal != nullptr) { + auto result = gnssHal->getExtensionXtra([](const sp<IGnssXtra>& xtraIface) { + gnssXtraIface = xtraIface; + }); + + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to Xtra"); } + + result = gnssHal->getExtensionAGnssRil([](const sp<IAGnssRil>& rilIface) { + agnssRilIface = rilIface; + }); + + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to AGnssRil"); + } + + result = gnssHal->getExtensionAGnss([](const sp<IAGnss>& assistedGnssIface) { + agnssIface = assistedGnssIface; + }); + + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to AGnss"); + } + + result = gnssHal->getExtensionGnssNavigationMessage( + [](const sp<IGnssNavigationMessage>& navigationMessageIface) { + gnssNavigationMessageIface = navigationMessageIface; + }); + + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to GnssNavigationMessage"); + } + + result = gnssHal->getExtensionGnssMeasurement([]( + const sp<IGnssMeasurement>& measurementIface) { + gnssMeasurementIface = measurementIface; + }); + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to GnssMeasurement"); + } + + result = gnssHal->getExtensionGnssDebug([](const sp<IGnssDebug>& debugIface) { + gnssDebugIface = debugIface; + }); + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to GnssDebug"); + } + + result = gnssHal->getExtensionGnssNi([](const sp<IGnssNi>& niIface) { + gnssNiIface = niIface; + }); + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to GnssNi"); + } + + result = gnssHal->getExtensionGnssConfiguration([](const sp<IGnssConfiguration>& configIface) { + gnssConfigurationIface = configIface; + }); + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to GnssConfiguration"); + } + + result = gnssHal->getExtensionGnssGeofencing([](const sp<IGnssGeofencing>& geofenceIface) { + gnssGeofencingIface = geofenceIface; + }); + if (!result.getStatus().isOk()) { + ALOGD("Unable to get a handle to GnssGeofencing"); + } + + } else { + ALOGE("Unable to get GPS service\n"); } - if (sGpsInterface) { - sGpsXtraInterface = - (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); - sAGpsInterface = - (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); - sGpsNiInterface = - (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); - sGpsDebugInterface = - (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE); - sAGpsRilInterface = - (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); - sGpsGeofencingInterface = - (const GpsGeofencingInterface*)sGpsInterface->get_extension(GPS_GEOFENCING_INTERFACE); - sGpsMeasurementInterface = - (const GpsMeasurementInterface*)sGpsInterface->get_extension(GPS_MEASUREMENT_INTERFACE); - sGpsNavigationMessageInterface = - (const GpsNavigationMessageInterface*)sGpsInterface->get_extension( - GPS_NAVIGATION_MESSAGE_INTERFACE); - sGnssConfigurationInterface = - (const GnssConfigurationInterface*)sGpsInterface->get_extension( - GNSS_CONFIGURATION_INTERFACE); - } + ProcessState::self()->setThreadPoolMaxThreadCount(0); + ProcessState::self()->startThreadPool(); } static jboolean android_location_GnssLocationProvider_is_supported( - JNIEnv* /* env */, jclass /* clazz */) -{ - return (sGpsInterface != NULL) ? JNI_TRUE : JNI_FALSE; + JNIEnv* /* env */, jclass /* clazz */) { + return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE; } static jboolean android_location_GnssLocationProvider_is_agps_ril_supported( - JNIEnv* /* env */, jclass /* clazz */) -{ - return (sAGpsRilInterface != NULL) ? JNI_TRUE : JNI_FALSE; + JNIEnv* /* env */, jclass /* clazz */) { + return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE; } static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported( - JNIEnv* /* env */, jclass /* jclazz */) -{ - return (sGnssConfigurationInterface != NULL) ? JNI_TRUE : JNI_FALSE; + JNIEnv* /* env */, jclass /* jclazz */) { + return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE; } -static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) -{ - // this must be set before calling into the HAL library +static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) { + /* + * This must be set before calling into the HAL library. + */ if (!mCallbacksObj) mCallbacksObj = env->NewGlobalRef(obj); - // fail if the main interface fails to initialize - if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) + sp<IGnssCallback> gnssCbIface = new GnssCallback(); + /* + * Fail if the main interface fails to initialize + */ + if (gnssHal == nullptr) { + ALOGE("Unable to Initialize GNSS HAL\n"); return JNI_FALSE; + } + + auto result = gnssHal->setCallback(gnssCbIface); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("SetCallback for Gnss Interface fails\n"); + return JNI_FALSE; + } - // if XTRA initialization fails we will disable it by sGpsXtraInterface to NULL, - // but continue to allow the rest of the GPS interface to work. - if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0) - sGpsXtraInterface = NULL; - if (sAGpsInterface) - sAGpsInterface->init(&sAGpsCallbacks); - if (sGpsNiInterface) - sGpsNiInterface->init(&sGpsNiCallbacks); - if (sAGpsRilInterface) - sAGpsRilInterface->init(&sAGpsRilCallbacks); - if (sGpsGeofencingInterface) - sGpsGeofencingInterface->init(&sGpsGeofenceCallbacks); + sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback(); + if (gnssXtraIface == nullptr) { + ALOGE("Unable to initialize GNSS Xtra interface\n"); + } + + result = gnssXtraIface->setCallback(gnssXtraCbIface); + if ((!result) || (!result.getStatus().isOk())) { + gnssXtraIface = nullptr; + ALOGE("SetCallback for Gnss Xtra Interface fails\n"); + } + + sp<IAGnssCallback> aGnssCbIface = new AGnssCallback(); + if (agnssIface != nullptr) { + agnssIface->setCallback(aGnssCbIface); + } else { + ALOGE("Unable to Initialize AGnss interface\n"); + } + + sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback(); + if (gnssGeofencingIface != nullptr) { + gnssGeofencingIface->setCallback(gnssGeofencingCbIface); + } else { + ALOGE("Unable to initialize GNSS Geofencing interface\n"); + } + + sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback(); + if (gnssNiCbIface != nullptr) { + gnssNiIface->setCallback(gnssNiCbIface); + } else { + ALOGE("Unable to initialize GNSS NI interface\n"); + } return JNI_TRUE; } -static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) -{ - if (sGpsInterface) - sGpsInterface->cleanup(); +static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) { + if (gnssHal != nullptr) { + gnssHal->cleanup(); + } } static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */, jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, - jint preferred_time) -{ - if (sGpsInterface) { - if (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy, - preferred_time) == 0) { - return JNI_TRUE; - } else { + jint preferred_time) { + if (gnssHal != nullptr) { + auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode), + static_cast<IGnss::GnssPositionRecurrence>(recurrence), + min_interval, + preferred_accuracy, + preferred_time); + if (!result.getStatus().isOk()) { + ALOGE("%s: GNSS setPositionMode failed\n", __func__); return JNI_FALSE; + } else { + return result; } - } - else + } else { return JNI_FALSE; + } } -static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) -{ - if (sGpsInterface) { - if (sGpsInterface->start() == 0) { - return JNI_TRUE; - } else { +static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) { + if (gnssHal != nullptr) { + auto result = gnssHal->start(); + if (!result.getStatus().isOk()) { return JNI_FALSE; + } else { + return result; } - } - else + } else { return JNI_FALSE; + } } -static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) -{ - if (sGpsInterface) { - if (sGpsInterface->stop() == 0) { - return JNI_TRUE; - } else { +static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) { + if (gnssHal != nullptr) { + auto result = gnssHal->stop(); + if (!result.getStatus().isOk()) { return JNI_FALSE; + } else { + return result; } - } - else + } else { return JNI_FALSE; + } } - static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */, jobject /* obj */, - jint flags) -{ - if (sGpsInterface) - sGpsInterface->delete_aiding_data(flags); + jint flags) { + if (gnssHal != nullptr) { + auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags)); + if (!result.getStatus().isOk()) { + ALOGE("Error in deleting aiding data"); + } + } } +/* + * This enum is used by the read_sv_status method to combine the svid, + * constellation and svFlag fields. + */ +enum ShiftWidth: uint8_t { + SVID_SHIFT_WIDTH = 7, + CONSTELLATION_TYPE_SHIFT_WIDTH = 3 +}; + static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */, jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray, - jfloatArray azumArray) -{ - // this should only be called from within a call to reportSvStatus + jfloatArray azumArray) { + /* + * This method should only be called from within a call to reportSvStatus. + */ jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0); jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0); jfloat* elev = env->GetFloatArrayElements(elevArray, 0); jfloat* azim = env->GetFloatArrayElements(azumArray, 0); - // GNSS SV info. - for (size_t i = 0; i < sGnssSvListSize; ++i) { - const GnssSvInfo& info = sGnssSvList[i]; + /* + * Read GNSS SV info. + */ + for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) { + const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i]; svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) | - (info.constellation << CONSTELLATION_TYPE_SHIFT_WIDTH) | - info.flags; - cn0s[i] = info.c_n0_dbhz; - elev[i] = info.elevation; - azim[i] = info.azimuth; + (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) | + static_cast<uint32_t>(info.svFlag); + cn0s[i] = info.cN0Dbhz; + elev[i] = info.elevationDegrees; + azim[i] = info.azimuthDegrees; } env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0); env->ReleaseFloatArrayElements(cn0Array, cn0s, 0); env->ReleaseFloatArrayElements(elevArray, elev, 0); env->ReleaseFloatArrayElements(azumArray, azim, 0); - return (jint) sGnssSvListSize; + return static_cast<jint>(GnssCallback::sGnssSvListSize); } static void android_location_GnssLocationProvider_agps_set_reference_location_cellid( - JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) -{ - AGpsRefLocation location; + JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) { + IAGnssRil::AGnssRefLocation location; - if (!sAGpsRilInterface) { - ALOGE("no AGPS RIL interface in agps_set_reference_location_cellid"); + if (agnssRilIface == nullptr) { + ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid"); return; } - switch(type) { - case AGPS_REF_LOCATION_TYPE_GSM_CELLID: - case AGPS_REF_LOCATION_TYPE_UMTS_CELLID: - location.type = type; - location.u.cellID.mcc = mcc; - location.u.cellID.mnc = mnc; - location.u.cellID.lac = lac; - location.u.cellID.cid = cid; - break; + switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) { + case IAGnssRil::AGnssRefLocationType::GSM_CELLID: + case IAGnssRil::AGnssRefLocationType::UMTS_CELLID: + location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type); + location.cellID.mcc = mcc; + location.cellID.mnc = mnc; + location.cellID.lac = lac; + location.cellID.cid = cid; + break; default: - ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__); + ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__); return; break; } - sAGpsRilInterface->set_ref_location(&location, sizeof(location)); -} - -static void android_location_GnssLocationProvider_agps_send_ni_message(JNIEnv* env, - jobject /* obj */, jbyteArray ni_msg, jint size) -{ - size_t sz; - if (!sAGpsRilInterface) { - ALOGE("no AGPS RIL interface in send_ni_message"); - return; - } - if (size < 0) - return; - sz = (size_t)size; - jbyte* b = env->GetByteArrayElements(ni_msg, 0); - sAGpsRilInterface->ni_message((uint8_t *)b,sz); - env->ReleaseByteArrayElements(ni_msg,b,0); + agnssRilIface->setRefLocation(location); } static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */, - jint type, jstring setid_string) -{ - if (!sAGpsRilInterface) { + jint type, jstring setid_string) { + if (agnssRilIface == nullptr) { ALOGE("no AGPS RIL interface in agps_set_id"); return; } const char *setid = env->GetStringUTFChars(setid_string, NULL); - sAGpsRilInterface->set_set_id(type, setid); + agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid); env->ReleaseStringUTFChars(setid_string, setid); } static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */, - jbyteArray nmeaArray, jint buffer_size) -{ + jbyteArray nmeaArray, jint buffer_size) { // this should only be called from within a call to reportNmea - jbyte* nmea = (jbyte *)env->GetPrimitiveArrayCritical(nmeaArray, 0); - int length = sNmeaStringLength; + jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0)); + int length = GnssCallback::sNmeaStringLength; if (length > buffer_size) length = buffer_size; - memcpy(nmea, sNmeaString, length); + memcpy(nmea, GnssCallback::sNmeaString, length); env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT); return (jint) length; } static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */, - jlong time, jlong timeReference, jint uncertainty) -{ - if (sGpsInterface) - sGpsInterface->inject_time(time, timeReference, uncertainty); + jlong time, jlong timeReference, jint uncertainty) { + if (gnssHal != nullptr) { + auto result = gnssHal->injectTime(time, timeReference, uncertainty); + if (!result || !result.getStatus().isOk()) { + ALOGE("%s: Gnss injectTime() failed", __func__); + } + } } static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */, - jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) -{ - if (sGpsInterface) - sGpsInterface->inject_location(latitude, longitude, accuracy); + jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) { + if (gnssHal != nullptr) { + auto result = gnssHal->injectLocation(latitude, longitude, accuracy); + if (!result || !result.getStatus().isOk()) { + ALOGE("%s: Gnss injectLocation() failed", __func__); + } + } } static jboolean android_location_GnssLocationProvider_supports_xtra( - JNIEnv* /* env */, jobject /* obj */) -{ - return (sGpsXtraInterface != NULL) ? JNI_TRUE : JNI_FALSE; + JNIEnv* /* env */, jobject /* obj */) { + return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE; } static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */, - jbyteArray data, jint length) -{ - if (!sGpsXtraInterface) { - ALOGE("no XTRA interface in inject_xtra_data"); + jbyteArray data, jint length) { + if (gnssXtraIface == nullptr) { + ALOGE("XTRA Interface not supported"); return; } - jbyte* bytes = (jbyte *)env->GetPrimitiveArrayCritical(data, 0); - sGpsXtraInterface->inject_xtra_data((char *)bytes, length); + jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0)); + gnssXtraIface->injectXtraData(std::string((const char*)bytes, length)); env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); } static void android_location_GnssLocationProvider_agps_data_conn_open( - JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) -{ - if (!sAGpsInterface) { + JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) { + if (agnssIface == nullptr) { ALOGE("no AGPS interface in agps_data_conn_open"); return; } @@ -872,124 +1244,165 @@ static void android_location_GnssLocationProvider_agps_data_conn_open( const char *apnStr = env->GetStringUTFChars(apn, NULL); - size_t interface_size = sAGpsInterface->size; - if (interface_size == sizeof(AGpsInterface)) { - sAGpsInterface->data_conn_open_with_apn_ip_type(apnStr, apnIpType); - } else if (interface_size == sizeof(AGpsInterface_v1)) { - sAGpsInterface->data_conn_open(apnStr); - } else { - ALOGE("Invalid size of AGpsInterface found: %zd.", interface_size); + auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType)); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("%s: Failed to set APN and its IP type", __func__); } - env->ReleaseStringUTFChars(apn, apnStr); } static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */, - jobject /* obj */) -{ - if (!sAGpsInterface) { - ALOGE("no AGPS interface in agps_data_conn_closed"); + jobject /* obj */) { + if (agnssIface == nullptr) { + ALOGE("%s: AGPS interface not supported", __func__); return; } - sAGpsInterface->data_conn_closed(); + + auto result = agnssIface->dataConnClosed(); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("%s: Failed to close AGnss data connection", __func__); + } } static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */, - jobject /* obj */) -{ - if (!sAGpsInterface) { - ALOGE("no AGPS interface in agps_data_conn_failed"); + jobject /* obj */) { + if (agnssIface == nullptr) { + ALOGE("%s: AGPS interface not supported", __func__); return; } - sAGpsInterface->data_conn_failed(); + + auto result = agnssIface->dataConnFailed(); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__); + } } static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */, - jint type, jstring hostname, jint port) -{ - if (!sAGpsInterface) { + jint type, jstring hostname, jint port) { + if (agnssIface == nullptr) { ALOGE("no AGPS interface in set_agps_server"); return; } + const char *c_hostname = env->GetStringUTFChars(hostname, NULL); - sAGpsInterface->set_server(type, c_hostname, port); + auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type), + c_hostname, + port); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("%s: Failed to set AGnss host name and port", __func__); + } + env->ReleaseStringUTFChars(hostname, c_hostname); } static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */, - jobject /* obj */, jint notifId, jint response) -{ - if (!sGpsNiInterface) { + jobject /* obj */, jint notifId, jint response) { + if (gnssNiIface == nullptr) { ALOGE("no NI interface in send_ni_response"); return; } - sGpsNiInterface->respond(notifId, response); + gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response)); } static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env, jobject /* obj */) { jstring result = NULL; - if (sGpsDebugInterface) { - const size_t maxLength = 2047; - char buffer[maxLength+1]; - size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength); - if (length > maxLength) length = maxLength; - buffer[length] = 0; - result = env->NewStringUTF(buffer); + /* + * TODO(b/33089503) : Create a jobject to represent GnssDebug. + */ + if (gnssDebugIface != nullptr) { + IGnssDebug::DebugData data; + gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) { + data = debugData; + }); + + std::stringstream internalState; + if (data.position.valid) { + internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees + << ", LongitudeDegrees: " << data.position.longitudeDegrees + << ", altitudeMeters: " << data.position.altitudeMeters + << ", accuracyMeters: " << data.position.accuracyMeters + << ", ageSeconds: " << data.position.ageSeconds << std::endl; + } + + if (data.time.valid) { + internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate + << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl; + } + + if (data.satelliteDataArray.size() != 0) { + internalState << "Satellite Data:: "; + } + + for (size_t i = 0; i < data.satelliteDataArray.size(); i++) { + internalState << "svid: " << data.satelliteDataArray[i].svid + << ", constellation: " + << static_cast<uint32_t>(data.satelliteDataArray[i].constellation) + << ", ephemerisType: " + << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType) + << ", ephemerisAgeSeconds: " + << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl; + } + result = env->NewStringUTF(internalState.str().c_str()); } return result; } -static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env, jobject /* obj */, - jboolean connected, jint type, jboolean roaming, jboolean available, jstring extraInfo, jstring apn) -{ - - if (sAGpsRilInterface && sAGpsRilInterface->update_network_state) { - if (extraInfo) { - const char *extraInfoStr = env->GetStringUTFChars(extraInfo, NULL); - sAGpsRilInterface->update_network_state(connected, type, roaming, extraInfoStr); - env->ReleaseStringUTFChars(extraInfo, extraInfoStr); - } else { - sAGpsRilInterface->update_network_state(connected, type, roaming, NULL); +static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env, + jobject /* obj */, + jboolean connected, + jint type, + jboolean roaming, + jboolean available, + jstring extraInfo, + jstring apn) { + if (agnssRilIface != nullptr) { + auto result = agnssRilIface->updateNetworkState(connected, + static_cast<IAGnssRil::NetworkType>(type), + roaming); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("updateNetworkState failed"); } - // update_network_availability callback was not included in original AGpsRilInterface - if (sAGpsRilInterface->size >= sizeof(AGpsRilInterface) - && sAGpsRilInterface->update_network_availability) { - const char *c_apn = env->GetStringUTFChars(apn, NULL); - sAGpsRilInterface->update_network_availability(available, c_apn); - env->ReleaseStringUTFChars(apn, c_apn); + const char *c_apn = env->GetStringUTFChars(apn, NULL); + result = agnssRilIface->updateNetworkAvailability(available, c_apn); + if ((!result) || (!result.getStatus().isOk())) { + ALOGE("updateNetworkAvailability failed"); } + + env->ReleaseStringUTFChars(apn, c_apn); + } else { + ALOGE("AGnssRilInterface does not exist"); } } static jboolean android_location_GnssLocationProvider_is_geofence_supported( - JNIEnv* /* env */, jobject /* obj */) -{ - return (sGpsGeofencingInterface != NULL) ? JNI_TRUE : JNI_FALSE; + JNIEnv* /* env */, jobject /* obj */) { + return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE; } static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */, - jobject /* obj */, jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius, + jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius, jint last_transition, jint monitor_transition, jint notification_responsiveness, jint unknown_timer) { - if (sGpsGeofencingInterface != NULL) { - sGpsGeofencingInterface->add_geofence_area(geofence_id, latitude, longitude, - radius, last_transition, monitor_transition, notification_responsiveness, - unknown_timer); - return JNI_TRUE; + if (gnssGeofencingIface != nullptr) { + auto result = gnssGeofencingIface->addGeofence( + geofenceId, latitude, longitude, radius, + static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition), + monitor_transition, notification_responsiveness, unknown_timer); + return boolToJbool(result.getStatus().isOk()); } else { - ALOGE("Geofence interface not available"); + ALOGE("Geofence Interface not available"); } return JNI_FALSE; } static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */, - jobject /* obj */, jint geofence_id) { - if (sGpsGeofencingInterface != NULL) { - sGpsGeofencingInterface->remove_geofence_area(geofence_id); - return JNI_TRUE; + jobject /* obj */, jint geofenceId) { + if (gnssGeofencingIface != nullptr) { + auto result = gnssGeofencingIface->removeGeofence(geofenceId); + return boolToJbool(result.getStatus().isOk()); } else { ALOGE("Geofence interface not available"); } @@ -997,10 +1410,10 @@ static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* } static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */, - jobject /* obj */, jint geofence_id) { - if (sGpsGeofencingInterface != NULL) { - sGpsGeofencingInterface->pause_geofence(geofence_id); - return JNI_TRUE; + jobject /* obj */, jint geofenceId) { + if (gnssGeofencingIface != nullptr) { + auto result = gnssGeofencingIface->pauseGeofence(geofenceId); + return boolToJbool(result.getStatus().isOk()); } else { ALOGE("Geofence interface not available"); } @@ -1008,706 +1421,340 @@ static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* } static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */, - jobject /* obj */, jint geofence_id, jint monitor_transition) { - if (sGpsGeofencingInterface != NULL) { - sGpsGeofencingInterface->resume_geofence(geofence_id, monitor_transition); - return JNI_TRUE; + jobject /* obj */, jint geofenceId, jint monitor_transition) { + if (gnssGeofencingIface != nullptr) { + auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition); + return boolToJbool(result.getStatus().isOk()); } else { ALOGE("Geofence interface not available"); } return JNI_FALSE; } -template<class T> -class JavaMethodHelper { - public: - // Helper function to call setter on a Java object. - static void callJavaMethod( - JNIEnv* env, - jclass clazz, - jobject object, - const char* method_name, - T value); - - private: - static const char *const signature_; -}; - -template<class T> -void JavaMethodHelper<T>::callJavaMethod( - JNIEnv* env, - jclass clazz, - jobject object, - const char* method_name, - T value) { - jmethodID method = env->GetMethodID(clazz, method_name, signature_); - env->CallVoidMethod(object, method, value); -} - -class JavaObject { - public: - JavaObject(JNIEnv* env, const char* class_name); - virtual ~JavaObject(); - - template<class T> - void callSetter(const char* method_name, T value); - template<class T> - void callSetter(const char* method_name, T* value, size_t size); - jobject get(); - - private: - JNIEnv* env_; - jclass clazz_; - jobject object_; -}; - -JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) { - clazz_ = env_->FindClass(class_name); - jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V"); - object_ = env_->NewObject(clazz_, ctor); -} - -JavaObject::~JavaObject() { - env_->DeleteLocalRef(clazz_); -} - -template<class T> -void JavaObject::callSetter(const char* method_name, T value) { - JavaMethodHelper<T>::callJavaMethod( - env_, clazz_, object_, method_name, value); -} - -template<> -void JavaObject::callSetter( - const char* method_name, uint8_t* value, size_t size) { - jbyteArray array = env_->NewByteArray(size); - env_->SetByteArrayRegion(array, 0, size, (jbyte*) value); - jmethodID method = env_->GetMethodID( - clazz_, - method_name, - "([B)V"); - env_->CallVoidMethod(object_, method, array); - env_->DeleteLocalRef(array); -} - -jobject JavaObject::get() { - return object_; -} - -// Define Java method signatures for all known types. - -template<> -const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V"; -template<> -const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V"; -template<> -const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V"; -template<> -const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V"; -template<> -const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V"; -template<> -const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V"; -template<> -const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V"; -template<> -const char *const JavaMethodHelper<float>::signature_ = "(F)V"; -template<> -const char *const JavaMethodHelper<double>::signature_ = "(D)V"; -template<> -const char *const JavaMethodHelper<bool>::signature_ = "(Z)V"; - -#define SET(setter, value) object.callSetter("set" # setter, (value)) - -// If you want to check if a flag is not set, use SET_IF_NOT(FLAG, setter, -// value) to do that. SET_IF(!FLAG, setter, value) won't compile. -// -// This macros generates compilation error if the provided 'flag' is not a -// single token. For example, 'GNSS_CLOCK_HAS_BIAS' can be accepted, but -// '!GNSS_CLOCK_HAS_DRIFT' will fail to compile. -#define SET_IF(flag, setter, value) do { \ - if (flags & flag) { \ - JavaObject& name_check_##flag = object; \ - name_check_##flag.callSetter("set" # setter, (value)); \ - } \ - } while (false) -#define SET_IF_NOT(flag, setter, value) do { \ - if (!(flags & flag)) { \ - JavaObject& name_check_##flag = object; \ - name_check_##flag.callSetter("set" # setter, (value)); \ - } \ - } while (false) - -static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) { - static uint32_t discontinuity_count_to_handle_old_clock_type = 0; - JavaObject object(env, "android/location/GnssClock"); - GpsClockFlags flags = clock->flags; - - SET_IF(GPS_CLOCK_HAS_LEAP_SECOND, - LeapSecond, - static_cast<int32_t>(clock->leap_second)); - - // GnssClock only supports the more effective HW_CLOCK type, so type - // handling and documentation complexity has been removed. To convert the - // old GPS_CLOCK types (active only in a limited number of older devices), - // the GPS time information is handled as an always discontinuous HW clock, - // with the GPS time information put into the full_bias_ns instead - so that - // time_ns - full_bias_ns = local estimate of GPS time. Additionally, the - // sign of full_bias_ns and bias_ns has flipped between GpsClock & - // GnssClock, so that is also handled below. - switch (clock->type) { - case GPS_CLOCK_TYPE_UNKNOWN: - // Clock type unsupported. - ALOGE("Unknown clock type provided."); - break; - case GPS_CLOCK_TYPE_LOCAL_HW_TIME: - // Already local hardware time. No need to do anything. - break; - case GPS_CLOCK_TYPE_GPS_TIME: - // GPS time, need to convert. - flags |= GPS_CLOCK_HAS_FULL_BIAS; - clock->full_bias_ns = clock->time_ns; - clock->time_ns = 0; - SET(HardwareClockDiscontinuityCount, - discontinuity_count_to_handle_old_clock_type++); - break; - } - - SET(TimeNanos, clock->time_ns); - SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY, - TimeUncertaintyNanos, - clock->time_uncertainty_ns); - - // Definition of sign for full_bias_ns & bias_ns has been changed since N, - // so flip signs here. - SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, -(clock->full_bias_ns)); - SET_IF(GPS_CLOCK_HAS_BIAS, BiasNanos, -(clock->bias_ns)); - - SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY, - BiasUncertaintyNanos, - clock->bias_uncertainty_ns); - SET_IF(GPS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps); - SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY, - DriftUncertaintyNanosPerSecond, - clock->drift_uncertainty_nsps); - - return object.get(); -} - -static jobject translate_gnss_clock(JNIEnv* env, GnssClock* clock) { - JavaObject object(env, "android/location/GnssClock"); - GnssClockFlags flags = clock->flags; - - SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND, - LeapSecond, - static_cast<int32_t>(clock->leap_second)); - SET(TimeNanos, clock->time_ns); - SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY, - TimeUncertaintyNanos, - clock->time_uncertainty_ns); - SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, clock->full_bias_ns); - SET_IF(GNSS_CLOCK_HAS_BIAS, BiasNanos, clock->bias_ns); - SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY, - BiasUncertaintyNanos, - clock->bias_uncertainty_ns); - SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps); - SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY, - DriftUncertaintyNanosPerSecond, - clock->drift_uncertainty_nsps); - - SET(HardwareClockDiscontinuityCount, clock->hw_clock_discontinuity_count); - - return object.get(); -} - -static jobject translate_gps_measurement(JNIEnv* env, - GpsMeasurement* measurement) { - JavaObject object(env, "android/location/GnssMeasurement"); - GpsMeasurementFlags flags = measurement->flags; - SET(Svid, static_cast<int32_t>(measurement->prn)); - if (measurement->prn >= 1 && measurement->prn <= 32) { - SET(ConstellationType, static_cast<int32_t>(GNSS_CONSTELLATION_GPS)); - } else { - ALOGD("Unknown constellation type with Svid = %d.", measurement->prn); - SET(ConstellationType, - static_cast<int32_t>(GNSS_CONSTELLATION_UNKNOWN)); - } - SET(TimeOffsetNanos, measurement->time_offset_ns); - SET(State, static_cast<int32_t>(measurement->state)); - SET(ReceivedSvTimeNanos, measurement->received_gps_tow_ns); - SET(ReceivedSvTimeUncertaintyNanos, - measurement->received_gps_tow_uncertainty_ns); - SET(Cn0DbHz, measurement->c_n0_dbhz); - SET(PseudorangeRateMetersPerSecond, measurement->pseudorange_rate_mps); - SET(PseudorangeRateUncertaintyMetersPerSecond, - measurement->pseudorange_rate_uncertainty_mps); - SET(AccumulatedDeltaRangeState, - static_cast<int32_t>(measurement->accumulated_delta_range_state)); - SET(AccumulatedDeltaRangeMeters, measurement->accumulated_delta_range_m); - SET(AccumulatedDeltaRangeUncertaintyMeters, - measurement->accumulated_delta_range_uncertainty_m); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY, - CarrierFrequencyHz, - measurement->carrier_frequency_hz); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES, - CarrierCycles, - measurement->carrier_cycles); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE, - CarrierPhase, - measurement->carrier_phase); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY, - CarrierPhaseUncertainty, - measurement->carrier_phase_uncertainty); - SET(MultipathIndicator, - static_cast<int32_t>(measurement->multipath_indicator)); - SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db); - - return object.get(); -} - -static jobject translate_gnss_measurement(JNIEnv* env, - GnssMeasurement* measurement) { - JavaObject object(env, "android/location/GnssMeasurement"); - - GnssMeasurementFlags flags = measurement->flags; - - SET(Svid, static_cast<int32_t>(measurement->svid)); - SET(ConstellationType, static_cast<int32_t>(measurement->constellation)); - SET(TimeOffsetNanos, measurement->time_offset_ns); - SET(State, static_cast<int32_t>(measurement->state)); - SET(ReceivedSvTimeNanos, measurement->received_sv_time_in_ns); - SET(ReceivedSvTimeUncertaintyNanos, - measurement->received_sv_time_uncertainty_in_ns); - SET(Cn0DbHz, measurement->c_n0_dbhz); - SET(PseudorangeRateMetersPerSecond, measurement->pseudorange_rate_mps); - SET(PseudorangeRateUncertaintyMetersPerSecond, - measurement->pseudorange_rate_uncertainty_mps); - SET(AccumulatedDeltaRangeState, - static_cast<int32_t>(measurement->accumulated_delta_range_state)); - SET(AccumulatedDeltaRangeMeters, measurement->accumulated_delta_range_m); - SET(AccumulatedDeltaRangeUncertaintyMeters, - measurement->accumulated_delta_range_uncertainty_m); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY, - CarrierFrequencyHz, - measurement->carrier_frequency_hz); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES, - CarrierCycles, - measurement->carrier_cycles); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE, - CarrierPhase, - measurement->carrier_phase); - SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY, - CarrierPhaseUncertainty, - measurement->carrier_phase_uncertainty); - SET(MultipathIndicator, - static_cast<int32_t>(measurement->multipath_indicator)); - SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db); - - return object.get(); -} - -static jobjectArray translate_gps_measurements(JNIEnv* env, - GpsMeasurement* measurements, - size_t count) { - if (count == 0) { - return NULL; - } - - jclass gnssMeasurementClass = env->FindClass( - "android/location/GnssMeasurement"); - jobjectArray gnssMeasurementArray = env->NewObjectArray( - count, - gnssMeasurementClass, - NULL /* initialElement */); - - for (uint16_t i = 0; i < count; ++i) { - jobject gnssMeasurement = translate_gps_measurement( - env, - &measurements[i]); - env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement); - env->DeleteLocalRef(gnssMeasurement); +static jboolean android_location_GnssLocationProvider_is_measurement_supported( + JNIEnv* env, jclass clazz) { + if (gnssMeasurementIface != nullptr) { + return JNI_TRUE; } - env->DeleteLocalRef(gnssMeasurementClass); - return gnssMeasurementArray; + return JNI_FALSE; } -static jobjectArray translate_gnss_measurements(JNIEnv* env, - GnssMeasurement* measurements, - size_t count) { - if (count == 0) { - return NULL; - } - - jclass gnssMeasurementClass = env->FindClass( - "android/location/GnssMeasurement"); - jobjectArray gnssMeasurementArray = env->NewObjectArray( - count, - gnssMeasurementClass, - NULL /* initialElement */); - - for (uint16_t i = 0; i < count; ++i) { - jobject gnssMeasurement = translate_gnss_measurement( - env, - &measurements[i]); - env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement); - env->DeleteLocalRef(gnssMeasurement); +static jboolean android_location_GnssLocationProvider_start_measurement_collection( + JNIEnv* env, + jobject obj) { + if (gnssMeasurementIface == nullptr) { + ALOGE("GNSS Measurement interface is not available."); + return JNI_FALSE; } - env->DeleteLocalRef(gnssMeasurementClass); - return gnssMeasurementArray; -} - -static void set_measurement_data(JNIEnv *env, - jobject clock, - jobjectArray measurementArray) { - jclass gnssMeasurementsEventClass = env->FindClass( - "android/location/GnssMeasurementsEvent"); - jmethodID gnssMeasurementsEventCtor = env->GetMethodID( - gnssMeasurementsEventClass, - "<init>", - "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V"); - - jobject gnssMeasurementsEvent = env->NewObject( - gnssMeasurementsEventClass, - gnssMeasurementsEventCtor, - clock, - measurementArray); - env->CallVoidMethod(mCallbacksObj, - method_reportMeasurementData, - gnssMeasurementsEvent); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(gnssMeasurementsEventClass); - env->DeleteLocalRef(gnssMeasurementsEvent); -} - -static void measurement_callback(GpsData* data) { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (data == NULL) { - ALOGE("Invalid data provided to gps_measurement_callback"); - return; - } - if (data->size != sizeof(GpsData)) { - ALOGE("Invalid GpsData size found in gps_measurement_callback, " - "size=%zd", - data->size); - return; + sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback(); + IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface); + if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) { + ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d", + static_cast<int32_t>(result)); + return JNI_FALSE; + } else { + ALOGD("gnss measurement infc has been enabled"); } - jobject clock; - jobjectArray measurementArray; - clock = translate_gps_clock(env, &data->clock); - measurementArray = translate_gps_measurements( - env, data->measurements, data->measurement_count); - set_measurement_data(env, clock, measurementArray); - - env->DeleteLocalRef(clock); - env->DeleteLocalRef(measurementArray); + return JNI_TRUE; } -static void gnss_measurement_callback(GnssData* data) { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (data == NULL) { - ALOGE("Invalid data provided to gps_measurement_callback"); - return; - } - if (data->size != sizeof(GnssData)) { - ALOGE("Invalid GnssData size found in gnss_measurement_callback, " - "size=%zd", - data->size); - return; +static jboolean android_location_GnssLocationProvider_stop_measurement_collection( + JNIEnv* env, + jobject obj) { + if (gnssMeasurementIface == nullptr) { + ALOGE("Measurement interface not available"); + return JNI_FALSE; } - jobject clock; - jobjectArray measurementArray; - clock = translate_gnss_clock(env, &data->clock); - measurementArray = translate_gnss_measurements( - env, data->measurements, data->measurement_count); - set_measurement_data(env, clock, measurementArray); - - env->DeleteLocalRef(clock); - env->DeleteLocalRef(measurementArray); + auto result = gnssMeasurementIface->close(); + return boolToJbool(result.getStatus().isOk()); } -GpsMeasurementCallbacks sGpsMeasurementCallbacks = { - sizeof(GpsMeasurementCallbacks), - measurement_callback, - gnss_measurement_callback, -}; - -static jboolean android_location_GnssLocationProvider_is_measurement_supported( +static jboolean android_location_GnssLocationProvider_is_navigation_message_supported( JNIEnv* env, jclass clazz) { - if (sGpsMeasurementInterface != NULL) { + if (gnssNavigationMessageIface != nullptr) { return JNI_TRUE; } return JNI_FALSE; } -static jboolean android_location_GnssLocationProvider_start_measurement_collection( +static jboolean android_location_GnssLocationProvider_start_navigation_message_collection( JNIEnv* env, jobject obj) { - if (sGpsMeasurementInterface == NULL) { - ALOGE("Measurement interface is not available."); + if (gnssNavigationMessageIface == nullptr) { + ALOGE("Navigation Message interface is not available."); return JNI_FALSE; } - int result = sGpsMeasurementInterface->init(&sGpsMeasurementCallbacks); - if (result != GPS_GEOFENCE_OPERATION_SUCCESS) { - ALOGE("An error has been found on GpsMeasurementInterface::init, status=%d", result); + sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface = + new GnssNavigationMessageCallback(); + IGnssNavigationMessage::GnssNavigationMessageStatus result = + gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface); + + if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) { + ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result)); return JNI_FALSE; } return JNI_TRUE; } -static jboolean android_location_GnssLocationProvider_stop_measurement_collection( +static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection( JNIEnv* env, jobject obj) { - if (sGpsMeasurementInterface == NULL) { - ALOGE("Measurement interface not available"); + if (gnssNavigationMessageIface == nullptr) { + ALOGE("Navigation Message interface is not available."); return JNI_FALSE; } - sGpsMeasurementInterface->close(); - return JNI_TRUE; + auto result = gnssNavigationMessageIface->close(); + return boolToJbool(result.getStatus().isOk()); } -static jobject translate_gps_navigation_message(JNIEnv* env, GpsNavigationMessage* message) { - size_t dataLength = message->data_length; - uint8_t* data = message->data; - if (dataLength == 0 || data == NULL) { - ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength); - return NULL; +static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*, + jobject, + jint emergencySuplPdn) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); + return JNI_FALSE; } - JavaObject object(env, "android/location/GnssNavigationMessage"); - SET(Svid, static_cast<int32_t>(message->prn)); - if (message->prn >=1 && message->prn <= 32) { - SET(ConstellationType, static_cast<int32_t>(GNSS_CONSTELLATION_GPS)); - // Legacy driver doesn't set the higher byte to constellation type - // correctly. Set the higher byte to 'GPS'. - SET(Type, static_cast<int32_t>(message->type | 0x0100)); + + auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn); + if (result.getStatus().isOk()) { + return result; } else { - ALOGD("Unknown constellation type with Svid = %d.", message->prn); - SET(ConstellationType, - static_cast<int32_t>(GNSS_CONSTELLATION_UNKNOWN)); - SET(Type, static_cast<int32_t>(GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN)); + return JNI_FALSE; } - SET(MessageId, static_cast<int32_t>(message->message_id)); - SET(SubmessageId, static_cast<int32_t>(message->submessage_id)); - object.callSetter("setData", data, dataLength); - SET(Status, static_cast<int32_t>(message->status)); - return object.get(); } -static jobject translate_gnss_navigation_message( - JNIEnv* env, GnssNavigationMessage* message) { - size_t dataLength = message->data_length; - uint8_t* data = message->data; - if (dataLength == 0 || data == NULL) { - ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength); - return NULL; +static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*, + jobject, + jint version) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); + return JNI_FALSE; + } + auto result = gnssConfigurationIface->setSuplVersion(version); + if (result.getStatus().isOk()) { + return result; + } else { + return JNI_FALSE; } - JavaObject object(env, "android/location/GnssNavigationMessage"); - SET(Type, static_cast<int32_t>(message->type)); - SET(Svid, static_cast<int32_t>(message->svid)); - SET(MessageId, static_cast<int32_t>(message->message_id)); - SET(SubmessageId, static_cast<int32_t>(message->submessage_id)); - object.callSetter("setData", data, dataLength); - SET(Status, static_cast<int32_t>(message->status)); - return object.get(); } -static void navigation_message_callback(GpsNavigationMessage* message) { - if (message == NULL) { - ALOGE("Invalid Navigation Message provided to callback"); - return; +static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*, + jobject, + jint suplEs) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); + return JNI_FALSE; } - if (message->size != sizeof(GpsNavigationMessage)) { - ALOGE("Invalid GpsNavigationMessage size found: %zd", message->size); - return; + + auto result = gnssConfigurationIface->setSuplEs(suplEs); + if (result.getStatus().isOk()) { + return result; + } else { + return JNI_FALSE; } - JNIEnv* env = AndroidRuntime::getJNIEnv(); - jobject navigationMessage = translate_gps_navigation_message(env, message); - env->CallVoidMethod(mCallbacksObj, - method_reportNavigationMessages, - navigationMessage); - env->DeleteLocalRef(navigationMessage); } -static void gnss_navigation_message_callback(GnssNavigationMessage* message) { - if (message == NULL) { - ALOGE("Invalid Navigation Message provided to callback"); - return; +static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*, + jobject, + jint mode) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); + return JNI_FALSE; } - if (message->size != sizeof(GnssNavigationMessage)) { - ALOGE("Invalid GnssNavigationMessage size found: %zd", message->size); - return; + + auto result = gnssConfigurationIface->setSuplMode(mode); + if (result.getStatus().isOk()) { + return result; + } else { + return JNI_FALSE; } - JNIEnv* env = AndroidRuntime::getJNIEnv(); - jobject navigationMessage = translate_gnss_navigation_message(env, message); - env->CallVoidMethod(mCallbacksObj, - method_reportNavigationMessages, - navigationMessage); - env->DeleteLocalRef(navigationMessage); } -GpsNavigationMessageCallbacks sGpsNavigationMessageCallbacks = { - sizeof(GpsNavigationMessageCallbacks), - navigation_message_callback, - gnss_navigation_message_callback, -}; +static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*, + jobject, + jint gpsLock) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); + return JNI_FALSE; + } -static jboolean android_location_GnssLocationProvider_is_navigation_message_supported( - JNIEnv* env, - jclass clazz) { - if(sGpsNavigationMessageInterface != NULL) { - return JNI_TRUE; + auto result = gnssConfigurationIface->setGpsLock(gpsLock); + if (result.getStatus().isOk()) { + return result; + } else { + return JNI_FALSE; } - return JNI_FALSE; } -static jboolean android_location_GnssLocationProvider_start_navigation_message_collection( - JNIEnv* env, - jobject obj) { - if (sGpsNavigationMessageInterface == NULL) { - ALOGE("Navigation Message interface is not available."); +static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*, + jobject, + jint lppProfile) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); return JNI_FALSE; } - int result = sGpsNavigationMessageInterface->init(&sGpsNavigationMessageCallbacks); - if (result != GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS) { - ALOGE("An error has been found in %s: %d", __FUNCTION__, result); + auto result = gnssConfigurationIface->setLppProfile(lppProfile); + + if (result.getStatus().isOk()) { + return result; + } else { return JNI_FALSE; } - - return JNI_TRUE; } -static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection( - JNIEnv* env, - jobject obj) { - if (sGpsNavigationMessageInterface == NULL) { - ALOGE("Navigation Message interface is not available."); +static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*, + jobject, + jint gnssPosProtocol) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); return JNI_FALSE; } - sGpsNavigationMessageInterface->close(); - return JNI_TRUE; -} - -static void android_location_GnssLocationProvider_configuration_update(JNIEnv* env, jobject obj, - jstring config_content) -{ - if (!sGnssConfigurationInterface) { - ALOGE("no GPS configuration interface in configuraiton_update"); - return; + auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol); + if (result.getStatus().isOk()) { + return result; + } else { + return JNI_FALSE; } - const char *data = env->GetStringUTFChars(config_content, NULL); - ALOGD("GPS configuration:\n %s", data); - sGnssConfigurationInterface->configuration_update( - data, env->GetStringUTFLength(config_content)); - env->ReleaseStringUTFChars(config_content, data); } static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ - {"class_init_native", "()V", (void *)android_location_GnssLocationProvider_class_init_native}, - {"native_is_supported", "()Z", (void*)android_location_GnssLocationProvider_is_supported}, + {"class_init_native", "()V", reinterpret_cast<void *>( + android_location_GnssLocationProvider_class_init_native)}, + {"native_is_supported", "()Z", reinterpret_cast<void *>( + android_location_GnssLocationProvider_is_supported)}, {"native_is_agps_ril_supported", "()Z", - (void*)android_location_GnssLocationProvider_is_agps_ril_supported}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)}, {"native_is_gnss_configuration_supported", "()Z", - (void*)android_location_gpsLocationProvider_is_gnss_configuration_supported}, - {"native_init", "()Z", (void*)android_location_GnssLocationProvider_init}, - {"native_cleanup", "()V", (void*)android_location_GnssLocationProvider_cleanup}, + reinterpret_cast<void *>( + android_location_gpsLocationProvider_is_gnss_configuration_supported)}, + {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)}, + {"native_cleanup", "()V", reinterpret_cast<void *>( + android_location_GnssLocationProvider_cleanup)}, {"native_set_position_mode", "(IIIII)Z", - (void*)android_location_GnssLocationProvider_set_position_mode}, - {"native_start", "()Z", (void*)android_location_GnssLocationProvider_start}, - {"native_stop", "()Z", (void*)android_location_GnssLocationProvider_stop}, + reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)}, + {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)}, + {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)}, {"native_delete_aiding_data", "(I)V", - (void*)android_location_GnssLocationProvider_delete_aiding_data}, + reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)}, {"native_read_sv_status", "([I[F[F[F)I", - (void*)android_location_GnssLocationProvider_read_sv_status}, - {"native_read_nmea", "([BI)I", (void*)android_location_GnssLocationProvider_read_nmea}, - {"native_inject_time", "(JJI)V", (void*)android_location_GnssLocationProvider_inject_time}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)}, + {"native_read_nmea", "([BI)I", reinterpret_cast<void *>( + android_location_GnssLocationProvider_read_nmea)}, + {"native_inject_time", "(JJI)V", reinterpret_cast<void *>( + android_location_GnssLocationProvider_inject_time)}, {"native_inject_location", "(DDF)V", - (void*)android_location_GnssLocationProvider_inject_location}, - {"native_supports_xtra", "()Z", (void*)android_location_GnssLocationProvider_supports_xtra}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)}, + {"native_supports_xtra", "()Z", reinterpret_cast<void *>( + android_location_GnssLocationProvider_supports_xtra)}, {"native_inject_xtra_data", "([BI)V", - (void*)android_location_GnssLocationProvider_inject_xtra_data}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)}, {"native_agps_data_conn_open", "(Ljava/lang/String;I)V", - (void*)android_location_GnssLocationProvider_agps_data_conn_open}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)}, {"native_agps_data_conn_closed", "()V", - (void*)android_location_GnssLocationProvider_agps_data_conn_closed}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)}, {"native_agps_data_conn_failed", "()V", - (void*)android_location_GnssLocationProvider_agps_data_conn_failed}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)}, {"native_agps_set_id", "(ILjava/lang/String;)V", - (void*)android_location_GnssLocationProvider_agps_set_id}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)}, {"native_agps_set_ref_location_cellid", "(IIIII)V", - (void*)android_location_GnssLocationProvider_agps_set_reference_location_cellid}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_agps_set_reference_location_cellid)}, {"native_set_agps_server", "(ILjava/lang/String;I)V", - (void*)android_location_GnssLocationProvider_set_agps_server}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)}, {"native_send_ni_response", "(II)V", - (void*)android_location_GnssLocationProvider_send_ni_response}, - {"native_agps_ni_message", - "([BI)V", - (void *)android_location_GnssLocationProvider_agps_send_ni_message}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)}, {"native_get_internal_state", "()Ljava/lang/String;", - (void*)android_location_GnssLocationProvider_get_internal_state}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)}, {"native_update_network_state", "(ZIZZLjava/lang/String;Ljava/lang/String;)V", - (void*)android_location_GnssLocationProvider_update_network_state }, + reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)}, {"native_is_geofence_supported", "()Z", - (void*) android_location_GnssLocationProvider_is_geofence_supported}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)}, {"native_add_geofence", "(IDDDIIII)Z", - (void *)android_location_GnssLocationProvider_add_geofence}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)}, {"native_remove_geofence", "(I)Z", - (void *)android_location_GnssLocationProvider_remove_geofence}, - {"native_pause_geofence", "(I)Z", (void *)android_location_GnssLocationProvider_pause_geofence}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)}, + {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>( + android_location_GnssLocationProvider_pause_geofence)}, {"native_resume_geofence", "(II)Z", - (void *)android_location_GnssLocationProvider_resume_geofence}, + reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)}, {"native_is_measurement_supported", "()Z", - (void*) android_location_GnssLocationProvider_is_measurement_supported}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_is_measurement_supported)}, {"native_start_measurement_collection", "()Z", - (void*) android_location_GnssLocationProvider_start_measurement_collection}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_start_measurement_collection)}, {"native_stop_measurement_collection", "()Z", - (void*) android_location_GnssLocationProvider_stop_measurement_collection}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_stop_measurement_collection)}, {"native_is_navigation_message_supported", "()Z", - (void*) android_location_GnssLocationProvider_is_navigation_message_supported}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_is_navigation_message_supported)}, {"native_start_navigation_message_collection", "()Z", - (void*) android_location_GnssLocationProvider_start_navigation_message_collection}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_start_navigation_message_collection)}, {"native_stop_navigation_message_collection", "()Z", - (void*) android_location_GnssLocationProvider_stop_navigation_message_collection}, - {"native_configuration_update", - "(Ljava/lang/String;)V", - (void*)android_location_GnssLocationProvider_configuration_update}, + reinterpret_cast<void *>( + android_location_GnssLocationProvider_stop_navigation_message_collection)}, + {"native_set_supl_es", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)}, + {"native_set_supl_version", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)}, + {"native_set_supl_mode", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)}, + {"native_set_lpp_profile", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)}, + {"native_set_gnss_pos_protocol_select", + "(I)Z", + reinterpret_cast<void *>( + android_location_GnssLocationProvider_set_gnss_pos_protocol_select)}, + {"native_set_gps_lock", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)}, + {"native_set_emergency_supl_pdn", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)}, }; -int register_android_server_location_GnssLocationProvider(JNIEnv* env) -{ +int register_android_server_location_GnssLocationProvider(JNIEnv* env) { return jniRegisterNativeMethods( env, "com/android/server/location/GnssLocationProvider", |