Add CTS test for Satellite PVT
Bug: 171537015
Test: atest CtsLocationPrivilegedTestCases
Change-Id: I69873f25e9c861ef1a1b8c5e4162df8c29207146
diff --git a/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java b/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java
index 0a09c23..0bfd514 100644
--- a/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java
+++ b/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java
@@ -16,6 +16,8 @@
package android.location.cts.common;
+import static org.junit.Assert.assertNotNull;
+
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.GnssClock;
@@ -24,6 +26,7 @@
import android.location.GnssNavigationMessage;
import android.location.GnssStatus;
import android.location.LocationManager;
+import android.location.SatellitePvt;
import android.util.Log;
import java.util.ArrayList;
@@ -298,7 +301,29 @@
measurement.getAutomaticGainControlLevelDb() >= -100
&& measurement.getAutomaticGainControlLevelDb() <= 100);
}
+ }
+ /**
+ * Assert all SystemApi fields in Gnss Measurement are in expected range.
+ *
+ * @param testLocationManager TestLocationManager
+ * @param measurement GnssMeasurement
+ * @param softAssert custom SoftAssert
+ * @param timeInNs event time in ns
+ */
+ public static void assertAllGnssMeasurementSystemFields(
+ TestLocationManager testLocationManager, GnssMeasurement measurement,
+ SoftAssert softAssert, long timeInNs, boolean requireSatPvt) {
+ if (requireSatPvt) {
+ softAssert.assertTrue("GnssMeasurement must has satellite PVT",
+ timeInNs,
+ "measurement.hasSatellitePvt() == true",
+ String.valueOf(measurement.hasSatellitePvt()),
+ measurement.hasSatellitePvt());
+ }
+ if (measurement.hasSatellitePvt()) {
+ verifySatellitePvt(measurement, softAssert, timeInNs);
+ }
}
/**
@@ -876,4 +901,71 @@
}
return GnssBand.GNSS_L1; // default to L1 band
}
+
+ /**
+ * Assert most of the fields in Satellite PVT are in expected range.
+ *
+ * @param measurement GnssMeasurement
+ * @param softAssert custom SoftAssert
+ * @param timeInNs event time in ns
+ */
+ private static void verifySatellitePvt(GnssMeasurement measurement,
+ SoftAssert softAssert, long timeInNs) {
+ SatellitePvt satellitePvt = measurement.getSatellitePvt();
+ assertNotNull("SatellitePvt cannot be null when HAS_SATELLITE_PVT is true.", satellitePvt);
+ softAssert.assertTrue("x_meters : "
+ + "Satellite position X in WGS84 ECEF (meters)",
+ timeInNs,
+ "-43000000 <= X <= 43000000",
+ String.valueOf(satellitePvt.getPositionEcef().getXMeters()),
+ satellitePvt.getPositionEcef().getXMeters() >= -43000000 &&
+ satellitePvt.getPositionEcef().getXMeters() <= 43000000);
+ softAssert.assertTrue("y_meters : "
+ + "Satellite position Y in WGS84 ECEF (meters)",
+ timeInNs,
+ "-43000000 <= X <= 43000000",
+ String.valueOf(satellitePvt.getPositionEcef().getYMeters()),
+ satellitePvt.getPositionEcef().getYMeters() >= -43000000 &&
+ satellitePvt.getPositionEcef().getYMeters() <= 43000000);
+ softAssert.assertTrue("z_meters : "
+ + "Satellite position Z in WGS84 ECEF (meters)",
+ timeInNs,
+ "-43000000 <= X <= 43000000",
+ String.valueOf(satellitePvt.getPositionEcef().getZMeters()),
+ satellitePvt.getPositionEcef().getZMeters() >= -43000000 &&
+ satellitePvt.getPositionEcef().getZMeters() <= 43000000);
+ softAssert.assertTrue("ure_meters : "
+ + "The Signal in Space User Range Error (URE) (meters)",
+ timeInNs,
+ "X > 0",
+ String.valueOf(satellitePvt.getPositionEcef().getUreMeters()),
+ satellitePvt.getPositionEcef().getUreMeters() > 0);
+ softAssert.assertTrue("x_mps : "
+ + "Satellite velocity X in WGS84 ECEF (meters per second)",
+ timeInNs,
+ "-4000 <= X <= 4000",
+ String.valueOf(satellitePvt.getVelocityEcef().getXMetersPerSecond()),
+ satellitePvt.getVelocityEcef().getXMetersPerSecond() >= -4000 &&
+ satellitePvt.getVelocityEcef().getXMetersPerSecond() <= 4000);
+ softAssert.assertTrue("y_mps : "
+ + "Satellite velocity Y in WGS84 ECEF (meters per second)",
+ timeInNs,
+ "-4000 <= X <= 4000",
+ String.valueOf(satellitePvt.getVelocityEcef().getYMetersPerSecond()),
+ satellitePvt.getVelocityEcef().getYMetersPerSecond() >= -4000 &&
+ satellitePvt.getVelocityEcef().getYMetersPerSecond() <= 4000);
+ softAssert.assertTrue("z_mps : "
+ + "Satellite velocity Z in WGS84 ECEF (meters per second)",
+ timeInNs,
+ "-4000 <= X <= 4000",
+ String.valueOf(satellitePvt.getVelocityEcef().getZMetersPerSecond()),
+ satellitePvt.getVelocityEcef().getZMetersPerSecond() >= -4000 &&
+ satellitePvt.getVelocityEcef().getZMetersPerSecond() <= 4000);
+ softAssert.assertTrue("ure_rate_mps : "
+ + "The Signal in Space User Range Error Rate (URE Rate) (meters per second)",
+ timeInNs,
+ "X > 0",
+ String.valueOf(satellitePvt.getVelocityEcef().getUreRateMetersPerSecond()),
+ satellitePvt.getVelocityEcef().getUreRateMetersPerSecond() > 0);
+ }
}
diff --git a/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementValuesTest.java b/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementValuesTest.java
new file mode 100644
index 0000000..70249cb
--- /dev/null
+++ b/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementValuesTest.java
@@ -0,0 +1,131 @@
+package android.location.cts.privileged;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.Manifest;
+import android.content.Context;
+import android.location.GnssMeasurement;
+import android.location.GnssMeasurementRequest;
+import android.location.GnssMeasurementsEvent;
+import android.location.cts.common.SoftAssert;
+import android.location.cts.common.TestGnssMeasurementListener;
+import android.location.cts.common.TestLocationListener;
+import android.location.cts.common.TestLocationManager;
+import android.location.cts.common.TestMeasurementUtil;
+import android.util.Log;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test the {@link GnssMeasurement} values.
+ *
+ * 1. Register for location updates.
+ * 2. Register a listener for {@link GnssMeasurementsEvent}s.
+ * 3. Wait for {@link #LOCATION_TO_COLLECT_COUNT} locations.
+ * 3.1 Confirm locations have been found.
+ * 4. Check {@link GnssMeasurementsEvent} status: if the status is not
+ * {@link GnssMeasurementsEvent.Callback#STATUS_READY}, the test will be skipped if the device
+ * does not support the GPS feature.
+ * 5. Verify {@link GnssMeasurement}s, the test will fail if any of the fields is not populated
+ * or in the expected range.
+ */
+@RunWith(AndroidJUnit4.class)
+public class GnssMeasurementValuesTest {
+
+ private static final String TAG = "GnssMeasValuesTest";
+ private static final int LOCATION_TO_COLLECT_COUNT = 20;
+
+ private Context mContext;
+ private TestGnssMeasurementListener mMeasurementListener;
+ private TestLocationListener mLocationListener;
+ private TestLocationManager mTestLocationManager;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = ApplicationProvider.getApplicationContext();
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(Manifest.permission.LOCATION_HARDWARE);
+ mTestLocationManager = new TestLocationManager(mContext);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // Unregister listeners
+ if (mLocationListener != null) {
+ mTestLocationManager.removeLocationUpdates(mLocationListener);
+ }
+ if (mMeasurementListener != null) {
+ mTestLocationManager.unregisterGnssMeasurementCallback(mMeasurementListener);
+ }
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .dropShellPermissionIdentity();
+ }
+
+ /**
+ * Tests that one can listen for {@link GnssMeasurementsEvent} with correlationVectorOutputs
+ * enabled for collection purposes.
+ * It only performs valid checks for the measurements received.
+ * This tests uses actual data retrieved from GPS HAL.
+ */
+ @Test
+ public void testListenForGnssMeasurements() throws Exception {
+ boolean isSatPvtSupported = false;
+ // Checks if GPS hardware feature is present, skips test (pass) if not
+ if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG)) {
+ return;
+ }
+
+ if (TestMeasurementUtil.isAutomotiveDevice(mContext)) {
+ Log.i(TAG, "Test is being skipped because the system has the AUTOMOTIVE feature.");
+ return;
+ }
+
+ isSatPvtSupported = mTestLocationManager.getLocationManager().getGnssCapabilities()
+ .hasSatellitePvt();
+
+ mLocationListener = new TestLocationListener(LOCATION_TO_COLLECT_COUNT);
+ mTestLocationManager.requestLocationUpdates(mLocationListener);
+
+ mMeasurementListener = new TestGnssMeasurementListener(TAG);
+ mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
+
+ SoftAssert softAssert = new SoftAssert(TAG);
+ boolean success = mLocationListener.await();
+ softAssert.assertTrue(
+ "Time elapsed without getting enough location fixes."
+ + " Possibly, the test has been run deep indoors."
+ + " Consider retrying test outdoors.",
+ success);
+
+ Log.i(TAG, "Location status received = " + mLocationListener.isLocationReceived());
+
+ List<GnssMeasurementsEvent> events = mMeasurementListener.getEvents();
+ int eventCount = events.size();
+ Log.i(TAG, "Number of GnssMeasurement Event received = " + eventCount);
+
+ softAssert.assertTrue(
+ "GnssMeasurementEvent count", "X > 0",
+ String.valueOf(eventCount), eventCount > 0);
+
+ for (GnssMeasurementsEvent event : events) {
+ // Verify Gps Event optional fields are in required ranges
+ assertNotNull("GnssMeasurementEvent cannot be null.", event);
+ long timeInNs = event.getClock().getTimeNanos();
+ for (GnssMeasurement measurement : event.getMeasurements()) {
+ TestMeasurementUtil.assertAllGnssMeasurementSystemFields(mTestLocationManager,
+ measurement, softAssert, timeInNs, isSatPvtSupported);
+ }
+ }
+ softAssert.assertAll();
+ }
+}