From c06b5366620e5ecd6457449d019f4e5760f0886e Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Fri, 25 Oct 2019 14:14:35 -0700 Subject: [PATCH] Add GNSS HAL 2.1 Bug: 136136192 Bug: 141758837 Test: atest VtsHalGnssV2_1TargetTest Change-Id: I8e6d52695c8ab0aeacacb0107a6c0c8271983ed3 --- .../compatibility_matrix.current.xml | 2 +- current.txt | 4 + gnss/1.1/default/Android.bp | 2 + gnss/1.1/default/Gnss.cpp | 18 +- gnss/2.0/default/Android.bp | 5 +- gnss/2.0/default/Gnss.cpp | 21 +- gnss/2.0/default/GnssMeasurement.cpp | 58 +--- gnss/2.0/default/GnssMeasurement.h | 1 - gnss/2.0/vts/functional/Android.bp | 1 + gnss/2.1/Android.bp | 24 ++ gnss/2.1/IGnss.hal | 53 +++ gnss/2.1/IGnssCallback.hal | 58 ++++ gnss/2.1/IGnssMeasurement.hal | 51 +++ gnss/2.1/IGnssMeasurementCallback.hal | 77 +++++ gnss/2.1/default/Android.bp | 42 +++ gnss/2.1/default/Gnss.cpp | 301 ++++++++++++++++++ gnss/2.1/default/Gnss.h | 106 ++++++ gnss/2.1/default/GnssMeasurement.cpp | 123 +++++++ gnss/2.1/default/GnssMeasurement.h | 78 +++++ gnss/2.1/default/OWNERS | 4 + .../android.hardware.gnss@2.1-service.rc | 4 + .../android.hardware.gnss@2.1-service.xml | 12 + gnss/2.1/default/service.cpp | 41 +++ gnss/2.1/vts/OWNERS | 4 + gnss/2.1/vts/functional/Android.bp | 35 ++ .../functional/VtsHalGnssV2_1TargetTest.cpp | 29 ++ gnss/2.1/vts/functional/gnss_hal_test.cpp | 217 +++++++++++++ gnss/2.1/vts/functional/gnss_hal_test.h | 191 +++++++++++ .../vts/functional/gnss_hal_test_cases.cpp | 128 ++++++++ gnss/common/utils/default/Android.bp | 4 + gnss/common/utils/default/Utils.cpp | 200 ++++++++++-- gnss/common/utils/default/include/Utils.h | 26 +- 32 files changed, 1805 insertions(+), 115 deletions(-) create mode 100644 gnss/2.1/Android.bp create mode 100644 gnss/2.1/IGnss.hal create mode 100644 gnss/2.1/IGnssCallback.hal create mode 100644 gnss/2.1/IGnssMeasurement.hal create mode 100644 gnss/2.1/IGnssMeasurementCallback.hal create mode 100644 gnss/2.1/default/Android.bp create mode 100644 gnss/2.1/default/Gnss.cpp create mode 100644 gnss/2.1/default/Gnss.h create mode 100644 gnss/2.1/default/GnssMeasurement.cpp create mode 100644 gnss/2.1/default/GnssMeasurement.h create mode 100644 gnss/2.1/default/OWNERS create mode 100644 gnss/2.1/default/android.hardware.gnss@2.1-service.rc create mode 100644 gnss/2.1/default/android.hardware.gnss@2.1-service.xml create mode 100644 gnss/2.1/default/service.cpp create mode 100644 gnss/2.1/vts/OWNERS create mode 100644 gnss/2.1/vts/functional/Android.bp create mode 100644 gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp create mode 100644 gnss/2.1/vts/functional/gnss_hal_test.cpp create mode 100644 gnss/2.1/vts/functional/gnss_hal_test.h create mode 100644 gnss/2.1/vts/functional/gnss_hal_test_cases.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cf27a3f646..aecc4e0407 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -189,7 +189,7 @@ - test DeviceManifestTest#GnssHalVersionCompatibility. --> 1.1 - 2.0 + 2.0-1 IGnss default diff --git a/current.txt b/current.txt index 5847f71162..940575e034 100644 --- a/current.txt +++ b/current.txt @@ -595,6 +595,10 @@ f18695dd36ee205640b8326a17453858a7b4596653aaa6ef0016b0aef1bd4dac android.hardwar 4d85e814f94949dae4dc6cb82bbd7d6bb24ffafda6ddb2eac928d2a4fc2e21ce android.hardware.cas@1.2::types 66931c2506fbb5af61f20138cb05e0a09e7bf67d6964c231d27c648933bb33ec android.hardware.drm@1.3::ICryptoFactory 994d08ab27d613022c258a9ec48cece7adf2a305e92df5d76ef923e2c6665f64 android.hardware.drm@1.3::IDrmFactory +1bd8028b974bf1d65cfa102196a2b008afc5d42fe73fed2cb94fa7533d07f581 android.hardware.gnss@2.1::IGnss +ba62e1e8993bfb9f27fa04816fa0f2241ae2d01edfa3d0c04182e2e5de80045c android.hardware.gnss@2.1::IGnssCallback +5a125c49ca83629e22afc8c39e865509343bfa2c38f0baea9a186bbac103492d android.hardware.gnss@2.1::IGnssMeasurement +0bfb291708dd4a7c6ec6b9883e2b8592357edde8d7e962ef83918e4a2154ce69 android.hardware.gnss@2.1::IGnssMeasurementCallback ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth 26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp index 95bd7f33cb..9c498d58a0 100644 --- a/gnss/1.1/default/Android.bp +++ b/gnss/1.1/default/Android.bp @@ -14,6 +14,8 @@ cc_binary { "libhidlbase", "libutils", "liblog", + "android.hardware.gnss@2.1", + "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", ], diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp index 4abe707d4a..5043649b2d 100644 --- a/gnss/1.1/default/Gnss.cpp +++ b/gnss/1.1/default/Gnss.cpp @@ -44,7 +44,7 @@ Return Gnss::start() { auto svStatus = this->getMockSvStatus(); this->reportSvStatus(svStatus); - auto location = Utils::getMockLocation(); + auto location = Utils::getMockLocationV1_0(); this->reportLocation(location); std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); @@ -197,14 +197,14 @@ Return Gnss::injectBestLocation(const GnssLocation&) { Return Gnss::getMockSvStatus() const { std::unique_lock lock(mGnssConfiguration->getMutex()); GnssSvInfo mockGnssSvInfoList[] = { - Utils::getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5), - Utils::getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5), - Utils::getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0), - Utils::getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0), - Utils::getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0), - Utils::getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0), - Utils::getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0), - Utils::getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)}; + Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5), + Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5), + Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0), + Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0), + Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0), + Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0), + Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0), + Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)}; GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)}; for (uint32_t i = 0; i < svStatus.numSvs; i++) { diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp index 3ba89da6aa..37de55dfe3 100644 --- a/gnss/2.0/default/Android.bp +++ b/gnss/2.0/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "AGnss.cpp", "AGnssRil.cpp", "Gnss.cpp", - "GnssBatching.cpp", + "GnssBatching.cpp", "GnssMeasurement.cpp", "GnssMeasurementCorrections.cpp", "GnssVisibilityControl.cpp", @@ -35,9 +35,10 @@ cc_binary { "libhidlbase", "libutils", "liblog", - "android.hardware.gnss@2.0", "android.hardware.gnss.measurement_corrections@1.0", "android.hardware.gnss.visibility_control@1.0", + "android.hardware.gnss@2.1", + "android.hardware.gnss@2.0", "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", ], diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp index 3d64fc30cc..09f2fc0ef2 100644 --- a/gnss/2.0/default/Gnss.cpp +++ b/gnss/2.0/default/Gnss.cpp @@ -19,7 +19,6 @@ #include "Gnss.h" #include -#include #include "AGnss.h" #include "AGnssRil.h" @@ -47,24 +46,6 @@ using GnssSvFlags = IGnssCallback::GnssSvFlags; sp Gnss::sGnssCallback_2_0 = nullptr; sp Gnss::sGnssCallback_1_1 = nullptr; -namespace { - -V2_0::GnssLocation getMockLocationV2_0() { - const ElapsedRealtime timestamp = { - .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | - ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS, - .timestampNs = static_cast(::android::elapsedRealtimeNano()), - // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. - // In an actual implementation provide an estimate of the synchronization uncertainty - // or don't set the field. - .timeUncertaintyNs = 1000000}; - - V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp}; - return location; -} - -} // namespace - Gnss::Gnss() : mMinIntervalMs(1000) {} Gnss::~Gnss() { @@ -86,7 +67,7 @@ Return Gnss::start() { mIsActive = true; mThread = std::thread([this]() { while (mIsActive == true) { - const auto location = getMockLocationV2_0(); + const auto location = Utils::getMockLocationV2_0(); this->reportLocation(location); std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp index 1f95ff95dc..d778d508cd 100644 --- a/gnss/2.0/default/GnssMeasurement.cpp +++ b/gnss/2.0/default/GnssMeasurement.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "GnssMeasurement" #include "GnssMeasurement.h" +#include "Utils.h" #include #include @@ -29,6 +30,7 @@ namespace implementation { using GnssConstellationType = V2_0::GnssConstellationType; using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementState = V2_0::IGnssMeasurementCallback::GnssMeasurementState; +using Utils = common::Utils; sp GnssMeasurement::sCallback = nullptr; @@ -81,7 +83,7 @@ void GnssMeasurement::start() { mIsActive = true; mThread = std::thread([this]() { while (mIsActive == true) { - auto measurement = this->getMockMeasurement(); + auto measurement = Utils::getMockMeasurementV2_0(); this->reportMeasurement(measurement); std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); @@ -97,60 +99,6 @@ void GnssMeasurement::stop() { } } -GnssData GnssMeasurement::getMockMeasurement() { - V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = { - .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY, - .svid = (int16_t)6, - .constellation = V1_0::GnssConstellationType::UNKNOWN, - .timeOffsetNs = 0.0, - .receivedSvTimeInNs = 8195997131077, - .receivedSvTimeUncertaintyInNs = 15, - .cN0DbHz = 30.0, - .pseudorangeRateMps = -484.13739013671875, - .pseudorangeRateUncertaintyMps = 1.0379999876022339, - .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback:: - GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN, - .accumulatedDeltaRangeM = 0.0, - .accumulatedDeltaRangeUncertaintyM = 0.0, - .carrierFrequencyHz = 1.59975e+09, - .multipathIndicator = - V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN}; - V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0}; - V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = { - .v1_1 = measurement_1_1, - .codeType = "C", - .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC | - GnssMeasurementState::STATE_SUBFRAME_SYNC | - GnssMeasurementState::STATE_TOW_DECODED | - GnssMeasurementState::STATE_GLO_STRING_SYNC | - GnssMeasurementState::STATE_GLO_TOD_DECODED, - .constellation = GnssConstellationType::GLONASS, - }; - - hidl_vec measurements(1); - measurements[0] = measurement_2_0; - V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000, - .fullBiasNs = -1226701900521857520, - .biasNs = 0.59689998626708984, - .biasUncertaintyNs = 47514.989972114563, - .driftNsps = -51.757811607455452, - .driftUncertaintyNsps = 310.64968328491528, - .hwClockDiscontinuityCount = 1}; - - ElapsedRealtime timestamp = { - .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | - ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS, - .timestampNs = static_cast(::android::elapsedRealtimeNano()), - // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. - // In an actual implementation provide an estimate of the synchronization uncertainty - // or don't set the field. - .timeUncertaintyNs = 1000000}; - - GnssData gnssData = { - .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp}; - return gnssData; -} - void GnssMeasurement::reportMeasurement(const GnssData& data) { ALOGD("reportMeasurement()"); std::unique_lock lock(mMutex); diff --git a/gnss/2.0/default/GnssMeasurement.h b/gnss/2.0/default/GnssMeasurement.h index c24c00e341..d8ffd59305 100644 --- a/gnss/2.0/default/GnssMeasurement.h +++ b/gnss/2.0/default/GnssMeasurement.h @@ -59,7 +59,6 @@ struct GnssMeasurement : public IGnssMeasurement { private: void start(); void stop(); - GnssData getMockMeasurement(); void reportMeasurement(const GnssData&); static sp sCallback; diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp index 9aa13349b0..da5289d006 100644 --- a/gnss/2.0/vts/functional/Android.bp +++ b/gnss/2.0/vts/functional/Android.bp @@ -28,6 +28,7 @@ cc_test { "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", ], test_suites: ["general-tests", "vts-core"], diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp new file mode 100644 index 0000000000..5d3d62df80 --- /dev/null +++ b/gnss/2.1/Android.bp @@ -0,0 +1,24 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.gnss@2.1", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IGnss.hal", + "IGnssCallback.hal", + "IGnssMeasurement.hal", + "IGnssMeasurementCallback.hal", + ], + interfaces: [ + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.visibility_control@1.0", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/gnss/2.1/IGnss.hal b/gnss/2.1/IGnss.hal new file mode 100644 index 0000000000..812f9cc370 --- /dev/null +++ b/gnss/2.1/IGnss.hal @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 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@2.1; + +import @2.0::IGnss; + +import IGnssCallback; +import IGnssMeasurement; + +/** + * Represents the standard GNSS (Global Navigation Satellite System) interface. + */ +interface IGnss extends @2.0::IGnss { + /** + * Opens the interface and provides the callback routines to the implementation of this + * interface. + * + * The framework calls this method to instruct the GPS engine to prepare for serving requests + * from the framework. The GNSS HAL implementation must respond to all GNSS requests from the + * framework upon successful return from this method until cleanup() method is called to + * close this interface. + * + * @param callback Callback interface for IGnss. + * + * @return success Returns true on success. + */ + setCallback_2_1(IGnssCallback callback) generates (bool success); + + /** + * This method returns the IGnssMeasurement interface. + * + * At least one of getExtensionGnssMeasurement(), getExtensionGnssMeasurement_1_1(), + * getExtensionGnssMeasurement_2_0(), and getExtensionGnssMeasurement_2_1() methods must return + * a non-null handle, and the other methods must return nullptr. + * + * @return gnssMeasurementIface Handle to the IGnssMeasurement interface. + */ + getExtensionGnssMeasurement_2_1() generates (IGnssMeasurement gnssMeasurementIface); +}; \ No newline at end of file diff --git a/gnss/2.1/IGnssCallback.hal b/gnss/2.1/IGnssCallback.hal new file mode 100644 index 0000000000..da7074263c --- /dev/null +++ b/gnss/2.1/IGnssCallback.hal @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 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@2.1; + +import @2.0::IGnssCallback; + +/** + * This interface is required for the HAL to communicate certain information + * like status and location info back to the platform, the platform implements + * the interfaces and passes a handle to the HAL. + */ +interface IGnssCallback extends @2.0::IGnssCallback { + + /** Extends a GnssSvInfo, adding a basebandCN0DbHz. */ + struct GnssSvInfo { + /** + * GNSS satellite information for a single satellite and frequency. + */ + @2.0::IGnssCallback.GnssSvInfo v2_0; + + /** + * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains + * the measured C/N0 value for the signal measured at the baseband. + * + * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port, + * which is reported in cN0DbHz. + * + * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only + * processes one of the components, then the reported basebandCN0DbHz reflects only the + * component that is processed. + * + * This value is mandatory. Like cN0DbHz, it may be reported as 0 for satellites being + * reported that may be searched for, but not yet tracked. + */ + double basebandCN0DbHz; + }; + + /** + * Callback for the HAL to pass a vector of GnssSvInfo back to the client. + * + * @param svInfoList SV info list information from HAL. + */ + gnssSvStatusCb_2_1(vec svInfoList); +}; diff --git a/gnss/2.1/IGnssMeasurement.hal b/gnss/2.1/IGnssMeasurement.hal new file mode 100644 index 0000000000..d2c76e6989 --- /dev/null +++ b/gnss/2.1/IGnssMeasurement.hal @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 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@2.1; + +import @1.0::IGnssMeasurement; +import @1.1::IGnssMeasurement; +import @2.0::IGnssMeasurement; +import IGnssMeasurementCallback; + +/** + * Extended interface for GNSS Measurements support. + */ +interface IGnssMeasurement extends @2.0::IGnssMeasurement { + + /** + * Initializes the interface and registers the callback routines with the HAL. After a + * successful call to 'setCallback_2_1' the HAL must begin to provide updates at an average + * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec + * can be tolerated.) + * + * @param callback Handle to GnssMeasurement callback interface. + * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode + * no clock discontinuities are expected and, when supported, carrier phase should be + * continuous in good signal conditions. All non-blacklisted, healthy constellations, + * satellites and frequency bands that the chipset supports must be reported in this mode. + * The GNSS chipset is allowed to consume more power in this mode. If false, API must behave + * as in HAL V1_0, optimizing power via duty cycling, constellations and frequency limits, + * etc. + * + * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has + * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC + * for any other error. The HAL must not generate any other updates upon returning this + * error code. + */ + setCallback_2_1(IGnssMeasurementCallback callback, bool enableFullTracking) + generates (GnssMeasurementStatus initRet); +}; diff --git a/gnss/2.1/IGnssMeasurementCallback.hal b/gnss/2.1/IGnssMeasurementCallback.hal new file mode 100644 index 0000000000..ca6175f508 --- /dev/null +++ b/gnss/2.1/IGnssMeasurementCallback.hal @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 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@2.1; + +import @1.0::IGnssMeasurementCallback; +import @1.1::IGnssMeasurementCallback; +import @2.0::IGnssMeasurementCallback; +import @2.0::ElapsedRealtime; + +/** The callback interface to report measurements from the HAL. */ +interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback { + + /** + * Extends a GNSS Measurement, adding a basebandCN0DbHz. + */ + struct GnssMeasurement { + /** + * GNSS measurement information for a single satellite and frequency, as in the 2.0 version + * of the HAL. + */ + @2.0::IGnssMeasurementCallback.GnssMeasurement v2_0; + + /** + * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains + * the measured C/N0 value for the signal measured at the baseband. + * + * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port, + * which is reported in cN0DbHz. + * + * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only + * processes one of the components, then the reported basebandCN0DbHz reflects only the + * component that is processed. + * + * This value is mandatory. + */ + double basebandCN0DbHz; + }; + + /** + * Complete set of GNSS Measurement data, same as 2.0 with additional double (i.e., + * basebandCN0DbHz) in measurements. + */ + struct GnssData { + /** The full set of satellite measurement observations. */ + vec measurements; + + /** The GNSS clock time reading. */ + GnssClock clock; + + /** + * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos() + * clock. + */ + ElapsedRealtime elapsedRealtime; + }; + + /** + * Callback for the hal to pass a GnssData structure back to the client. + * + * @param data Contains a reading of GNSS measurements. + */ + gnssMeasurementCb_2_1(GnssData data); +}; diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp new file mode 100644 index 0000000000..a7cf63da5a --- /dev/null +++ b/gnss/2.1/default/Android.bp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 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. + */ + +cc_binary { + name: "android.hardware.gnss@2.1-service", + init_rc: ["android.hardware.gnss@2.1-service.rc"], + relative_install_path: "hw", + vendor: true, + vintf_fragments: ["android.hardware.gnss@2.1-service.xml"], + srcs: [ + "Gnss.cpp", + "GnssMeasurement.cpp", + "service.cpp" + ], + shared_libs: [ + "libhidlbase", + "libutils", + "liblog", + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.visibility_control@1.0", + "android.hardware.gnss@2.1", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + ], + static_libs: [ + "android.hardware.gnss@common-default-lib", + ], +} diff --git a/gnss/2.1/default/Gnss.cpp b/gnss/2.1/default/Gnss.cpp new file mode 100644 index 0000000000..2771f27b79 --- /dev/null +++ b/gnss/2.1/default/Gnss.cpp @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2019 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 "Gnss" + +#include "Gnss.h" +#include "GnssMeasurement.h" +#include "Utils.h" + +#include + +using ::android::hardware::gnss::common::Utils; + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +sp Gnss::sGnssCallback_2_1 = nullptr; + +Gnss::Gnss() : mMinIntervalMs(1000) {} + +Gnss::~Gnss() { + stop(); +} + +Return Gnss::start() { + ALOGD("start"); + if (mIsActive) { + ALOGW("Gnss has started. Restarting..."); + stop(); + } + + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + auto svStatus = Utils::getMockSvInfoListV2_1(); + this->reportSvStatus(svStatus); + + const auto location = Utils::getMockLocationV2_0(); + this->reportLocation(location); + + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); + } + }); + return true; +} + +Return Gnss::stop() { + ALOGD("stop"); + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } + return true; +} + +// Methods from V1_0::IGnss follow. +Return Gnss::setCallback(const sp&) { + // TODO implement + return bool{}; +} + +Return Gnss::cleanup() { + // TODO implement + return Void(); +} + +Return Gnss::injectTime(int64_t, int64_t, int32_t) { + // TODO implement + return bool{}; +} + +Return Gnss::injectLocation(double, double, float) { + // TODO implement + return bool{}; +} + +Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) { + // TODO implement + return Void(); +} + +Return Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode, + V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t, + uint32_t) { + // TODO implement + return bool{}; +} + +Return> Gnss::getExtensionAGnssRil() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssGeofencing() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionAGnss() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssNi() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssMeasurement() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssNavigationMessage() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionXtra() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssConfiguration() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssDebug() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssBatching() { + // TODO implement + return ::android::sp{}; +} + +// Methods from V1_1::IGnss follow. +Return Gnss::setCallback_1_1(const sp&) { + // TODO implement + return bool{}; +} + +Return Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode, + V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t, + uint32_t, bool) { + return true; +} + +Return> Gnss::getExtensionGnssConfiguration_1_1() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssMeasurement_1_1() { + // TODO implement + return ::android::sp{}; +} + +Return Gnss::injectBestLocation(const V1_0::GnssLocation&) { + // TODO implement + return bool{}; +} + +// Methods from V2_0::IGnss follow. +Return Gnss::setCallback_2_0(const sp&) { + // TODO implement + return bool{}; +} + +Return> Gnss::getExtensionGnssConfiguration_2_0() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssDebug_2_0() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionAGnss_2_0() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionAGnssRil_2_0() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssMeasurement_2_0() { + // TODO implement + return ::android::sp{}; +} + +Return> +Gnss::getExtensionMeasurementCorrections() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionVisibilityControl() { + // TODO implement + return ::android::sp{}; +} + +Return> Gnss::getExtensionGnssBatching_2_0() { + // TODO implement + return ::android::sp{}; +} + +Return Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) { + // TODO implement + return bool{}; +} + +// Methods from V2_1::IGnss follow. +Return Gnss::setCallback_2_1(const sp& callback) { + ALOGD("Gnss::setCallback_2_1"); + if (callback == nullptr) { + ALOGE("%s: Null callback ignored", __func__); + return false; + } + + sGnssCallback_2_1 = callback; + + using Capabilities = V2_0::IGnssCallback::Capabilities; + const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS | + Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST; + auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_0(capabilities); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } + + V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020}; + + ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } + + auto gnssName = "Android Mock GNSS Implementation v2.1"; + ret = sGnssCallback_2_1->gnssNameCb(gnssName); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } + + return true; +} + +Return> Gnss::getExtensionGnssMeasurement_2_1() { + ALOGD("Gnss::getExtensionGnssMeasurement_2_1"); + return new GnssMeasurement(); +} + +void Gnss::reportSvStatus(const hidl_vec& svInfoList) const { + std::unique_lock lock(mMutex); + if (sGnssCallback_2_1 == nullptr) { + ALOGE("%s: sGnssCallback v2.1 is null.", __func__); + return; + } + auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + +void Gnss::reportLocation(const V2_0::GnssLocation& location) const { + std::unique_lock lock(mMutex); + if (sGnssCallback_2_1 == nullptr) { + ALOGE("%s: sGnssCallback v2.1 is null.", __func__); + return; + } + auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gnss/2.1/default/Gnss.h b/gnss/2.1/default/Gnss.h new file mode 100644 index 0000000000..a61f71cf75 --- /dev/null +++ b/gnss/2.1/default/Gnss.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2019 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 +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { + +using GnssSvInfo = IGnssCallback::GnssSvInfo; + +namespace implementation { + +struct Gnss : public IGnss { + Gnss(); + ~Gnss(); + // Methods from V1_0::IGnss follow. + Return setCallback(const sp& callback) override; + Return start() override; + Return stop() override; + Return cleanup() override; + Return injectTime(int64_t timeMs, int64_t timeReferenceMs, + int32_t uncertaintyMs) override; + Return injectLocation(double latitudeDegrees, double longitudeDegrees, + float accuracyMeters) override; + Return deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override; + Return setPositionMode(V1_0::IGnss::GnssPositionMode mode, + V1_0::IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs) override; + Return> getExtensionAGnssRil() override; + Return> getExtensionGnssGeofencing() override; + Return> getExtensionAGnss() override; + Return> getExtensionGnssNi() override; + Return> getExtensionGnssMeasurement() override; + Return> getExtensionGnssNavigationMessage() override; + Return> getExtensionXtra() override; + Return> getExtensionGnssConfiguration() override; + Return> getExtensionGnssDebug() override; + Return> getExtensionGnssBatching() override; + + // Methods from V1_1::IGnss follow. + Return setCallback_1_1(const sp& callback) override; + Return setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode, + V1_0::IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs, bool lowPowerMode) override; + Return> getExtensionGnssConfiguration_1_1() override; + Return> getExtensionGnssMeasurement_1_1() override; + Return injectBestLocation(const V1_0::GnssLocation& location) override; + + // Methods from V2_0::IGnss follow. + Return setCallback_2_0(const sp& callback) override; + Return> getExtensionGnssConfiguration_2_0() override; + Return> getExtensionGnssDebug_2_0() override; + Return> getExtensionAGnss_2_0() override; + Return> getExtensionAGnssRil_2_0() override; + Return> getExtensionGnssMeasurement_2_0() override; + Return> + getExtensionMeasurementCorrections() override; + Return> getExtensionVisibilityControl() + override; + Return> getExtensionGnssBatching_2_0() override; + Return injectBestLocation_2_0(const V2_0::GnssLocation& location) override; + + // Methods from V2_1::IGnss follow. + Return setCallback_2_1(const sp& callback) override; + Return> getExtensionGnssMeasurement_2_1() override; + + private: + void reportLocation(const V2_0::GnssLocation&) const; + void reportSvStatus(const hidl_vec&) const; + + static sp sGnssCallback_2_1; + std::atomic mMinIntervalMs; + std::atomic mIsActive; + std::thread mThread; + mutable std::mutex mMutex; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gnss/2.1/default/GnssMeasurement.cpp b/gnss/2.1/default/GnssMeasurement.cpp new file mode 100644 index 0000000000..ebfa7ddf1d --- /dev/null +++ b/gnss/2.1/default/GnssMeasurement.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2019 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 "GnssMeasurement" + +#include "GnssMeasurement.h" +#include +#include "Utils.h" + +namespace android { +namespace hardware { +namespace gnss { + +using common::Utils; + +namespace V2_1 { +namespace implementation { + +sp GnssMeasurement::sCallback = nullptr; + +GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {} + +GnssMeasurement::~GnssMeasurement() { + stop(); +} + +// Methods from V1_0::IGnssMeasurement follow. +Return GnssMeasurement::setCallback( + const sp&) { + // TODO implement + return V1_0::IGnssMeasurement::GnssMeasurementStatus{}; +} + +Return GnssMeasurement::close() { + ALOGD("close"); + std::unique_lock lock(mMutex); + stop(); + sCallback = nullptr; + return Void(); +} + +// Methods from V1_1::IGnssMeasurement follow. +Return GnssMeasurement::setCallback_1_1( + const sp&, bool) { + // TODO implement + return V1_0::IGnssMeasurement::GnssMeasurementStatus{}; +} + +// Methods from V2_0::IGnssMeasurement follow. +Return GnssMeasurement::setCallback_2_0( + const sp&, bool) { + // TODO implement + return V1_0::IGnssMeasurement::GnssMeasurementStatus{}; +} + +// Methods from V2_1::IGnssMeasurement follow. +Return GnssMeasurement::setCallback_2_1( + const sp& callback, bool) { + ALOGD("setCallback_2_1"); + std::unique_lock lock(mMutex); + sCallback = callback; + + if (mIsActive) { + ALOGW("GnssMeasurement callback already set. Resetting the callback..."); + stop(); + } + start(); + + return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS; +} + +void GnssMeasurement::start() { + ALOGD("start"); + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + auto measurement = Utils::getMockMeasurementV2_1(); + this->reportMeasurement(measurement); + + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); + } + }); +} + +void GnssMeasurement::stop() { + ALOGD("stop"); + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } +} + +void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) { + ALOGD("reportMeasurement()"); + std::unique_lock lock(mMutex); + if (sCallback == nullptr) { + ALOGE("%s: GnssMeasurement::sCallback is null.", __func__); + return; + } + auto ret = sCallback->gnssMeasurementCb_2_1(data); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gnss/2.1/default/GnssMeasurement.h b/gnss/2.1/default/GnssMeasurement.h new file mode 100644 index 0000000000..ee329039d9 --- /dev/null +++ b/gnss/2.1/default/GnssMeasurement.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2019 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 +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; + +struct GnssMeasurement : public IGnssMeasurement { + GnssMeasurement(); + ~GnssMeasurement(); + // Methods from V1_0::IGnssMeasurement follow. + Return setCallback( + const sp& callback) override; + Return close() override; + + // Methods from V1_1::IGnssMeasurement follow. + Return setCallback_1_1( + const sp& callback, bool enableFullTracking) override; + + // Methods from V2_0::IGnssMeasurement follow. + Return setCallback_2_0( + const sp& callback, bool enableFullTracking) override; + + // Methods from V2_1::IGnssMeasurement follow. + Return setCallback_2_1( + const sp& callback, bool enableFullTracking) override; + + private: + void start(); + void stop(); + void reportMeasurement(const GnssDataV2_1&); + + static sp sCallback; + std::atomic mMinIntervalMillis; + std::atomic mIsActive; + std::thread mThread; + mutable std::mutex mMutex; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gnss/2.1/default/OWNERS b/gnss/2.1/default/OWNERS new file mode 100644 index 0000000000..b7b4a2e902 --- /dev/null +++ b/gnss/2.1/default/OWNERS @@ -0,0 +1,4 @@ +gomo@google.com +smalkos@google.com +wyattriley@google.com +yuhany@google.com diff --git a/gnss/2.1/default/android.hardware.gnss@2.1-service.rc b/gnss/2.1/default/android.hardware.gnss@2.1-service.rc new file mode 100644 index 0000000000..5926c775d2 --- /dev/null +++ b/gnss/2.1/default/android.hardware.gnss@2.1-service.rc @@ -0,0 +1,4 @@ +service vendor.gnss-2-1 /vendor/bin/hw/android.hardware.gnss@2.1-service + class hal + user system + group system diff --git a/gnss/2.1/default/android.hardware.gnss@2.1-service.xml b/gnss/2.1/default/android.hardware.gnss@2.1-service.xml new file mode 100644 index 0000000000..12a1fdfa08 --- /dev/null +++ b/gnss/2.1/default/android.hardware.gnss@2.1-service.xml @@ -0,0 +1,12 @@ + + + android.hardware.gnss + hwbinder + 2.1 + 1.1 + + IGnss + default + + + diff --git a/gnss/2.1/default/service.cpp b/gnss/2.1/default/service.cpp new file mode 100644 index 0000000000..5e004d5697 --- /dev/null +++ b/gnss/2.1/default/service.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 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 "android.hardware.gnss@2.1-service" + +#include +#include +#include "Gnss.h" + +using ::android::OK; +using ::android::sp; +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; +using ::android::hardware::gnss::V2_1::IGnss; +using ::android::hardware::gnss::V2_1::implementation::Gnss; + +int main(int /* argc */, char* /* argv */[]) { + sp gnss = new Gnss(); + configureRpcThreadpool(1, true /* will join */); + if (gnss->registerAsService() != OK) { + ALOGE("Could not register gnss 2.1 service."); + return 1; + } + joinRpcThreadpool(); + + ALOGE("Service exited!"); + return 1; +} \ No newline at end of file diff --git a/gnss/2.1/vts/OWNERS b/gnss/2.1/vts/OWNERS new file mode 100644 index 0000000000..b7b4a2e902 --- /dev/null +++ b/gnss/2.1/vts/OWNERS @@ -0,0 +1,4 @@ +gomo@google.com +smalkos@google.com +wyattriley@google.com +yuhany@google.com diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp new file mode 100644 index 0000000000..83404992de --- /dev/null +++ b/gnss/2.1/vts/functional/Android.bp @@ -0,0 +1,35 @@ +// +// Copyright (C) 2019 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. +// + +cc_test { + name: "VtsHalGnssV2_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "gnss_hal_test.cpp", + "gnss_hal_test_cases.cpp", + "VtsHalGnssV2_1TargetTest.cpp", + ], + static_libs: [ + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.visibility_control@1.0", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", + "android.hardware.gnss@common-vts-lib", + ], + test_suites: ["general-tests", "vts-core"], +} diff --git a/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp new file mode 100644 index 0000000000..e61d885654 --- /dev/null +++ b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 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 "VtsHalGnssV2_1TargetTest" + +#include +#include +#include + +#include "gnss_hal_test.h" + +using android::hardware::gnss::V2_1::IGnss; + +INSTANTIATE_TEST_SUITE_P( + PerInstance, GnssHalTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), + android::hardware::PrintInstanceNameToString); \ No newline at end of file diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp new file mode 100644 index 0000000000..7cfe0db381 --- /dev/null +++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2019 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 "GnssHalTest" + +#include +#include +#include "Utils.h" + +#include + +using ::android::hardware::gnss::common::Utils; + +// Implementations for the main test class for GNSS HAL +void GnssHalTest::SetUp() { + gnss_hal_ = IGnss::getService(GetParam()); + ASSERT_NE(gnss_hal_, nullptr); + + SetUpGnssCallback(); +} + +void GnssHalTest::TearDown() { + if (gnss_hal_ != nullptr) { + gnss_hal_->cleanup(); + gnss_hal_ = nullptr; + } + + // Set to nullptr to destruct the callback event queues and warn of any unprocessed events. + gnss_cb_ = nullptr; +} + +void GnssHalTest::SetUpGnssCallback() { + gnss_cb_ = new GnssCallback(); + ASSERT_NE(gnss_cb_, nullptr); + + auto result = gnss_hal_->setCallback_2_1(gnss_cb_); + if (!result.isOk()) { + ALOGE("result of failed setCallback %s", result.description().c_str()); + } + + ASSERT_TRUE(result.isOk()); + ASSERT_TRUE(result); + + /* + * All capabilities, name and systemInfo callbacks should trigger + */ + EXPECT_TRUE(gnss_cb_->capabilities_cbq_.retrieve(gnss_cb_->last_capabilities_, TIMEOUT_SEC)); + EXPECT_TRUE(gnss_cb_->info_cbq_.retrieve(gnss_cb_->last_info_, TIMEOUT_SEC)); + EXPECT_TRUE(gnss_cb_->name_cbq_.retrieve(gnss_cb_->last_name_, TIMEOUT_SEC)); + + EXPECT_EQ(gnss_cb_->capabilities_cbq_.calledCount(), 1); + EXPECT_EQ(gnss_cb_->info_cbq_.calledCount(), 1); + EXPECT_EQ(gnss_cb_->name_cbq_.calledCount(), 1); +} + +void GnssHalTest::StopAndClearLocations() { + const auto result = gnss_hal_->stop(); + + EXPECT_TRUE(result.isOk()); + EXPECT_TRUE(result); + + /* + * Clear notify/waiting counter, allowing up till the timeout after + * the last reply for final startup messages to arrive (esp. system + * info.) + */ + while (gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, TIMEOUT_SEC)) { + } + gnss_cb_->location_cbq_.reset(); +} + +void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) { + const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider) + const int kPreferredTimeMsec = 0; // Ideally immediate + + const auto result = gnss_hal_->setPositionMode_1_1( + IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, + min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode); + + ASSERT_TRUE(result.isOk()); + EXPECT_TRUE(result); +} + +bool GnssHalTest::StartAndCheckFirstLocation() { + const auto result = gnss_hal_->start(); + + EXPECT_TRUE(result.isOk()); + EXPECT_TRUE(result); + + /* + * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS, + * so allow time to demodulate ephemeris over the air. + */ + const int kFirstGnssLocationTimeoutSeconds = 75; + + EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, + kFirstGnssLocationTimeoutSeconds)); + int locationCalledCount = gnss_cb_->location_cbq_.calledCount(); + EXPECT_EQ(locationCalledCount, 1); + + if (locationCalledCount > 0) { + // don't require speed on first fix + CheckLocation(gnss_cb_->last_location_, false); + return true; + } + return false; +} + +void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) { + const bool check_more_accuracies = + (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017); + + Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies); +} + +void GnssHalTest::StartAndCheckLocations(int count) { + const int kMinIntervalMsec = 500; + const int kLocationTimeoutSubsequentSec = 2; + const bool kLowPowerMode = false; + + SetPositionMode(kMinIntervalMsec, kLowPowerMode); + + EXPECT_TRUE(StartAndCheckFirstLocation()); + + for (int i = 1; i < count; i++) { + EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, + kLocationTimeoutSubsequentSec)); + int locationCalledCount = gnss_cb_->location_cbq_.calledCount(); + EXPECT_EQ(locationCalledCount, i + 1); + // Don't cause confusion by checking details if no location yet + if (locationCalledCount > 0) { + // Should be more than 1 location by now, but if not, still don't check first fix speed + CheckLocation(gnss_cb_->last_location_, locationCalledCount > 1); + } + } +} + +GnssHalTest::GnssCallback::GnssCallback() + : info_cbq_("system_info"), + name_cbq_("name"), + capabilities_cbq_("capabilities"), + location_cbq_("location"), + sv_info_list_cbq_("sv_info") {} + +Return GnssHalTest::GnssCallback::gnssSetSystemInfoCb( + const IGnssCallback_1_0::GnssSystemInfo& info) { + ALOGI("Info received, year %d", info.yearOfHw); + info_cbq_.store(info); + return Void(); +} + +Return GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) { + ALOGI("Capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return Void(); +} + +Return GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { + ALOGI("Capabilities (v2.0) received %d", capabilities); + capabilities_cbq_.store(capabilities); + return Void(); +} + +Return GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) { + ALOGI("Name received: %s", name.c_str()); + name_cbq_.store(name); + return Void(); +} + +Return GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) { + ALOGI("Location received"); + GnssLocation_2_0 location_v2_0; + location_v2_0.v1_0 = location; + return gnssLocationCbImpl(location_v2_0); +} + +Return GnssHalTest::GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) { + ALOGI("Location (v2.0) received"); + return gnssLocationCbImpl(location); +} + +Return GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) { + location_cbq_.store(location); + return Void(); +} + +Return GnssHalTest::GnssCallback::gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus&) { + ALOGI("gnssSvStatusCb"); + return Void(); +} + +Return GnssHalTest::GnssCallback::gnssSvStatusCb_2_1( + const hidl_vec& svInfoList) { + ALOGI("gnssSvStatusCb_2_1. Size = %d", (int)svInfoList.size()); + sv_info_list_cbq_.store(svInfoList); + return Void(); +} + +Return GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_1( + const IGnssMeasurementCallback_2_1::GnssData& data) { + ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size()); + measurement_cbq_.store(data); + return Void(); +} diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h new file mode 100644 index 0000000000..2e1add01ea --- /dev/null +++ b/gnss/2.1/vts/functional/gnss_hal_test.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2019 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 GNSS_HAL_TEST_H_ +#define GNSS_HAL_TEST_H_ + +#include +#include "GnssCallbackEventQueue.h" + +#include + +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; + +using android::hardware::gnss::common::GnssCallbackEventQueue; +using android::hardware::gnss::V1_0::GnssLocationFlags; +using android::hardware::gnss::V2_1::IGnss; + +using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation; +using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation; + +using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback; +using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback; +using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback; + +using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback; + +using android::sp; + +#define TIMEOUT_SEC 2 // for basic commands/responses + +// The main test class for GNSS HAL. +class GnssHalTest : public testing::TestWithParam { + public: + virtual void SetUp() override; + + virtual void TearDown() override; + + /* Callback class for data & Event. */ + class GnssCallback : public IGnssCallback_2_1 { + public: + IGnssCallback_1_0::GnssSystemInfo last_info_; + android::hardware::hidl_string last_name_; + uint32_t last_capabilities_; + GnssLocation_2_0 last_location_; + + GnssCallbackEventQueue info_cbq_; + GnssCallbackEventQueue name_cbq_; + GnssCallbackEventQueue capabilities_cbq_; + GnssCallbackEventQueue location_cbq_; + GnssCallbackEventQueue> sv_info_list_cbq_; + + GnssCallback(); + virtual ~GnssCallback() = default; + + // Dummy callback handlers + Return gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override { + return Void(); + } + Return gnssNmeaCb(int64_t /* timestamp */, + const android::hardware::hidl_string& /* nmea */) override { + return Void(); + } + Return gnssAcquireWakelockCb() override { return Void(); } + Return gnssReleaseWakelockCb() override { return Void(); } + Return gnssRequestLocationCb(bool /* independentFromGnss */) override { + return Void(); + } + Return gnssRequestTimeCb() override { return Void(); } + // Actual (test) callback handlers + Return gnssNameCb(const android::hardware::hidl_string& name) override; + Return gnssLocationCb(const GnssLocation_1_0& location) override; + Return gnssSetCapabilitesCb(uint32_t capabilities) override; + Return gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) override; + Return gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus& svStatus) override; + + // New in v2.0 + Return gnssLocationCb_2_0(const GnssLocation_2_0& location) override; + Return gnssRequestLocationCb_2_0(bool /* independentFromGnss */, + bool /* isUserEmergency */) override { + return Void(); + } + Return gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override; + Return gnssSvStatusCb_2_0(const hidl_vec&) override { + return Void(); + } + + // New in v2.1 + Return gnssSvStatusCb_2_1( + const hidl_vec& svInfoList) override; + + private: + Return gnssLocationCbImpl(const GnssLocation_2_0& location); + }; + + /* Callback class for GnssMeasurement. */ + class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 { + public: + GnssCallbackEventQueue measurement_cbq_; + + GnssMeasurementCallback() : measurement_cbq_("measurement"){}; + virtual ~GnssMeasurementCallback() = default; + + // Methods from V1_0::IGnssMeasurementCallback follow. + Return GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override { + return Void(); + } + + // Methods from V1_1::IGnssMeasurementCallback follow. + Return gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override { + return Void(); + } + + // Methods from V2_0::IGnssMeasurementCallback follow. + Return gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override { + return Void(); + } + + // Methods from V2_1::IGnssMeasurementCallback follow. + Return gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override; + }; + + /* + * SetUpGnssCallback: + * Set GnssCallback and verify the result. + */ + void SetUpGnssCallback(); + + /* + * StartAndCheckFirstLocation: + * Helper function to start location, and check the first one. + * + *

