diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl index ea980308b7..9df7fe521b 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -44,6 +44,7 @@ interface IGnss { @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence(); @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage(); android.hardware.gnss.IAGnss getExtensionAGnss(); + android.hardware.gnss.IGnssDebug getExtensionGnssDebug(); const int ERROR_INVALID_ARGUMENT = 1; const int ERROR_ALREADY_INIT = 2; const int ERROR_GENERIC = 3; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssDebug.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssDebug.aidl new file mode 100644 index 0000000000..27d9887083 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssDebug.aidl @@ -0,0 +1,94 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +interface IGnssDebug { + android.hardware.gnss.IGnssDebug.DebugData getDebugData(); + @Backing(type="int") @VintfStability + enum SatelliteEphemerisType { + EPHEMERIS = 0, + ALMANAC_ONLY = 1, + NOT_AVAILABLE = 2, + } + @Backing(type="int") @VintfStability + enum SatelliteEphemerisSource { + DEMODULATED = 0, + SUPL_PROVIDED = 1, + OTHER_SERVER_PROVIDED = 2, + OTHER = 3, + } + @Backing(type="int") @VintfStability + enum SatelliteEphemerisHealth { + GOOD = 0, + BAD = 1, + UNKNOWN = 2, + } + @VintfStability + parcelable TimeDebug { + long timeEstimateMs; + float timeUncertaintyNs; + float frequencyUncertaintyNsPerSec; + } + @VintfStability + parcelable PositionDebug { + boolean valid; + double latitudeDegrees; + double longitudeDegrees; + float altitudeMeters; + float speedMetersPerSec; + float bearingDegrees; + double horizontalAccuracyMeters; + double verticalAccuracyMeters; + double speedAccuracyMetersPerSecond; + double bearingAccuracyDegrees; + float ageSeconds; + } + @VintfStability + parcelable SatelliteData { + int svid; + android.hardware.gnss.GnssConstellationType constellation; + android.hardware.gnss.IGnssDebug.SatelliteEphemerisType ephemerisType; + android.hardware.gnss.IGnssDebug.SatelliteEphemerisSource ephemerisSource; + android.hardware.gnss.IGnssDebug.SatelliteEphemerisHealth ephemerisHealth; + float ephemerisAgeSeconds; + boolean serverPredictionIsAvailable; + float serverPredictionAgeSeconds; + } + @VintfStability + parcelable DebugData { + android.hardware.gnss.IGnssDebug.PositionDebug position; + android.hardware.gnss.IGnssDebug.TimeDebug time; + List satelliteDataArray; + } +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 91403cadfd..2751521efc 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -20,6 +20,7 @@ import android.hardware.gnss.IAGnss; import android.hardware.gnss.IGnssBatching; import android.hardware.gnss.IGnssCallback; import android.hardware.gnss.IGnssConfiguration; +import android.hardware.gnss.IGnssDebug; import android.hardware.gnss.IGnssGeofence; import android.hardware.gnss.IGnssMeasurementInterface; import android.hardware.gnss.IGnssNavigationMessageInterface; @@ -134,4 +135,13 @@ interface IGnss { * @return The IAGnss interface. */ IAGnss getExtensionAGnss(); + + /** + * This method returns the IGnssDebug interface. + * + * This method must return non-null. + * + * @return Handle to the IGnssDebug interface. + */ + IGnssDebug getExtensionGnssDebug(); } diff --git a/gnss/aidl/android/hardware/gnss/IGnssDebug.aidl b/gnss/aidl/android/hardware/gnss/IGnssDebug.aidl new file mode 100644 index 0000000000..475a4a3a7f --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssDebug.aidl @@ -0,0 +1,208 @@ +/* + * 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. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssConstellationType; + +/** + * Extended interface for GNSS Debug support + * + * This information is used for debugging purpose, e.g., shown in a bugreport to + * describe the chipset states including time, position, and satellite data. + */ +@VintfStability +interface IGnssDebug { + /** Satellite's ephemeris type */ + @VintfStability + @Backing(type="int") + enum SatelliteEphemerisType { + EPHEMERIS = 0, + ALMANAC_ONLY = 1, + NOT_AVAILABLE = 2, + } + + /** Satellite's ephemeris source */ + @VintfStability + @Backing(type="int") + enum SatelliteEphemerisSource { + DEMODULATED = 0, + SUPL_PROVIDED = 1, + OTHER_SERVER_PROVIDED = 2, + OTHER = 3, + } + + /** Satellite's ephemeris health */ + @VintfStability + @Backing(type="int") + enum SatelliteEphemerisHealth { + GOOD = 0, + BAD = 1, + UNKNOWN = 2, + } + + /** + * Provides the current best known UTC time estimate. + * If no fresh information is available, e.g. after a delete all, + * then whatever the effective defaults are on the device must be + * provided (e.g. Jan. 1, 2017, with an uncertainty of 5 years) expressed + * in the specified units. + */ + @VintfStability + parcelable TimeDebug { + /** UTC time estimate in milliseconds. */ + long timeEstimateMs; + + /** 68% time error estimate in nanoseconds. */ + float timeUncertaintyNs; + + /** + * 68% error estimate in local clock drift, + * in nanoseconds per second (also known as parts per billion - ppb.) + */ + float frequencyUncertaintyNsPerSec; + } + + @VintfStability + parcelable PositionDebug { + /** + * Validity of the data in this struct. False only if no + * latitude/longitude information is known. + */ + boolean valid; + + /** Latitude expressed in degrees */ + double latitudeDegrees; + + /** Longitude expressed in degrees */ + double longitudeDegrees; + + /** Altitude above ellipsoid expressed in meters */ + float altitudeMeters; + + /** Represents horizontal speed in meters per second. */ + float speedMetersPerSec; + + /** Represents heading in degrees. */ + float bearingDegrees; + + /** + * Estimated horizontal accuracy of position expressed in meters, + * radial, 68% confidence. + */ + double horizontalAccuracyMeters; + + /** + * Estimated vertical accuracy of position expressed in meters, with + * 68% confidence. + */ + double verticalAccuracyMeters; + + /** + * Estimated speed accuracy in meters per second with 68% confidence. + */ + double speedAccuracyMetersPerSecond; + + /** + * Estimated bearing accuracy degrees with 68% confidence. + */ + double bearingAccuracyDegrees; + + /** + * Time duration before this report that this position information was + * valid. This can, for example, be a previous injected location with + * an age potentially thousands of seconds old, or + * extrapolated to the current time (with appropriately increased + * accuracy estimates), with a (near) zero age. + */ + float ageSeconds; + } + + @VintfStability + parcelable SatelliteData { + /** Satellite vehicle ID number */ + int svid; + + /** Defines the constellation type of the given SV. */ + GnssConstellationType constellation; + + /** + * Defines the standard broadcast ephemeris or almanac availability for + * the satellite. To report status of predicted orbit and clock + * information, see the serverPrediction fields below. + */ + SatelliteEphemerisType ephemerisType; + + /** Defines the ephemeris source of the satellite. */ + SatelliteEphemerisSource ephemerisSource; + + /** + * Defines whether the satellite is known healthy + * (safe for use in location calculation.) + */ + SatelliteEphemerisHealth ephemerisHealth; + + /** + * Time duration from this report (current time), minus the + * effective time of the ephemeris source (e.g. TOE, TOA.) + * Set to 0 when ephemerisType is NOT_AVAILABLE. + */ + float ephemerisAgeSeconds; + + /** + * True if a server has provided a predicted orbit and clock model for + * this satellite. + */ + boolean serverPredictionIsAvailable; + + /** + * Time duration from this report (current time) minus the time of the + * start of the server predicted information. For example, a 1 day + * old prediction would be reported as 86400 seconds here. + */ + float serverPredictionAgeSeconds; + } + + /** + * Provides a set of debug information that is filled by the GNSS chipset + * when the method getDebugData() is invoked. + */ + @VintfStability + parcelable DebugData { + /** Current best known position. */ + PositionDebug position; + + /** Current best know time estimate */ + TimeDebug time; + + /** + * Provides a list of the available satellite data, for all + * satellites and constellations the device can track, + * including GnssConstellationType UNKNOWN. + */ + List satelliteDataArray; + } + + /** + * This methods requests position, time and satellite ephemeris debug information + * from the HAL. + * + * @return ret debugData information from GNSS Hal that contains the current best + * known position, best known time estimate and a complete list of + * constellations that the device can track. + */ + DebugData getDebugData(); +} diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 1236714bb8..24569aec21 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -58,6 +58,7 @@ cc_binary { "AGnss.cpp", "Gnss.cpp", "GnssBatching.cpp", + "GnssDebug.cpp", "GnssGeofence.cpp", "GnssHidlHal.cpp", "GnssNavigationMessageInterface.cpp", diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 0e3cdd3a6a..45d6b1d2f4 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -21,6 +21,7 @@ #include "AGnss.h" #include "GnssBatching.h" #include "GnssConfiguration.h" +#include "GnssDebug.h" #include "GnssGeofence.h" #include "GnssMeasurementInterface.h" #include "GnssNavigationMessageInterface.h" @@ -120,4 +121,11 @@ ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr* iGnssDebug) { + ALOGD("Gnss::getExtensionGnssDebug"); + + *iGnssDebug = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 4feb781d10..f59607f267 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ class Gnss : public BnGnss { ndk::ScopedAStatus getExtensionGnssNavigationMessage( std::shared_ptr* iGnssNavigationMessage) override; ndk::ScopedAStatus getExtensionAGnss(std::shared_ptr* iAGnss) override; + ndk::ScopedAStatus getExtensionGnssDebug(std::shared_ptr* iGnssDebug) override; std::shared_ptr mGnssConfiguration; std::shared_ptr mGnssPowerIndication; diff --git a/gnss/aidl/default/GnssDebug.cpp b/gnss/aidl/default/GnssDebug.cpp new file mode 100644 index 0000000000..f40c0bcef0 --- /dev/null +++ b/gnss/aidl/default/GnssDebug.cpp @@ -0,0 +1,50 @@ +/* + * 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 "GnssDebugAidl" + +#include "GnssDebug.h" +#include +#include "MockLocation.h" + +namespace aidl::android::hardware::gnss { + +ndk::ScopedAStatus GnssDebug::getDebugData(DebugData* debugData) { + ALOGD("GnssDebug::getDebugData"); + + PositionDebug positionDebug = {.valid = true, + .latitudeDegrees = 37.4219999, + .longitudeDegrees = -122.0840575, + .altitudeMeters = 1.60062531, + .speedMetersPerSec = 0, + .bearingDegrees = 0, + .horizontalAccuracyMeters = 5, + .verticalAccuracyMeters = 5, + .speedAccuracyMetersPerSecond = 1, + .bearingAccuracyDegrees = 90, + .ageSeconds = 0.99}; + TimeDebug timeDebug = {.timeEstimateMs = 1519930775453L, + .timeUncertaintyNs = 1000, + .frequencyUncertaintyNsPerSec = 5.0e4}; + std::vector satelliteDataArrayDebug = {}; + debugData->position = positionDebug; + debugData->time = timeDebug; + debugData->satelliteDataArray = satelliteDataArrayDebug; + + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssDebug.h b/gnss/aidl/default/GnssDebug.h new file mode 100644 index 0000000000..001d47cf5c --- /dev/null +++ b/gnss/aidl/default/GnssDebug.h @@ -0,0 +1,28 @@ +/* + * 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. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::gnss { + +struct GnssDebug : public BnGnssDebug { + public: + ndk::ScopedAStatus getDebugData(DebugData* debugData) override; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index aac59db2a0..36be631743 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -19,10 +19,12 @@ #include #include #include +#include #include #include #include #include +#include #include "AGnssCallbackAidl.h" #include "GnssBatchingCallback.h" #include "GnssGeofenceCallback.h" @@ -43,6 +45,7 @@ using android::hardware::gnss::IGnss; using android::hardware::gnss::IGnssBatching; using android::hardware::gnss::IGnssBatchingCallback; using android::hardware::gnss::IGnssConfiguration; +using android::hardware::gnss::IGnssDebug; using android::hardware::gnss::IGnssGeofence; using android::hardware::gnss::IGnssGeofenceCallback; using android::hardware::gnss::IGnssMeasurementCallback; @@ -55,6 +58,12 @@ using android::hardware::gnss::SatellitePvt; using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; +static bool IsAutomotiveDevice() { + char buffer[PROPERTY_VALUE_MAX] = {0}; + property_get("ro.hardware.type", buffer, ""); + return strncmp(buffer, "automotive", PROPERTY_VALUE_MAX) == 0; +} + /* * SetupTeardownCreateCleanup: * Requests the gnss HAL then calls cleanup @@ -820,3 +829,50 @@ TEST_P(GnssHalTest, TestAGnssExtension) { status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275); ASSERT_TRUE(status.isOk()); } + +/* + * GnssDebugValuesSanityTest: + * Ensures that GnssDebug values make sense. + */ +TEST_P(GnssHalTest, GnssDebugValuesSanityTest) { + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + sp iGnssDebug; + auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug); + ASSERT_TRUE(status.isOk()); + + if (!IsAutomotiveDevice() && gnss_cb_->info_cbq_.calledCount() > 0) { + ASSERT_TRUE(iGnssDebug != nullptr); + + IGnssDebug::DebugData data; + auto status = iGnssDebug->getDebugData(&data); + ASSERT_TRUE(status.isOk()); + + if (data.position.valid) { + ASSERT_TRUE(data.position.latitudeDegrees >= -90 && + data.position.latitudeDegrees <= 90); + ASSERT_TRUE(data.position.longitudeDegrees >= -180 && + data.position.longitudeDegrees <= 180); + ASSERT_TRUE(data.position.altitudeMeters >= -1000 && // Dead Sea: -414m + data.position.altitudeMeters <= 20000); // Mount Everest: 8850m + ASSERT_TRUE(data.position.speedMetersPerSec >= 0 && + data.position.speedMetersPerSec <= 600); + ASSERT_TRUE(data.position.bearingDegrees >= -360 && + data.position.bearingDegrees <= 360); + ASSERT_TRUE(data.position.horizontalAccuracyMeters > 0 && + data.position.horizontalAccuracyMeters <= 20000000); + ASSERT_TRUE(data.position.verticalAccuracyMeters > 0 && + data.position.verticalAccuracyMeters <= 20000); + ASSERT_TRUE(data.position.speedAccuracyMetersPerSecond > 0 && + data.position.speedAccuracyMetersPerSecond <= 500); + ASSERT_TRUE(data.position.bearingAccuracyDegrees > 0 && + data.position.bearingAccuracyDegrees <= 180); + ASSERT_TRUE(data.position.ageSeconds >= 0); + } + ASSERT_TRUE(data.time.timeEstimateMs >= 1483228800000); // Jan 01 2017 00:00:00 GMT. + ASSERT_TRUE(data.time.timeUncertaintyNs > 0); + ASSERT_TRUE(data.time.frequencyUncertaintyNsPerSec > 0 && + data.time.frequencyUncertaintyNsPerSec <= 2.0e5); // 200 ppm + } +}