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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<uint32_t>(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<void> GnssCallback::gnssLocationCb(
|
||||
const ::android::hardware::gnss::V1_0::GnssLocation& location) {
|
||||
JNIEnv* env = getJniEnv();
|
||||
|
||||
jobject jLocation = translateLocation(env, location);
|
||||
bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
|
||||
hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) != 0;
|
||||
|
||||
env->CallVoidMethod(mCallbacksObj,
|
||||
method_reportLocation,
|
||||
location.gnssLocationFlags,
|
||||
static_cast<jdouble>(location.latitudeDegrees),
|
||||
static_cast<jdouble>(location.longitudeDegrees),
|
||||
static_cast<jdouble>(location.altitudeMeters),
|
||||
static_cast<jfloat>(location.speedMetersPerSec),
|
||||
static_cast<jfloat>(location.bearingDegrees),
|
||||
static_cast<jfloat>(location.horizontalAccuracyMeters),
|
||||
static_cast<jfloat>(location.verticalAccuracyMeters),
|
||||
static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
|
||||
static_cast<jfloat>(location.bearingAccuracyDegrees),
|
||||
static_cast<jlong>(location.timestamp));
|
||||
boolToJbool(hasLatLong),
|
||||
jLocation);
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
return Void();
|
||||
}
|
||||
@@ -463,20 +493,12 @@ Return<void> 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<jdouble>(location.latitudeDegrees),
|
||||
static_cast<jdouble>(location.longitudeDegrees),
|
||||
static_cast<jdouble>(location.altitudeMeters),
|
||||
static_cast<jfloat>(location.speedMetersPerSec),
|
||||
static_cast<jfloat>(location.bearingDegrees),
|
||||
static_cast<jfloat>(location.horizontalAccuracyMeters),
|
||||
static_cast<jfloat>(location.verticalAccuracyMeters),
|
||||
static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
|
||||
static_cast<jfloat>(location.bearingAccuracyDegrees),
|
||||
static_cast<jlong>(location.timestamp),
|
||||
jLocation,
|
||||
transition,
|
||||
timestamp);
|
||||
|
||||
@@ -488,20 +510,13 @@ Return<void> 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<jdouble>(location.latitudeDegrees),
|
||||
static_cast<jdouble>(location.longitudeDegrees),
|
||||
static_cast<jdouble>(location.altitudeMeters),
|
||||
static_cast<jfloat>(location.speedMetersPerSec),
|
||||
static_cast<jfloat>(location.bearingDegrees),
|
||||
static_cast<jfloat>(location.horizontalAccuracyMeters),
|
||||
static_cast<jfloat>(location.verticalAccuracyMeters),
|
||||
static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
|
||||
static_cast<jfloat>(location.bearingAccuracyDegrees),
|
||||
static_cast<jlong>(location.timestamp));
|
||||
jLocation);
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
return Void();
|
||||
}
|
||||
@@ -949,9 +964,6 @@ struct GnssBatchingCallback : public IGnssBatchingCallback {
|
||||
Return<void> gnssLocationBatchCb(
|
||||
const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations)
|
||||
override;
|
||||
private:
|
||||
jobject translateLocation(
|
||||
JNIEnv* env, const hardware::gnss::V1_0::GnssLocation* location);
|
||||
};
|
||||
|
||||
Return<void> GnssBatchingCallback::gnssLocationBatchCb(
|
||||
@@ -962,7 +974,7 @@ Return<void> 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<void> 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<uint32_t>(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",
|
||||
|
||||
Reference in New Issue
Block a user