diff --git a/current.txt b/current.txt index 62b9877829..40d1289a16 100644 --- a/current.txt +++ b/current.txt @@ -648,11 +648,13 @@ f18695dd36ee205640b8326a17453858a7b4596653aaa6ef0016b0aef1bd4dac android.hardwar 446287268831f4ddfac4a51bb1c32ae1e48e47bccd535fccc2c4546d0e7c4013 android.hardware.dumpstate@1.1::types f284ffde7cadf5a1364b75ab313baf22401eeca289bdde2a2dc7a27ea4ab98d7 android.hardware.dumpstate@1.1::IDumpstateDevice 769d346927a94fd40ee80a5a976d8d15cf022ef99c5900738f4a82f26c0ed229 android.hardware.gnss@2.1::types -88371e0edf69a1f72bfc45ecb2335e9b145e87339d3eecc92664a1fb200213ba android.hardware.gnss@2.1::IGnss -ba62e1e8993bfb9f27fa04816fa0f2241ae2d01edfa3d0c04182e2e5de80045c android.hardware.gnss@2.1::IGnssCallback -ccdf3c0fb2c02a6d4dc57afb276c3497ae8172b80b00ebc0bf8a0238dd38b01d android.hardware.gnss@2.1::IGnssConfiguration -5a125c49ca83629e22afc8c39e865509343bfa2c38f0baea9a186bbac103492d android.hardware.gnss@2.1::IGnssMeasurement -d7bf37660a0946de9599dcbae997b077ee3e604fc2044534d40d3da04297a5d3 android.hardware.gnss@2.1::IGnssMeasurementCallback +626db710bf917ecf551a0b0b1f25be10bf52758f43e0fc808b148b6aae2ef73e android.hardware.gnss@2.1::IGnss +ba5ac712b2a656dc07c83ab4a7a2c2f3bee1bbcb752e8b8ffa9b672f3b5b0728 android.hardware.gnss@2.1::IGnssAntennaInfo +0bc3ed97cbc3f6abc89c68f4e9f4d124f9f723431997dc88c2186cf4d2ad47ee android.hardware.gnss@2.1::IGnssAntennaInfoCallback +50c5d009af76d65b3023a9d94ee519545e72cb7c59bc7166d768d6f00923774d android.hardware.gnss@2.1::IGnssCallback +737d750017738f0753d13ba01a3310e0161f294b8ae80b3fd63eaa227e9d9c66 android.hardware.gnss@2.1::IGnssConfiguration +7913a11206a577b12ade86a7cf3f95c2639cb514d086673f279bf99238c9917e android.hardware.gnss@2.1::IGnssMeasurement +9999f2484f35ebfacdd433dfeae459f2a582334315959653ec8efde7699ec556 android.hardware.gnss@2.1::IGnssMeasurementCallback 6670e7780803a8c696c6391fda5589a334b1b37dc7be9393792ed35035413633 android.hardware.gnss.measurement_corrections@1.1::IMeasurementCorrections a3f439b782a6a92aaf3c0250f3526e94e8bf8844c3d578f0815e21b12c431346 android.hardware.gnss.measurement_corrections@1.1::types ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp index 7efc4a60aa..21223997b3 100644 --- a/gnss/2.1/Android.bp +++ b/gnss/2.1/Android.bp @@ -9,6 +9,8 @@ hidl_interface { srcs: [ "types.hal", "IGnss.hal", + "IGnssAntennaInfo.hal", + "IGnssAntennaInfoCallback.hal", "IGnssCallback.hal", "IGnssMeasurement.hal", "IGnssMeasurementCallback.hal", diff --git a/gnss/2.1/IGnss.hal b/gnss/2.1/IGnss.hal index ce37647868..e4da5078ee 100644 --- a/gnss/2.1/IGnss.hal +++ b/gnss/2.1/IGnss.hal @@ -18,10 +18,10 @@ package android.hardware.gnss@2.1; import android.hardware.gnss.measurement_corrections@1.1::IMeasurementCorrections; import @2.0::IGnss; - import IGnssCallback; import IGnssMeasurement; import IGnssConfiguration; +import IGnssAntennaInfo; /** * Represents the standard GNSS (Global Navigation Satellite System) interface. @@ -72,5 +72,15 @@ interface IGnss extends @2.0::IGnss { * * @return measurementCorrectionsIface Handle to the IMeasurementCorrections interface. */ - getExtensionMeasurementCorrections_1_1() generates (IMeasurementCorrections measurementCorrectionsIface); -}; \ No newline at end of file + getExtensionMeasurementCorrections_1_1() + generates (IMeasurementCorrections measurementCorrectionsIface); + + /** + * This method returns the IGnssAntennaInfo interface. + * + * This method must return non-null. + * + * @return gnssAntennaInfoIface Handle to the IGnssAntennaInfo interface. + */ + getExtensionGnssAntennaInfo() generates (IGnssAntennaInfo gnssAntennaInfoIface); +}; diff --git a/gnss/2.1/IGnssAntennaInfo.hal b/gnss/2.1/IGnssAntennaInfo.hal new file mode 100644 index 0000000000..f77d874c08 --- /dev/null +++ b/gnss/2.1/IGnssAntennaInfo.hal @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 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 IGnssAntennaInfoCallback; + +/** + * Extended interface for GNSS antenna information support. + */ +interface IGnssAntennaInfo { + enum GnssAntennaInfoStatus : int32_t { + SUCCESS = 0, + ERROR_ALREADY_INIT = -100, + ERROR_GENERIC = -101, + }; + + /** + * Registers the callback routines with the HAL. + * + * @param callback Handle to the GnssAntennaInfo callback interface. + */ + setCallback(IGnssAntennaInfoCallback callback) generates (GnssAntennaInfoStatus initRet); + + /** + * Stops updates from the HAL, and unregisters the callback routines. + * After a call to close(), the previously registered callbacks must be + * considered invalid by the HAL. + * If close() is invoked without a previous setCallback, this function must perform + * no work. + */ + close(); +}; diff --git a/gnss/2.1/IGnssAntennaInfoCallback.hal b/gnss/2.1/IGnssAntennaInfoCallback.hal new file mode 100644 index 0000000000..883111e9c8 --- /dev/null +++ b/gnss/2.1/IGnssAntennaInfoCallback.hal @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2020 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; + +/** + * The callback interface to report GNSS antenna information from the HAL. + */ +interface IGnssAntennaInfoCallback { + /** + * A row of doubles. This is used to represent a row in a 2D array, which are used to + * characterize the phase center variation corrections and signal gain corrections. + */ + struct Row { + vec row; + }; + + /** + * A point in 3D space, with associated uncertainty. + */ + struct Coord { + double x; + + double xUncertainty; + + double y; + + double yUncertainty; + + double z; + + double zUncertainty; + }; + + struct GnssAntennaInfo { + /** + * The carrier frequency in MHz. + */ + double carrierFrequencyMHz; + + /** + * Phase center offset (PCO) with associated 1-sigma uncertainty. PCO is defined with + * respect to the origin of the Android sensor coordinate system, e.g., center of primary + * screen for mobiles - see sensor or form factor documents for details. + */ + Coord phaseCenterOffsetCoordinateMillimeters; + + /** + * 2D vectors representing the phase center variation (PCV) corrections, in + * millimeters, at regularly spaced azimuthal angle (theta) and zenith angle + * (phi). The PCV correction is added to the phase measurement to obtain the + * corrected value. + * + * The azimuthal angle, theta, is defined with respect to the X axis of the + * Android sensor coordinate system, increasing toward the Y axis. The zenith + * angle, phi, is defined with respect to the Z axis of the Android Sensor + * coordinate system, increasing toward the X-Y plane. + * + * Each row vector (outer vectors) represents a fixed theta. The first row + * corresponds to a theta angle of 0 degrees. The last row corresponds to a + * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular + * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows). + * + * The columns (inner vectors) represent fixed zenith angles, beginning at 0 + * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular + * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1). + * + * This field is optional, i.e., an empty vector. + */ + vec phaseCenterVariationCorrectionMillimeters; + + /** + * 2D vectors of 1-sigma uncertainty in millimeters associated with the PCV + * correction values. + * + * This field is optional, i.e., an empty vector. + */ + vec phaseCenterVariationCorrectionUncertaintyMillimeters; + + /** + * 2D vectors representing the signal gain corrections at regularly spaced + * azimuthal angle (theta) and zenith angle (phi). The values are calculated or + * measured at the antenna feed point without considering the radio and receiver + * noise figure and path loss contribution, in dBi, i.e., decibel over isotropic + * antenna with the same total power. The signal gain correction is added the + * signal gain measurement to obtain the corrected value. + * + * The azimuthal angle, theta, is defined with respect to the X axis of the + * Android sensor coordinate system, increasing toward the Y axis. The zenith + * angle, phi, is defined with respect to the Z axis of the Android Sensor + * coordinate system, increasing toward the X-Y plane. + * + * Each row vector (outer vectors) represents a fixed theta. The first row + * corresponds to a theta angle of 0 degrees. The last row corresponds to a + * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular + * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows). + * + * The columns (inner vectors) represent fixed zenith angles, beginning at 0 + * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular + * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1). + * + * This field is optional, i.e., an empty vector. + */ + vec signalGainCorrectionDbi; + + /** + * 2D vectors of 1-sigma uncertainty in dBi associated with the signal + * gain correction values. + * + * This field is optional, i.e., an empty vector. + */ + vec signalGainCorrectionUncertaintyDbi; + }; + + /** + * Called when on connection, and on known-change to these values, such as upon a known + * GNSS RF antenna tuning change, or a foldable device state change. + * + * This is optional. It can never be called if the GNSS antenna information is not + * available. + */ + gnssAntennaInfoCb(vec gnssAntennaInfos); +}; diff --git a/gnss/2.1/IGnssCallback.hal b/gnss/2.1/IGnssCallback.hal index da7074263c..f7b7477ad0 100644 --- a/gnss/2.1/IGnssCallback.hal +++ b/gnss/2.1/IGnssCallback.hal @@ -24,8 +24,20 @@ import @2.0::IGnssCallback; * the interfaces and passes a handle to the HAL. */ interface IGnssCallback extends @2.0::IGnssCallback { + /** + * Flags for the gnssSetCapabilities callback. + */ + @export(name = "", value_prefix = "GPS_CAPABILITY_") + enum Capabilities : @2.0::IGnssCallback.Capabilities { + /** + * GNSS supports measurement corrections + */ + ANTENNA_INFO = 1 << 11, + }; - /** Extends a GnssSvInfo, adding a basebandCN0DbHz. */ + /** + * Extends a GnssSvInfo, adding a basebandCN0DbHz. + */ struct GnssSvInfo { /** * GNSS satellite information for a single satellite and frequency. diff --git a/gnss/2.1/IGnssConfiguration.hal b/gnss/2.1/IGnssConfiguration.hal index 8360ba9953..550f3251df 100644 --- a/gnss/2.1/IGnssConfiguration.hal +++ b/gnss/2.1/IGnssConfiguration.hal @@ -65,4 +65,4 @@ interface IGnssConfiguration extends @2.0::IGnssConfiguration { * @return success Whether the HAL accepts and abides by the provided blacklist. */ setBlacklist_2_1(vec blacklist) generates (bool success); -}; \ No newline at end of file +}; diff --git a/gnss/2.1/IGnssMeasurement.hal b/gnss/2.1/IGnssMeasurement.hal index d2c76e6989..49ba7ebd2a 100644 --- a/gnss/2.1/IGnssMeasurement.hal +++ b/gnss/2.1/IGnssMeasurement.hal @@ -25,7 +25,6 @@ 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 @@ -47,5 +46,5 @@ interface IGnssMeasurement extends @2.0::IGnssMeasurement { * error code. */ setCallback_2_1(IGnssMeasurementCallback callback, bool enableFullTracking) - generates (GnssMeasurementStatus initRet); + generates (GnssMeasurementStatus initRet); }; diff --git a/gnss/2.1/IGnssMeasurementCallback.hal b/gnss/2.1/IGnssMeasurementCallback.hal index 0385abd467..1aee272fde 100644 --- a/gnss/2.1/IGnssMeasurementCallback.hal +++ b/gnss/2.1/IGnssMeasurementCallback.hal @@ -21,36 +21,56 @@ import @2.0::IGnssMeasurementCallback; import @2.0::ElapsedRealtime; import GnssSignalType; -/** The callback interface to report measurements from the HAL. */ +/** + * The callback interface to report measurements from the HAL. + */ interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback { - /** * Flags to indicate what fields in GnssMeasurement are valid. */ enum GnssMeasurementFlags : uint32_t { - /** A valid 'snr' is stored in the data structure. */ - HAS_SNR = 1 << 0, - /** A valid 'carrier frequency' is stored in the data structure. */ - HAS_CARRIER_FREQUENCY = 1 << 9, - /** A valid 'carrier cycles' is stored in the data structure. */ - HAS_CARRIER_CYCLES = 1 << 10, - /** A valid 'carrier phase' is stored in the data structure. */ - HAS_CARRIER_PHASE = 1 << 11, - /** A valid 'carrier phase uncertainty' is stored in the data structure. */ - HAS_CARRIER_PHASE_UNCERTAINTY = 1 << 12, - /** A valid automatic gain control is stored in the data structure. */ - HAS_AUTOMATIC_GAIN_CONTROL = 1 << 13, - /** A valid receiver inter-signal bias is stored in the data structure. */ - HAS_RECEIVER_ISB = 1 << 16, - /** A valid receiver inter-signal bias uncertainty is stored in the data structure. */ - HAS_RECEIVER_ISB_UNCERTAINTY = 1 << 17, - /** A valid satellite inter-signal bias is stored in the data structure. */ - HAS_SATELLITE_ISB = 1 << 18, - /** A valid satellite inter-signal bias uncertainty is stored in the data structure. */ - HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19 + /** + * A valid 'snr' is stored in the data structure. + */ + HAS_SNR = 1 << 0, + /** + * A valid 'carrier frequency' is stored in the data structure. + */ + HAS_CARRIER_FREQUENCY = 1 << 9, + /** + * A valid 'carrier cycles' is stored in the data structure. + */ + HAS_CARRIER_CYCLES = 1 << 10, + /** + * A valid 'carrier phase' is stored in the data structure. + */ + HAS_CARRIER_PHASE = 1 << 11, + /** + * A valid 'carrier phase uncertainty' is stored in the data structure. + */ + HAS_CARRIER_PHASE_UNCERTAINTY = 1 << 12, + /** + * A valid automatic gain control is stored in the data structure. + */ + HAS_AUTOMATIC_GAIN_CONTROL = 1 << 13, + /** + * A valid receiver inter-signal bias is stored in the data structure. + */ + HAS_RECEIVER_ISB = 1 << 16, + /** + * A valid receiver inter-signal bias uncertainty is stored in the data structure. + */ + HAS_RECEIVER_ISB_UNCERTAINTY = 1 << 17, + /** + * A valid satellite inter-signal bias is stored in the data structure. + */ + HAS_SATELLITE_ISB = 1 << 18, + /** + * A valid satellite inter-signal bias uncertainty is stored in the data structure. + */ + HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19, }; - /** * Extends a GNSS Measurement, adding basebandCN0DbHz, GnssMeasurementFlags, * receiverInterSignalBiasNs, receiverInterSignalBiasUncertaintyNs, satelliteInterSignalBiasNs @@ -160,10 +180,14 @@ interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback { * Complete set of GNSS Measurement data, same as 2.0 with additional fields in measurements. */ struct GnssData { - /** The full set of satellite measurement observations. */ + /** + * The full set of satellite measurement observations. + */ vec measurements; - /** The GNSS clock time reading. */ + /** + * The GNSS clock time reading. + */ GnssClock clock; /** diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 1f1078e398..c4dc8fd55d 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -22,6 +22,7 @@ cc_binary { vintf_fragments: ["android.hardware.gnss@2.1-service.xml"], srcs: [ "Gnss.cpp", + "GnssAntennaInfo.cpp", "GnssDebug.cpp", "GnssMeasurement.cpp", "GnssMeasurementCorrections.cpp", diff --git a/gnss/2.1/default/Gnss.cpp b/gnss/2.1/default/Gnss.cpp index 679eb35804..c1af103f36 100644 --- a/gnss/2.1/default/Gnss.cpp +++ b/gnss/2.1/default/Gnss.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "Gnss" #include "Gnss.h" +#include "GnssAntennaInfo.h" #include "GnssDebug.h" #include "GnssMeasurement.h" #include "GnssMeasurementCorrections.h" @@ -334,9 +335,10 @@ Return Gnss::setCallback_2_1(const sp& callback) { sGnssCallback_2_1 = callback; - using Capabilities = V2_0::IGnssCallback::Capabilities; + using Capabilities = V2_1::IGnssCallback::Capabilities; const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS | - Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST; + Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST | + Capabilities::ANTENNA_INFO; auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_0(capabilities); if (!ret.isOk()) { ALOGE("%s: Unable to invoke callback", __func__); @@ -374,6 +376,11 @@ Gnss::getExtensionMeasurementCorrections_1_1() { return new GnssMeasurementCorrections(); } +Return> Gnss::getExtensionGnssAntennaInfo() { + ALOGD("Gnss::getExtensionGnssAntennaInfo"); + return new GnssAntennaInfo(); +} + void Gnss::reportSvStatus(const hidl_vec& svInfoList) const { std::unique_lock lock(mMutex); // TODO(skz): update this to call 2_0 callback if non-null diff --git a/gnss/2.1/default/Gnss.h b/gnss/2.1/default/Gnss.h index c47206a7a4..bd5e6e852c 100644 --- a/gnss/2.1/default/Gnss.h +++ b/gnss/2.1/default/Gnss.h @@ -22,6 +22,7 @@ #include #include #include +#include "GnssAntennaInfo.h" #include "GnssConfiguration.h" namespace android { @@ -91,6 +92,7 @@ struct Gnss : public IGnss { Return> getExtensionGnssConfiguration_2_1() override; Return> getExtensionMeasurementCorrections_1_1() override; + Return> getExtensionGnssAntennaInfo() override; private: void reportLocation(const V2_0::GnssLocation&) const; diff --git a/gnss/2.1/default/GnssAntennaInfo.cpp b/gnss/2.1/default/GnssAntennaInfo.cpp new file mode 100644 index 0000000000..d32a0afc48 --- /dev/null +++ b/gnss/2.1/default/GnssAntennaInfo.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 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 "GnssAntennaInfo" + +#include "GnssAntennaInfo.h" +#include "Utils.h" + +#include + +using ::android::hardware::gnss::common::Utils; + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +sp GnssAntennaInfo::sCallback = nullptr; + +GnssAntennaInfo::GnssAntennaInfo() : mMinIntervalMillis(1000) {} + +GnssAntennaInfo::~GnssAntennaInfo() { + stop(); +} + +// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow. +Return GnssAntennaInfo::setCallback( + const sp& callback) { + ALOGD("setCallback"); + std::unique_lock lock(mMutex); + sCallback = callback; + + if (mIsActive) { + ALOGW("GnssAntennaInfo callback already set. Resetting the callback..."); + stop(); + } + start(); + + return GnssAntennaInfoStatus::SUCCESS; +} + +Return GnssAntennaInfo::close() { + ALOGD("close"); + std::unique_lock lock(mMutex); + stop(); + sCallback = nullptr; + return Void(); +} + +// Private methods +void GnssAntennaInfo::start() { + ALOGD("start"); + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + if (sCallback != nullptr) { + auto antennaInfos = Utils::getMockAntennaInfos(); + this->reportAntennaInfo(antennaInfos); + } + + /** For mock implementation this is good. On real device, we should only report + antennaInfo at start and when there is a configuration change. **/ + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); + } + }); +} + +void GnssAntennaInfo::stop() { + ALOGD("stop"); + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } +} + +void GnssAntennaInfo::reportAntennaInfo( + const hidl_vec& antennaInfo) const { + std::unique_lock lock(mMutex); + + if (sCallback == nullptr) { + ALOGE("%s: No non-null callback", __func__); + return; + } + + auto ret = sCallback->gnssAntennaInfoCb(antennaInfo); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/gnss/2.1/default/GnssAntennaInfo.h b/gnss/2.1/default/GnssAntennaInfo.h new file mode 100644 index 0000000000..f4bfd24367 --- /dev/null +++ b/gnss/2.1/default/GnssAntennaInfo.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V2_1_GNSSANTENNAINFO_H +#define ANDROID_HARDWARE_GNSS_V2_1_GNSSANTENNAINFO_H + +#include + +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; + +struct GnssAntennaInfo : public IGnssAntennaInfo { + GnssAntennaInfo(); + ~GnssAntennaInfo(); + + // Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow. + Return setCallback( + const sp& callback) override; + Return close() override; + + private: + void start(); + void stop(); + void reportAntennaInfo( + const hidl_vec& antennaInfo) const; + + 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 + +#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H \ 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 index 93f89f54e0..83c4c3cd10 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test.cpp +++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp @@ -262,4 +262,11 @@ Return GnssHalTest::GnssMeasurementCorrectionsCallback::setCapabilitiesCb( ALOGI("GnssMeasurementCorrectionsCallback capabilities received %d", capabilities); capabilities_cbq_.store(capabilities); return Void(); +} + +Return GnssHalTest::GnssAntennaInfoCallback::gnssAntennaInfoCb( + const hidl_vec& gnssAntennaInfos) { + ALOGD("GnssAntennaInfo v2.1 received. Size = %d", (int)gnssAntennaInfos.size()); + antenna_info_cbq_.store(gnssAntennaInfos); + return Void(); } \ No newline at end of file diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h index b99cf2322a..3472edb907 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test.h +++ b/gnss/2.1/vts/functional/gnss_hal_test.h @@ -31,6 +31,8 @@ using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrec using android::hardware::gnss::V1_0::GnssLocationFlags; using android::hardware::gnss::V2_0::GnssConstellationType; using android::hardware::gnss::V2_1::IGnss; +using android::hardware::gnss::V2_1::IGnssAntennaInfo; +using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation; using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation; @@ -152,6 +154,20 @@ class GnssHalTest : public testing::TestWithParam { Return setCapabilitiesCb(uint32_t capabilities) override; }; + /* Callback class for GnssAntennaInfo. */ + class GnssAntennaInfoCallback : public IGnssAntennaInfoCallback { + public: + GnssCallbackEventQueue> + antenna_info_cbq_; + + GnssAntennaInfoCallback() : antenna_info_cbq_("info"){}; + virtual ~GnssAntennaInfoCallback() = default; + + // Methods from V2_1::GnssAntennaInfoCallback follow. + Return gnssAntennaInfoCb( + const hidl_vec& gnssAntennaInfos); + }; + /* * SetUpGnssCallback: * Set GnssCallback and verify the result. diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp index 9ac9436b0d..7b054c0033 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp @@ -139,7 +139,7 @@ TEST_P(GnssHalTest, TestGnssMeasurementFields) { std::string codeType = lastMeasurement.clock.referenceSignalTypeForIsb.codeType; ASSERT_TRUE(referenceConstellation >= GnssConstellationType::UNKNOWN && - referenceConstellation >= GnssConstellationType::IRNSS); + referenceConstellation <= GnssConstellationType::IRNSS); ASSERT_TRUE(carrierFrequencyHz > 0); ASSERT_TRUE(codeType != ""); @@ -153,6 +153,85 @@ TEST_P(GnssHalTest, TestGnssMeasurementFields) { iGnssMeasurement->close(); } +/* + * TestGnssAntennaInfo: + * Sets a GnssAntennaInfoCallback, waits for report, and verifies + * 1. phaseCenterOffsetCoordinateMillimeters is valid + * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid. + * PhaseCenterVariationCorrections and SignalGainCorrections are optional. + */ +TEST_P(GnssHalTest, TestGnssAntennaInfo) { + const int kAntennaInfoTimeoutSeconds = 2; + + auto gnssAntennaInfo = gnss_hal_->getExtensionGnssAntennaInfo(); + ASSERT_TRUE(gnssAntennaInfo.isOk()); + + // Skip test if GnssAntennaInfo v2.1 is not supported + sp iGnssAntennaInfo = gnssAntennaInfo; + if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::ANTENNA_INFO) || + iGnssAntennaInfo == nullptr) { + ALOGD("GnssAntennaInfo v2.1 is not supported."); + return; + } + + sp callback = new GnssAntennaInfoCallback(); + auto result = iGnssAntennaInfo->setCallback(callback); + ASSERT_TRUE(result.isOk()); + EXPECT_EQ(result, IGnssAntennaInfo::GnssAntennaInfoStatus::SUCCESS); + + hidl_vec antennaInfos; + ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds)); + EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1); + ASSERT_TRUE(antennaInfos.size() > 0); + + for (auto antennaInfo : antennaInfos) { + // Remaining fields are optional + if (antennaInfo.phaseCenterVariationCorrectionMillimeters != NULL) { + int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size(); + int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size(); + // Must have at least 1 row and 2 columns + ASSERT_TRUE(numRows >= 1 && numColumns >= 2); + + // Corrections and uncertainties must have same dimensions + ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() == + antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size()); + ASSERT_TRUE( + antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() == + antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size()); + + // Must be rectangular + for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) { + ASSERT_TRUE(row.row.size() == numColumns); + } + for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) { + ASSERT_TRUE(row.row.size() == numColumns); + } + } + if (antennaInfo.signalGainCorrectionDbi != NULL) { + int numRows = antennaInfo.signalGainCorrectionDbi.size(); + int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size(); + // Must have at least 1 row and 2 columns + ASSERT_TRUE(numRows >= 1 && numColumns >= 2); + + // Corrections and uncertainties must have same dimensions + ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() == + antennaInfo.signalGainCorrectionUncertaintyDbi.size()); + ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() == + antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size()); + + // Must be rectangular + for (auto row : antennaInfo.signalGainCorrectionDbi) { + ASSERT_TRUE(row.row.size() == numColumns); + } + for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) { + ASSERT_TRUE(row.row.size() == numColumns); + } + } + } + + iGnssAntennaInfo->close(); +} + /* * TestGnssSvInfoFields: * Gets 1 location and a GnssSvInfo, and verifies diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 0cdc865849..2e5b87330f 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -235,6 +235,58 @@ GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationTyp return svInfo; } +hidl_vec Utils::getMockAntennaInfos() { + GnssAntennaInfo mockAntennaInfo_1 = { + .carrierFrequencyMHz = 123412.12, + .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1, + .xUncertainty = 0.1, + .y = 2, + .yUncertainty = 0.1, + .z = 3, + .zUncertainty = 0.1}, + .phaseCenterVariationCorrectionMillimeters = + { + Row{hidl_vec{1, -1, 5, -2, 3, -1}}, + Row{hidl_vec{-2, 3, 2, 0, 1, 2}}, + Row{hidl_vec{1, 3, 2, -1, -3, 5}}, + }, + .phaseCenterVariationCorrectionUncertaintyMillimeters = + { + Row{hidl_vec{0.1, 0.2, 0.4, 0.1, 0.2, 0.3}}, + Row{hidl_vec{0.3, 0.2, 0.3, 0.6, 0.1, 0.1}}, + Row{hidl_vec{0.1, 0.1, 0.4, 0.2, 0.5, 0.3}}, + }, + .signalGainCorrectionDbi = + { + Row{hidl_vec{2, -3, 1, -3, 0, -4}}, + Row{hidl_vec{1, 0, -4, 1, 3, -2}}, + Row{hidl_vec{3, -2, 0, -2, 3, 0}}, + }, + .signalGainCorrectionUncertaintyDbi = + { + Row{hidl_vec{0.3, 0.1, 0.2, 0.6, 0.1, 0.3}}, + Row{hidl_vec{0.1, 0.1, 0.5, 0.2, 0.3, 0.1}}, + Row{hidl_vec{0.2, 0.4, 0.2, 0.1, 0.1, 0.2}}, + }, + }; + + GnssAntennaInfo mockAntennaInfo_2 = { + .carrierFrequencyMHz = 532324.23, + .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5, + .xUncertainty = 0.1, + .y = 6, + .yUncertainty = 0.1, + .z = 7, + .zUncertainty = 0.1}, + }; + + hidl_vec mockAntennaInfos = { + mockAntennaInfo_1, + mockAntennaInfo_2, + }; + return mockAntennaInfos; +} + } // namespace common } // namespace gnss } // namespace hardware diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h index e0c61a41e1..d9ad5a5a66 100644 --- a/gnss/common/utils/default/include/Utils.h +++ b/gnss/common/utils/default/include/Utils.h @@ -33,6 +33,9 @@ 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; +using GnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo; +using Row = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::Row; +using Coord = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::Coord; struct Utils { static GnssDataV2_0 getMockMeasurementV2_0(); @@ -46,6 +49,7 @@ struct Utils { static GnssSvInfoV1_0 getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type, float cN0DbHz, float elevationDegrees, float azimuthDegrees); + static hidl_vec getMockAntennaInfos(); }; } // namespace common