Note this leaves the Location request active, to enable Stop call vs. other call + * reordering tests. + * + * returns true if a location was successfully generated + */ + bool StartAndCheckFirstLocation(); + + /* + * CheckLocation: + * Helper function to vet Location fields + * + * check_speed: true if speed related fields are also verified. + */ + void CheckLocation(const GnssLocation_2_0& location, const bool check_speed); + + /* + * StartAndCheckLocations: + * Helper function to collect, and check a number of + * normal ~1Hz locations. + * + * Note this leaves the Location request active, to enable Stop call vs. other call + * reordering tests. + */ + void StartAndCheckLocations(int count); + + /* + * StopAndClearLocations: + * Helper function to stop locations, and clear any remaining notifications + */ + void StopAndClearLocations(); + + /* + * SetPositionMode: + * Helper function to set positioning mode and verify output + */ + void SetPositionMode(const int min_interval_msec, const bool low_power_mode); + + sp gnss_hal_; // GNSS HAL to call into + sp gnss_cb_; // Primary callback interface +}; + +#endif // GNSS_HAL_TEST_H_ diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp new file mode 100644 index 0000000000..ef8249b4d0 --- /dev/null +++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2019 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 "GnssHalTestCases" + +#include +#include "Utils.h" + +#include + +using android::hardware::hidl_string; +using android::hardware::hidl_vec; + +using android::hardware::gnss::common::Utils; + +using IGnssMeasurement_2_1 = android::hardware::gnss::V2_1::IGnssMeasurement; +using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement; +using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement; +using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement; + +/* + * SetupTeardownCreateCleanup: + * Requests the gnss HAL then calls cleanup + * + * Empty test fixture to verify basic Setup & Teardown + */ +TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {} + +/* + * TestGnssMeasurementExtension: + * Gets the GnssMeasurementExtension and verifies that it returns an actual extension. + */ +TEST_P(GnssHalTest, TestGnssMeasurementExtension) { + auto gnssMeasurement_2_1 = gnss_hal_->getExtensionGnssMeasurement_2_1(); + auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0(); + auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1(); + auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement(); + ASSERT_TRUE(gnssMeasurement_2_1.isOk() && gnssMeasurement_2_0.isOk() && + gnssMeasurement_1_1.isOk() && gnssMeasurement_1_0.isOk()); + sp iGnssMeas_2_1 = gnssMeasurement_2_1; + sp iGnssMeas_2_0 = gnssMeasurement_2_0; + sp iGnssMeas_1_1 = gnssMeasurement_1_1; + sp iGnssMeas_1_0 = gnssMeasurement_1_0; + // At least one interface is non-null. + int numNonNull = (int)(iGnssMeas_2_1 != nullptr) + (int)(iGnssMeas_2_0 != nullptr) + + (int)(iGnssMeas_1_1 != nullptr) + (int)(iGnssMeas_1_0 != nullptr); + ASSERT_TRUE(numNonNull >= 1); +} + +/* + * TestGnssMeasurementFields: + * Sets a GnssMeasurementCallback, waits for a measurement, and verifies + * 1. basebandCN0DbHz is valid + */ +TEST_P(GnssHalTest, TestGnssMeasurementFields) { + const int kFirstGnssMeasurementTimeoutSeconds = 10; + + auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_1(); + ASSERT_TRUE(gnssMeasurement.isOk()); + + // Skip test if GnssMeasurement v2.1 is not supported + sp iGnssMeasurement = gnssMeasurement; + if (iGnssMeasurement == nullptr) { + return; + } + + sp callback = new GnssMeasurementCallback(); + auto result = iGnssMeasurement->setCallback_2_1(callback, /* enableFullTracking= */ true); + ASSERT_TRUE(result.isOk()); + EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS); + + IGnssMeasurementCallback_2_1::GnssData lastMeasurement; + ASSERT_TRUE(callback->measurement_cbq_.retrieve(lastMeasurement, + kFirstGnssMeasurementTimeoutSeconds)); + EXPECT_EQ(callback->measurement_cbq_.calledCount(), 1); + ASSERT_TRUE(lastMeasurement.measurements.size() > 0); + for (auto measurement : lastMeasurement.measurements) { + // Verify basebandCn0DbHz is valid. + ASSERT_TRUE(measurement.basebandCN0DbHz > 0.0 && measurement.basebandCN0DbHz <= 65.0); + } + + iGnssMeasurement->close(); +} + +/* + * TestGnssSvInfoFields: + * Gets 1 location and a GnssSvInfo, and verifies + * 1. basebandCN0DbHz is valid. + */ +TEST_P(GnssHalTest, TestGnssSvInfoFields) { + gnss_cb_->location_cbq_.reset(); + StartAndCheckFirstLocation(); + int location_called_count = gnss_cb_->location_cbq_.calledCount(); + + // Tolerate 1 less sv status to handle edge cases in reporting. + int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size, 0); + ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)", + sv_info_list_cbq_size, location_called_count); + + hidl_vec last_sv_info_list; + ASSERT_TRUE(gnss_cb_->sv_info_list_cbq_.retrieve(last_sv_info_list, 1)); + + bool nonZeroCn0Found = false; + for (auto sv_info : last_sv_info_list) { + ASSERT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0); + if (sv_info.basebandCN0DbHz > 0.0) { + nonZeroCn0Found = true; + } + } + // Assert at least one value is non-zero. Zero is ok in status as it's possibly + // reporting a searched but not found satellite. + ASSERT_TRUE(nonZeroCn0Found); + StopAndClearLocations(); +} diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 4ea97fac67..577f6ae5e3 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -28,6 +28,10 @@ cc_library_static { ], export_include_dirs: ["include"], shared_libs: [ + "libhidlbase", + "libutils", "android.hardware.gnss@1.0", + "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", ], } diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index b9a06e8d6d..6c6d696f3d 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -16,6 +16,7 @@ #include #include +#include namespace android { namespace hardware { @@ -23,31 +24,188 @@ namespace gnss { namespace common { using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags; +using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; +using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState; +using ElapsedRealtime = V2_0::ElapsedRealtime; +using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags; +using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType; +using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback; -GnssLocation Utils::getMockLocation() { - GnssLocation location = {.gnssLocationFlags = 0xFF, - .latitudeDegrees = kMockLatitudeDegrees, - .longitudeDegrees = kMockLongitudeDegrees, - .altitudeMeters = kMockAltitudeMeters, - .speedMetersPerSec = kMockSpeedMetersPerSec, - .bearingDegrees = kMockBearingDegrees, - .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, - .verticalAccuracyMeters = kMockVerticalAccuracyMeters, - .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, - .bearingAccuracyDegrees = kMockBearingAccuracyDegrees, - .timestamp = kMockTimestamp}; +GnssDataV2_1 Utils::getMockMeasurementV2_1() { + GnssDataV2_0 gnssDataV2_0 = Utils::getMockMeasurementV2_0(); + V2_1::IGnssMeasurementCallback::GnssMeasurement gnssMeasurementV2_1 = { + .v2_0 = gnssDataV2_0.measurements[0], + .basebandCN0DbHz = 25.0, + }; + hidl_vec measurements(1); + measurements[0] = gnssMeasurementV2_1; + GnssDataV2_1 gnssDataV2_1 = { + .measurements = measurements, + .clock = gnssDataV2_0.clock, + .elapsedRealtime = gnssDataV2_0.elapsedRealtime, + }; + return gnssDataV2_1; +} + +GnssDataV2_0 Utils::getMockMeasurementV2_0() { + V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = { + .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY, + .svid = (int16_t)6, + .constellation = V1_0::GnssConstellationType::UNKNOWN, + .timeOffsetNs = 0.0, + .receivedSvTimeInNs = 8195997131077, + .receivedSvTimeUncertaintyInNs = 15, + .cN0DbHz = 30.0, + .pseudorangeRateMps = -484.13739013671875, + .pseudorangeRateUncertaintyMps = 1.0379999876022339, + .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback:: + GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN, + .accumulatedDeltaRangeM = 0.0, + .accumulatedDeltaRangeUncertaintyM = 0.0, + .carrierFrequencyHz = 1.59975e+09, + .multipathIndicator = + V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN}; + V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0}; + V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = { + .v1_1 = measurement_1_1, + .codeType = "C", + .state = GnssMeasurementStateV2_0::STATE_CODE_LOCK | + GnssMeasurementStateV2_0::STATE_BIT_SYNC | + GnssMeasurementStateV2_0::STATE_SUBFRAME_SYNC | + GnssMeasurementStateV2_0::STATE_TOW_DECODED | + GnssMeasurementStateV2_0::STATE_GLO_STRING_SYNC | + GnssMeasurementStateV2_0::STATE_GLO_TOD_DECODED, + .constellation = GnssConstellationTypeV2_0::GLONASS, + }; + + hidl_vec measurements(1); + measurements[0] = measurement_2_0; + V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000, + .fullBiasNs = -1226701900521857520, + .biasNs = 0.59689998626708984, + .biasUncertaintyNs = 47514.989972114563, + .driftNsps = -51.757811607455452, + .driftUncertaintyNsps = 310.64968328491528, + .hwClockDiscontinuityCount = 1}; + + ElapsedRealtime timestamp = { + .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | + ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = static_cast(::android::elapsedRealtimeNano()), + // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. + // In an actual implementation provide an estimate of the synchronization uncertainty + // or don't set the field. + .timeUncertaintyNs = 1000000}; + + GnssDataV2_0 gnssData = { + .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp}; + return gnssData; +} + +V2_0::GnssLocation Utils::getMockLocationV2_0() { + const V2_0::ElapsedRealtime timestamp = { + .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | + V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = static_cast(::android::elapsedRealtimeNano()), + // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. + // In an actual implementation provide an estimate of the synchronization uncertainty + // or don't set the field. + .timeUncertaintyNs = 1000000}; + + V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocationV1_0(), + .elapsedRealtime = timestamp}; return location; } -GnssSvInfo Utils::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz, - float elevationDegrees, float azimuthDegrees) { - GnssSvInfo svInfo = {.svid = svid, - .constellation = type, - .cN0Dbhz = cN0DbHz, - .elevationDegrees = elevationDegrees, - .azimuthDegrees = azimuthDegrees, - .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA | - GnssSvFlags::HAS_ALMANAC_DATA}; +V1_0::GnssLocation Utils::getMockLocationV1_0() { + V1_0::GnssLocation location = { + .gnssLocationFlags = 0xFF, + .latitudeDegrees = kMockLatitudeDegrees, + .longitudeDegrees = kMockLongitudeDegrees, + .altitudeMeters = kMockAltitudeMeters, + .speedMetersPerSec = kMockSpeedMetersPerSec, + .bearingDegrees = kMockBearingDegrees, + .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, + .verticalAccuracyMeters = kMockVerticalAccuracyMeters, + .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, + .bearingAccuracyDegrees = kMockBearingAccuracyDegrees, + .timestamp = kMockTimestamp}; + return location; +} + +hidl_vec Utils::getMockSvInfoListV2_1() { + GnssSvInfoV1_0 gnssSvInfoV1_0 = + Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS, 32.5, 59.1, 166.5); + GnssSvInfoV2_0 gnssSvInfoV2_0 = + Utils::getMockSvInfoV2_0(gnssSvInfoV1_0, V2_0::GnssConstellationType::GPS); + hidl_vec gnssSvInfoList = { + Utils::getMockSvInfoV2_1(gnssSvInfoV2_0, 27.5), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GPS, 27.0, + 29.0, 56.5), + V2_0::GnssConstellationType::GPS), + 22.0), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GPS, 30.5, + 71.0, 77.0), + V2_0::GnssConstellationType::GPS), + 25.5), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(26, V1_0::GnssConstellationType::GPS, 24.1, + 28.0, 253.0), + V2_0::GnssConstellationType::GPS), + 19.1), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GLONASS, + 20.5, 11.5, 116.0), + V2_0::GnssConstellationType::GLONASS), + 15.5), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GLONASS, + 21.5, 28.5, 186.0), + V2_0::GnssConstellationType::GLONASS), + 16.5), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(18, V1_0::GnssConstellationType::GLONASS, + 28.3, 38.8, 69.0), + V2_0::GnssConstellationType::GLONASS), + 25.3), + getMockSvInfoV2_1( + getMockSvInfoV2_0(getMockSvInfoV1_0(10, V1_0::GnssConstellationType::GLONASS, + 25.0, 66.0, 247.0), + V2_0::GnssConstellationType::GLONASS), + 20.0), + }; + return gnssSvInfoList; +} + +GnssSvInfoV2_1 Utils::getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz) { + GnssSvInfoV2_1 gnssSvInfoV2_1 = { + .v2_0 = gnssSvInfoV2_0, + .basebandCN0DbHz = basebandCN0DbHz, + }; + return gnssSvInfoV2_1; +} + +GnssSvInfoV2_0 Utils::getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0, + V2_0::GnssConstellationType type) { + GnssSvInfoV2_0 gnssSvInfoV2_0 = { + .v1_0 = gnssSvInfoV1_0, + .constellation = type, + }; + return gnssSvInfoV2_0; +} + +GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type, + float cN0DbHz, float elevationDegrees, + float azimuthDegrees) { + GnssSvInfoV1_0 svInfo = {.svid = svid, + .constellation = type, + .cN0Dbhz = cN0DbHz, + .elevationDegrees = elevationDegrees, + .azimuthDegrees = azimuthDegrees, + .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA | + GnssSvFlags::HAS_ALMANAC_DATA}; return svInfo; } diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h index 47c88129f3..e0c61a41e1 100644 --- a/gnss/common/utils/default/include/Utils.h +++ b/gnss/common/utils/default/include/Utils.h @@ -18,20 +18,34 @@ #define android_hardware_gnss_common_default_Utils_H_ #include +#include +#include -using GnssConstellationType = ::android::hardware::gnss::V1_0::GnssConstellationType; -using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation; -using GnssSvInfo = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvInfo; +using ::android::hardware::hidl_vec; namespace android { namespace hardware { namespace gnss { namespace common { +using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData; +using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; +using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo; +using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo; +using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo; + struct Utils { - static GnssLocation getMockLocation(); - static GnssSvInfo getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz, - float elevationDegrees, float azimuthDegrees); + static GnssDataV2_0 getMockMeasurementV2_0(); + static GnssDataV2_1 getMockMeasurementV2_1(); + static V2_0::GnssLocation getMockLocationV2_0(); + static V1_0::GnssLocation getMockLocationV1_0(); + static hidl_vec getMockSvInfoListV2_1(); + static GnssSvInfoV2_1 getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz); + static GnssSvInfoV2_0 getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0, + V2_0::GnssConstellationType type); + static GnssSvInfoV1_0 getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type, + float cN0DbHz, float elevationDegrees, + float azimuthDegrees); }; } // namespace common