From 5d5bac8383b74a05db65483e6f1ab826b52a69ea Mon Sep 17 00:00:00 2001 From: Wyatt Riley Date: Tue, 1 Nov 2016 07:05:16 -0700 Subject: [PATCH] High speed GPS/GNSS Navigation Information Block When speed goes above 400m/s, the GnssLocationProvider will stop output of location, measurements and navigation message. Test: Several on device tests, see bug for details Bug: 31711586 Change-Id: I8bceb9a67b10ac7cf21983bb856ed0608957096a --- .../server/location/GnssLocationProvider.java | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index ae98077c7c2c2..5f58c5d9e56ab 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -417,6 +417,12 @@ public class GnssLocationProvider implements LocationProviderInterface { private int mYearOfHardware = 0; + // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL + // stops output right at 600m/s, depriving this of the information of a device that reaches + // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases. + private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F; + private boolean mItarSpeedLimitExceeded = false; + private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() { @Override public void registerGnssStatusCallback(IGnssStatusListener callback) { @@ -1414,6 +1420,12 @@ public class GnssLocationProvider implements LocationProviderInterface { mStarted = true; mSingleShot = singleShot; mPositionMode = GPS_POSITION_MODE_STANDALONE; + // Notify about suppressed output, if speed limit was previously exceeded. + // Elsewhere, we check again with every speed output reported. + if (mItarSpeedLimitExceeded) { + Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " + + "until slow enough speed reported."); + } boolean agpsEnabled = (Settings.Global.getInt(mContext.getContentResolver(), @@ -1500,7 +1512,17 @@ public class GnssLocationProvider implements LocationProviderInterface { * called from native code to update our position. */ private void reportLocation(int flags, double latitude, double longitude, double altitude, - float speed, float bearing, float accuracy, long timestamp) { + float speedMetersPerSecond, float bearing, float accuracy, long timestamp) { + if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { + mItarSpeedLimitExceeded = speedMetersPerSecond > ITAR_SPEED_LIMIT_METERS_PER_SECOND; + } + + if (mItarSpeedLimitExceeded) { + Log.i(TAG, "Hal reported a speed in excess of ITAR limit." + + " GPS/GNSS Navigation output blocked."); + return; // No output of location allowed + } + if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + " timestamp: " + timestamp); @@ -1520,7 +1542,7 @@ public class GnssLocationProvider implements LocationProviderInterface { mLocation.removeAltitude(); } if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { - mLocation.setSpeed(speed); + mLocation.setSpeed(speedMetersPerSecond); } else { mLocation.removeSpeed(); } @@ -1704,23 +1726,29 @@ public class GnssLocationProvider implements LocationProviderInterface { * called from native code to report NMEA data received */ private void reportNmea(long timestamp) { - int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); - String nmea = new String(mNmeaBuffer, 0 /* offset */, length); - mListenerHelper.onNmeaReceived(timestamp, nmea); + if (!mItarSpeedLimitExceeded) { + int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); + String nmea = new String(mNmeaBuffer, 0 /* offset */, length); + mListenerHelper.onNmeaReceived(timestamp, nmea); + } } /** * called from native code - Gps measurements callback */ private void reportMeasurementData(GnssMeasurementsEvent event) { - mGnssMeasurementsProvider.onMeasurementsAvailable(event); + if (!mItarSpeedLimitExceeded) { + mGnssMeasurementsProvider.onMeasurementsAvailable(event); + } } /** * called from native code - GPS navigation message callback */ private void reportNavigationMessage(GnssNavigationMessage event) { - mGnssNavigationMessageProvider.onNavigationMessageAvailable(event); + if (!mItarSpeedLimitExceeded) { + mGnssNavigationMessageProvider.onNavigationMessageAvailable(event); + } } /**