Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d22983a authored by Wyatt Riley's avatar Wyatt Riley
Browse files

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
parent 0a54d4bb
Loading
Loading
Loading
Loading
+13 −133
Original line number Diff line number Diff line
@@ -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);
            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());
            }
            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.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;
+53 −77
Original line number Diff line number Diff line
@@ -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",