From 5d22983acfa5c3c429e21198b7848597e7606d9b Mon Sep 17 00:00:00 2001 From: Wyatt Riley Date: Fri, 10 Feb 2017 17:06:00 -0800 Subject: [PATCH] Common code for 4 jni Location conversions Cleans up a TODO after GNSS location batching work Bug: 35273058 Change-Id: Ibb9220269940377a7065b5df3e5672c2a49a50cf Fixes: 35273058 Test: GnssLogger.apk, Maps & 3rd party app work as expected --- .../server/location/GnssLocationProvider.java | 146 ++---------------- ...d_server_location_GnssLocationProvider.cpp | 130 +++++++--------- 2 files changed, 66 insertions(+), 210 deletions(-) diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 17b005d8c890d..7757771b3f885 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -263,8 +263,6 @@ public class GnssLocationProvider implements LocationProviderInterface { private Object mLock = new Object(); - private int mLocationFlags = LOCATION_INVALID; - // current status private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; @@ -1458,7 +1456,6 @@ public class GnssLocationProvider implements LocationProviderInterface { native_stop(); mTimeToFirstFix = 0; mLastFixTime = 0; - mLocationFlags = LOCATION_INVALID; // reset SV count to zero updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); @@ -1482,12 +1479,9 @@ 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 speedMetersPerSecond, float bearing, float horizontalAccuracyMeters, - float verticalAccuracyMeters, float speedAccuracyMetersPerSeconds, - float bearingAccuracyDegrees, long timestamp) { - if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { - mItarSpeedLimitExceeded = speedMetersPerSecond > ITAR_SPEED_LIMIT_METERS_PER_SECOND; + private void reportLocation(boolean hasLatLong, Location location) { + if (location.hasSpeed()) { + mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND; } if (mItarSpeedLimitExceeded) { @@ -1496,54 +1490,13 @@ public class GnssLocationProvider implements LocationProviderInterface { return; // No output of location allowed } - if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + - " timestamp: " + timestamp + " flags: " + flags); + if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString()); synchronized (mLocation) { - mLocationFlags = flags; - if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { - mLocation.setLatitude(latitude); - mLocation.setLongitude(longitude); - mLocation.setTime(timestamp); - // It would be nice to push the elapsed real-time timestamp - // further down the stack, but this is still useful - mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); - } - if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { - mLocation.setAltitude(altitude); - } else { - mLocation.removeAltitude(); - } - if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { - mLocation.setSpeed(speedMetersPerSecond); - } else { - mLocation.removeSpeed(); - } - if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { - mLocation.setBearing(bearing); - } else { - mLocation.removeBearing(); - } - if ((flags & LOCATION_HAS_HORIZONTAL_ACCURACY) == LOCATION_HAS_HORIZONTAL_ACCURACY) { - mLocation.setAccuracy(horizontalAccuracyMeters); - } else { - mLocation.removeAccuracy(); - } - if ((flags & LOCATION_HAS_VERTICAL_ACCURACY) == LOCATION_HAS_VERTICAL_ACCURACY) { - mLocation.setVerticalAccuracyMeters(verticalAccuracyMeters); - } else { - mLocation.removeVerticalAccuracy(); - } - if((flags & LOCATION_HAS_SPEED_ACCURACY) == LOCATION_HAS_SPEED_ACCURACY) { - mLocation.setSpeedAccuracyMetersPerSecond(speedAccuracyMetersPerSeconds); - } else { - mLocation.removeSpeedAccuracy(); - } - if((flags & LOCATION_HAS_BEARING_ACCURACY) == LOCATION_HAS_BEARING_ACCURACY) { - mLocation.setBearingAccuracyDegrees(bearingAccuracyDegrees); - } else { - mLocation.removeBearingAccuracy(); - } + mLocation = location; + // It would be nice to push the elapsed real-time timestamp + // further down the stack, but this is still useful + mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); mLocation.setExtras(mLocationExtras); try { @@ -1555,7 +1508,7 @@ public class GnssLocationProvider implements LocationProviderInterface { mLastFixTime = System.currentTimeMillis(); // report time to first fix - if (mTimeToFirstFix == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { + if (mTimeToFirstFix == 0 && hasLatLong) { mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime); if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix); @@ -1877,52 +1830,6 @@ public class GnssLocationProvider implements LocationProviderInterface { sendMessage(DOWNLOAD_XTRA_DATA, 0, null); } - /** - * Helper method to construct a location object. - */ - private Location buildLocation( - int flags, - double latitude, - double longitude, - double altitude, - float speed, - float bearing, - float horizontalAccuracy, - float verticalAccuracy, - float speedAccuracy, - float bearingAccuracy, - long timestamp) { - Location location = new Location(LocationManager.GPS_PROVIDER); - if((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { - location.setLatitude(latitude); - location.setLongitude(longitude); - location.setTime(timestamp); - location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); - } - if((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { - location.setAltitude(altitude); - } - if((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { - location.setSpeed(speed); - } - if((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { - location.setBearing(bearing); - } - if((flags & LOCATION_HAS_HORIZONTAL_ACCURACY) == LOCATION_HAS_HORIZONTAL_ACCURACY) { - location.setAccuracy(horizontalAccuracy); - } - if((flags & LOCATION_HAS_VERTICAL_ACCURACY) == LOCATION_HAS_VERTICAL_ACCURACY) { - location.setVerticalAccuracyMeters(verticalAccuracy); - } - if((flags & LOCATION_HAS_SPEED_ACCURACY) == LOCATION_HAS_SPEED_ACCURACY) { - location.setSpeedAccuracyMetersPerSecond(speedAccuracy); - } - if((flags & LOCATION_HAS_BEARING_ACCURACY) == LOCATION_HAS_BEARING_ACCURACY) { - location.setBearingAccuracyDegrees(bearingAccuracy); - } - return location; - } - /** * Converts the GPS HAL status to the internal Geofence Hardware status. */ @@ -1949,25 +1856,12 @@ public class GnssLocationProvider implements LocationProviderInterface { * Called from native to report GPS Geofence transition * All geofence callbacks are called on the same thread */ - private void reportGeofenceTransition(int geofenceId, int flags, double latitude, - double longitude, double altitude, float speed, float bearing, float horizontalAccuracy, - float verticalAccuracy, float speedAccuracy, float bearingAccuracy, long timestamp, - int transition, long transitionTimestamp) { + private void reportGeofenceTransition(int geofenceId, Location location, int transition, + long transitionTimestamp) { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - Location location = buildLocation( - flags, - latitude, - longitude, - altitude, - speed, - bearing, - horizontalAccuracy, - verticalAccuracy, - speedAccuracy, - bearingAccuracy, - timestamp); + mGeofenceHardwareImpl.reportGeofenceTransition( geofenceId, location, @@ -1980,24 +1874,10 @@ public class GnssLocationProvider implements LocationProviderInterface { /** * called from native code to report GPS status change. */ - private void reportGeofenceStatus(int status, int flags, double latitude, - double longitude, double altitude, float speed, float bearing, float horizontalAccuracy, - float verticalAccuracy, float speedAccuracy, float bearingAccuracy, long timestamp) { + private void reportGeofenceStatus(int status, Location location) { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - Location location = buildLocation( - flags, - latitude, - longitude, - altitude, - speed, - bearing, - horizontalAccuracy, - verticalAccuracy, - speedAccuracy, - bearingAccuracy, - timestamp); int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE; if(status == GPS_GEOFENCE_AVAILABLE) { monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE; diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 1578562a4faff..4c897058fad8e 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -289,6 +289,40 @@ static JNIEnv* getJniEnv() { return env; } +static jobject translateLocation(JNIEnv* env, const hardware::gnss::V1_0::GnssLocation& location) { + JavaObject object(env, "android/location/Location", "gps"); + + uint16_t flags = static_cast(location.gnssLocationFlags); + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) { + SET(Latitude, location.latitudeDegrees); + SET(Longitude, location.longitudeDegrees); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) { + SET(Altitude, location.altitudeMeters); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) { + SET(Speed, location.speedMetersPerSec); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) { + SET(Bearing, location.bearingDegrees); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) { + SET(Accuracy, location.horizontalAccuracyMeters); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) { + SET(VerticalAccuracyMeters, location.verticalAccuracyMeters); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) { + SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond); + } + if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) { + SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees); + } + SET(Time, location.timestamp); + + return object.get(); +} + /* * GnssCallback class implements the callback methods for IGnss interface. */ @@ -321,19 +355,15 @@ size_t GnssCallback::sGnssSvListSize = 0; Return GnssCallback::gnssLocationCb( const ::android::hardware::gnss::V1_0::GnssLocation& location) { JNIEnv* env = getJniEnv(); + + jobject jLocation = translateLocation(env, location); + bool hasLatLong = (static_cast(location.gnssLocationFlags) & + hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) != 0; + env->CallVoidMethod(mCallbacksObj, method_reportLocation, - location.gnssLocationFlags, - static_cast(location.latitudeDegrees), - static_cast(location.longitudeDegrees), - static_cast(location.altitudeMeters), - static_cast(location.speedMetersPerSec), - static_cast(location.bearingDegrees), - static_cast(location.horizontalAccuracyMeters), - static_cast(location.verticalAccuracyMeters), - static_cast(location.speedAccuracyMetersPerSecond), - static_cast(location.bearingAccuracyDegrees), - static_cast(location.timestamp)); + boolToJbool(hasLatLong), + jLocation); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } @@ -463,20 +493,12 @@ Return GnssGeofenceCallback::gnssGeofenceTransitionCb( hardware::gnss::V1_0::GnssUtcTime timestamp) { JNIEnv* env = getJniEnv(); + jobject jLocation = translateLocation(env, location); + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofenceId, - location.gnssLocationFlags, - static_cast(location.latitudeDegrees), - static_cast(location.longitudeDegrees), - static_cast(location.altitudeMeters), - static_cast(location.speedMetersPerSec), - static_cast(location.bearingDegrees), - static_cast(location.horizontalAccuracyMeters), - static_cast(location.verticalAccuracyMeters), - static_cast(location.speedAccuracyMetersPerSecond), - static_cast(location.bearingAccuracyDegrees), - static_cast(location.timestamp), + jLocation, transition, timestamp); @@ -488,20 +510,13 @@ Return GnssGeofenceCallback::gnssGeofenceStatusCb( GeofenceAvailability status, const android::hardware::gnss::V1_0::GnssLocation& location) { JNIEnv* env = getJniEnv(); + + jobject jLocation = translateLocation(env, location); + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status, - location.gnssLocationFlags, - static_cast(location.latitudeDegrees), - static_cast(location.longitudeDegrees), - static_cast(location.altitudeMeters), - static_cast(location.speedMetersPerSec), - static_cast(location.bearingDegrees), - static_cast(location.horizontalAccuracyMeters), - static_cast(location.verticalAccuracyMeters), - static_cast(location.speedAccuracyMetersPerSecond), - static_cast(location.bearingAccuracyDegrees), - static_cast(location.timestamp)); + jLocation); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } @@ -949,9 +964,6 @@ struct GnssBatchingCallback : public IGnssBatchingCallback { Return gnssLocationBatchCb( const ::android::hardware::hidl_vec & locations) override; - private: - jobject translateLocation( - JNIEnv* env, const hardware::gnss::V1_0::GnssLocation* location); }; Return GnssBatchingCallback::gnssLocationBatchCb( @@ -962,7 +974,7 @@ Return GnssBatchingCallback::gnssLocationBatchCb( env->FindClass("android/location/Location"), nullptr); for (uint16_t i = 0; i < locations.size(); ++i) { - jobject jLocation = translateLocation(env, &locations[i]); + jobject jLocation = translateLocation(env, locations[i]); env->SetObjectArrayElement(jLocations, i, jLocation); env->DeleteLocalRef(jLocation); } @@ -975,45 +987,9 @@ Return GnssBatchingCallback::gnssLocationBatchCb( return Void(); } -// TODO: Use this common code to translate location for Geofencing and regular Location -jobject GnssBatchingCallback::translateLocation( - JNIEnv* env, const hardware::gnss::V1_0::GnssLocation* location) { - JavaObject object(env, "android/location/Location", "gps"); - - uint16_t flags = static_cast(location->gnssLocationFlags); - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) { - SET(Latitude, location->latitudeDegrees); - SET(Longitude, location->longitudeDegrees); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) { - SET(Altitude, location->altitudeMeters); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) { - SET(Speed, location->speedMetersPerSec); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) { - SET(Bearing, location->bearingDegrees); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) { - SET(Accuracy, location->horizontalAccuracyMeters); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) { - SET(VerticalAccuracyMeters, location->verticalAccuracyMeters); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) { - SET(SpeedAccuracyMetersPerSecond, location->speedAccuracyMetersPerSecond); - } - if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) { - SET(BearingAccuracyDegrees, location->bearingAccuracyDegrees); - } - SET(Time, location->timestamp); - - return object.get(); -} - - static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { - method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFFFFJ)V"); + method_reportLocation = env->GetMethodID(clazz, "reportLocation", + "(ZLandroid/location/Location;)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V"); @@ -1027,9 +1003,9 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition", - "(IIDDDFFFFFFJIJ)V"); + "(ILandroid/location/Location;IJ)V"); method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus", - "(IIDDDFFFFFFJ)V"); + "(ILandroid/location/Location;)V"); method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus", "(II)V"); method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",