/* * 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() { if (gnssHalAidl != nullptr) { gnssHalDeathRecipientAidl = new GnssDeathRecipientAidl(); status_t linked = IInterface::asBinder(gnssHalAidl)->linkToDeath(gnssHalDeathRecipientAidl); if (linked != OK) { ALOGE("Unable to link to GNSS AIDL HAL death notification"); } else { ALOGD("Successfully linked to GNSS AIDL HAl death notification"); } } 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(gnssHalAidl->getInterfaceVersion()); 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