diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index a9c6b8d67cacc..11714dc821af4 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -50,6 +50,7 @@ #include "android_runtime/Log.h" #include "gnss/AGnss.h" #include "gnss/AGnssRil.h" +#include "gnss/Gnss.h" #include "gnss/GnssAntennaInfo.h" #include "gnss/GnssAntennaInfoCallback.h" #include "gnss/GnssBatching.h" @@ -68,18 +69,7 @@ static jclass class_gnssPowerStats; -static jmethodID method_reportLocation; -static jmethodID method_reportStatus; -static jmethodID method_reportSvStatus; -static jmethodID method_reportNmea; -static jmethodID method_setTopHalCapabilities; -static jmethodID method_setGnssYearOfHardware; -static jmethodID method_setGnssHardwareModelName; -static jmethodID method_psdsDownloadRequest; static jmethodID method_reportNiNotification; -static jmethodID method_requestLocation; -static jmethodID method_requestUtcTime; -static jmethodID method_reportGnssServiceDied; static jmethodID method_reportGnssPowerStats; static jmethodID method_reportNfwNotification; static jmethodID method_isInEmergencySession; @@ -92,7 +82,6 @@ using android::status_t; using android::String16; using android::wp; using android::binder::Status; -using android::gnss::GnssConfigurationInterface; using android::hardware::Return; using android::hardware::Void; @@ -128,12 +117,8 @@ using android::hardware::gnss::GnssConstellationType; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPowerIndicationCallback; -using android::hardware::gnss::PsdsType; -using IAGnssAidl = android::hardware::gnss::IAGnss; -using IAGnssRilAidl = android::hardware::gnss::IAGnssRil; using IGnssAidl = android::hardware::gnss::IGnss; -using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback; using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching; using IGnssDebugAidl = android::hardware::gnss::IGnssDebug; using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds; @@ -142,575 +127,30 @@ using IGnssConfigurationAidl = android::hardware::gnss::IGnssConfiguration; using GnssLocationAidl = android::hardware::gnss::GnssLocation; using IGnssAntennaInfoAidl = android::hardware::gnss::IGnssAntennaInfo; -struct GnssDeathRecipient : virtual public hidl_death_recipient -{ - // hidl_death_recipient interface - virtual void serviceDied(uint64_t cookie, const wp& who) override { - ALOGE("IGNSS hidl service failed, trying to recover..."); - - JNIEnv* env = android::AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(android::mCallbacksObj, method_reportGnssServiceDied); - } -}; - -// Must match the value from GnssMeasurement.java -static const uint32_t SVID_FLAGS_HAS_BASEBAND_CN0 = (1<<4); - -sp gnssHalDeathRecipient = nullptr; -sp gnssHal = nullptr; -sp gnssHal_V1_1 = nullptr; -sp gnssHal_V2_0 = nullptr; -sp gnssHal_V2_1 = nullptr; -sp gnssHalAidl = nullptr; -sp gnssBatchingAidlIface = nullptr; -sp gnssPsdsAidlIface = nullptr; -sp gnssXtraIface = nullptr; sp gnssNiIface = nullptr; sp gnssPowerIndicationIface = nullptr; -std::unique_ptr gnssConfigurationIface = nullptr; +std::unique_ptr gnssHal = nullptr; +std::unique_ptr agnssIface = nullptr; +std::unique_ptr agnssRilIface = nullptr; +std::unique_ptr gnssAntennaInfoIface = nullptr; +std::unique_ptr gnssConfigurationIface = nullptr; std::unique_ptr gnssMeasurementIface = nullptr; std::unique_ptr gnssNavigationMessageIface = nullptr; std::unique_ptr gnssBatchingIface = nullptr; -std::unique_ptr gnssGeofencingIface = nullptr; -std::unique_ptr agnssIface = nullptr; std::unique_ptr gnssDebugIface = nullptr; -std::unique_ptr agnssRilIface = nullptr; +std::unique_ptr gnssGeofencingIface = nullptr; +std::unique_ptr gnssPsdsIface = nullptr; std::unique_ptr gnssVisibilityControlIface = nullptr; -std::unique_ptr gnssAntennaInfoIface = nullptr; std::unique_ptr gnssMeasurementCorrectionsIface = nullptr; -#define WAKE_LOCK_NAME "GPS" - namespace android { namespace { -// Returns true if location has lat/long information. -bool hasLatLong(const GnssLocationAidl& location) { - return (location.gnssLocationFlags & GnssLocationAidl::HAS_LAT_LONG) != 0; -} - -// Returns true if location has lat/long information. -bool hasLatLong(const GnssLocation_V1_0& location) { - return (static_cast(location.gnssLocationFlags) & - GnssLocationFlags::HAS_LAT_LONG) != 0; -} - -// Returns true if location has lat/long information. -bool hasLatLong(const GnssLocation_V2_0& location) { - return hasLatLong(location.v1_0); -} - -bool isSvStatusRegistered = false; -bool isNmeaRegistered = false; - } // namespace -static inline jboolean boolToJbool(bool value) { - return value ? JNI_TRUE : JNI_FALSE; -} - -static GnssLocationAidl createGnssLocation(jint gnssLocationFlags, jdouble latitudeDegrees, - jdouble longitudeDegrees, jdouble altitudeMeters, - jfloat speedMetersPerSec, jfloat bearingDegrees, - jfloat horizontalAccuracyMeters, - jfloat verticalAccuracyMeters, - jfloat speedAccuracyMetersPerSecond, - jfloat bearingAccuracyDegrees, jlong timestamp, - jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, - jdouble elapsedRealtimeUncertaintyNanos) { - GnssLocationAidl location; - location.gnssLocationFlags = static_cast(gnssLocationFlags); - location.latitudeDegrees = static_cast(latitudeDegrees); - location.longitudeDegrees = static_cast(longitudeDegrees); - location.altitudeMeters = static_cast(altitudeMeters); - location.speedMetersPerSec = static_cast(speedMetersPerSec); - location.bearingDegrees = static_cast(bearingDegrees); - location.horizontalAccuracyMeters = static_cast(horizontalAccuracyMeters); - location.verticalAccuracyMeters = static_cast(verticalAccuracyMeters); - location.speedAccuracyMetersPerSecond = static_cast(speedAccuracyMetersPerSecond); - location.bearingAccuracyDegrees = static_cast(bearingAccuracyDegrees); - location.timestampMillis = static_cast(timestamp); - - location.elapsedRealtime.flags = static_cast(elapsedRealtimeFlags); - location.elapsedRealtime.timestampNs = static_cast(elapsedRealtimeNanos); - location.elapsedRealtime.timeUncertaintyNs = - static_cast(elapsedRealtimeUncertaintyNanos); - - return location; -} - -static GnssLocation_V1_0 createGnssLocation_V1_0( - jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, - jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, - jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, - jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, - jlong timestamp) { - GnssLocation_V1_0 location; - location.gnssLocationFlags = static_cast(gnssLocationFlags); - location.latitudeDegrees = static_cast(latitudeDegrees); - location.longitudeDegrees = static_cast(longitudeDegrees); - location.altitudeMeters = static_cast(altitudeMeters); - location.speedMetersPerSec = static_cast(speedMetersPerSec); - location.bearingDegrees = static_cast(bearingDegrees); - location.horizontalAccuracyMeters = static_cast(horizontalAccuracyMeters); - location.verticalAccuracyMeters = static_cast(verticalAccuracyMeters); - location.speedAccuracyMetersPerSecond = static_cast(speedAccuracyMetersPerSecond); - location.bearingAccuracyDegrees = static_cast(bearingAccuracyDegrees); - location.timestamp = static_cast(timestamp); - - return location; -} - -static GnssLocation_V2_0 createGnssLocation_V2_0( - jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, - jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, - jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, - jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, - jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, - jdouble elapsedRealtimeUncertaintyNanos) { - GnssLocation_V2_0 location; - location.v1_0 = createGnssLocation_V1_0( - gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters, - speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters, - verticalAccuracyMeters, speedAccuracyMetersPerSecond, - bearingAccuracyDegrees, timestamp); - - location.elapsedRealtime.flags = static_cast(elapsedRealtimeFlags); - location.elapsedRealtime.timestampNs = static_cast(elapsedRealtimeNanos); - location.elapsedRealtime.timeUncertaintyNs = static_cast(elapsedRealtimeUncertaintyNanos); - - return location; -} - -/* - * GnssCallback class implements the callback methods for IGnss interface. - */ -struct GnssCallback : public IGnssCallback_V2_1 { - Return gnssLocationCb(const GnssLocation_V1_0& location) override; - Return gnssStatusCb(const IGnssCallback_V1_0::GnssStatusValue status) override; - Return gnssSvStatusCb(const IGnssCallback_V1_0::GnssSvStatus& svStatus) override { - return gnssSvStatusCbImpl( - svStatus); - } - Return gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override; - Return gnssSetCapabilitesCb(uint32_t capabilities) override; - Return gnssAcquireWakelockCb() override; - Return gnssReleaseWakelockCb() override; - Return gnssRequestTimeCb() override; - Return gnssRequestLocationCb(const bool independentFromGnss) override; - - Return gnssSetSystemInfoCb(const IGnssCallback_V1_0::GnssSystemInfo& info) override; - - // New in 1.1 - Return gnssNameCb(const android::hardware::hidl_string& name) override; - - // New in 2.0 - Return gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool isUserEmergency) - override; - Return gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override; - Return gnssLocationCb_2_0(const GnssLocation_V2_0& location) override; - Return gnssSvStatusCb_2_0(const hidl_vec& svInfoList) override { - return gnssSvStatusCbImpl, - IGnssCallback_V1_0::GnssSvInfo>(svInfoList); - } - - // New in 2.1 - Return gnssSvStatusCb_2_1(const hidl_vec& svInfoList) override { - return gnssSvStatusCbImpl, - IGnssCallback_V1_0::GnssSvInfo>(svInfoList); - } - Return gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override; - - // TODO: Reconsider allocation cost vs threadsafety on these statics - static const char* sNmeaString; - static size_t sNmeaStringLength; - - template - static Return gnssLocationCbImpl(const T& location); - - template - static Return gnssSvStatusCbImpl(const T_list& svStatus); - -private: - template - static uint32_t getHasBasebandCn0DbHzFlag(const T& svStatus) { - return 0; - } - - template - static double getBasebandCn0DbHz(const T& svStatus, size_t i) { - return 0.0; - } - - template - static uint32_t getGnssSvInfoListSize(const T& svInfoList) { - return svInfoList.size(); - } - - static const IGnssCallbackAidl::GnssSvInfo& getGnssSvInfoOfIndex( - const std::vector& svInfoList, size_t i) { - return svInfoList[i]; - } - - static const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex( - const IGnssCallback_V1_0::GnssSvStatus& svStatus, size_t i) { - return svStatus.gnssSvList.data()[i]; - } - - static const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex( - const hidl_vec& svInfoList, size_t i) { - return svInfoList[i].v1_0; - } - - static const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex( - const hidl_vec& svInfoList, size_t i) { - return svInfoList[i].v2_0.v1_0; - } - - template - static uint32_t getConstellationType(const T& svInfoList, size_t i) { - return static_cast(svInfoList[i].constellation); - } -}; - -Return GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) { - ALOGD("%s: name=%s\n", __func__, name.c_str()); - - JNIEnv* env = getJniEnv(); - jstring jstringName = env->NewStringUTF(name.c_str()); - env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName); - if (jstringName) { - env->DeleteLocalRef(jstringName); - } - checkAndClearExceptionFromCallback(env, __FUNCTION__); - - return Void(); -} - -const char* GnssCallback::sNmeaString = nullptr; -size_t GnssCallback::sNmeaStringLength = 0; - -template -Return GnssCallback::gnssLocationCbImpl(const T& location) { - JNIEnv* env = getJniEnv(); - - jobject jLocation = translateGnssLocation(env, location); - - env->CallVoidMethod(mCallbacksObj, - method_reportLocation, - boolToJbool(hasLatLong(location)), - jLocation); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(jLocation); - return Void(); -} - -Return GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) { - return gnssLocationCbImpl(location); -} - -Return -GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) { - return gnssLocationCbImpl(location); -} - -Return GnssCallback::gnssStatusCb(const IGnssCallback_V2_0::GnssStatusValue status) { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_reportStatus, status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -template<> -uint32_t GnssCallback::getHasBasebandCn0DbHzFlag(const hidl_vec& - svStatus) { - return SVID_FLAGS_HAS_BASEBAND_CN0; -} - -template <> -uint32_t GnssCallback::getHasBasebandCn0DbHzFlag( - const std::vector& svStatus) { - return SVID_FLAGS_HAS_BASEBAND_CN0; -} - -template <> -double GnssCallback::getBasebandCn0DbHz( - const std::vector& svInfoList, size_t i) { - return svInfoList[i].basebandCN0DbHz; -} - -template<> -double GnssCallback::getBasebandCn0DbHz(const hidl_vec& svInfoList, - size_t i) { - return svInfoList[i].basebandCN0DbHz; -} - -template <> -uint32_t GnssCallback::getGnssSvInfoListSize(const IGnssCallback_V1_0::GnssSvStatus& svStatus) { - return svStatus.numSvs; -} - -template <> -uint32_t GnssCallback::getConstellationType(const IGnssCallback_V1_0::GnssSvStatus& svStatus, - size_t i) { - return static_cast(svStatus.gnssSvList.data()[i].constellation); -} - -template <> -uint32_t GnssCallback::getConstellationType( - const hidl_vec& svInfoList, size_t i) { - return static_cast(svInfoList[i].v2_0.constellation); -} - -template -Return GnssCallback::gnssSvStatusCbImpl(const T_list& svStatus) { - // In HIDL or AIDL v1, if no listener is registered, do not report svInfoList to the framework. - if (gnssHalAidl == nullptr || gnssHalAidl->getInterfaceVersion() <= 1) { - if (!isSvStatusRegistered) { - return Void(); - } - } - - JNIEnv* env = getJniEnv(); - - uint32_t listSize = getGnssSvInfoListSize(svStatus); - - jintArray svidWithFlagArray = env->NewIntArray(listSize); - jfloatArray cn0Array = env->NewFloatArray(listSize); - jfloatArray elevArray = env->NewFloatArray(listSize); - jfloatArray azimArray = env->NewFloatArray(listSize); - jfloatArray carrierFreqArray = env->NewFloatArray(listSize); - jfloatArray basebandCn0Array = env->NewFloatArray(listSize); - - jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0); - jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0); - jfloat* elev = env->GetFloatArrayElements(elevArray, 0); - jfloat* azim = env->GetFloatArrayElements(azimArray, 0); - jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0); - jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0); - - /* - * Read GNSS SV info. - */ - for (size_t i = 0; i < listSize; ++i) { - enum ShiftWidth: uint8_t { - SVID_SHIFT_WIDTH = 12, - CONSTELLATION_TYPE_SHIFT_WIDTH = 8 - }; - - const T_sv_info& info = getGnssSvInfoOfIndex(svStatus, i); - svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) | - (getConstellationType(svStatus, i) << CONSTELLATION_TYPE_SHIFT_WIDTH) | - static_cast(info.svFlag); - cn0s[i] = info.cN0Dbhz; - elev[i] = info.elevationDegrees; - azim[i] = info.azimuthDegrees; - carrierFreq[i] = info.carrierFrequencyHz; - svidWithFlags[i] |= getHasBasebandCn0DbHzFlag(svStatus); - basebandCn0s[i] = getBasebandCn0DbHz(svStatus, i); - } - - env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0); - env->ReleaseFloatArrayElements(cn0Array, cn0s, 0); - env->ReleaseFloatArrayElements(elevArray, elev, 0); - env->ReleaseFloatArrayElements(azimArray, azim, 0); - env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0); - env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0); - - env->CallVoidMethod(mCallbacksObj, method_reportSvStatus, - static_cast(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray, - carrierFreqArray, basebandCn0Array); - - env->DeleteLocalRef(svidWithFlagArray); - env->DeleteLocalRef(cn0Array); - env->DeleteLocalRef(elevArray); - env->DeleteLocalRef(azimArray); - env->DeleteLocalRef(carrierFreqArray); - env->DeleteLocalRef(basebandCn0Array); - - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -Return GnssCallback::gnssNmeaCb(int64_t timestamp, - const ::android::hardware::hidl_string& nmea) { - // In HIDL, if no listener is registered, do not report nmea to the framework. - if (!isNmeaRegistered) { - return Void(); - } - JNIEnv* env = getJniEnv(); - /* - * 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(); -} - -Return GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) { - ALOGD("%s: %du\n", __func__, capabilities); - - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -Return GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { - return GnssCallback::gnssSetCapabilitesCb(capabilities); -} - -Return GnssCallback::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) { - return GnssCallback::gnssSetCapabilitesCb(capabilities); -} - -Return GnssCallback::gnssAcquireWakelockCb() { - acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); - return Void(); -} - -Return GnssCallback::gnssReleaseWakelockCb() { - release_wake_lock(WAKE_LOCK_NAME); - return Void(); -} - -Return GnssCallback::gnssRequestTimeCb() { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestUtcTime); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -Return GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) { - return GnssCallback::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */ - false); -} - -Return GnssCallback::gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool - isUserEmergency) { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss), - boolToJbool(isUserEmergency)); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -Return GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSystemInfo& info) { - ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw); - - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, - info.yearOfHw); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback { -public: - Status gnssSetCapabilitiesCb(const int capabilities) override; - Status gnssStatusCb(const GnssStatusValue status) override; - Status gnssSvStatusCb(const std::vector& svInfoList) override; - Status gnssLocationCb(const GnssLocationAidl& location) override; - Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override; - Status gnssAcquireWakelockCb() override; - Status gnssReleaseWakelockCb() override; - Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override; - Status gnssRequestTimeCb() override; - Status gnssRequestLocationCb(const bool independentFromGnss, - const bool isUserEmergency) override; -}; - -Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) { - ALOGD("GnssCallbackAidl::%s: %du\n", __func__, capabilities); - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue status) { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_reportStatus, status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssSvStatusCb(const std::vector& svInfoList) { - GnssCallback::gnssSvStatusCbImpl, GnssSvInfo>(svInfoList); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssLocationCb(const GnssLocationAidl& location) { - GnssCallback::gnssLocationCbImpl(location); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssNmeaCb(const int64_t timestamp, const std::string& nmea) { - // In AIDL v1, if no listener is registered, do not report nmea to the framework. - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() <= 1) { - if (!isNmeaRegistered) { - return Status::ok(); - } - } - JNIEnv* env = getJniEnv(); - /* - * The Java code will call back to read these values. - * We do this to avoid creating unnecessary String objects. - */ - GnssCallback::sNmeaString = nmea.c_str(); - GnssCallback::sNmeaStringLength = nmea.size(); - - env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssAcquireWakelockCb() { - acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssReleaseWakelockCb() { - release_wake_lock(WAKE_LOCK_NAME); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) { - ALOGD("%s: yearOfHw=%d, name=%s\n", __func__, info.yearOfHw, info.name.c_str()); - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, info.yearOfHw); - jstring jstringName = env->NewStringUTF(info.name.c_str()); - env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName); - if (jstringName) { - env->DeleteLocalRef(jstringName); - } - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssRequestTimeCb() { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestUtcTime); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); -} - -Status GnssCallbackAidl::gnssRequestLocationCb(const bool independentFromGnss, - const bool isUserEmergency) { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss), - boolToJbool(isUserEmergency)); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); -} - /* * GnssPowerIndicationCallback class implements the callback methods for the IGnssPowerIndication * interface. @@ -755,35 +195,6 @@ Status GnssPowerIndicationCallback::gnssPowerStatsCb(const GnssPowerStats& data) return Status::ok(); } -/* - * GnssPsdsCallback class implements the callback methods for the IGnssPsds - * interface. - */ -struct GnssPsdsCallbackAidl : public android::hardware::gnss::BnGnssPsdsCallback { - Status downloadRequestCb(PsdsType psdsType) override { - ALOGD("%s. psdsType: %d", __func__, static_cast(psdsType)); - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, psdsType); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Status::ok(); - } -}; - -/** - * GnssXtraCallback class implements the callback methods for the IGnssXtra - * interface. - */ -class GnssXtraCallback : public IGnssXtraCallback { - Return downloadRequestCb() override; -}; - -Return GnssXtraCallback::downloadRequestCb() { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - /* * GnssNiCallback implements callback methods required by the IGnssNi interface. */ @@ -822,41 +233,7 @@ Return GnssNiCallback::niNotifyCb( /* Initializes the GNSS service handle. */ static void android_location_gnss_hal_GnssNative_set_gps_service_handle() { - gnssHalAidl = waitForVintfService(); - if (gnssHalAidl != nullptr) { - ALOGD("Successfully got GNSS AIDL handle. Version=%d.", gnssHalAidl->getInterfaceVersion()); - if (gnssHalAidl->getInterfaceVersion() >= 2) { - return; - } - } - - ALOGD("Trying IGnss_V2_1::getService()"); - gnssHal_V2_1 = IGnss_V2_1::getService(); - if (gnssHal_V2_1 != nullptr) { - gnssHal = gnssHal_V2_1; - gnssHal_V2_0 = gnssHal_V2_1; - gnssHal_V1_1 = gnssHal_V2_1; - gnssHal = gnssHal_V2_1; - return; - } - - ALOGD("gnssHal 2.1 was null, trying 2.0"); - gnssHal_V2_0 = IGnss_V2_0::getService(); - if (gnssHal_V2_0 != nullptr) { - gnssHal = gnssHal_V2_0; - gnssHal_V1_1 = gnssHal_V2_0; - return; - } - - ALOGD("gnssHal 2.0 was null, trying 1.1"); - gnssHal_V1_1 = IGnss_V1_1::getService(); - if (gnssHal_V1_1 != nullptr) { - gnssHal = gnssHal_V1_1; - return; - } - - ALOGD("gnssHal 1.1 was null, trying 1.0"); - gnssHal = IGnss_V1_0::getService(); + gnssHal = std::make_unique(); } /* One time initialization at system boot */ @@ -865,21 +242,10 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc android_location_gnss_hal_GnssNative_set_gps_service_handle(); // Cache methodIDs and class IDs. - method_reportLocation = env->GetMethodID(clazz, "reportLocation", - "(ZLandroid/location/Location;)V"); - method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); - method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V"); - method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); - method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V"); - method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); - method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName", - "(Ljava/lang/String;)V"); - method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "(I)V"); + method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;II)V"); - method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V"); - method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); - method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V"); + method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification", "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V"); method_reportGnssPowerStats = @@ -894,17 +260,19 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc class_gnssPowerStats = (jclass)env->NewGlobalRef(gnssPowerStatsClass); method_gnssPowerStatsCtor = env->GetMethodID(class_gnssPowerStats, "", "(IJDDDDDD[D)V"); + gnss::AGnss_class_init_once(env, clazz); + gnss::AGnssRil_class_init_once(env, clazz); + gnss::Gnss_class_init_once(env, clazz); gnss::GnssAntennaInfo_class_init_once(env, clazz); gnss::GnssBatching_class_init_once(env, clazz); gnss::GnssConfiguration_class_init_once(env); gnss::GnssGeofence_class_init_once(env, clazz); gnss::GnssMeasurement_class_init_once(env, clazz); gnss::GnssNavigationMessage_class_init_once(env, clazz); + gnss::GnssPsds_class_init_once(env, clazz); gnss::GnssVisibilityControl_class_init_once(env, clazz); gnss::MeasurementCorrections_class_init_once(env, clazz); gnss::MeasurementCorrectionsCallback_class_init_once(env, clazz); - gnss::AGnss_class_init_once(env, clazz); - gnss::AGnssRil_class_init_once(env, clazz); gnss::Utils_class_init_once(env); } @@ -923,313 +291,26 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject android_location_gnss_hal_GnssNative_set_gps_service_handle(); } - if (gnssHal == nullptr && gnssHalAidl == nullptr) { + if (gnssHal == nullptr || !gnssHal->isSupported()) { ALOGE("Unable to get GPS service\n"); return; } - // TODO: linkToDeath for AIDL HAL - - if (gnssHal != nullptr) { - gnssHalDeathRecipient = new GnssDeathRecipient(); - hardware::Return linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0); - if (!linked.isOk()) { - ALOGE("Transaction error in linking to GnssHAL death: %s", - linked.description().c_str()); - } else if (!linked) { - ALOGW("Unable to link to GnssHal death notifications"); - } else { - ALOGD("Link to death notification successful"); - } - } - - if (gnssHalAidl != nullptr) { - sp gnssPsdsAidl; - auto status = gnssHalAidl->getExtensionPsds(&gnssPsdsAidl); - if (status.isOk()) { - gnssPsdsAidlIface = gnssPsdsAidl; - } else { - ALOGD("Unable to get a handle to PSDS AIDL interface."); - } - } else if (gnssHal != nullptr) { - auto gnssXtra = gnssHal->getExtensionXtra(); - if (!gnssXtra.isOk()) { - ALOGD("Unable to get a handle to Xtra"); - } else { - gnssXtraIface = gnssXtra; - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp agnssRilAidl; - auto status = gnssHalAidl->getExtensionAGnssRil(&agnssRilAidl); - if (checkAidlStatus(status, "Unable to get a handle to AGnssRil interface.")) { - agnssRilIface = std::make_unique(agnssRilAidl); - } - } else if (gnssHal_V2_0 != nullptr) { - auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0(); - if (checkHidlReturn(agnssRil_V2_0, "Unable to get a handle to AGnssRil_V2_0")) { - agnssRilIface = std::make_unique(agnssRil_V2_0); - } - } else if (gnssHal != nullptr) { - auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil(); - if (checkHidlReturn(agnssRil_V1_0, "Unable to get a handle to AGnssRil_V1_0")) { - agnssRilIface = std::make_unique(agnssRil_V1_0); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp agnssAidl; - auto status = gnssHalAidl->getExtensionAGnss(&agnssAidl); - if (checkAidlStatus(status, "Unable to get a handle to AGnss interface.")) { - agnssIface = std::make_unique(agnssAidl); - } - } else if (gnssHal_V2_0 != nullptr) { - auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0(); - if (checkHidlReturn(agnss_V2_0, "Unable to get a handle to AGnss_V2_0")) { - agnssIface = std::make_unique(agnss_V2_0); - } - } else if (gnssHal != nullptr) { - auto agnss_V1_0 = gnssHal->getExtensionAGnss(); - if (checkHidlReturn(agnss_V1_0, "Unable to get a handle to AGnss_V1_0")) { - agnssIface = std::make_unique(agnss_V1_0); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp gnssNavigationMessage; - auto status = gnssHalAidl->getExtensionGnssNavigationMessage(&gnssNavigationMessage); - if (checkAidlStatus(status, - "Unable to get a handle to GnssNavigationMessage AIDL interface.")) { - gnssNavigationMessageIface = - std::make_unique(gnssNavigationMessage); - } - } else if (gnssHal != nullptr) { - auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage(); - if (checkHidlReturn(gnssNavigationMessage, - "Unable to get a handle to GnssNavigationMessage interface.")) { - gnssNavigationMessageIface = - std::make_unique(gnssNavigationMessage); - } - } - - // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means, - // 2.1@IGnss can be paired with {1.0, 1,1, 2.0, 2.1}@IGnssMeasurement - // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement - // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement - // 1.0@IGnss is paired with 1.0@IGnssMeasurement - gnssMeasurementIface = nullptr; - if (gnssHalAidl != nullptr) { - sp gnssMeasurement; - auto status = gnssHalAidl->getExtensionGnssMeasurement(&gnssMeasurement); - if (checkAidlStatus(status, "Unable to get a handle to GnssMeasurement AIDL interface.")) { - gnssMeasurementIface = - std::make_unique(gnssMeasurement); - } - } - if (gnssHal_V2_1 != nullptr && gnssMeasurementIface == nullptr) { - auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1(); - if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) { - gnssMeasurementIface = - std::make_unique(gnssMeasurement); - } - } - if (gnssHal_V2_0 != nullptr && gnssMeasurementIface == nullptr) { - auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0(); - if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_0")) { - gnssMeasurementIface = - std::make_unique(gnssMeasurement); - } - } - if (gnssHal_V1_1 != nullptr && gnssMeasurementIface == nullptr) { - auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1(); - if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_1")) { - gnssMeasurementIface = - std::make_unique(gnssMeasurement); - } - } - if (gnssHal != nullptr && gnssMeasurementIface == nullptr) { - auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement(); - if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_0")) { - gnssMeasurementIface = - std::make_unique(gnssMeasurement); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp gnssAntennaInfoAidl; - auto status = gnssHalAidl->getExtensionGnssAntennaInfo(&gnssAntennaInfoAidl); - if (checkAidlStatus(status, "Unable to get a handle to GnssAntennaInfo interface.")) { - gnssAntennaInfoIface = std::make_unique(gnssAntennaInfoAidl); - } - } else if (gnssHal_V2_1 != nullptr) { - auto gnssAntennaInfo_V2_1 = gnssHal_V2_1->getExtensionGnssAntennaInfo(); - if (checkHidlReturn(gnssAntennaInfo_V2_1, - "Unable to get a handle to GnssAntennaInfo_V2_1")) { - gnssAntennaInfoIface = - std::make_unique(gnssAntennaInfo_V2_1); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp - gnssMeasurementCorrectionsAidl; - auto status = - gnssHalAidl->getExtensionMeasurementCorrections(&gnssMeasurementCorrectionsAidl); - if (checkAidlStatus(status, - "Unable to get a handle to GnssVisibilityControl AIDL interface.")) { - gnssMeasurementCorrectionsIface = - std::make_unique( - gnssMeasurementCorrectionsAidl); - } - } - if (gnssHal_V2_1 != nullptr && gnssMeasurementCorrectionsIface == nullptr) { - auto gnssCorrections = gnssHal_V2_1->getExtensionMeasurementCorrections_1_1(); - if (checkHidlReturn(gnssCorrections, - "Unable to get a handle to GnssMeasurementCorrections HIDL " - "interface")) { - gnssMeasurementCorrectionsIface = - std::make_unique(gnssCorrections); - } - } - if (gnssHal_V2_0 != nullptr && gnssMeasurementCorrectionsIface == nullptr) { - auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections(); - if (checkHidlReturn(gnssCorrections, - "Unable to get a handle to GnssMeasurementCorrections HIDL " - "interface")) { - gnssMeasurementCorrectionsIface = - std::make_unique(gnssCorrections); - } - } - - // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means, - // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug - // 1.0@IGnss is paired with 1.0@IGnssDebug - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp gnssDebugAidl; - auto status = gnssHalAidl->getExtensionGnssDebug(&gnssDebugAidl); - if (checkAidlStatus(status, "Unable to get a handle to GnssDebug interface.")) { - gnssDebugIface = std::make_unique(gnssDebugAidl); - } - } - if (gnssHal_V2_0 != nullptr && gnssDebugIface == nullptr) { - auto gnssDebug_V2_0 = gnssHal_V2_0->getExtensionGnssDebug_2_0(); - if (checkHidlReturn(gnssDebug_V2_0, "Unable to get a handle to GnssDebug_V2_0.")) { - gnssDebugIface = std::make_unique(gnssDebug_V2_0); - } - } - if (gnssHal != nullptr && gnssDebugIface == nullptr) { - auto gnssDebug_V1_0 = gnssHal->getExtensionGnssDebug(); - if (checkHidlReturn(gnssDebug_V1_0, "Unable to get a handle to GnssDebug_V1_0.")) { - gnssDebugIface = std::make_unique(gnssDebug_V1_0); - } - } - - if (gnssHal != nullptr) { - auto gnssNi = gnssHal->getExtensionGnssNi(); - if (!gnssNi.isOk()) { - ALOGD("Unable to get a handle to GnssNi"); - } else { - gnssNiIface = gnssNi; - } - } - - if (gnssHalAidl != nullptr) { - sp gnssConfigurationAidl; - auto status = gnssHalAidl->getExtensionGnssConfiguration(&gnssConfigurationAidl); - if (checkAidlStatus(status, - "Unable to get a handle to GnssConfiguration AIDL interface.")) { - gnssConfigurationIface = - std::make_unique(gnssConfigurationAidl); - } - } else if (gnssHal_V2_1 != nullptr) { - auto gnssConfiguration = gnssHal_V2_1->getExtensionGnssConfiguration_2_1(); - if (checkHidlReturn(gnssConfiguration, - "Unable to get a handle to GnssConfiguration_V2_1")) { - gnssConfigurationIface = - std::make_unique(gnssConfiguration); - } - } else if (gnssHal_V2_0 != nullptr) { - auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0(); - if (checkHidlReturn(gnssConfiguration, - "Unable to get a handle to GnssConfiguration_V2_0")) { - gnssConfigurationIface = - std::make_unique(gnssConfiguration); - } - } else if (gnssHal_V1_1 != nullptr) { - auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1(); - if (checkHidlReturn(gnssConfiguration, - "Unable to get a handle to GnssConfiguration_V1_1")) { - gnssConfigurationIface = - std::make_unique(gnssConfiguration); - } - } else if (gnssHal != nullptr) { - auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration(); - if (checkHidlReturn(gnssConfiguration, - "Unable to get a handle to GnssConfiguration_V1_0")) { - gnssConfigurationIface = - std::make_unique(gnssConfiguration); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp gnssGeofence; - auto status = gnssHalAidl->getExtensionGnssGeofence(&gnssGeofence); - if (checkAidlStatus(status, "Unable to get a handle to GnssGeofence AIDL interface.")) { - gnssGeofencingIface = std::make_unique(gnssGeofence); - } - } else if (gnssHal != nullptr) { - auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing(); - if (checkHidlReturn(gnssGeofencing, "Unable to get a handle to GnssGeofencing")) { - gnssGeofencingIface = std::make_unique(gnssGeofencing); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp gnssBatchingAidl; - auto status = gnssHalAidl->getExtensionGnssBatching(&gnssBatchingAidl); - if (checkAidlStatus(status, "Unable to get a handle to GnssBatching interface.")) { - gnssBatchingIface = std::make_unique(gnssBatchingAidl); - } - } else if (gnssHal_V2_0 != nullptr) { - auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0(); - if (checkHidlReturn(gnssBatching_V2_0, "Unable to get a handle to GnssBatching_V2_0")) { - gnssBatchingIface = std::make_unique(gnssBatching_V2_0); - } - } - if (gnssHal != nullptr && gnssBatchingIface == nullptr) { - auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching(); - if (checkHidlReturn(gnssBatching_V1_0, "Unable to get a handle to GnssBatching")) { - gnssBatchingIface = std::make_unique(gnssBatching_V1_0); - } - } - - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp - gnssVisibilityControlAidl; - auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl); - if (checkAidlStatus(status, - "Unable to get a handle to GnssVisibilityControl AIDL interface.")) { - gnssVisibilityControlIface = - std::make_unique(gnssVisibilityControlAidl); - } - } else if (gnssHal_V2_0 != nullptr) { - auto gnssVisibilityControlHidl = gnssHal_V2_0->getExtensionVisibilityControl(); - if (checkHidlReturn(gnssVisibilityControlHidl, - "Unable to get a handle to GnssVisibilityControl HIDL interface")) { - gnssVisibilityControlIface = - std::make_unique(gnssVisibilityControlHidl); - } - } - - if (gnssHalAidl != nullptr) { - sp gnssPowerIndication; - auto status = gnssHalAidl->getExtensionGnssPowerIndication(&gnssPowerIndication); - if (checkAidlStatus(status, "Unable to get a handle to GnssPowerIndication interface.")) { - gnssPowerIndicationIface = gnssPowerIndication; - } - } + gnssHal->linkToDeath(); + gnssPsdsIface = gnssHal->getGnssPsdsInterface(); + agnssRilIface = gnssHal->getAGnssRilInterface(); + agnssIface = gnssHal->getAGnssInterface(); + gnssNavigationMessageIface = gnssHal->getGnssNavigationMessageInterface(); + gnssMeasurementIface = gnssHal->getGnssMeasurementInterface(); + gnssAntennaInfoIface = gnssHal->getGnssAntennaInfoInterface(); + gnssMeasurementCorrectionsIface = gnssHal->getMeasurementCorrectionsInterface(); + gnssDebugIface = gnssHal->getGnssDebugInterface(); + gnssNiIface = gnssHal->getGnssNiInterface(); + gnssConfigurationIface = gnssHal->getGnssConfigurationInterface(); + gnssGeofencingIface = gnssHal->getGnssGeofenceInterface(); + gnssBatchingIface = gnssHal->getGnssBatchingInterface(); + gnssVisibilityControlIface = gnssHal->getGnssVisibilityControlInterface(); + gnssPowerIndicationIface = gnssHal->getGnssPowerIndicationInterface(); if (mCallbacksObj) { ALOGE("Callbacks already initialized"); @@ -1239,7 +320,7 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject } static jboolean android_location_gnss_hal_GnssNative_is_supported(JNIEnv* /* env */, jclass) { - return (gnssHalAidl != nullptr || gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE; + return (gnssHal != nullptr && gnssHal->isSupported()) ? JNI_TRUE : JNI_FALSE; } static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported( @@ -1268,52 +349,18 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl /* * Fail if the main interface fails to initialize */ - if (gnssHal == nullptr && gnssHalAidl == nullptr) { + if (!gnssHal->isSupported()) { ALOGE("Unable to initialize GNSS HAL."); return JNI_FALSE; } - // Set top level IGnss.hal callback. - if (gnssHal != nullptr) { - Return result = false; - sp gnssCbIface = new GnssCallback(); - if (gnssHal_V2_1 != nullptr) { - result = gnssHal_V2_1->setCallback_2_1(gnssCbIface); - } else if (gnssHal_V2_0 != nullptr) { - result = gnssHal_V2_0->setCallback_2_0(gnssCbIface); - } else if (gnssHal_V1_1 != nullptr) { - result = gnssHal_V1_1->setCallback_1_1(gnssCbIface); - } else { - result = gnssHal->setCallback(gnssCbIface); - } - if (!checkHidlReturn(result, "IGnss setCallback() failed.")) { - return JNI_FALSE; - } - } + // Set top level IGnss HAL callback. + gnssHal->setCallback(); - if (gnssHalAidl != nullptr) { - sp gnssCbIfaceAidl = new GnssCallbackAidl(); - auto status = gnssHalAidl->setCallback(gnssCbIfaceAidl); - if (!checkAidlStatus(status, "IGnssAidl setCallback() failed.")) { - return JNI_FALSE; - } - } - - // Set IGnssPsds or IGnssXtra callback. - if (gnssPsdsAidlIface != nullptr) { - sp gnssPsdsCallbackAidl = new GnssPsdsCallbackAidl(); - auto status = gnssPsdsAidlIface->setCallback(gnssPsdsCallbackAidl); - if (!checkAidlStatus(status, "IGnssPsdsAidl setCallback() failed.")) { - gnssPsdsAidlIface = nullptr; - } - } else if (gnssXtraIface != nullptr) { - sp gnssXtraCbIface = new GnssXtraCallback(); - auto result = gnssXtraIface->setCallback(gnssXtraCbIface); - if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) { - gnssXtraIface = nullptr; - } else { - ALOGI("Unable to initialize IGnssXtra interface."); - } + // Set IGnssPsds callback. + if (gnssPsdsIface == nullptr || + !gnssPsdsIface->setCallback(std::make_unique())) { + ALOGI("Unable to initialize IGnssPsds interface."); } // Set IAGnss callback. @@ -1373,145 +420,47 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl } static void android_location_gnss_hal_GnssNative_cleanup(JNIEnv* /* env */, jclass) { - if (gnssHalAidl != nullptr) { - auto status = gnssHalAidl->close(); - checkAidlStatus(status, "IGnssAidl close() failed."); - } - - if (gnssHal != nullptr) { - auto result = gnssHal->cleanup(); - checkHidlReturn(result, "IGnss cleanup() failed."); - } + gnssHal->close(); } static jboolean android_location_gnss_hal_GnssNative_set_position_mode( JNIEnv* /* env */, jclass, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time, jboolean low_power_mode) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - IGnssAidl::PositionModeOptions options; - options.mode = static_cast(mode); - options.recurrence = static_cast(recurrence); - options.minIntervalMs = min_interval; - options.preferredAccuracyMeters = preferred_accuracy; - options.preferredTimeMs = preferred_time; - options.lowPowerMode = low_power_mode; - auto status = gnssHalAidl->setPositionMode(options); - return checkAidlStatus(status, "IGnssAidl setPositionMode() failed."); - } - - Return result = false; - if (gnssHal_V1_1 != nullptr) { - result = gnssHal_V1_1->setPositionMode_1_1(static_cast(mode), - static_cast(recurrence), - min_interval, - preferred_accuracy, - preferred_time, - low_power_mode); - } else if (gnssHal != nullptr) { - result = gnssHal->setPositionMode(static_cast(mode), - static_cast(recurrence), - min_interval, - preferred_accuracy, - preferred_time); - } - - return checkHidlReturn(result, "IGnss setPositionMode() failed."); + return gnssHal->setPositionMode(mode, recurrence, min_interval, preferred_accuracy, + preferred_time, low_power_mode); } static jboolean android_location_gnss_hal_GnssNative_start(JNIEnv* /* env */, jclass) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->start(); - return checkAidlStatus(status, "IGnssAidl start() failed."); - } - - if (gnssHal == nullptr) { - return JNI_FALSE; - } - - auto result = gnssHal->start(); - return checkHidlReturn(result, "IGnss start() failed."); + return gnssHal->start(); } static jboolean android_location_gnss_hal_GnssNative_stop(JNIEnv* /* env */, jclass) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->stop(); - return checkAidlStatus(status, "IGnssAidl stop() failed."); - } - - if (gnssHal == nullptr) { - return JNI_FALSE; - } - - auto result = gnssHal->stop(); - return checkHidlReturn(result, "IGnss stop() failed."); + return gnssHal->stop(); } static jboolean android_location_gnss_hal_GnssNative_start_sv_status_collection(JNIEnv* /* env */, jclass) { - isSvStatusRegistered = true; - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->startSvStatus(); - return checkAidlStatus(status, "IGnssAidl startSvStatus() failed."); - } - if (gnssHal == nullptr) { - return JNI_FALSE; - } - return JNI_TRUE; + return gnssHal->startSvStatus(); } static jboolean android_location_gnss_hal_GnssNative_stop_sv_status_collection(JNIEnv* /* env */, jclass) { - isSvStatusRegistered = false; - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->stopSvStatus(); - return checkAidlStatus(status, "IGnssAidl stopSvStatus() failed."); - } - if (gnssHal == nullptr) { - return JNI_FALSE; - } - return JNI_TRUE; + return gnssHal->stopSvStatus(); } static jboolean android_location_gnss_hal_GnssNative_start_nmea_message_collection( JNIEnv* /* env */, jclass) { - isNmeaRegistered = true; - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->startNmea(); - return checkAidlStatus(status, "IGnssAidl startNmea() failed."); - } - if (gnssHal == nullptr) { - return JNI_FALSE; - } - return JNI_TRUE; + return gnssHal->startNmea(); } static jboolean android_location_gnss_hal_GnssNative_stop_nmea_message_collection(JNIEnv* /* env */, jclass) { - isNmeaRegistered = false; - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->stopNmea(); - return checkAidlStatus(status, "IGnssAidl stopNmea() failed."); - } - if (gnssHal == nullptr) { - return JNI_FALSE; - } - return JNI_TRUE; + return gnssHal->stopNmea(); } static void android_location_gnss_hal_GnssNative_delete_aiding_data(JNIEnv* /* env */, jclass, jint flags) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->deleteAidingData(static_cast(flags)); - checkAidlStatus(status, "IGnssAidl deleteAidingData() failed."); - return; - } - - if (gnssHal == nullptr) { - return; - } - - auto result = gnssHal->deleteAidingData(static_cast(flags)); - checkHidlReturn(result, "IGnss deleteAidingData() failed."); + gnssHal->deleteAidingData(flags); } static void android_location_gnss_hal_GnssNative_agps_set_reference_location_cellid( @@ -1535,30 +484,13 @@ static void android_location_gnss_hal_GnssNative_agps_set_id(JNIEnv* env, jclass static jint android_location_gnss_hal_GnssNative_read_nmea(JNIEnv* env, jclass, jbyteArray nmeaArray, jint buffer_size) { - // this should only be called from within a call to reportNmea - jbyte* nmea = reinterpret_cast(env->GetPrimitiveArrayCritical(nmeaArray, 0)); - int length = GnssCallback::sNmeaStringLength; - if (length > buffer_size) - length = buffer_size; - memcpy(nmea, GnssCallback::sNmeaString, length); - env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT); - return (jint) length; + return gnssHal->readNmea(nmeaArray, buffer_size); } static void android_location_gnss_hal_GnssNative_inject_time(JNIEnv* /* env */, jclass, jlong time, jlong timeReference, jint uncertainty) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - auto status = gnssHalAidl->injectTime(time, timeReference, uncertainty); - checkAidlStatus(status, "IGnssAidl injectTime() failed."); - return; - } - - if (gnssHal == nullptr) { - return; - } - auto result = gnssHal->injectTime(time, timeReference, uncertainty); - checkHidlReturn(result, "IGnss injectTime() failed."); + gnssHal->injectTime(time, timeReference, uncertainty); } static void android_location_gnss_hal_GnssNative_inject_best_location( @@ -1568,58 +500,12 @@ static void android_location_gnss_hal_GnssNative_inject_best_location( jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, jdouble elapsedRealtimeUncertaintyNanos) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - GnssLocationAidl location = - createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, - altitudeMeters, speedMetersPerSec, bearingDegrees, - horizontalAccuracyMeters, verticalAccuracyMeters, - speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp, - elapsedRealtimeFlags, elapsedRealtimeNanos, - elapsedRealtimeUncertaintyNanos); - auto status = gnssHalAidl->injectBestLocation(location); - checkAidlStatus(status, "IGnssAidl injectBestLocation() failed."); - return; - } - - if (gnssHal_V2_0 != nullptr) { - GnssLocation_V2_0 location = createGnssLocation_V2_0( - gnssLocationFlags, - latitudeDegrees, - longitudeDegrees, - altitudeMeters, - speedMetersPerSec, - bearingDegrees, - horizontalAccuracyMeters, - verticalAccuracyMeters, - speedAccuracyMetersPerSecond, - bearingAccuracyDegrees, - timestamp, - elapsedRealtimeFlags, - elapsedRealtimeNanos, - elapsedRealtimeUncertaintyNanos); - auto result = gnssHal_V2_0->injectBestLocation_2_0(location); - checkHidlReturn(result, "IGnss injectBestLocation_2_0() failed."); - return; - } - - if (gnssHal_V1_1 != nullptr) { - GnssLocation_V1_0 location = createGnssLocation_V1_0( - gnssLocationFlags, - latitudeDegrees, - longitudeDegrees, - altitudeMeters, - speedMetersPerSec, - bearingDegrees, - horizontalAccuracyMeters, - verticalAccuracyMeters, - speedAccuracyMetersPerSecond, - bearingAccuracyDegrees, - timestamp); - auto result = gnssHal_V1_1->injectBestLocation(location); - checkHidlReturn(result, "IGnss injectBestLocation() failed."); - } - - ALOGE("IGnss injectBestLocation() is called but gnssHal_V1_1 is not available."); + gnssHal->injectBestLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, + altitudeMeters, speedMetersPerSec, bearingDegrees, + horizontalAccuracyMeters, verticalAccuracyMeters, + speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp, + elapsedRealtimeFlags, elapsedRealtimeNanos, + elapsedRealtimeUncertaintyNanos); } static void android_location_gnss_hal_GnssNative_inject_location( @@ -1629,51 +515,25 @@ static void android_location_gnss_hal_GnssNative_inject_location( jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, jdouble elapsedRealtimeUncertaintyNanos) { - if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - GnssLocationAidl location = - createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, - altitudeMeters, speedMetersPerSec, bearingDegrees, - horizontalAccuracyMeters, verticalAccuracyMeters, - speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp, - elapsedRealtimeFlags, elapsedRealtimeNanos, - elapsedRealtimeUncertaintyNanos); - auto status = gnssHalAidl->injectLocation(location); - checkAidlStatus(status, "IGnssAidl injectLocation() failed."); - return; - } - - if (gnssHal == nullptr) { - return; - } - auto result = - gnssHal->injectLocation(latitudeDegrees, longitudeDegrees, horizontalAccuracyMeters); - checkHidlReturn(result, "IGnss injectLocation() failed."); + gnssHal->injectLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters, + speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters, + verticalAccuracyMeters, speedAccuracyMetersPerSecond, + bearingAccuracyDegrees, timestamp, elapsedRealtimeFlags, + elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos); } static jboolean android_location_gnss_hal_GnssNative_supports_psds(JNIEnv* /* env */, jclass) { - return (gnssPsdsAidlIface != nullptr || gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE; + return (gnssPsdsIface != nullptr) ? JNI_TRUE : JNI_FALSE; } static void android_location_gnss_hal_GnssNative_inject_psds_data(JNIEnv* env, jclass, jbyteArray data, jint length, jint psdsType) { - if (gnssPsdsAidlIface == nullptr && gnssXtraIface == nullptr) { - ALOGE("%s: IGnssPsdsAidl or IGnssXtra interface not available.", __func__); + if (gnssPsdsIface == nullptr) { + ALOGE("%s: IGnssPsds or IGnssXtra interface not available.", __func__); return; } - - jbyte* bytes = reinterpret_cast(env->GetPrimitiveArrayCritical(data, 0)); - if (gnssPsdsAidlIface != nullptr) { - auto status = gnssPsdsAidlIface->injectPsdsData(static_cast(psdsType), - std::vector((const uint8_t*)bytes, - (const uint8_t*)bytes + - length)); - checkAidlStatus(status, "IGnssPsdsAidl injectPsdsData() failed."); - } else if (gnssXtraIface != nullptr) { - auto result = gnssXtraIface->injectXtraData(std::string((const char*)bytes, length)); - checkHidlReturn(result, "IGnssXtra injectXtraData() failed."); - } - env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); + gnssPsdsIface->injectPsdsData(data, length, psdsType); } static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open( diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index e52df15b973aa..0531ae2a8ccd4 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -28,6 +28,8 @@ cc_library_shared { "AGnssRil.cpp", "AGnssRilCallback.cpp", "GnssAntennaInfo.cpp", + "Gnss.cpp", + "GnssCallback.cpp", "GnssAntennaInfoCallback.cpp", "GnssBatching.cpp", "GnssBatchingCallback.cpp", @@ -39,6 +41,8 @@ cc_library_shared { "GnssMeasurementCallback.cpp", "GnssNavigationMessage.cpp", "GnssNavigationMessageCallback.cpp", + "GnssPsds.cpp", + "GnssPsdsCallback.cpp", "GnssVisibilityControl.cpp", "GnssVisibilityControlCallback.cpp", "MeasurementCorrections.cpp", @@ -55,6 +59,7 @@ cc_defaults { "libhidlbase", "liblog", "libnativehelper", + "libhardware_legacy", "libutils", "android.hardware.gnss-V2-cpp", "android.hardware.gnss@1.0", diff --git a/services/core/jni/gnss/Gnss.cpp b/services/core/jni/gnss/Gnss.cpp new file mode 100644 index 0000000000000..f6459eaa444ef --- /dev/null +++ b/services/core/jni/gnss/Gnss.cpp @@ -0,0 +1,759 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Define LOG_TAG before to overwrite the default value. +#define LOG_TAG "GnssJni" + +#include "Gnss.h" + +#include + +#include "Utils.h" + +namespace android::gnss { + +using hardware::Return; + +using GnssLocationAidl = hardware::gnss::GnssLocation; +using GnssLocation_V1_0 = hardware::gnss::V1_0::GnssLocation; +using GnssLocation_V2_0 = hardware::gnss::V2_0::GnssLocation; +using IAGnssAidl = hardware::gnss::IAGnss; +using IAGnssRilAidl = hardware::gnss::IAGnssRil; +using IGnssAidl = hardware::gnss::IGnss; +using IGnss_V1_0 = hardware::gnss::V1_0::IGnss; +using IGnss_V1_1 = hardware::gnss::V1_1::IGnss; +using IGnss_V2_0 = hardware::gnss::V2_0::IGnss; +using IGnss_V2_1 = hardware::gnss::V2_1::IGnss; +using IGnssAntennaInfoAidl = hardware::gnss::IGnssAntennaInfo; +using IGnssCallbackAidl = hardware::gnss::IGnssCallback; +using IGnssCallback_V1_0 = hardware::gnss::V1_0::IGnssCallback; +using IGnssCallback_V2_0 = hardware::gnss::V2_0::IGnssCallback; +using IGnssCallback_V2_1 = hardware::gnss::V2_1::IGnssCallback; +using IGnssConfigurationAidl = android::hardware::gnss::IGnssConfiguration; +using IGnssDebugAidl = hardware::gnss::IGnssDebug; +using android::hardware::gnss::IGnssPsds; + +namespace { + +GnssLocationAidl createGnssLocation(jint gnssLocationFlags, jdouble latitudeDegrees, + jdouble longitudeDegrees, jdouble altitudeMeters, + jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, + jfloat bearingAccuracyDegrees, jlong timestamp, + jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, + jdouble elapsedRealtimeUncertaintyNanos) { + GnssLocationAidl location; + location.gnssLocationFlags = static_cast(gnssLocationFlags); + location.latitudeDegrees = static_cast(latitudeDegrees); + location.longitudeDegrees = static_cast(longitudeDegrees); + location.altitudeMeters = static_cast(altitudeMeters); + location.speedMetersPerSec = static_cast(speedMetersPerSec); + location.bearingDegrees = static_cast(bearingDegrees); + location.horizontalAccuracyMeters = static_cast(horizontalAccuracyMeters); + location.verticalAccuracyMeters = static_cast(verticalAccuracyMeters); + location.speedAccuracyMetersPerSecond = static_cast(speedAccuracyMetersPerSecond); + location.bearingAccuracyDegrees = static_cast(bearingAccuracyDegrees); + location.timestampMillis = static_cast(timestamp); + + location.elapsedRealtime.flags = static_cast(elapsedRealtimeFlags); + location.elapsedRealtime.timestampNs = static_cast(elapsedRealtimeNanos); + location.elapsedRealtime.timeUncertaintyNs = + static_cast(elapsedRealtimeUncertaintyNanos); + + return location; +} + +GnssLocation_V1_0 createGnssLocation_V1_0(jint gnssLocationFlags, jdouble latitudeDegrees, + jdouble longitudeDegrees, jdouble altitudeMeters, + jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, + jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, + jfloat bearingAccuracyDegrees, jlong timestamp) { + GnssLocation_V1_0 location; + location.gnssLocationFlags = static_cast(gnssLocationFlags); + location.latitudeDegrees = static_cast(latitudeDegrees); + location.longitudeDegrees = static_cast(longitudeDegrees); + location.altitudeMeters = static_cast(altitudeMeters); + location.speedMetersPerSec = static_cast(speedMetersPerSec); + location.bearingDegrees = static_cast(bearingDegrees); + location.horizontalAccuracyMeters = static_cast(horizontalAccuracyMeters); + location.verticalAccuracyMeters = static_cast(verticalAccuracyMeters); + location.speedAccuracyMetersPerSecond = static_cast(speedAccuracyMetersPerSecond); + location.bearingAccuracyDegrees = static_cast(bearingAccuracyDegrees); + location.timestamp = static_cast(timestamp); + + return location; +} + +GnssLocation_V2_0 createGnssLocation_V2_0(jint gnssLocationFlags, jdouble latitudeDegrees, + jdouble longitudeDegrees, jdouble altitudeMeters, + jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, + jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, + jfloat bearingAccuracyDegrees, jlong timestamp, + jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, + jdouble elapsedRealtimeUncertaintyNanos) { + GnssLocation_V2_0 location; + location.v1_0 = createGnssLocation_V1_0(gnssLocationFlags, latitudeDegrees, longitudeDegrees, + altitudeMeters, speedMetersPerSec, bearingDegrees, + horizontalAccuracyMeters, verticalAccuracyMeters, + speedAccuracyMetersPerSecond, bearingAccuracyDegrees, + timestamp); + + location.elapsedRealtime.flags = static_cast(elapsedRealtimeFlags); + location.elapsedRealtime.timestampNs = static_cast(elapsedRealtimeNanos); + location.elapsedRealtime.timeUncertaintyNs = + static_cast(elapsedRealtimeUncertaintyNanos); + + return location; +} + +} // anonymous namespace + +// Implementation of GnssHal, which unifies all versions of GNSS HALs + +GnssHal::GnssHal() { + gnssHalAidl = waitForVintfService(); + if (gnssHalAidl != nullptr) { + ALOGD("Successfully got GNSS AIDL handle. Version=%d.", gnssHalAidl->getInterfaceVersion()); + if (gnssHalAidl->getInterfaceVersion() >= 2) { + return; + } + } + + ALOGD("Trying IGnss_V2_1::getService()"); + gnssHal_V2_1 = IGnss_V2_1::getService(); + if (gnssHal_V2_1 != nullptr) { + gnssHal_V2_0 = gnssHal_V2_1; + gnssHal_V1_1 = gnssHal_V2_1; + gnssHal = gnssHal_V2_1; + return; + } + + ALOGD("gnssHal 2.1 was null, trying 2.0"); + gnssHal_V2_0 = IGnss_V2_0::getService(); + if (gnssHal_V2_0 != nullptr) { + gnssHal_V1_1 = gnssHal_V2_0; + gnssHal = gnssHal_V2_0; + return; + } + + ALOGD("gnssHal 2.0 was null, trying 1.1"); + gnssHal_V1_1 = IGnss_V1_1::getService(); + if (gnssHal_V1_1 != nullptr) { + gnssHal = gnssHal_V1_1; + return; + } + + ALOGD("gnssHal 1.1 was null, trying 1.0"); + gnssHal = IGnss_V1_0::getService(); +} + +jboolean GnssHal::isSupported() { + return (gnssHalAidl != nullptr || gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE; +} + +void GnssHal::linkToDeath() { + // TODO: linkToDeath for AIDL HAL + + if (gnssHal != nullptr) { + gnssHalDeathRecipient = new GnssDeathRecipient(); + hardware::Return linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0); + if (!linked.isOk()) { + ALOGE("Transaction error in linking to GnssHAL death: %s", + linked.description().c_str()); + } else if (!linked) { + ALOGW("Unable to link to GnssHal death notifications"); + } else { + ALOGD("Link to death notification successful"); + } + } +} + +jboolean GnssHal::setCallback() { + if (gnssHalAidl != nullptr) { + sp gnssCbIfaceAidl = new GnssCallbackAidl(); + auto status = gnssHalAidl->setCallback(gnssCbIfaceAidl); + if (!checkAidlStatus(status, "IGnssAidl setCallback() failed.")) { + return JNI_FALSE; + } + } + if (gnssHal != nullptr) { + Return result = false; + sp gnssCbIface = new GnssCallbackHidl(); + if (gnssHal_V2_1 != nullptr) { + result = gnssHal_V2_1->setCallback_2_1(gnssCbIface); + } else if (gnssHal_V2_0 != nullptr) { + result = gnssHal_V2_0->setCallback_2_0(gnssCbIface); + } else if (gnssHal_V1_1 != nullptr) { + result = gnssHal_V1_1->setCallback_1_1(gnssCbIface); + } else { + result = gnssHal->setCallback(gnssCbIface); + } + if (!checkHidlReturn(result, "IGnss setCallback() failed.")) { + return JNI_FALSE; + } + } + return JNI_TRUE; +} + +void GnssHal::close() { + if (gnssHalAidl != nullptr) { + auto status = gnssHalAidl->close(); + checkAidlStatus(status, "IGnssAidl close() failed."); + } + + if (gnssHal != nullptr) { + auto result = gnssHal->cleanup(); + checkHidlReturn(result, "IGnss cleanup() failed."); + } +} + +jboolean GnssHal::start() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->start(); + return checkAidlStatus(status, "IGnssAidl start() failed."); + } + + if (gnssHal == nullptr) { + return JNI_FALSE; + } + + auto result = gnssHal->start(); + return checkHidlReturn(result, "IGnss start() failed."); +} + +jboolean GnssHal::stop() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->stop(); + return checkAidlStatus(status, "IGnssAidl stop() failed."); + } + + if (gnssHal == nullptr) { + return JNI_FALSE; + } + + auto result = gnssHal->stop(); + return checkHidlReturn(result, "IGnss stop() failed."); +} + +jboolean GnssHal::startSvStatus() { + isSvStatusRegistered = true; + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->startSvStatus(); + return checkAidlStatus(status, "IGnssAidl startSvStatus() failed."); + } + if (gnssHal == nullptr) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +jboolean GnssHal::stopSvStatus() { + isSvStatusRegistered = false; + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->stopSvStatus(); + return checkAidlStatus(status, "IGnssAidl stopSvStatus() failed."); + } + if (gnssHal == nullptr) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +jboolean GnssHal::startNmea() { + isNmeaRegistered = true; + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->startNmea(); + return checkAidlStatus(status, "IGnssAidl startNmea() failed."); + } + if (gnssHal == nullptr) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +jboolean GnssHal::stopNmea() { + isNmeaRegistered = false; + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->stopNmea(); + return checkAidlStatus(status, "IGnssAidl stopNmea() failed."); + } + if (gnssHal == nullptr) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +jint GnssHal::readNmea(jbyteArray& nmeaArray, jint& buffer_size) { + // this should only be called from within a call to reportNmea + JNIEnv* env = getJniEnv(); + jbyte* nmea = reinterpret_cast(env->GetPrimitiveArrayCritical(nmeaArray, 0)); + int length = GnssCallbackHidl::sNmeaStringLength; + if (length > buffer_size) { + length = buffer_size; + } + memcpy(nmea, GnssCallbackHidl::sNmeaString, length); + env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT); + return (jint)length; +} + +jboolean GnssHal::setPositionMode(jint mode, jint recurrence, jint min_interval, + jint preferred_accuracy, jint preferred_time, + jboolean low_power_mode) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + IGnssAidl::PositionModeOptions options; + options.mode = static_cast(mode); + options.recurrence = static_cast(recurrence); + options.minIntervalMs = min_interval; + options.preferredAccuracyMeters = preferred_accuracy; + options.preferredTimeMs = preferred_time; + options.lowPowerMode = low_power_mode; + auto status = gnssHalAidl->setPositionMode(options); + return checkAidlStatus(status, "IGnssAidl setPositionMode() failed."); + } + + Return result = false; + if (gnssHal_V1_1 != nullptr) { + result = gnssHal_V1_1->setPositionMode_1_1(static_cast(mode), + static_cast( + recurrence), + min_interval, preferred_accuracy, preferred_time, + low_power_mode); + } else if (gnssHal != nullptr) { + result = gnssHal->setPositionMode(static_cast(mode), + static_cast( + recurrence), + min_interval, preferred_accuracy, preferred_time); + } + return checkHidlReturn(result, "IGnss setPositionMode() failed."); +} + +void GnssHal::deleteAidingData(jint flags) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->deleteAidingData(static_cast(flags)); + checkAidlStatus(status, "IGnssAidl deleteAidingData() failed."); + return; + } + + if (gnssHal == nullptr) { + return; + } + + auto result = gnssHal->deleteAidingData(static_cast(flags)); + checkHidlReturn(result, "IGnss deleteAidingData() failed."); +} + +void GnssHal::injectTime(jlong time, jlong timeReference, jint uncertainty) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + auto status = gnssHalAidl->injectTime(time, timeReference, uncertainty); + checkAidlStatus(status, "IGnssAidl injectTime() failed."); + return; + } + + if (gnssHal == nullptr) { + return; + } + auto result = gnssHal->injectTime(time, timeReference, uncertainty); + checkHidlReturn(result, "IGnss injectTime() failed."); +} + +void GnssHal::injectLocation(jint gnssLocationFlags, jdouble latitudeDegrees, + jdouble longitudeDegrees, jdouble altitudeMeters, + jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, + jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, + jdouble elapsedRealtimeUncertaintyNanos) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + GnssLocationAidl location = + createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, + altitudeMeters, speedMetersPerSec, bearingDegrees, + horizontalAccuracyMeters, verticalAccuracyMeters, + speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp, + elapsedRealtimeFlags, elapsedRealtimeNanos, + elapsedRealtimeUncertaintyNanos); + auto status = gnssHalAidl->injectLocation(location); + checkAidlStatus(status, "IGnssAidl injectLocation() failed."); + return; + } + + if (gnssHal == nullptr) { + return; + } + auto result = + gnssHal->injectLocation(latitudeDegrees, longitudeDegrees, horizontalAccuracyMeters); + checkHidlReturn(result, "IGnss injectLocation() failed."); +} + +void GnssHal::injectBestLocation(jint gnssLocationFlags, jdouble latitudeDegrees, + jdouble longitudeDegrees, jdouble altitudeMeters, + jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, + jlong timestamp, jint elapsedRealtimeFlags, + jlong elapsedRealtimeNanos, + jdouble elapsedRealtimeUncertaintyNanos) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + GnssLocationAidl location = + createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, + altitudeMeters, speedMetersPerSec, bearingDegrees, + horizontalAccuracyMeters, verticalAccuracyMeters, + speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp, + elapsedRealtimeFlags, elapsedRealtimeNanos, + elapsedRealtimeUncertaintyNanos); + auto status = gnssHalAidl->injectBestLocation(location); + checkAidlStatus(status, "IGnssAidl injectBestLocation() failed."); + return; + } + + if (gnssHal_V2_0 != nullptr) { + GnssLocation_V2_0 location = + createGnssLocation_V2_0(gnssLocationFlags, latitudeDegrees, longitudeDegrees, + altitudeMeters, speedMetersPerSec, bearingDegrees, + horizontalAccuracyMeters, verticalAccuracyMeters, + speedAccuracyMetersPerSecond, bearingAccuracyDegrees, + timestamp, elapsedRealtimeFlags, elapsedRealtimeNanos, + elapsedRealtimeUncertaintyNanos); + auto result = gnssHal_V2_0->injectBestLocation_2_0(location); + checkHidlReturn(result, "IGnss injectBestLocation_2_0() failed."); + return; + } + + if (gnssHal_V1_1 != nullptr) { + GnssLocation_V1_0 location = + createGnssLocation_V1_0(gnssLocationFlags, latitudeDegrees, longitudeDegrees, + altitudeMeters, speedMetersPerSec, bearingDegrees, + horizontalAccuracyMeters, verticalAccuracyMeters, + speedAccuracyMetersPerSecond, bearingAccuracyDegrees, + timestamp); + auto result = gnssHal_V1_1->injectBestLocation(location); + checkHidlReturn(result, "IGnss injectBestLocation() failed."); + return; + } + + ALOGE("IGnss injectBestLocation() is called but gnssHal_V1_1 is not available."); +} + +std::unique_ptr GnssHal::getAGnssInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp agnssAidl; + auto status = gnssHalAidl->getExtensionAGnss(&agnssAidl); + if (checkAidlStatus(status, "Unable to get a handle to AGnss interface.")) { + return std::make_unique(agnssAidl); + } + } else if (gnssHal_V2_0 != nullptr) { + auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0(); + if (checkHidlReturn(agnss_V2_0, "Unable to get a handle to AGnss_V2_0")) { + return std::make_unique(agnss_V2_0); + } + } else if (gnssHal != nullptr) { + auto agnss_V1_0 = gnssHal->getExtensionAGnss(); + if (checkHidlReturn(agnss_V1_0, "Unable to get a handle to AGnss_V1_0")) { + return std::make_unique(agnss_V1_0); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getAGnssRilInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp agnssRilAidl; + auto status = gnssHalAidl->getExtensionAGnssRil(&agnssRilAidl); + if (checkAidlStatus(status, "Unable to get a handle to AGnssRil interface.")) { + return std::make_unique(agnssRilAidl); + } + } else if (gnssHal_V2_0 != nullptr) { + auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0(); + if (checkHidlReturn(agnssRil_V2_0, "Unable to get a handle to AGnssRil_V2_0")) { + return std::make_unique(agnssRil_V2_0); + } + } else if (gnssHal != nullptr) { + auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil(); + if (checkHidlReturn(agnssRil_V1_0, "Unable to get a handle to AGnssRil_V1_0")) { + return std::make_unique(agnssRil_V1_0); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssNavigationMessageInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp gnssNavigationMessage; + auto status = gnssHalAidl->getExtensionGnssNavigationMessage(&gnssNavigationMessage); + if (checkAidlStatus(status, + "Unable to get a handle to GnssNavigationMessage AIDL interface.")) { + return std::make_unique(gnssNavigationMessage); + } + } else if (gnssHal != nullptr) { + auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage(); + if (checkHidlReturn(gnssNavigationMessage, + "Unable to get a handle to GnssNavigationMessage interface.")) { + return std::make_unique(gnssNavigationMessage); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssMeasurementInterface() { + // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means, + // 2.1@IGnss can be paired with {1.0, 1,1, 2.0, 2.1}@IGnssMeasurement + // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement + // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement + // 1.0@IGnss is paired with 1.0@IGnssMeasurement + if (gnssHalAidl != nullptr) { + sp gnssMeasurement; + auto status = gnssHalAidl->getExtensionGnssMeasurement(&gnssMeasurement); + if (checkAidlStatus(status, "Unable to get a handle to GnssMeasurement AIDL interface.")) { + return std::make_unique(gnssMeasurement); + } + } + if (gnssHal_V2_1 != nullptr) { + auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1(); + if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) { + return std::make_unique(gnssMeasurement); + } + } + if (gnssHal_V2_0 != nullptr) { + auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0(); + if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_0")) { + return std::make_unique(gnssMeasurement); + } + } + if (gnssHal_V1_1 != nullptr) { + auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1(); + if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_1")) { + return std::make_unique(gnssMeasurement); + } + } + if (gnssHal != nullptr) { + auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement(); + if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_0")) { + return std::make_unique(gnssMeasurement); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssDebugInterface() { + // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means, + // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug + // 1.0@IGnss is paired with 1.0@IGnssDebug + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp gnssDebugAidl; + auto status = gnssHalAidl->getExtensionGnssDebug(&gnssDebugAidl); + if (checkAidlStatus(status, "Unable to get a handle to GnssDebug interface.")) { + return std::make_unique(gnssDebugAidl); + } + } + if (gnssHal_V2_0 != nullptr) { + auto gnssDebug_V2_0 = gnssHal_V2_0->getExtensionGnssDebug_2_0(); + if (checkHidlReturn(gnssDebug_V2_0, "Unable to get a handle to GnssDebug_V2_0.")) { + return std::make_unique(gnssDebug_V2_0); + } + } + if (gnssHal != nullptr) { + auto gnssDebug_V1_0 = gnssHal->getExtensionGnssDebug(); + if (checkHidlReturn(gnssDebug_V1_0, "Unable to get a handle to GnssDebug_V1_0.")) { + return std::make_unique(gnssDebug_V1_0); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssConfigurationInterface() { + if (gnssHalAidl != nullptr) { + sp gnssConfigurationAidl; + auto status = gnssHalAidl->getExtensionGnssConfiguration(&gnssConfigurationAidl); + if (checkAidlStatus(status, + "Unable to get a handle to GnssConfiguration AIDL interface.")) { + return std::make_unique(gnssConfigurationAidl); + } + } else if (gnssHal_V2_1 != nullptr) { + auto gnssConfiguration = gnssHal_V2_1->getExtensionGnssConfiguration_2_1(); + if (checkHidlReturn(gnssConfiguration, + "Unable to get a handle to GnssConfiguration_V2_1")) { + return std::make_unique(gnssConfiguration); + } + } else if (gnssHal_V2_0 != nullptr) { + auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0(); + if (checkHidlReturn(gnssConfiguration, + "Unable to get a handle to GnssConfiguration_V2_0")) { + return std::make_unique(gnssConfiguration); + } + } else if (gnssHal_V1_1 != nullptr) { + auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1(); + if (checkHidlReturn(gnssConfiguration, + "Unable to get a handle to GnssConfiguration_V1_1")) { + return std::make_unique(gnssConfiguration); + } + } else if (gnssHal != nullptr) { + auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration(); + if (checkHidlReturn(gnssConfiguration, + "Unable to get a handle to GnssConfiguration_V1_0")) { + return std::make_unique(gnssConfiguration); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssGeofenceInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp gnssGeofence; + auto status = gnssHalAidl->getExtensionGnssGeofence(&gnssGeofence); + if (checkAidlStatus(status, "Unable to get a handle to GnssGeofence AIDL interface.")) { + return std::make_unique(gnssGeofence); + } + } else if (gnssHal != nullptr) { + auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing(); + if (checkHidlReturn(gnssGeofencing, "Unable to get a handle to GnssGeofencing")) { + return std::make_unique(gnssGeofencing); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssBatchingInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp gnssBatchingAidl; + auto status = gnssHalAidl->getExtensionGnssBatching(&gnssBatchingAidl); + if (checkAidlStatus(status, "Unable to get a handle to GnssBatching interface.")) { + return std::make_unique(gnssBatchingAidl); + } + } + if (gnssHal_V2_0 != nullptr) { + auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0(); + if (checkHidlReturn(gnssBatching_V2_0, "Unable to get a handle to GnssBatching_V2_0")) { + return std::make_unique(gnssBatching_V2_0); + } + } + if (gnssHal != nullptr) { + auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching(); + if (checkHidlReturn(gnssBatching_V1_0, "Unable to get a handle to GnssBatching")) { + return std::make_unique(gnssBatching_V1_0); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getMeasurementCorrectionsInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp + gnssMeasurementCorrectionsAidl; + auto status = + gnssHalAidl->getExtensionMeasurementCorrections(&gnssMeasurementCorrectionsAidl); + if (checkAidlStatus(status, + "Unable to get a handle to GnssVisibilityControl AIDL interface.")) { + return std::make_unique( + gnssMeasurementCorrectionsAidl); + } + } + if (gnssHal_V2_1 != nullptr) { + auto gnssCorrections = gnssHal_V2_1->getExtensionMeasurementCorrections_1_1(); + if (checkHidlReturn(gnssCorrections, + "Unable to get a handle to GnssMeasurementCorrections HIDL " + "interface")) { + return std::make_unique(gnssCorrections); + } + } + if (gnssHal_V2_0 != nullptr) { + auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections(); + if (checkHidlReturn(gnssCorrections, + "Unable to get a handle to GnssMeasurementCorrections HIDL " + "interface")) { + return std::make_unique(gnssCorrections); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssVisibilityControlInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp + gnssVisibilityControlAidl; + auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl); + if (checkAidlStatus(status, + "Unable to get a handle to GnssVisibilityControl AIDL interface.")) { + return std::make_unique(gnssVisibilityControlAidl); + } + } else if (gnssHal_V2_0 != nullptr) { + auto gnssVisibilityControlHidl = gnssHal_V2_0->getExtensionVisibilityControl(); + if (checkHidlReturn(gnssVisibilityControlHidl, + "Unable to get a handle to GnssVisibilityControl HIDL interface")) { + return std::make_unique(gnssVisibilityControlHidl); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssAntennaInfoInterface() { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp gnssAntennaInfoAidl; + auto status = gnssHalAidl->getExtensionGnssAntennaInfo(&gnssAntennaInfoAidl); + if (checkAidlStatus(status, "Unable to get a handle to GnssAntennaInfo interface.")) { + return std::make_unique(gnssAntennaInfoAidl); + } + } else if (gnssHal_V2_1 != nullptr) { + auto gnssAntennaInfo_V2_1 = gnssHal_V2_1->getExtensionGnssAntennaInfo(); + if (checkHidlReturn(gnssAntennaInfo_V2_1, + "Unable to get a handle to GnssAntennaInfo_V2_1")) { + return std::make_unique(gnssAntennaInfo_V2_1); + } + } + return nullptr; +} + +std::unique_ptr GnssHal::getGnssPsdsInterface() { + if (gnssHalAidl != nullptr) { + sp gnssPsdsAidl; + auto status = gnssHalAidl->getExtensionPsds(&gnssPsdsAidl); + if (checkAidlStatus(status, "Unable to get a handle to PSDS interface.")) { + return std::make_unique(gnssPsdsAidl); + } + } else if (gnssHal != nullptr) { + auto gnssXtra = gnssHal->getExtensionXtra(); + if (checkHidlReturn(gnssXtra, "Unable to get a handle to XTRA interface.")) { + return std::make_unique(gnssXtra); + } + } + return nullptr; +} + +sp GnssHal::getGnssPowerIndicationInterface() { + if (gnssHalAidl != nullptr) { + sp gnssPowerIndication; + auto status = gnssHalAidl->getExtensionGnssPowerIndication(&gnssPowerIndication); + if (checkAidlStatus(status, "Unable to get a handle to GnssPowerIndication")) { + return gnssPowerIndication; + } + } + return nullptr; +} + +sp GnssHal::getGnssNiInterface() { + if (gnssHal != nullptr) { + auto gnssNi = gnssHal->getExtensionGnssNi(); + if (checkHidlReturn(gnssNi, "Unable to get a handle to GnssNi")) { + return gnssNi; + } + } + return nullptr; +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/Gnss.h b/services/core/jni/gnss/Gnss.h new file mode 100644 index 0000000000000..c6743d62af459 --- /dev/null +++ b/services/core/jni/gnss/Gnss.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSS_H +#define _ANDROID_SERVER_GNSS_GNSS_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include +#include +#include +#include + +#include "AGnss.h" +#include "AGnssRil.h" +#include "GnssAntennaInfo.h" +#include "GnssBatching.h" +#include "GnssCallback.h" +#include "GnssConfiguration.h" +#include "GnssDebug.h" +#include "GnssGeofence.h" +#include "GnssMeasurement.h" +#include "GnssNavigationMessage.h" +#include "GnssPsds.h" +#include "GnssVisibilityControl.h" +#include "MeasurementCorrections.h" +#include "jni.h" + +namespace android::gnss { + +struct GnssDeathRecipient : virtual public hardware::hidl_death_recipient { + // hidl_death_recipient interface + virtual void serviceDied(uint64_t cookie, const wp& who) override { + ALOGE("IGNSS hidl service failed, trying to recover..."); + + JNIEnv* env = android::AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(android::mCallbacksObj, method_reportGnssServiceDied); + } +}; + +class GnssHal { +public: + GnssHal(); + ~GnssHal() {} + + jboolean isSupported(); + jboolean setCallback(); + jboolean start(); + jboolean stop(); + jboolean setPositionMode(jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, + jint preferred_time, jboolean low_power_mode); + jboolean startSvStatus(); + jboolean stopSvStatus(); + jboolean startNmea(); + jboolean stopNmea(); + jint readNmea(jbyteArray& nmeaArray, jint& buffer_size); + void linkToDeath(); + void close(); + void deleteAidingData(jint flags); + void injectTime(jlong time, jlong timeReference, jint uncertainty); + void injectLocation(jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, + jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, + jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, + jdouble elapsedRealtimeUncertaintyNanos); + void injectBestLocation(jint gnssLocationFlags, jdouble latitudeDegrees, + jdouble longitudeDegrees, jdouble altitudeMeters, + jfloat speedMetersPerSec, jfloat bearingDegrees, + jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, + jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, + jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos, + jdouble elapsedRealtimeUncertaintyNanos); + + std::unique_ptr getAGnssInterface(); + std::unique_ptr getAGnssRilInterface(); + std::unique_ptr getGnssNavigationMessageInterface(); + std::unique_ptr getGnssMeasurementInterface(); + std::unique_ptr getGnssDebugInterface(); + std::unique_ptr getGnssConfigurationInterface(); + std::unique_ptr getGnssGeofenceInterface(); + std::unique_ptr getGnssBatchingInterface(); + std::unique_ptr getMeasurementCorrectionsInterface(); + std::unique_ptr getGnssVisibilityControlInterface(); + std::unique_ptr getGnssAntennaInfoInterface(); + std::unique_ptr getGnssPsdsInterface(); + + sp getGnssPowerIndicationInterface(); + sp getGnssNiInterface(); + +private: + sp gnssHalDeathRecipient = nullptr; + sp gnssHal = nullptr; + sp gnssHal_V1_1 = nullptr; + sp gnssHal_V2_0 = nullptr; + sp gnssHal_V2_1 = nullptr; + sp gnssHalAidl = nullptr; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_Gnss_H diff --git a/services/core/jni/gnss/GnssCallback.cpp b/services/core/jni/gnss/GnssCallback.cpp new file mode 100644 index 0000000000000..b931e915a7538 --- /dev/null +++ b/services/core/jni/gnss/GnssCallback.cpp @@ -0,0 +1,413 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssCallbckJni" + +#include "GnssCallback.h" + +#include + +#define WAKE_LOCK_NAME "GPS" + +namespace android::gnss { + +using android::hardware::gnss::V1_0::GnssLocationFlags; +using binder::Status; +using hardware::hidl_vec; +using hardware::Return; +using hardware::Void; + +using GnssLocationAidl = android::hardware::gnss::GnssLocation; +using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation; +using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation; +using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback; +using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback; +using IGnssCallback_V2_0 = android::hardware::gnss::V2_0::IGnssCallback; +using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback; + +jmethodID method_reportGnssServiceDied; + +namespace { + +jmethodID method_reportLocation; +jmethodID method_reportStatus; +jmethodID method_reportSvStatus; +jmethodID method_reportNmea; +jmethodID method_setTopHalCapabilities; +jmethodID method_setGnssYearOfHardware; +jmethodID method_setGnssHardwareModelName; +jmethodID method_requestLocation; +jmethodID method_requestUtcTime; + +// Returns true if location has lat/long information. +inline bool hasLatLong(const GnssLocationAidl& location) { + return (location.gnssLocationFlags & hardware::gnss::GnssLocation::HAS_LAT_LONG) != 0; +} + +// Returns true if location has lat/long information. +inline bool hasLatLong(const GnssLocation_V1_0& location) { + return (static_cast(location.gnssLocationFlags) & GnssLocationFlags::HAS_LAT_LONG) != + 0; +} + +// Returns true if location has lat/long information. +inline bool hasLatLong(const GnssLocation_V2_0& location) { + return hasLatLong(location.v1_0); +} + +inline jboolean boolToJbool(bool value) { + return value ? JNI_TRUE : JNI_FALSE; +} + +// Must match the value from GnssMeasurement.java +const uint32_t SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4); + +} // anonymous namespace + +bool isSvStatusRegistered = false; +bool isNmeaRegistered = false; + +void Gnss_class_init_once(JNIEnv* env, jclass& clazz) { + method_reportLocation = + env->GetMethodID(clazz, "reportLocation", "(ZLandroid/location/Location;)V"); + method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); + method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V"); + method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); + + method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V"); + method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); + method_setGnssHardwareModelName = + env->GetMethodID(clazz, "setGnssHardwareModelName", "(Ljava/lang/String;)V"); + + method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V"); + method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); + method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V"); +} + +Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) { + ALOGD("GnssCallbackAidl::%s: %du\n", __func__, capabilities); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue status) { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_reportStatus, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssSvStatusCb(const std::vector& svInfoList) { + GnssCallbackHidl::gnssSvStatusCbImpl, GnssSvInfo>(svInfoList); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssLocationCb(const hardware::gnss::GnssLocation& location) { + GnssCallbackHidl::gnssLocationCbImpl(location); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssNmeaCb(const int64_t timestamp, const std::string& nmea) { + // In AIDL v1, if no listener is registered, do not report nmea to the framework. + if (getInterfaceVersion() <= 1) { + if (!isNmeaRegistered) { + return Status::ok(); + } + } + JNIEnv* env = getJniEnv(); + /* + * The Java code will call back to read these values. + * We do this to avoid creating unnecessary String objects. + */ + GnssCallbackHidl::sNmeaString = nmea.c_str(); + GnssCallbackHidl::sNmeaStringLength = nmea.size(); + + env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssAcquireWakelockCb() { + acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssReleaseWakelockCb() { + release_wake_lock(WAKE_LOCK_NAME); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) { + ALOGD("%s: yearOfHw=%d, name=%s\n", __func__, info.yearOfHw, info.name.c_str()); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, info.yearOfHw); + jstring jstringName = env->NewStringUTF(info.name.c_str()); + env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName); + if (jstringName) { + env->DeleteLocalRef(jstringName); + } + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssRequestTimeCb() { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestUtcTime); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +Status GnssCallbackAidl::gnssRequestLocationCb(const bool independentFromGnss, + const bool isUserEmergency) { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss), + boolToJbool(isUserEmergency)); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +// Implementation of IGnssCallbackHidl + +Return GnssCallbackHidl::gnssNameCb(const android::hardware::hidl_string& name) { + ALOGD("%s: name=%s\n", __func__, name.c_str()); + + JNIEnv* env = getJniEnv(); + jstring jstringName = env->NewStringUTF(name.c_str()); + env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName); + if (jstringName) { + env->DeleteLocalRef(jstringName); + } + checkAndClearExceptionFromCallback(env, __FUNCTION__); + + return Void(); +} + +const char* GnssCallbackHidl::sNmeaString = nullptr; +size_t GnssCallbackHidl::sNmeaStringLength = 0; + +template +Return GnssCallbackHidl::gnssLocationCbImpl(const T& location) { + JNIEnv* env = getJniEnv(); + + jobject jLocation = translateGnssLocation(env, location); + + env->CallVoidMethod(mCallbacksObj, method_reportLocation, boolToJbool(hasLatLong(location)), + jLocation); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(jLocation); + return Void(); +} + +Return GnssCallbackHidl::gnssLocationCb(const GnssLocation_V1_0& location) { + return gnssLocationCbImpl(location); +} + +Return GnssCallbackHidl::gnssLocationCb_2_0(const GnssLocation_V2_0& location) { + return gnssLocationCbImpl(location); +} + +Return GnssCallbackHidl::gnssStatusCb(const IGnssCallback_V2_0::GnssStatusValue status) { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_reportStatus, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +template <> +uint32_t GnssCallbackHidl::getHasBasebandCn0DbHzFlag( + const hidl_vec& svStatus) { + return SVID_FLAGS_HAS_BASEBAND_CN0; +} + +template <> +uint32_t GnssCallbackHidl::getHasBasebandCn0DbHzFlag( + const std::vector& svStatus) { + return SVID_FLAGS_HAS_BASEBAND_CN0; +} + +template <> +double GnssCallbackHidl::getBasebandCn0DbHz( + const std::vector& svInfoList, size_t i) { + return svInfoList[i].basebandCN0DbHz; +} + +template <> +double GnssCallbackHidl::getBasebandCn0DbHz( + const hidl_vec& svInfoList, size_t i) { + return svInfoList[i].basebandCN0DbHz; +} + +template <> +uint32_t GnssCallbackHidl::getGnssSvInfoListSize(const IGnssCallback_V1_0::GnssSvStatus& svStatus) { + return svStatus.numSvs; +} + +template <> +uint32_t GnssCallbackHidl::getConstellationType(const IGnssCallback_V1_0::GnssSvStatus& svStatus, + size_t i) { + return static_cast(svStatus.gnssSvList.data()[i].constellation); +} + +template <> +uint32_t GnssCallbackHidl::getConstellationType( + const hidl_vec& svInfoList, size_t i) { + return static_cast(svInfoList[i].v2_0.constellation); +} + +template +Return GnssCallbackHidl::gnssSvStatusCbImpl(const T_list& svStatus) { + // In HIDL or AIDL v1, if no listener is registered, do not report svInfoList to the framework. + if (!isSvStatusRegistered) { + return Void(); + } + + JNIEnv* env = getJniEnv(); + + uint32_t listSize = getGnssSvInfoListSize(svStatus); + + jintArray svidWithFlagArray = env->NewIntArray(listSize); + jfloatArray cn0Array = env->NewFloatArray(listSize); + jfloatArray elevArray = env->NewFloatArray(listSize); + jfloatArray azimArray = env->NewFloatArray(listSize); + jfloatArray carrierFreqArray = env->NewFloatArray(listSize); + jfloatArray basebandCn0Array = env->NewFloatArray(listSize); + + jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0); + jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0); + jfloat* elev = env->GetFloatArrayElements(elevArray, 0); + jfloat* azim = env->GetFloatArrayElements(azimArray, 0); + jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0); + jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0); + + /* + * Read GNSS SV info. + */ + for (size_t i = 0; i < listSize; ++i) { + enum ShiftWidth : uint8_t { SVID_SHIFT_WIDTH = 12, CONSTELLATION_TYPE_SHIFT_WIDTH = 8 }; + + const T_sv_info& info = getGnssSvInfoOfIndex(svStatus, i); + svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) | + (getConstellationType(svStatus, i) << CONSTELLATION_TYPE_SHIFT_WIDTH) | + static_cast(info.svFlag); + cn0s[i] = info.cN0Dbhz; + elev[i] = info.elevationDegrees; + azim[i] = info.azimuthDegrees; + carrierFreq[i] = info.carrierFrequencyHz; + svidWithFlags[i] |= getHasBasebandCn0DbHzFlag(svStatus); + basebandCn0s[i] = getBasebandCn0DbHz(svStatus, i); + } + + env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0); + env->ReleaseFloatArrayElements(cn0Array, cn0s, 0); + env->ReleaseFloatArrayElements(elevArray, elev, 0); + env->ReleaseFloatArrayElements(azimArray, azim, 0); + env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0); + env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0); + + env->CallVoidMethod(mCallbacksObj, method_reportSvStatus, static_cast(listSize), + svidWithFlagArray, cn0Array, elevArray, azimArray, carrierFreqArray, + basebandCn0Array); + + env->DeleteLocalRef(svidWithFlagArray); + env->DeleteLocalRef(cn0Array); + env->DeleteLocalRef(elevArray); + env->DeleteLocalRef(azimArray); + env->DeleteLocalRef(carrierFreqArray); + env->DeleteLocalRef(basebandCn0Array); + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return GnssCallbackHidl::gnssNmeaCb(int64_t timestamp, + const ::android::hardware::hidl_string& nmea) { + // In HIDL, if no listener is registered, do not report nmea to the framework. + if (!isNmeaRegistered) { + return Void(); + } + JNIEnv* env = getJniEnv(); + /* + * 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(); +} + +Return GnssCallbackHidl::gnssSetCapabilitesCb(uint32_t capabilities) { + ALOGD("%s: %du\n", __func__, capabilities); + + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return GnssCallbackHidl::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { + return GnssCallbackHidl::gnssSetCapabilitesCb(capabilities); +} + +Return GnssCallbackHidl::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) { + return GnssCallbackHidl::gnssSetCapabilitesCb(capabilities); +} + +Return GnssCallbackHidl::gnssAcquireWakelockCb() { + acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); + return Void(); +} + +Return GnssCallbackHidl::gnssReleaseWakelockCb() { + release_wake_lock(WAKE_LOCK_NAME); + return Void(); +} + +Return GnssCallbackHidl::gnssRequestTimeCb() { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestUtcTime); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return GnssCallbackHidl::gnssRequestLocationCb(const bool independentFromGnss) { + return GnssCallbackHidl::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */ + false); +} + +Return GnssCallbackHidl::gnssRequestLocationCb_2_0(const bool independentFromGnss, + const bool isUserEmergency) { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss), + boolToJbool(isUserEmergency)); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return GnssCallbackHidl::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSystemInfo& info) { + ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw); + + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, info.yearOfHw); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +} // namespace android::gnss \ No newline at end of file diff --git a/services/core/jni/gnss/GnssCallback.h b/services/core/jni/gnss/GnssCallback.h new file mode 100644 index 0000000000000..a7f96fb0f5c70 --- /dev/null +++ b/services/core/jni/gnss/GnssCallback.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSSCALLBACK_H +#define _ANDROID_SERVER_GNSS_GNSSCALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include + +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +namespace { + +extern jmethodID method_reportLocation; +extern jmethodID method_reportStatus; +extern jmethodID method_reportSvStatus; +extern jmethodID method_reportNmea; +extern jmethodID method_setTopHalCapabilities; +extern jmethodID method_setGnssYearOfHardware; +extern jmethodID method_setGnssHardwareModelName; +extern jmethodID method_requestLocation; +extern jmethodID method_requestUtcTime; + +} // anonymous namespace + +extern bool isSvStatusRegistered; +extern bool isNmeaRegistered; + +extern jmethodID method_reportGnssServiceDied; + +void Gnss_class_init_once(JNIEnv* env, jclass& clazz); + +/* + * GnssCallbackAidl class implements the callback methods for AIDL IGnssCallback interface. + */ +class GnssCallbackAidl : public hardware::gnss::BnGnssCallback { +public: + binder::Status gnssSetCapabilitiesCb(const int capabilities) override; + binder::Status gnssStatusCb(const GnssStatusValue status) override; + binder::Status gnssSvStatusCb(const std::vector& svInfoList) override; + binder::Status gnssLocationCb(const hardware::gnss::GnssLocation& location) override; + binder::Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override; + binder::Status gnssAcquireWakelockCb() override; + binder::Status gnssReleaseWakelockCb() override; + binder::Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override; + binder::Status gnssRequestTimeCb() override; + binder::Status gnssRequestLocationCb(const bool independentFromGnss, + const bool isUserEmergency) override; +}; + +/* + * GnssCallbackHidl class implements the callback methods for HIDL IGnssCallback interface. + */ +struct GnssCallbackHidl : public hardware::gnss::V2_1::IGnssCallback { + hardware::Return gnssLocationCb( + const hardware::gnss::V1_0::GnssLocation& location) override; + hardware::Return gnssStatusCb( + const hardware::gnss::V1_0::IGnssCallback::GnssStatusValue status) override; + hardware::Return gnssSvStatusCb( + const hardware::gnss::V1_0::IGnssCallback::GnssSvStatus& svStatus) override { + return gnssSvStatusCbImpl(svStatus); + } + hardware::Return gnssNmeaCb(int64_t timestamp, + const hardware::hidl_string& nmea) override; + hardware::Return gnssSetCapabilitesCb(uint32_t capabilities) override; + hardware::Return gnssAcquireWakelockCb() override; + hardware::Return gnssReleaseWakelockCb() override; + hardware::Return gnssRequestTimeCb() override; + hardware::Return gnssRequestLocationCb(const bool independentFromGnss) override; + + hardware::Return gnssSetSystemInfoCb( + const hardware::gnss::V1_0::IGnssCallback::GnssSystemInfo& info) override; + + // New in 1.1 + hardware::Return gnssNameCb(const hardware::hidl_string& name) override; + + // New in 2.0 + hardware::Return gnssRequestLocationCb_2_0(const bool independentFromGnss, + const bool isUserEmergency) override; + hardware::Return gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override; + hardware::Return gnssLocationCb_2_0( + const hardware::gnss::V2_0::GnssLocation& location) override; + hardware::Return gnssSvStatusCb_2_0( + const hardware::hidl_vec& svInfoList) + override { + return gnssSvStatusCbImpl< + hardware::hidl_vec, + hardware::gnss::V1_0::IGnssCallback::GnssSvInfo>(svInfoList); + } + + // New in 2.1 + hardware::Return gnssSvStatusCb_2_1( + const hardware::hidl_vec& svInfoList) + override { + return gnssSvStatusCbImpl< + hardware::hidl_vec, + hardware::gnss::V1_0::IGnssCallback::GnssSvInfo>(svInfoList); + } + hardware::Return gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override; + + // TODO: Reconsider allocation cost vs threadsafety on these statics + static const char* sNmeaString; + static size_t sNmeaStringLength; + + template + static hardware::Return gnssLocationCbImpl(const T& location); + + template + static hardware::Return gnssSvStatusCbImpl(const T_list& svStatus); + +private: + template + static uint32_t getHasBasebandCn0DbHzFlag(const T& svStatus) { + return 0; + } + + template + static double getBasebandCn0DbHz(const T& svStatus, size_t i) { + return 0.0; + } + + template + static uint32_t getGnssSvInfoListSize(const T& svInfoList) { + return svInfoList.size(); + } + + static const hardware::gnss::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex( + const std::vector& svInfoList, size_t i) { + return svInfoList[i]; + } + + static const hardware::gnss::V1_0::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex( + const hardware::gnss::V1_0::IGnssCallback::GnssSvStatus& svStatus, size_t i) { + return svStatus.gnssSvList.data()[i]; + } + + static const hardware::gnss::V1_0::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex( + const hardware::hidl_vec& svInfoList, + size_t i) { + return svInfoList[i].v1_0; + } + + static const hardware::gnss::V1_0::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex( + const hardware::hidl_vec& svInfoList, + size_t i) { + return svInfoList[i].v2_0.v1_0; + } + + template + static uint32_t getConstellationType(const T& svInfoList, size_t i) { + return static_cast(svInfoList[i].constellation); + } +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSCALLBACK_H \ No newline at end of file diff --git a/services/core/jni/gnss/GnssDebug.cpp b/services/core/jni/gnss/GnssDebug.cpp index da5331760e5ce..263a6c635f286 100644 --- a/services/core/jni/gnss/GnssDebug.cpp +++ b/services/core/jni/gnss/GnssDebug.cpp @@ -104,4 +104,10 @@ const android::hardware::gnss::IGnssDebug::SatelliteData& GnssDebugUtil::getSate return satelliteDataArray[i]; } +template <> +int64_t GnssDebugUtil::getTimeEstimateMs( + const android::hardware::gnss::IGnssDebug::DebugData& data) { + return data.time.timeEstimateMs; +} + } // namespace android::gnss diff --git a/services/core/jni/gnss/GnssDebug.h b/services/core/jni/gnss/GnssDebug.h index 1e1a7b4c1abd5..e02c2ac838e75 100644 --- a/services/core/jni/gnss/GnssDebug.h +++ b/services/core/jni/gnss/GnssDebug.h @@ -113,12 +113,6 @@ int64_t GnssDebugUtil::getTimeEstimateMs(const T& data) { return data.time.timeEstimate; } -template <> -int64_t GnssDebugUtil::getTimeEstimateMs( - const android::hardware::gnss::IGnssDebug::DebugData& data) { - return data.time.timeEstimateMs; -} - template jstring GnssDebugUtil::parseDebugData(JNIEnv* env, std::stringstream& internalState, const T_DebugData& data) { diff --git a/services/core/jni/gnss/GnssPsds.cpp b/services/core/jni/gnss/GnssPsds.cpp new file mode 100644 index 0000000000000..51a1450c0303b --- /dev/null +++ b/services/core/jni/gnss/GnssPsds.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Define LOG_TAG before to overwrite the default value. +#define LOG_TAG "GnssPsdsJni" + +#include "GnssPsds.h" + +#include "Utils.h" + +using android::hardware::hidl_bitfield; +using android::hardware::gnss::PsdsType; +using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds; +using IGnssPsdsHidl = android::hardware::gnss::V1_0::IGnssXtra; + +namespace android::gnss { + +// Implementation of GnssPsds (AIDL HAL) + +GnssPsdsAidl::GnssPsdsAidl(const sp& iGnssPsds) : mIGnssPsds(iGnssPsds) { + assert(mIGnssPsds != nullptr); +} + +jboolean GnssPsdsAidl::setCallback(const std::unique_ptr& callback) { + auto status = mIGnssPsds->setCallback(callback->getAidl()); + return checkAidlStatus(status, "IGnssPsdsAidl setCallback() failed."); +} + +void GnssPsdsAidl::injectPsdsData(const jbyteArray& data, const jint& length, + const jint& psdsType) { + JNIEnv* env = getJniEnv(); + jbyte* bytes = reinterpret_cast(env->GetPrimitiveArrayCritical(data, 0)); + auto status = mIGnssPsds->injectPsdsData(static_cast(psdsType), + std::vector((const uint8_t*)bytes, + (const uint8_t*)bytes + length)); + checkAidlStatus(status, "IGnssPsdsAidl injectPsdsData() failed."); + env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); +} + +// Implementation of GnssPsdsHidl + +GnssPsdsHidl::GnssPsdsHidl(const sp& iGnssXtra) + : mIGnssXtra(iGnssXtra) { + assert(mIGnssXtra != nullptr); +} + +jboolean GnssPsdsHidl::setCallback(const std::unique_ptr& callback) { + auto result = mIGnssXtra->setCallback(callback->getHidl()); + return checkHidlReturn(result, "IGnssPsdsHidl setCallback() failed."); +} + +void GnssPsdsHidl::injectPsdsData(const jbyteArray& data, const jint& length, const jint&) { + JNIEnv* env = getJniEnv(); + jbyte* bytes = reinterpret_cast(env->GetPrimitiveArrayCritical(data, 0)); + auto result = mIGnssXtra->injectXtraData(std::string((const char*)bytes, length)); + checkHidlReturn(result, "IGnssXtra injectXtraData() failed."); + env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssPsds.h b/services/core/jni/gnss/GnssPsds.h new file mode 100644 index 0000000000000..6b65ee8614f86 --- /dev/null +++ b/services/core/jni/gnss/GnssPsds.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSSPSDS_H +#define _ANDROID_SERVER_GNSS_GNSSPSDS_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include "GnssPsdsCallback.h" +#include "jni.h" + +namespace android::gnss { + +class GnssPsdsInterface { +public: + virtual ~GnssPsdsInterface() {} + virtual jboolean setCallback(const std::unique_ptr& callback); + virtual void injectPsdsData(const jbyteArray& data, const jint& length, const jint& psdsType); +}; + +class GnssPsdsAidl : public GnssPsdsInterface { +public: + GnssPsdsAidl(const sp& iGnssPsds); + jboolean setCallback(const std::unique_ptr& callback) override; + void injectPsdsData(const jbyteArray& data, const jint& length, const jint& psdsType) override; + +private: + const sp mIGnssPsds; +}; + +class GnssPsdsHidl : public GnssPsdsInterface { +public: + GnssPsdsHidl(const sp& iGnssXtra); + jboolean setCallback(const std::unique_ptr& callback) override; + void injectPsdsData(const jbyteArray& data, const jint& length, const jint& psdsType) override; + +private: + const sp mIGnssXtra; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSPSDS_H diff --git a/services/core/jni/gnss/GnssPsdsCallback.cpp b/services/core/jni/gnss/GnssPsdsCallback.cpp new file mode 100644 index 0000000000000..1dd7022c66ee2 --- /dev/null +++ b/services/core/jni/gnss/GnssPsdsCallback.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssPsdsCbJni" + +#include "GnssPsdsCallback.h" + +#include + +#include "Utils.h" + +namespace android::gnss { + +namespace { +jmethodID method_psdsDownloadRequest; +} // anonymous namespace + +using binder::Status; +using hardware::Return; +using hardware::Void; +using hardware::gnss::PsdsType; + +void GnssPsds_class_init_once(JNIEnv* env, jclass clazz) { + method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "(I)V"); +} + +// Implementation of android::hardware::gnss::IGnssPsdsCallback + +Status GnssPsdsCallbackAidl::downloadRequestCb(PsdsType psdsType) { + ALOGD("%s. psdsType: %d", __func__, static_cast(psdsType)); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, psdsType); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +// Implementation of android::hardware::gnss::V1_0::IGnssPsdsCallback + +Return GnssPsdsCallbackHidl::downloadRequestCb() { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssPsdsCallback.h b/services/core/jni/gnss/GnssPsdsCallback.h new file mode 100644 index 0000000000000..3ac7473c42a9d --- /dev/null +++ b/services/core/jni/gnss/GnssPsdsCallback.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSSPSDSCALLBACK_H +#define _ANDROID_SERVER_GNSS_GNSSPSDSCALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include "jni.h" + +namespace android::gnss { + +namespace { +extern jmethodID method_psdsDownloadRequest; +} // anonymous namespace + +void GnssPsds_class_init_once(JNIEnv* env, jclass clazz); + +class GnssPsdsCallbackAidl : public hardware::gnss::BnGnssPsdsCallback { +public: + GnssPsdsCallbackAidl() {} + binder::Status downloadRequestCb(hardware::gnss::PsdsType psdsType) override; +}; + +class GnssPsdsCallbackHidl : public hardware::gnss::V1_0::IGnssXtraCallback { +public: + GnssPsdsCallbackHidl() {} + hardware::Return downloadRequestCb() override; +}; + +class GnssPsdsCallback { +public: + GnssPsdsCallback() {} + sp getAidl() { + if (callbackAidl == nullptr) { + callbackAidl = sp::make(); + } + return callbackAidl; + } + + sp getHidl() { + if (callbackHidl == nullptr) { + callbackHidl = sp::make(); + } + return callbackHidl; + } + +private: + sp callbackAidl; + sp callbackHidl; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSPSDSCALLBACK_H \ No newline at end of file