From d87cf9176237bd3233edded7dbb9276226d764dc Mon Sep 17 00:00:00 2001 From: Wyatt Riley Date: Tue, 5 Dec 2017 09:31:52 -0800 Subject: [PATCH] Providing GNSS Model Name & Year GNSS Model Year moves from a TestApi to public GNSS Model Name is connected from a new .hal to public Bug: 38003769 Test: Builds, works with CTS & Test App on Pixel 2 Change-Id: I3e0a56c60e1a4d298e120df11ffd37b06ecea050 --- api/current.txt | 3 + api/test-current.txt | 4 -- .../android/location/ILocationManager.aidl | 1 + .../android/location/LocationManager.java | 30 +++++++-- .../server/LocationManagerService.java | 15 ++++- .../server/location/GnssLocationProvider.java | 64 +++++++++++++------ ...d_server_location_GnssLocationProvider.cpp | 10 +-- 7 files changed, 94 insertions(+), 33 deletions(-) diff --git a/api/current.txt b/api/current.txt index 8a09b82bf7701..40a55b14cfa06 100644 --- a/api/current.txt +++ b/api/current.txt @@ -21284,6 +21284,8 @@ package android.location { method public void clearTestProviderStatus(java.lang.String); method public java.util.List getAllProviders(); method public java.lang.String getBestProvider(android.location.Criteria, boolean); + method public java.lang.String getGnssHardwareModelName(); + method public int getGnssYearOfHardware(); method public deprecated android.location.GpsStatus getGpsStatus(android.location.GpsStatus); method public android.location.Location getLastKnownLocation(java.lang.String); method public android.location.LocationProvider getProvider(java.lang.String); @@ -21319,6 +21321,7 @@ package android.location { method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback); method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback); method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback); + field public static final java.lang.String GNSS_HARDWARE_MODEL_NAME_UNKNOWN = "Model Name Unknown"; field public static final java.lang.String GPS_PROVIDER = "gps"; field public static final java.lang.String KEY_LOCATION_CHANGED = "location"; field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled"; diff --git a/api/test-current.txt b/api/test-current.txt index 3fc5cd6efc76e..93a88dafd4ee7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -314,10 +314,6 @@ package android.location { method public void setType(int); } - public class LocationManager { - method public int getGnssYearOfHardware(); - } - } package android.net { diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 8f341a8fa6ee2..f9075cfd10d99 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -71,6 +71,7 @@ interface ILocationManager void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener); int getGnssYearOfHardware(); + String getGnssHardwareModelName(); int getGnssBatchSize(String packageName); boolean addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName); diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index d15ab33eed356..4802b23579069 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -19,6 +19,7 @@ package android.location; import com.android.internal.location.ProviderProperties; import android.Manifest; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -225,6 +226,12 @@ public class LocationManager { public static final String HIGH_POWER_REQUEST_CHANGE_ACTION = "android.location.HIGH_POWER_REQUEST_CHANGE"; + /** + * The value returned by {@link LocationManager#getGnssHardwareModelName()} when the hardware + * does not support providing the actual value. + */ + public static final String GNSS_HARDWARE_MODEL_NAME_UNKNOWN = "Model Name Unknown"; + // Map from LocationListeners to their associated ListenerTransport objects private HashMap mListeners = new HashMap(); @@ -1969,11 +1976,10 @@ public class LocationManager { } /** - * Returns the system information of the GPS hardware. - * May return 0 if GPS hardware is earlier than 2016. - * @hide + * Returns the model year of the GNSS hardware and software build. + * + * May return 0 if the model year is less than 2016. */ - @TestApi public int getGnssYearOfHardware() { try { return mService.getGnssYearOfHardware(); @@ -1982,6 +1988,22 @@ public class LocationManager { } } + /** + * Returns the Model Name (including Vendor and Hardware/Software Version) of the GNSS hardware + * driver. + * + * Will return {@link LocationManager#GNSS_HARDWARE_MODEL_NAME_UNKNOWN} when the GNSS hardware + * abstraction layer does not support providing this value. + */ + @NonNull + public String getGnssHardwareModelName() { + try { + return mService.getGnssHardwareModelName(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Returns the batch size (in number of Location objects) that are supported by the batching * interface. diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 0a862812e027d..57c992fdcf487 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -1144,7 +1144,7 @@ public class LocationManagerService extends ILocationManager.Stub { } /** - * Returns the system information of the GNSS hardware. + * Returns the year of the GNSS hardware. */ @Override public int getGnssYearOfHardware() { @@ -1155,6 +1155,19 @@ public class LocationManagerService extends ILocationManager.Stub { } } + + /** + * Returns the model name of the GNSS hardware. + */ + @Override + public String getGnssHardwareModelName() { + if (mGnssSystemInfoProvider != null) { + return mGnssSystemInfoProvider.getGnssHardwareModelName(); + } else { + return LocationManager.GNSS_HARDWARE_MODEL_NAME_UNKNOWN; + } + } + /** * Runs some checks for GNSS (FINE) level permissions, used by several methods which directly * (try to) access GNSS information at this layer. diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index b324002e589cc..e4690602ea3c7 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -414,16 +414,16 @@ public class GnssLocationProvider implements LocationProviderInterface { private WorkSource mClientSource = new WorkSource(); private GeofenceHardwareImpl mGeofenceHardwareImpl; - private int mYearOfHardware = 0; + + // Volatile for simple inter-thread sync on these values. + private volatile int mHardwareYear = 0; + private volatile String mHardwareModelName = LocationManager.GNSS_HARDWARE_MODEL_NAME_UNKNOWN; // 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; - // TODO: improve comment - // Volatile to ensure that potentially near-concurrent outputs from HAL - // react to this value change promptly private volatile boolean mItarSpeedLimitExceeded = false; // GNSS Metrics @@ -1825,33 +1825,53 @@ public class GnssLocationProvider implements LocationProviderInterface { /** * called from native code to inform us what the GPS engine capabilities are */ - private void setEngineCapabilities(int capabilities) { - mEngineCapabilities = capabilities; + private void setEngineCapabilities(final int capabilities) { + // send to handler thread for fast native return, and in-order handling + mHandler.post(new Runnable() { + @Override + public void run() { + mEngineCapabilities = capabilities; - if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) { - mOnDemandTimeInjection = true; - requestUtcTime(); - } + if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) { + mOnDemandTimeInjection = true; + requestUtcTime(); + } - mGnssMeasurementsProvider.onCapabilitiesUpdated( - (capabilities & GPS_CAPABILITY_MEASUREMENTS) == GPS_CAPABILITY_MEASUREMENTS); - mGnssNavigationMessageProvider.onCapabilitiesUpdated( - (capabilities & GPS_CAPABILITY_NAV_MESSAGES) == GPS_CAPABILITY_NAV_MESSAGES); + mGnssMeasurementsProvider.onCapabilitiesUpdated(hasCapability( + GPS_CAPABILITY_MEASUREMENTS)); + mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasCapability( + GPS_CAPABILITY_NAV_MESSAGES)); + } + }); + } + + /** + * Called from native code to inform us the hardware year. + */ + private void setGnssYearOfHardware(final int yearOfHardware) { + // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync + if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware); + mHardwareYear = yearOfHardware; } /** - * Called from native code to inform us the hardware information. + * Called from native code to inform us the hardware model name. */ - private void setGnssYearOfHardware(int yearOfHardware) { - if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware); - mYearOfHardware = yearOfHardware; + private void setGnssHardwareModelName(final String modelName) { + // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync + if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName); + mHardwareModelName = modelName; } public interface GnssSystemInfoProvider { /** - * Returns the year of GPS hardware. + * Returns the year of underlying GPS hardware. */ int getGnssYearOfHardware(); + /** + * Returns the model name of underlying GPS hardware. + */ + String getGnssHardwareModelName(); } /** @@ -1861,7 +1881,11 @@ public class GnssLocationProvider implements LocationProviderInterface { return new GnssSystemInfoProvider() { @Override public int getGnssYearOfHardware() { - return mYearOfHardware; + return mHardwareYear; + } + @Override + public String getGnssHardwareModelName() { + return mHardwareModelName; } }; } diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 246bd426e68c5..67bad0fab7c5a 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -48,6 +48,7 @@ static jmethodID method_reportAGpsStatus; static jmethodID method_reportNmea; static jmethodID method_setEngineCapabilities; static jmethodID method_setGnssYearOfHardware; +static jmethodID method_setGnssHardwareModelName; static jmethodID method_xtraDownloadRequest; static jmethodID method_reportNiNotification; static jmethodID method_requestRefLocation; @@ -373,12 +374,11 @@ struct GnssCallback : public IGnssCallback { Return GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) { ALOGD("%s: name=%s\n", __func__, name.c_str()); - // TODO(b/38003769): build Java code to connect to below code - /* JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareName, name); + jstring jstringName = env->NewStringUTF(name.c_str()); + env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName); checkAndClearExceptionFromCallback(env, __FUNCTION__); - */ + return Void(); } @@ -1031,6 +1031,8 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V"); method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); + method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName", + "(Ljava/lang/String;)V"); method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;II)V");