diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index f0f779dc9ac94..826171a0f10e6 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include "gnss/GnssAntennaInfoCallback.h" #include "gnss/GnssBatching.h" #include "gnss/GnssConfiguration.h" +#include "gnss/GnssDebug.h" #include "gnss/GnssGeofence.h" #include "gnss/GnssMeasurement.h" #include "gnss/GnssNavigationMessage.h" @@ -155,8 +157,6 @@ using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss; 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; -using IGnssDebug_V1_0 = android::hardware::gnss::V1_0::IGnssDebug; -using IGnssDebug_V2_0 = android::hardware::gnss::V2_0::IGnssDebug; using IGnssAntennaInfo = android::hardware::gnss::V2_1::IGnssAntennaInfo; using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil; using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil; @@ -179,6 +179,7 @@ using IAGnssAidl = android::hardware::gnss::IAGnss; 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; using IGnssPsdsCallbackAidl = android::hardware::gnss::IGnssPsdsCallback; using IGnssConfigurationAidl = android::hardware::gnss::IGnssConfiguration; @@ -209,8 +210,6 @@ sp gnssPsdsAidlIface = nullptr; sp gnssXtraIface = nullptr; sp agnssRilIface = nullptr; sp agnssRilIface_V2_0 = nullptr; -sp gnssDebugIface = nullptr; -sp gnssDebugIface_V2_0 = nullptr; sp gnssNiIface = nullptr; sp gnssPowerIndicationIface = nullptr; sp gnssCorrectionsIface_V1_0 = nullptr; @@ -224,6 +223,7 @@ std::unique_ptr gnssNavigationMes std::unique_ptr gnssBatchingIface = nullptr; std::unique_ptr gnssGeofencingIface = nullptr; std::unique_ptr agnssIface = nullptr; +std::unique_ptr gnssDebugIface = nullptr; #define WAKE_LOCK_NAME "GPS" @@ -1104,22 +1104,24 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject // 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 - gnssDebugIface = nullptr; - if (gnssHal_V2_0 != nullptr) { - auto gnssDebug = gnssHal_V2_0->getExtensionGnssDebug_2_0(); - if (!gnssDebug.isOk()) { - ALOGD("Unable to get a handle to GnssDebug_V2_0"); - } else { - gnssDebugIface_V2_0 = gnssDebug; - gnssDebugIface = gnssDebugIface_V2_0; + + 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 = gnssHal->getExtensionGnssDebug(); - if (!gnssDebug.isOk()) { - ALOGD("Unable to get a handle to GnssDebug"); - } else { - gnssDebugIface = gnssDebug; + 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); } } @@ -1639,108 +1641,16 @@ static void android_location_gnss_hal_GnssNative_send_ni_response(JNIEnv* /* env checkHidlReturn(result, "IGnssNi respond() failed."); } -const IGnssDebug_V1_0::SatelliteData& getSatelliteData( - const hidl_vec& satelliteDataArray, size_t i) { - return satelliteDataArray[i]; -} - -const IGnssDebug_V1_0::SatelliteData& getSatelliteData( - const hidl_vec& satelliteDataArray, size_t i) { - return satelliteDataArray[i].v1_0; -} - -template -uint32_t getConstellationType(const hidl_vec& satelliteDataArray, size_t i) { - return static_cast(satelliteDataArray[i].constellation); -} - -template -static jstring parseDebugData(JNIEnv* env, std::stringstream& internalState, const T& data) { - internalState << "Gnss Location Data:: "; - if (!data.position.valid) { - internalState << "not valid"; - } else { - internalState << "LatitudeDegrees: " << data.position.latitudeDegrees - << ", LongitudeDegrees: " << data.position.longitudeDegrees - << ", altitudeMeters: " << data.position.altitudeMeters - << ", speedMetersPerSecond: " << data.position.speedMetersPerSec - << ", bearingDegrees: " << data.position.bearingDegrees - << ", horizontalAccuracyMeters: " - << data.position.horizontalAccuracyMeters - << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters - << ", speedAccuracyMetersPerSecond: " - << data.position.speedAccuracyMetersPerSecond - << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees - << ", ageSeconds: " << data.position.ageSeconds; - } - internalState << std::endl; - - internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate - << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs - << ", frequencyUncertaintyNsPerSec: " - << data.time.frequencyUncertaintyNsPerSec << std::endl; - - if (data.satelliteDataArray.size() != 0) { - internalState << "Satellite Data for " << data.satelliteDataArray.size() - << " satellites:: " << std::endl; - } - - internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL, 7=IRNSS; " - << "ephType: 0=Eph, 1=Alm, 2=Unk; " - << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; " - << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl; - for (size_t i = 0; i < data.satelliteDataArray.size(); i++) { - IGnssDebug_V1_0::SatelliteData satelliteData = - getSatelliteData(data.satelliteDataArray, i); - internalState << "constell: " - << getConstellationType(data.satelliteDataArray, i) - << ", svid: " << std::setw(3) << satelliteData.svid - << ", serverPredAvail: " - << satelliteData.serverPredictionIsAvailable - << ", serverPredAgeSec: " << std::setw(7) - << satelliteData.serverPredictionAgeSeconds - << ", ephType: " - << static_cast(satelliteData.ephemerisType) - << ", ephSource: " - << static_cast(satelliteData.ephemerisSource) - << ", ephHealth: " - << static_cast(satelliteData.ephemerisHealth) - << ", ephAgeSec: " << std::setw(7) - << satelliteData.ephemerisAgeSeconds << std::endl; - } - return (jstring) env->NewStringUTF(internalState.str().c_str()); -} - static jstring android_location_gnss_hal_GnssNative_get_internal_state(JNIEnv* env, jclass) { - jstring internalStateStr = nullptr; /* * TODO: Create a jobject to represent GnssDebug. */ - std::stringstream internalState; - if (gnssDebugIface == nullptr) { ALOGE("%s: IGnssDebug interface not available.", __func__); - } else if (gnssDebugIface_V2_0 != nullptr) { - IGnssDebug_V2_0::DebugData data; - auto result = gnssDebugIface_V2_0->getDebugData_2_0( - [&data](const IGnssDebug_V2_0::DebugData& debugData) { - data = debugData; - }); - if (checkHidlReturn(result, "IGnssDebug getDebugData_2_0() failed.")) { - internalStateStr = parseDebugData(env, internalState, data); - } - } else { - IGnssDebug_V1_0::DebugData data; - auto result = gnssDebugIface->getDebugData( - [&data](const IGnssDebug_V1_0::DebugData& debugData) { - data = debugData; - }); - if (checkHidlReturn(result, "IGnssDebug getDebugData() failed.")) { - internalStateStr = parseDebugData(env, internalState, data); - } + return nullptr; } - return internalStateStr; + return gnssDebugIface->getDebugData(env); } static void android_location_gnss_hal_GnssNative_request_power_stats(JNIEnv* env) { diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index e49e81c046d24..63f5f526db179 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -29,6 +29,7 @@ cc_library_shared { "GnssBatching.cpp", "GnssBatchingCallback.cpp", "GnssConfiguration.cpp", + "GnssDebug.cpp", "GnssGeofence.cpp", "GnssGeofenceCallback.cpp", "GnssMeasurement.cpp", diff --git a/services/core/jni/gnss/GnssDebug.cpp b/services/core/jni/gnss/GnssDebug.cpp new file mode 100644 index 0000000000000..da5331760e5ce --- /dev/null +++ b/services/core/jni/gnss/GnssDebug.cpp @@ -0,0 +1,107 @@ +/* + * 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 before to overwrite the default value. +#define LOG_TAG "GnssDebugJni" + +#include "GnssDebug.h" + +#include "Utils.h" + +using android::hardware::gnss::IGnssDebug; +using IGnssDebug_V1_0 = android::hardware::gnss::V1_0::IGnssDebug; +using IGnssDebug_V2_0 = android::hardware::gnss::V2_0::IGnssDebug; + +namespace android::gnss { + +// Implementation of GnssDebug (AIDL HAL) + +GnssDebug::GnssDebug(const sp& iGnssDebug) : mIGnssDebug(iGnssDebug) { + assert(mIGnssDebug != nullptr); +} + +jstring GnssDebug::getDebugData(JNIEnv* env) { + std::stringstream internalState; + IGnssDebug::DebugData data; + auto status = mIGnssDebug->getDebugData(&data); + if (checkAidlStatus(status, "IGnssDebug getDebugData() failed.")) { + return GnssDebugUtil::parseDebugData(env, internalState, data); + } + return nullptr; +} + +// Implementation of GnssDebug_V1_0 + +GnssDebug_V1_0::GnssDebug_V1_0(const sp& iGnssDebug) + : mIGnssDebug_V1_0(iGnssDebug) { + assert(mIGnssDebug_V1_0 != nullptr); +} + +jstring GnssDebug_V1_0::getDebugData(JNIEnv* env) { + std::stringstream internalState; + IGnssDebug_V1_0::DebugData data; + auto result = mIGnssDebug_V1_0->getDebugData( + [&data](const IGnssDebug_V1_0::DebugData& debugData) { data = debugData; }); + if (checkHidlReturn(result, "IGnssDebug getDebugData_1_0() failed.")) { + return GnssDebugUtil::parseDebugData(env, internalState, + data); + } + return nullptr; +} + +// Implementation of GnssDebug_V2_0 + +GnssDebug_V2_0::GnssDebug_V2_0(const sp& iGnssDebug) + : mIGnssDebug_V2_0{iGnssDebug} { + assert(mIGnssDebug_V2_0 != nullptr); +} + +jstring GnssDebug_V2_0::getDebugData(JNIEnv* env) { + std::stringstream internalState; + IGnssDebug_V2_0::DebugData data; + auto result = mIGnssDebug_V2_0->getDebugData_2_0( + [&data](const IGnssDebug_V2_0::DebugData& debugData) { data = debugData; }); + if (checkHidlReturn(result, "IGnssDebug getDebugData_2_0() failed.")) { + return GnssDebugUtil::parseDebugData(env, internalState, + data); + } + return nullptr; +} + +const android::hardware::gnss::V1_0::IGnssDebug::SatelliteData& GnssDebugUtil::getSatelliteData( + const hardware::hidl_vec& + satelliteDataArray, + size_t i) { + return satelliteDataArray[i]; +} + +const android::hardware::gnss::V1_0::IGnssDebug::SatelliteData& GnssDebugUtil::getSatelliteData( + const hardware::hidl_vec& + satelliteDataArray, + size_t i) { + return satelliteDataArray[i].v1_0; +} + +const android::hardware::gnss::IGnssDebug::SatelliteData& GnssDebugUtil::getSatelliteData( + const std::vector& satelliteDataArray, + size_t i) { + return satelliteDataArray[i]; +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssDebug.h b/services/core/jni/gnss/GnssDebug.h new file mode 100644 index 0000000000000..9f5ff21a00c0b --- /dev/null +++ b/services/core/jni/gnss/GnssDebug.h @@ -0,0 +1,176 @@ +/* + * 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. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSSDEBUG_H +#define _ANDROID_SERVER_GNSS_GNSSDEBUG_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include +#include + +#include + +#include "jni.h" + +namespace android::gnss { + +class GnssDebugInterface { +public: + virtual ~GnssDebugInterface() {} + virtual jstring getDebugData(JNIEnv* env) = 0; +}; + +class GnssDebug : public GnssDebugInterface { +public: + GnssDebug(const sp& iGnssDebug); + jstring getDebugData(JNIEnv* env) override; + +private: + const sp mIGnssDebug; +}; + +class GnssDebug_V1_0 : public GnssDebugInterface { +public: + GnssDebug_V1_0(const sp& iGnssDebug); + jstring getDebugData(JNIEnv* env) override; + +private: + const sp mIGnssDebug_V1_0; +}; + +class GnssDebug_V2_0 : public GnssDebugInterface { +public: + GnssDebug_V2_0(const sp& iGnssDebug); + jstring getDebugData(JNIEnv* env) override; + +private: + const sp mIGnssDebug_V2_0; +}; + +struct GnssDebugUtil { + template + static uint32_t getConstellationType(const hardware::hidl_vec& satelliteDataArray, size_t i); + + template + static uint32_t getConstellationType(const std::vector& satelliteDataArray, size_t i); + + template + static uint32_t getTimeEstimateMs(const T& data); + + template + static jstring parseDebugData(JNIEnv* env, std::stringstream& internalState, + const T_DebugData& data); + + const static android::hardware::gnss::V1_0::IGnssDebug::SatelliteData& getSatelliteData( + const hardware::hidl_vec& + satelliteDataArray, + size_t i); + + const static android::hardware::gnss::V1_0::IGnssDebug::SatelliteData& getSatelliteData( + const hardware::hidl_vec& + satelliteDataArray, + size_t i); + + const static android::hardware::gnss::IGnssDebug::SatelliteData& getSatelliteData( + const std::vector& + satelliteDataArray, + size_t i); +}; + +template +uint32_t GnssDebugUtil::getConstellationType(const hardware::hidl_vec& satelliteDataArray, + size_t i) { + return static_cast(satelliteDataArray[i].constellation); +} + +template +uint32_t GnssDebugUtil::getConstellationType(const std::vector& satelliteDataArray, size_t i) { + return static_cast(satelliteDataArray[i].constellation); +} + +template +uint32_t GnssDebugUtil::getTimeEstimateMs(const T& data) { + return data.time.timeEstimate; +} + +template <> +uint32_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) { + internalState << "Gnss Location Data:: "; + if (!data.position.valid) { + internalState << "not valid"; + } else { + internalState << "LatitudeDegrees: " << data.position.latitudeDegrees + << ", LongitudeDegrees: " << data.position.longitudeDegrees + << ", altitudeMeters: " << data.position.altitudeMeters + << ", speedMetersPerSecond: " << data.position.speedMetersPerSec + << ", bearingDegrees: " << data.position.bearingDegrees + << ", horizontalAccuracyMeters: " << data.position.horizontalAccuracyMeters + << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters + << ", speedAccuracyMetersPerSecond: " + << data.position.speedAccuracyMetersPerSecond + << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees + << ", ageSeconds: " << data.position.ageSeconds; + } + internalState << std::endl; + + internalState << "Gnss Time Data:: timeEstimate: " << GnssDebugUtil::getTimeEstimateMs(data) + << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs + << ", frequencyUncertaintyNsPerSec: " << data.time.frequencyUncertaintyNsPerSec + << std::endl; + + if (data.satelliteDataArray.size() != 0) { + internalState << "Satellite Data for " << data.satelliteDataArray.size() + << " satellites:: " << std::endl; + } + + internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL, 7=IRNSS; " + << "ephType: 0=Eph, 1=Alm, 2=Unk; " + << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; " + << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl; + for (size_t i = 0; i < data.satelliteDataArray.size(); i++) { + T_SatelliteData satelliteData = getSatelliteData(data.satelliteDataArray, i); + internalState << "constell: " + << GnssDebugUtil::getConstellationType(data.satelliteDataArray, i) + << ", svid: " << std::setw(3) << satelliteData.svid + << ", serverPredAvail: " << satelliteData.serverPredictionIsAvailable + << ", serverPredAgeSec: " << std::setw(7) + << satelliteData.serverPredictionAgeSeconds + << ", ephType: " << static_cast(satelliteData.ephemerisType) + << ", ephSource: " << static_cast(satelliteData.ephemerisSource) + << ", ephHealth: " << static_cast(satelliteData.ephemerisHealth) + << ", ephAgeSec: " << std::setw(7) << satelliteData.ephemerisAgeSeconds + << std::endl; + } + return (jstring)env->NewStringUTF(internalState.str().c_str()); +} + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSDEBUG_H