Merge "Add IGnssConfiguration AIDL HAL (hardware/interfaces)"
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
new file mode 100644
index 0000000..89f5d53
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable BlocklistedSource {
+ android.hardware.gnss.GnssConstellationType constellation;
+ int svid;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
new file mode 100644
index 0000000..30d0227
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@Backing(type="int") @VintfStability
+enum GnssConstellationType {
+ UNKNOWN = 0,
+ GPS = 1,
+ SBAS = 2,
+ GLONASS = 3,
+ QZSS = 4,
+ BEIDOU = 5,
+ GALILEO = 6,
+ IRNSS = 7,
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 33377ca..146577e 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -18,5 +18,9 @@
package android.hardware.gnss;
@VintfStability
interface IGnss {
+ void setCallback(in android.hardware.gnss.IGnssCallback callback);
+ void close();
android.hardware.gnss.IGnssPsds getExtensionPsds();
+ android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
+ const int ERROR_INVALID_ARGUMENT = 1;
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
new file mode 100644
index 0000000..62870d6
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssCallback {
+ void gnssSetCapabilitiesCb(in int capabilities);
+ const int CAPABILITY_SATELLITE_BLOCKLIST = 1;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
new file mode 100644
index 0000000..5af30cf
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssConfiguration {
+ void setSuplVersion(in int version);
+ void setSuplMode(in int mode);
+ void setLppProfile(in int lppProfile);
+ void setGlonassPositioningProtocol(in int protocol);
+ void setEmergencySuplPdn(in boolean enable);
+ void setEsExtensionSec(in int emergencyExtensionSeconds);
+ void setBlocklist(in android.hardware.gnss.BlocklistedSource[] blocklist);
+ const int SUPL_MODE_MSB = 1;
+ const int SUPL_MODE_MSA = 2;
+ const int LPP_PROFILE_USER_PLANE = 1;
+ const int LPP_PROFILE_CONTROL_PLANE = 2;
+ const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 1;
+ const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 2;
+ const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 4;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
index 352a694..ddef928 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
@@ -18,6 +18,6 @@
package android.hardware.gnss;
@VintfStability
interface IGnssPsds {
- boolean injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData);
- boolean setCallback(in android.hardware.gnss.IGnssPsdsCallback callback);
+ void injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData);
+ void setCallback(in android.hardware.gnss.IGnssPsdsCallback callback);
}
diff --git a/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl
new file mode 100644
index 0000000..2fde5b2
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import android.hardware.gnss.GnssConstellationType;
+
+/**
+ * Represents a blocklisted source.
+ */
+@VintfStability
+parcelable BlocklistedSource {
+ /**
+ * Defines the constellation of the given satellite(s).
+ */
+ GnssConstellationType constellation;
+
+ /**
+ * Satellite (space vehicle) ID number, as defined in GnssSvInfo::svid, or 0 to blocklist all
+ * svid's for the specified constellation.
+ */
+ int svid;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl
new file mode 100644
index 0000000..af3e089
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+/**
+ * GNSS constellation type
+ *
+ * This is to specify the navigation satellite system, for example, as listed in Section 3.5 in
+ * RINEX Version 3.04.
+ */
+@VintfStability
+@Backing(type="int")
+enum GnssConstellationType {
+ UNKNOWN = 0,
+ /** Global Positioning System. */
+ GPS = 1,
+ /** Satellite-Based Augmentation System. */
+ SBAS = 2,
+ /** Global Navigation Satellite System. */
+ GLONASS = 3,
+ /** Quasi-Zenith Satellite System. */
+ QZSS = 4,
+ /** BeiDou Navigation Satellite System. */
+ BEIDOU = 5,
+ /** Galileo Navigation Satellite System. */
+ GALILEO = 6,
+ /** Indian Regional Navigation Satellite System. */
+ IRNSS = 7,
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 1da254c..24632aa 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,7 +16,9 @@
package android.hardware.gnss;
+import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.IGnssConfiguration;
/**
* Represents the standard GNSS (Global Navigation Satellite System) interface.
@@ -25,9 +27,52 @@
interface IGnss {
/**
+ * All GNSS Binder calls may return a ServiceSpecificException with the following error
+ * codes.
+ */
+ const int ERROR_INVALID_ARGUMENT = 1;
+
+ /**
+ * 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.
+ */
+ void setCallback(in IGnssCallback callback);
+
+ /**
+ * Closes the interface.
+ *
+ * The close() method is called by the framework to tell the GNSS HAL implementation to
+ * clear the callback and not expect any GNSS requests in the immediate future - e.g. this may
+ * be called when location is disabled by a user setting or low battery conditions. The GNSS HAL
+ * implementation must immediately stop responding to any existing requests until the
+ * setCallback() method is called again and the requests are re-initiated by the framework.
+ *
+ * After this method is called, the GNSS HAL implementation may choose to modify GNSS hardware
+ * states to save power. It is expected that when setCallback() method is called again to
+ * reopen this interface, to serve requests, there may be some minor delays in GNSS response
+ * requests as hardware readiness states are restored, not to exceed those that occur on normal
+ * device boot up.
+ */
+ void close();
+
+ /**
* This method returns the IGnssPsds interface.
*
* @return Handle to the IGnssPsds interface.
*/
IGnssPsds getExtensionPsds();
+
+ /**
+ * This method returns the IGnssConfiguration interface.
+ *
+ * @return Handle to the IGnssConfiguration interface.
+ */
+ IGnssConfiguration getExtensionGnssConfiguration();
}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
new file mode 100644
index 0000000..a46a018
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.IGnssConfiguration;
+
+/**
+ * This interface is required for the HAL to communicate certain information
+ * like status and location info back to the framework, the framework implements
+ * the interfaces and passes a handle to the HAL.
+ */
+@VintfStability
+interface IGnssCallback {
+
+ /** Capability bit mask indicating GNSS supports blocklisting satellites */
+ const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0;
+
+ /**
+ * Callback to inform framework of the GNSS HAL implementation's capabilities.
+ *
+ * @param capabilities Capability parameter is a bit field of the Capability bit masks.
+ */
+ void gnssSetCapabilitiesCb(in int capabilities);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl
new file mode 100644
index 0000000..e0ad357
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl
@@ -0,0 +1,122 @@
+/*
+ * 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;
+
+import android.hardware.gnss.BlocklistedSource;
+
+/**
+ * Extended interface for GNSS Configuration support.
+ */
+@VintfStability
+interface IGnssConfiguration {
+
+ /** SUPL mode bitmask for Mobile Station Based. */
+ const int SUPL_MODE_MSB = 0x01;
+
+ /** SUPL mode bitmask for Mobile Station Assisted. */
+ const int SUPL_MODE_MSA = 0x02;
+
+ /** LPP profile settings bitmask for enabling LTE Positioning Protocol User Plane. */
+ const int LPP_PROFILE_USER_PLANE = 0x01;
+
+ /** LPP profile settings bitmask for enabling LTE Positioning Protocol Control Plane. */
+ const int LPP_PROFILE_CONTROL_PLANE = 0x02;
+
+ /** A-Glonass positioning protocol bitmask for Radio Resource Control (RRC) Control Plane. */
+ const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 0x01;
+
+ /** A-Glonass positioning protocol bitmask for Radio Resource Location User Plane. */
+ const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 0x02;
+
+ /** A-Glonass positioning protocol bitmask for LTE Positioning Protocol User Plane. */
+ const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 0x04;
+
+ /**
+ * This method sets the SUPL version requested by Carrier. The GNSS HAL must use this version
+ * of the SUPL protocol if supported.
+ *
+ * @param version SUPL version requested by carrier. This is a bit mask with bits 0:7
+ * representing a service indicator field, bits 8:15 representing the minor version and bits
+ * 16:23 representing the major version.
+ */
+ void setSuplVersion(in int version);
+
+ /**
+ * This method sets the SUPL mode.
+ *
+ * @param mode Bitmask that specifies the SUPL mode which is set with the SUPL_MODE_* constants.
+ */
+ void setSuplMode(in int mode);
+
+ /**
+ * This method sets the LTE Positioning Profile configuration.
+ *
+ * @param lppProfile Bitmask that specifies the LTE Positioning Profile configuration to be set
+ * as per the LPP_PROFILE_* constants. If none of the bits are set, the default setting is
+ * Radio Resource Location Protocol (RRLP).
+ */
+ void setLppProfile(in int lppProfile);
+
+ /**
+ * This method selects positioning protocol on A-Glonass system.
+ *
+ * @param protocol Bitmask that specifies the positioning protocol to be set as per
+ * GLONASS_POS_PROTOCOL_* constants.
+ */
+ void setGlonassPositioningProtocol(in int protocol);
+
+ /**
+ * This method configures which PDN to use.
+ *
+ * @param enable Use emergency PDN if true and regular PDN if false.
+ */
+ void setEmergencySuplPdn(in boolean enable);
+
+ /**
+ * This method sets the emergency session extension duration. The GNSS HAL
+ * implementation must serve emergency SUPL and Control Plane network initiated
+ * location requests for this extra duration after the user initiated emergency
+ * session ends.
+ *
+ * @param emergencyExtensionSeconds Number of seconds to extend the emergency
+ * session duration post emergency call.
+ */
+ void setEsExtensionSec(in int emergencyExtensionSeconds);
+
+ /**
+ * Injects a vector of BlocklistedSource(s) which the HAL must not use to calculate the
+ * GNSS location output.
+ *
+ * The superset of all satellite sources provided, including wildcards, in the latest call
+ * to this method, is the set of satellites sources that must not be used in calculating
+ * location.
+ *
+ * All measurements from the specified satellites, across frequency bands, are blocklisted
+ * together.
+ *
+ * If this method is never called after the IGnssConfiguration.hal connection is made on boot,
+ * or is called with an empty vector, then no satellites are to be blocklisted as a result of
+ * this API.
+ *
+ * This blocklist must be considered as an additional source of which satellites
+ * should not be trusted for location on top of existing sources of similar information
+ * such as satellite broadcast health being unhealthy and measurement outlier removal.
+ *
+ * @param blocklist The BlocklistedSource(s) of satellites the HAL must not use.
+ */
+ void setBlocklist(in BlocklistedSource[] blocklist);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
index 6f53d6f..7c46096 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
@@ -32,18 +32,14 @@
* @param psdsType Type of PSDS data.
* @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is
* opaque to framework.
- *
- * @return True if the operation is successful.
*/
- boolean injectPsdsData(in PsdsType psdsType, in byte[] psdsData);
+ void injectPsdsData(in PsdsType psdsType, in byte[] psdsData);
/**
* Opens the PSDS interface and provides the callback routines to the implementation of this
* interface.
*
* @param callback Handle to the IGnssPsdsCallback interface.
- *
- * @return True if the operation is successful.
*/
- boolean setCallback(in IGnssPsdsCallback callback);
+ void setCallback(in IGnssPsdsCallback callback);
}
\ No newline at end of file
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 8c4ee40..1fe43c3 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -17,8 +17,13 @@
cc_binary {
name: "android.hardware.gnss-service.example",
relative_install_path: "hw",
- init_rc: ["gnss-default.rc"],
- vintf_fragments: ["gnss-default.xml"],
+ init_rc: [
+ "gnss-default.rc",
+ ],
+ vintf_fragments: [
+ "gnss-default.xml",
+ "gnss@2.1-service.xml",
+ ],
vendor: true,
cflags: [
"-Wall",
@@ -27,12 +32,26 @@
shared_libs: [
"libbase",
"libbinder_ndk",
+ "libhidlbase",
+ "libutils",
"liblog",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss.measurement_corrections@1.1",
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss-ndk_platform",
],
srcs: [
"Gnss.cpp",
+ "GnssHidlHal.cpp",
"GnssPsds.cpp",
+ "GnssConfiguration.cpp",
"service.cpp",
],
+ static_libs: [
+ "android.hardware.gnss@common-default-lib",
+ ],
}
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 2a35924..b4d92fd 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,14 +18,51 @@
#include "Gnss.h"
#include <log/log.h>
+#include "GnssConfiguration.h"
#include "GnssPsds.h"
namespace aidl::android::hardware::gnss {
+std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
+
+ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
+ ALOGD("Gnss::setCallback");
+ if (callback == nullptr) {
+ ALOGE("%s: Null callback ignored", __func__);
+ return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+ }
+
+ sGnssCallback = callback;
+
+ int capabilities = (int)IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST;
+ auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Gnss::close() {
+ ALOGD("Gnss::close");
+ sGnssCallback = nullptr;
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
ALOGD("Gnss::getExtensionPsds");
*iGnssPsds = SharedRefBase::make<GnssPsds>();
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
+ std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
+ ALOGD("Gnss::getExtensionGnssConfiguration");
+ if (mGnssConfiguration == nullptr) {
+ mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
+ }
+ *iGnssConfiguration = mGnssConfiguration;
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 9864e9d..61d7cf7 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -17,12 +17,24 @@
#pragma once
#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <aidl/android/hardware/gnss/BnGnssPsds.h>
+#include "GnssConfiguration.h"
namespace aidl::android::hardware::gnss {
class Gnss : public BnGnss {
+ public:
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssCallback>& callback) override;
+ ndk::ScopedAStatus close() override;
ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
+ ndk::ScopedAStatus getExtensionGnssConfiguration(
+ std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
+
+ std::shared_ptr<GnssConfiguration> mGnssConfiguration;
+
+ private:
+ static std::shared_ptr<IGnssCallback> sGnssCallback;
};
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.cpp b/gnss/aidl/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..30e0d8c
--- /dev/null
+++ b/gnss/aidl/default/GnssConfiguration.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "GnssConfigurationAidl"
+
+#include "GnssConfiguration.h"
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+ndk::ScopedAStatus GnssConfiguration::setBlocklist(const vector<BlocklistedSource>& sourceList) {
+ ALOGD("GnssConfiguration::setBlocklist");
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ mBlocklistedConstellationSet.clear();
+ mBlocklistedSourceSet.clear();
+ for (const auto& source : sourceList) {
+ if (source.svid == 0) {
+ // Wildcard blocklist, i.e., blocklist entire constellation.
+ mBlocklistedConstellationSet.insert(source.constellation);
+ } else {
+ mBlocklistedSourceSet.insert(source);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+bool GnssConfiguration::isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ if (mBlocklistedConstellationSet.find(static_cast<GnssConstellationType>(
+ gnssSvInfo.v2_0.constellation)) != mBlocklistedConstellationSet.end()) {
+ return true;
+ }
+ BlocklistedSource source = {
+ .constellation = static_cast<GnssConstellationType>(gnssSvInfo.v2_0.constellation),
+ .svid = gnssSvInfo.v2_0.v1_0.svid};
+ return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h
new file mode 100644
index 0000000..25fa16e
--- /dev/null
+++ b/gnss/aidl/default/GnssConfiguration.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
+#include <android/hardware/gnss/2.1/IGnssCallback.h>
+#include <mutex>
+#include <unordered_set>
+#include <vector>
+
+namespace aidl::android::hardware::gnss {
+
+using android::hardware::gnss::GnssConstellationType;
+
+struct BlocklistedSourceHash {
+ inline int operator()(const BlocklistedSource& source) const {
+ return int(source.constellation) * 1000 + int(source.svid);
+ }
+};
+
+struct BlocklistedSourceEqual {
+ inline bool operator()(const BlocklistedSource& s1, const BlocklistedSource& s2) const {
+ return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
+ }
+};
+
+using GnssSvInfoV2_1 = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
+using std::vector;
+using BlocklistedSourceSet =
+ std::unordered_set<BlocklistedSource, BlocklistedSourceHash, BlocklistedSourceEqual>;
+using BlocklistedConstellationSet = std::unordered_set<GnssConstellationType>;
+
+struct GnssConfiguration : public BnGnssConfiguration {
+ public:
+ ndk::ScopedAStatus setSuplVersion(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setSuplMode(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setLppProfile(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setGlonassPositioningProtocol(int) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus setEmergencySuplPdn(bool) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setEsExtensionSec(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setBlocklist(const vector<BlocklistedSource>& blocklist) override;
+
+ bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+
+ private:
+ BlocklistedSourceSet mBlocklistedSourceSet;
+ BlocklistedConstellationSet mBlocklistedConstellationSet;
+ mutable std::recursive_mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp
new file mode 100644
index 0000000..11fc806
--- /dev/null
+++ b/gnss/aidl/default/GnssHidlHal.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 "GnssHidlHal"
+
+#include "GnssHidlHal.h"
+//#include <android/hardware/gnss/1.0/IGnssCallback.h>
+
+namespace aidl::android::hardware::gnss {
+
+namespace V1_0 = ::android::hardware::gnss::V1_0;
+
+GnssHidlHal::GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl) : mGnssAidl(gnssAidl) {
+ Gnss* iGnss = mGnssAidl.get();
+ std::shared_ptr<IGnssConfiguration> iGnssConfiguration;
+ auto status = iGnss->getExtensionGnssConfiguration(&iGnssConfiguration);
+ if (!status.isOk()) {
+ ALOGE("Failed to getExtensionGnssConfiguration.");
+ } else {
+ mGnssConfigurationAidl = iGnss->mGnssConfiguration;
+ }
+};
+
+hidl_vec<GnssSvInfo> GnssHidlHal::filterBlocklistedSatellitesV2_1(
+ hidl_vec<GnssSvInfo> gnssSvInfoList) {
+ ALOGD("filterBlocklistSatellitesV2_1 - overridden by GnssHidlHal class");
+ if (mGnssConfigurationAidl == nullptr) {
+ ALOGE("Handle to AIDL GnssConfiguration is not available.");
+ return gnssSvInfoList;
+ }
+ for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+ if (mGnssConfigurationAidl->isBlocklistedV2_1(gnssSvInfoList[i])) {
+ ALOGD("Blocklisted constellation: %d, svid: %d",
+ (int)gnssSvInfoList[i].v2_0.constellation, gnssSvInfoList[i].v2_0.v1_0.svid);
+ gnssSvInfoList[i].v2_0.v1_0.svFlag &=
+ ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
+ }
+ }
+ return gnssSvInfoList;
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h
new file mode 100644
index 0000000..50aad3a
--- /dev/null
+++ b/gnss/aidl/default/GnssHidlHal.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include "v2_1/GnssTemplate.h"
+
+namespace aidl::android::hardware::gnss {
+
+using ::android::hardware::gnss::common::implementation::GnssTemplate;
+using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
+
+class GnssHidlHal : public GnssTemplate<::android::hardware::gnss::V2_1::IGnss> {
+ public:
+ GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl);
+
+ private:
+ hidl_vec<GnssSvInfo> filterBlocklistedSatellitesV2_1(
+ hidl_vec<GnssSvInfo> gnssSvInfoList) override;
+
+ std::shared_ptr<Gnss> mGnssAidl;
+ std::shared_ptr<GnssConfiguration> mGnssConfigurationAidl;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPsds.cpp b/gnss/aidl/default/GnssPsds.cpp
index c354217..6512af6 100644
--- a/gnss/aidl/default/GnssPsds.cpp
+++ b/gnss/aidl/default/GnssPsds.cpp
@@ -17,27 +17,28 @@
#define LOG_TAG "GnssPsdsAidl"
#include "GnssPsds.h"
-
+#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
namespace aidl::android::hardware::gnss {
std::shared_ptr<IGnssPsdsCallback> GnssPsds::sCallback = nullptr;
-ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback,
- bool* success) {
+ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback) {
ALOGD("setCallback");
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
- *success = true;
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType, const std::vector<uint8_t>& psdsData,
- bool* success) {
+ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType,
+ const std::vector<uint8_t>& psdsData) {
ALOGD("injectPsdsData. psdsType: %d, psdsData: %d bytes", static_cast<int>(psdsType),
static_cast<int>(psdsData.size()));
- *success = (psdsData.size() > 0);
- return ndk::ScopedAStatus::ok();
+ if (psdsData.size() > 0) {
+ return ndk::ScopedAStatus::ok();
+ } else {
+ return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT);
+ }
}
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPsds.h b/gnss/aidl/default/GnssPsds.h
index fc65bc1..de9e68f 100644
--- a/gnss/aidl/default/GnssPsds.h
+++ b/gnss/aidl/default/GnssPsds.h
@@ -22,10 +22,9 @@
struct GnssPsds : public BnGnssPsds {
public:
- ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback,
- bool* success) override;
- ndk::ScopedAStatus injectPsdsData(PsdsType psdsType, const std::vector<uint8_t>& psdsData,
- bool* success) override;
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback) override;
+ ndk::ScopedAStatus injectPsdsData(PsdsType psdsType,
+ const std::vector<uint8_t>& psdsData) override;
private:
// Guarded by mMutex
diff --git a/gnss/aidl/default/gnss@2.1-service.xml b/gnss/aidl/default/gnss@2.1-service.xml
new file mode 100644
index 0000000..12a1fdf
--- /dev/null
+++ b/gnss/aidl/default/gnss@2.1-service.xml
@@ -0,0 +1,12 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <version>2.1</version>
+ <version>1.1</version>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/gnss/aidl/default/service.cpp b/gnss/aidl/default/service.cpp
index c79a271..09f1ad2 100644
--- a/gnss/aidl/default/service.cpp
+++ b/gnss/aidl/default/service.cpp
@@ -14,22 +14,45 @@
* limitations under the License.
*/
-#include "Gnss.h"
+#define LOG_TAG "Gnss-main"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <pthread.h>
+#include "Gnss.h"
+#include "GnssHidlHal.h"
using aidl::android::hardware::gnss::Gnss;
+using aidl::android::hardware::gnss::GnssHidlHal;
+using ::android::OK;
+using ::android::sp;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::gnss::V2_1::IGnss;
int main() {
- ABinderProcess_setThreadPoolMaxThreadCount(0);
- std::shared_ptr<Gnss> vib = ndk::SharedRefBase::make<Gnss>();
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ std::shared_ptr<Gnss> gnssAidl = ndk::SharedRefBase::make<Gnss>();
const std::string instance = std::string() + Gnss::descriptor + "/default";
- binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
+ binder_status_t status =
+ AServiceManager_addService(gnssAidl->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
+ sp<IGnss> gnss = new GnssHidlHal(gnssAidl);
+ configureRpcThreadpool(1, true /* will join */);
+ if (gnss->registerAsService() != OK) {
+ ALOGE("Could not register gnss 2.1 service.");
+ return 0;
+ }
+
+ joinRpcThreadpool();
ABinderProcess_joinThreadPool();
+
return EXIT_FAILURE; // should not reach
}
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index e57b421..7f3e5ef 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -18,14 +18,22 @@
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
- srcs: ["VtsHalGnssTargetTest.cpp"],
+ srcs: [
+ "gnss_hal_test.cpp",
+ "gnss_hal_test_cases.cpp",
+ "GnssCallbackAidl.cpp",
+ "VtsHalGnssTargetTest.cpp",
+ ],
shared_libs: [
+ "android.hardware.gnss@2.1",
"libbinder",
],
static_libs: [
"android.hardware.gnss-cpp",
+ "android.hardware.gnss@common-vts-lib",
],
test_suites: [
+ "general-tests",
"vts",
],
}
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
new file mode 100644
index 0000000..f5c745b
--- /dev/null
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#include "GnssCallbackAidl.h"
+#include <log/log.h>
+
+android::binder::Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
+ ALOGI("Capabilities received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
new file mode 100644
index 0000000..7f802ea
--- /dev/null
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssCallback.h>
+#include "GnssCallbackEventQueue.h"
+
+/* Callback class for data & Event. */
+class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
+ public:
+ GnssCallbackAidl() : capabilities_cbq_("capabilities"){};
+ ~GnssCallbackAidl(){};
+
+ android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+
+ int last_capabilities_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
+};
\ No newline at end of file
diff --git a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
index e7ffc05..4bba92b 100644
--- a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
+++ b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
@@ -13,60 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
+
+#include "gnss_hal_test.h"
#include <android/hardware/gnss/IGnss.h>
-#include <android/hardware/gnss/IGnssPsds.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::binder::Status;
-using android::hardware::gnss::IGnss;
-using android::hardware::gnss::IGnssPsds;
-using android::hardware::gnss::PsdsType;
-class GnssAidlHalTest : public testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- gnss_hal_ = android::waitForDeclaredService<IGnss>(String16(GetParam().c_str()));
- ASSERT_NE(gnss_hal_, nullptr);
- }
-
- sp<IGnss> gnss_hal_;
-};
-
-/*
- * SetupTeardownCreateCleanup:
- * Requests the gnss HAL then calls cleanup
- *
- * Empty test fixture to verify basic Setup & Teardown
- */
-TEST_P(GnssAidlHalTest, SetupTeardownCreateCleanup) {}
-
-/*
- * TestPsdsExtension:
- * 1. Gets the PsdsExtension and verifies that it returns a non-null extension.
- * 2. Injects empty PSDS data and verifies that it returns false.
- */
-TEST_P(GnssAidlHalTest, TestPsdsExtension) {
- sp<IGnssPsds> iGnssPsds;
- auto status = gnss_hal_->getExtensionPsds(&iGnssPsds);
- ASSERT_TRUE(status.isOk());
- ASSERT_TRUE(iGnssPsds != nullptr);
-
- bool success;
- status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>(), &success);
- ASSERT_TRUE(status.isOk());
- ASSERT_FALSE(success);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssAidlHalTest);
-INSTANTIATE_TEST_SUITE_P(, GnssAidlHalTest,
- testing::ValuesIn(android::getAidlHalInstanceNames(IGnss::descriptor)),
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest);
+INSTANTIATE_TEST_SUITE_P(, GnssHalTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IGnssAidl::descriptor)),
android::PrintInstanceNameToString);
int main(int argc, char** argv) {
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
new file mode 100644
index 0000000..2447bf8
--- /dev/null
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#include "gnss_hal_test.h"
+#include <hidl/ServiceManagement.h>
+
+using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+
+void GnssHalTest::SetUp() {
+ // Get AIDL handle
+ aidl_gnss_hal_ = android::waitForDeclaredService<IGnssAidl>(String16(GetParam().c_str()));
+ ASSERT_NE(aidl_gnss_hal_, nullptr);
+
+ const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
+ android::hardware::gnss::V2_1::IGnss::descriptor);
+ gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
+ ASSERT_NE(gnss_hal_, nullptr);
+
+ SetUpGnssCallback();
+}
+
+void GnssHalTest::SetUpGnssCallback() {
+ aidl_gnss_cb_ = new GnssCallbackAidl();
+ ASSERT_NE(aidl_gnss_cb_, nullptr);
+
+ auto status = aidl_gnss_hal_->setCallback(aidl_gnss_cb_);
+ if (!status.isOk()) {
+ ALOGE("Failed to setCallback");
+ }
+
+ ASSERT_TRUE(status.isOk());
+
+ /*
+ * Capabilities callback should trigger.
+ */
+ EXPECT_TRUE(aidl_gnss_cb_->capabilities_cbq_.retrieve(aidl_gnss_cb_->last_capabilities_,
+ TIMEOUT_SEC));
+
+ EXPECT_EQ(aidl_gnss_cb_->capabilities_cbq_.calledCount(), 1);
+
+ // Invoke the super method.
+ GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+}
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
new file mode 100644
index 0000000..eb5301e
--- /dev/null
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/gnss/IGnss.h>
+#include <binder/IServiceManager.h>
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssCallbackAidl.h"
+#include "v2_1/gnss_hal_test_template.h"
+
+using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss;
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using IGnssAidl = android::hardware::gnss::IGnss;
+using android::hardware::gnss::BlocklistedSource;
+using android::hardware::gnss::IGnssConfiguration;
+
+// The main test class for GNSS HAL.
+class GnssHalTest : public GnssHalTestTemplate<IGnss_V2_1> {
+ public:
+ GnssHalTest(){};
+ ~GnssHalTest(){};
+ virtual void SetUp() override;
+ virtual void SetUpGnssCallback() override;
+
+ sp<IGnssAidl> aidl_gnss_hal_;
+ sp<GnssCallbackAidl> aidl_gnss_cb_; // Primary callback interface
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
new file mode 100644
index 0000000..2b8a447
--- /dev/null
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -0,0 +1,450 @@
+/*
+ * 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 "GnssHalTestCases"
+
+#include <android/hardware/gnss/IGnssPsds.h>
+#include "gnss_hal_test.h"
+
+using android::sp;
+using android::hardware::gnss::BlocklistedSource;
+using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssPsds;
+using android::hardware::gnss::PsdsType;
+
+/*
+ * SetupTeardownCreateCleanup:
+ * Requests the gnss HAL then calls cleanup
+ *
+ * Empty test fixture to verify basic Setup & Teardown
+ */
+TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
+
+/*
+ * TestPsdsExtension:
+ * 1. Gets the PsdsExtension and verifies that it returns a non-null extension.
+ * 2. Injects empty PSDS data and verifies that it returns false.
+ */
+TEST_P(GnssHalTest, TestPsdsExtension) {
+ sp<IGnssPsds> iGnssPsds;
+ auto status = aidl_gnss_hal_->getExtensionPsds(&iGnssPsds);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssPsds != nullptr);
+
+ status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>());
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ * or a source with constellation == UNKNOWN if none are found sufficient times
+ */
+BlocklistedSource FindStrongFrequentNonGpsSource(
+ const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+ const int min_observations) {
+ struct ComparableBlocklistedSource {
+ BlocklistedSource id;
+
+ ComparableBlocklistedSource() {
+ id.constellation = GnssConstellationTypeAidl::UNKNOWN;
+ id.svid = 0;
+ }
+
+ bool operator<(const ComparableBlocklistedSource& compare) const {
+ return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+ (id.constellation < compare.id.constellation)));
+ }
+ };
+
+ struct SignalCounts {
+ int observations;
+ float max_cn0_dbhz;
+ };
+
+ std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+
+ for (const auto& sv_info_vec : sv_info_list) {
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ ComparableBlocklistedSource source;
+ source.id.svid = gnss_sv.v2_0.v1_0.svid;
+ source.id.constellation =
+ static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation);
+
+ const auto& itSignal = mapSignals.find(source);
+ if (itSignal == mapSignals.end()) {
+ SignalCounts counts;
+ counts.observations = 1;
+ counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ mapSignals.insert(
+ std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
+ } else {
+ itSignal->second.observations++;
+ if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
+ itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ }
+ }
+ }
+ }
+ }
+
+ float max_cn0_dbhz_with_sufficient_count = 0.;
+ int total_observation_count = 0;
+ int blocklisted_source_count_observation = 0;
+
+ ComparableBlocklistedSource source_to_blocklist; // initializes to zero = UNKNOWN constellation
+ for (auto const& pairSignal : mapSignals) {
+ total_observation_count += pairSignal.second.observations;
+ if ((pairSignal.second.observations >= min_observations) &&
+ (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+ source_to_blocklist = pairSignal.first;
+ blocklisted_source_count_observation = pairSignal.second.observations;
+ max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+ }
+ }
+ ALOGD("Among %d observations, chose svid %d, constellation %d, "
+ "with %d observations at %.1f max CNo",
+ total_observation_count, source_to_blocklist.id.svid,
+ (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
+ max_cn0_dbhz_with_sufficient_count);
+
+ return source_to_blocklist.id;
+}
+
+/*
+ * BlocklistIndividualSatellites:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for common satellites (strongest and one other.)
+ * 2a & b) Turns off location, and blocklists common satellites.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use those satellites.
+ * 4a & b) Turns off location, and send in empty blocklist.
+ * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does re-use at least the previously strongest satellite
+ * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
+ * formerly strongest satellite
+ */
+TEST_P(GnssHalTest, BlocklistIndividualSatellites) {
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
+ ALOGI("Test BlocklistIndividualSatellites skipped. SATELLITE_BLOCKLIST capability not "
+ "supported.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kRetriesToUnBlocklist = 10;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ 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 + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ /*
+ * Identify strongest SV seen at least kLocationsToAwait -1 times
+ * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
+ * observability (one epoch RF null)
+ */
+
+ const int kGnssSvInfoListTimeout = 2;
+ std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+ int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+ kGnssSvInfoListTimeout);
+
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+
+ BlocklistedSource source_to_blocklist =
+ FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+
+ if (source_to_blocklist.constellation == GnssConstellationTypeAidl::UNKNOWN) {
+ // Cannot find a non-GPS satellite. Let the test pass.
+ ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
+ return;
+ }
+
+ // Stop locations, blocklist the common SV
+ StopAndClearLocations();
+
+ sp<IGnssConfiguration> gnss_configuration_hal;
+ auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ std::vector<BlocklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blocklist;
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ // retry and ensure satellite not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clear blocklist and restart - this time updating the blocklist while location is still on
+ sources.resize(0);
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ bool strongest_sv_is_reobserved = false;
+ // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
+ int unblocklist_loops_remaining = kRetriesToUnBlocklist;
+ while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
+ StopAndClearLocations();
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit loop if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
+ ", tries remaining %d",
+ sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
+
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
+ }
+ if (strongest_sv_is_reobserved) break;
+ }
+ }
+ EXPECT_TRUE(strongest_sv_is_reobserved);
+ StopAndClearLocations();
+}
+
+/*
+ * BlocklistConstellationLocationOff:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Turns off location, and blocklist first non-GPS constellations.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
+ */
+TEST_P(GnssHalTest, BlocklistConstellationLocationOff) {
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
+ ALOGI("Test BlocklistConstellationLocationOff skipped. SATELLITE_BLOCKLIST capability not "
+ "supported.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kGnssSvInfoListTimeout = 2;
+
+ // Find first non-GPS constellation to blocklist
+ GnssConstellationTypeAidl constellation_to_blocklist = static_cast<GnssConstellationTypeAidl>(
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
+
+ // Turns off location
+ StopAndClearLocations();
+
+ BlocklistedSource source_to_blocklist_1;
+ source_to_blocklist_1.constellation = constellation_to_blocklist;
+ source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
+ // supported.
+ BlocklistedSource source_to_blocklist_2;
+ source_to_blocklist_2.constellation = GnssConstellationTypeAidl::IRNSS;
+ source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ sp<IGnssConfiguration> gnss_configuration_hal;
+ auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<BlocklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blocklist_1;
+ sources[1] = source_to_blocklist_2;
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // 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 + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * BlocklistConstellationLocationOn:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Blocklist first non-GPS constellation, and turn off location.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
+ */
+TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
+ ALOGI("Test BlocklistConstellationLocationOn skipped. SATELLITE_BLOCKLIST capability not "
+ "supported.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kGnssSvInfoListTimeout = 2;
+
+ // Find first non-GPS constellation to blocklist
+ GnssConstellationTypeAidl constellation_to_blocklist = static_cast<GnssConstellationTypeAidl>(
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
+
+ BlocklistedSource source_to_blocklist_1;
+ source_to_blocklist_1.constellation = constellation_to_blocklist;
+ source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
+ // supported.
+ BlocklistedSource source_to_blocklist_2;
+ source_to_blocklist_2.constellation = GnssConstellationTypeAidl::IRNSS;
+ source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ sp<IGnssConfiguration> gnss_configuration_hal;
+ auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<BlocklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blocklist_1;
+ sources[1] = source_to_blocklist_2;
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ // Turns off location
+ StopAndClearLocations();
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // 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 + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+}
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 1fe6c3e..0128df4 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -127,12 +127,13 @@
std::atomic<long> mMinIntervalMs;
sp<GnssConfiguration> mGnssConfiguration;
std::atomic<bool> mIsActive;
- std::atomic<bool> mHardwareModeOn;
+ std::atomic<bool> mHardwareModeChecked;
std::atomic<int> mGnssFd;
std::thread mThread;
mutable std::mutex mMutex;
- hidl_vec<GnssSvInfo> filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList);
+ virtual hidl_vec<GnssSvInfo> filterBlocklistedSatellitesV2_1(
+ hidl_vec<GnssSvInfo> gnssSvInfoList);
};
template <class T_IGnss>
@@ -148,7 +149,7 @@
GnssTemplate<T_IGnss>::GnssTemplate()
: mMinIntervalMs(1000),
mGnssConfiguration{new GnssConfiguration()},
- mHardwareModeOn(false),
+ mHardwareModeChecked(false),
mGnssFd(-1) {}
template <class T_IGnss>
@@ -159,16 +160,18 @@
template <class T_IGnss>
std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
char inputBuffer[INPUT_BUFFER_SIZE];
- if (mGnssFd == -1) {
+ if (!mHardwareModeChecked) {
mGnssFd = open(GNSS_PATH, O_RDWR | O_NONBLOCK);
+ if (mGnssFd == -1) {
+ ALOGW("Failed to open /dev/gnss0 errno: %d", errno);
+ }
+ mHardwareModeChecked = true;
}
if (mGnssFd == -1) {
- ALOGW("Failed to open /dev/gnss0 errno: %d", errno);
return nullptr;
}
- // Indicates it is a hardwareMode, don't report the default location.
- mHardwareModeOn = true;
+
int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION));
if (bytes_write <= 0) {
return nullptr;
@@ -206,14 +209,12 @@
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
- auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
+ auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
this->reportSvStatus(svStatus);
auto currentLocation = getLocationFromHW();
- if (mHardwareModeOn) {
- if (currentLocation != nullptr) {
- // Only report location if the return from hardware is valid
- this->reportLocation(*currentLocation);
- }
+ if (mGnssFd != -1 && currentLocation != nullptr) {
+ // Only report location if the return from hardware is valid
+ this->reportLocation(*currentLocation);
} else {
if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) {
const auto location = Utils::getMockLocationV2_0();
@@ -230,8 +231,9 @@
}
template <class T_IGnss>
-hidl_vec<GnssSvInfo> GnssTemplate<T_IGnss>::filterBlacklistedSatellitesV2_1(
+hidl_vec<GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
hidl_vec<GnssSvInfo> gnssSvInfoList) {
+ ALOGD("filterBlocklistedSatellitesV2_1");
for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
gnssSvInfoList[i].v2_0.v1_0.svFlag &=
diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
index d057c61..1439158 100644
--- a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
+++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
@@ -119,7 +119,7 @@
* SetUpGnssCallback:
* Set GnssCallback and verify the result.
*/
- void SetUpGnssCallback();
+ virtual void SetUpGnssCallback();
/*
* StartAndCheckFirstLocation: