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

Commit d6dacc87 authored by Pierre Fite-georgel's avatar Pierre Fite-georgel Committed by Android (Google) Code Review
Browse files

Merge "Updating Framework to support update to the GnssLocation HAL v2.0."

parents ea548cc3 b50cdaf4
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -140,6 +140,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
    private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
    private static final int LOCATION_HAS_BEARING_ACCURACY = 128;

    // these need to match ElapsedRealtimeFlags enum in types.hal
    private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;

    // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
    private static final int GPS_DELETE_EPHEMERIS = 0x0001;
    private static final int GPS_DELETE_ALMANAC = 0x0002;
@@ -757,10 +760,16 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
        float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
        float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
        long timestamp = location.getTime();
        native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
                altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
                verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
                timestamp);

        int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS;
        long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();

        native_inject_best_location(
                gnssLocationFlags, latitudeDegrees, longitudeDegrees,
                altitudeMeters, speedMetersPerSec, bearingDegrees,
                horizontalAccuracyMeters, verticalAccuracyMeters,
                speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
                elapsedRealtimeFlags, elapsedRealtimeNanos);
    }

    /** Returns true if the location request is too frequent. */
@@ -1260,9 +1269,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements

        if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());

        // It would be nice to push the elapsed real-time timestamp
        // further down the stack, but this is still useful
        location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
        location.setExtras(mLocationExtras.getBundle());

        reportLocation(location);
@@ -2151,17 +2157,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
    private native int native_read_nmea(byte[] buffer, int bufferSize);

    private native void native_inject_best_location(
            int gnssLocationFlags,
            double latitudeDegrees,
            double longitudeDegrees,
            double altitudeMeters,
            float speedMetersPerSec,
            float bearingDegrees,
            float horizontalAccuracyMeters,
            float verticalAccuracyMeters,
            float speedAccuracyMetersPerSecond,
            float bearingAccuracyDegrees,
            long timestamp);
            int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
            double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
            float horizontalAccuracyMeters, float verticalAccuracyMeters,
            float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
            long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos);

    private native void native_inject_location(double latitude, double longitude, float accuracy);

+166 −79
Original line number Diff line number Diff line
@@ -36,13 +36,14 @@
#include "android_runtime/Log.h"

#include <arpa/inet.h>
#include <cinttypes>
#include <iomanip>
#include <limits>
#include <linux/in.h>
#include <linux/in6.h>
#include <pthread.h>
#include <string.h>
#include <cinttypes>
#include <iomanip>
#include <utils/SystemClock.h>

static jobject mCallbacksObj = nullptr;

@@ -111,10 +112,9 @@ using android::hardware::Void;
using android::hardware::hidl_vec;
using android::hardware::hidl_string;
using android::hardware::hidl_death_recipient;

using android::hardware::gnss::V1_0::GnssConstellationType;
using android::hardware::gnss::V1_0::GnssLocation;
using android::hardware::gnss::V1_0::GnssLocationFlags;

using android::hardware::gnss::V1_0::IAGnssRilCallback;
using android::hardware::gnss::V1_0::IGnssBatching;
using android::hardware::gnss::V1_0::IGnssBatchingCallback;
@@ -128,13 +128,17 @@ using android::hardware::gnss::V1_0::IGnssNiCallback;
using android::hardware::gnss::V1_0::IGnssXtra;
using android::hardware::gnss::V1_0::IGnssXtraCallback;

using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
using android::hardware::gnss::V2_0::IGnssCallback;

using android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
using android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
using android::hardware::gnss::measurement_corrections::V1_0::ReflectingPlane;

using android::hidl::base::V1_0::IBase;

using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
@@ -204,6 +208,20 @@ sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;

namespace android {

namespace {

// Returns true if location has lat/long information.
bool hasLatLong(const GnssLocation_V1_0& location) {
    return (static_cast<uint32_t>(location.gnssLocationFlags) &
            GnssLocationFlags::HAS_LAT_LONG) != 0;
}

// Returns true if location has lat/long information.
bool hasLatLong(const GnssLocation_V2_0& location) {
    return hasLatLong(location.v1_0);
}

}  // namespace
template<class T>
class JavaMethodHelper {
 public:
@@ -234,6 +252,8 @@ class JavaObject {
 public:
    JavaObject(JNIEnv* env, const char* class_name);
    JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
    JavaObject(JNIEnv* env, const char* class_name, jobject object);

    virtual ~JavaObject();

    template<class T>
@@ -260,6 +280,11 @@ JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_
    object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
}

JavaObject::JavaObject(JNIEnv* env, const char* class_name, jobject object)
    : env_(env), object_(object) {
    clazz_ = env_->FindClass(class_name);
}

JavaObject::~JavaObject() {
    env_->DeleteLocalRef(clazz_);
}
@@ -303,6 +328,8 @@ const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
template<>
const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
template<>
const char *const JavaMethodHelper<uint64_t>::signature_ = "(J)V";
template<>
const char *const JavaMethodHelper<float>::signature_ = "(F)V";
template<>
const char *const JavaMethodHelper<double>::signature_ = "(D)V";
@@ -416,7 +443,8 @@ static JNIEnv* getJniEnv() {
    return env;
}

static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
static jobject translateGnssLocation(JNIEnv* env,
                                     const GnssLocation_V1_0& location) {
    JavaObject object(env, "android/location/Location", "gps");

    uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
@@ -446,23 +474,33 @@ static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
        SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
    }
    SET(Time, location.timestamp);
    SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());

    return object.get();
}

static GnssLocation createGnssLocation(
        jint gnssLocationFlags,
        jdouble latitudeDegrees,
        jdouble longitudeDegrees,
        jdouble altitudeMeters,
        jfloat speedMetersPerSec,
        jfloat bearingDegrees,
        jfloat horizontalAccuracyMeters,
        jfloat verticalAccuracyMeters,
        jfloat speedAccuracyMetersPerSecond,
        jfloat bearingAccuracyDegrees,
static jobject translateGnssLocation(JNIEnv* env,
                                     const GnssLocation_V2_0& location) {
    JavaObject object(env, "android/location/Location",
                      translateGnssLocation(env, location.v1_0));

    const uint16_t flags = static_cast<uint16_t>(location.elapsedRealtime.flags);

    // Overwrite ElapsedRealtimeNanos when available from HAL.
    if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
        SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
    }

    return object.get();
}

static GnssLocation_V1_0 createGnssLocation_V1_0(
        jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
        jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
        jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
        jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
        jlong timestamp) {
    GnssLocation location;
    GnssLocation_V1_0 location;
    location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
    location.latitudeDegrees = static_cast<double>(latitudeDegrees);
    location.longitudeDegrees = static_cast<double>(longitudeDegrees);
@@ -478,11 +516,30 @@ static GnssLocation createGnssLocation(
    return location;
}

static GnssLocation_V2_0 createGnssLocation_V2_0(
        jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
        jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
        jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
        jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
        jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos) {
    GnssLocation_V2_0 location;
    location.v1_0 = createGnssLocation_V1_0(
            gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
            speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
            verticalAccuracyMeters, speedAccuracyMetersPerSecond,
            bearingAccuracyDegrees, timestamp);

    location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
    location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);

    return location;
}

/*
 * GnssCallback class implements the callback methods for IGnss interface.
 */
struct GnssCallback : public IGnssCallback {
    Return<void> gnssLocationCb(const GnssLocation& location) override;
    Return<void> gnssLocationCb(const GnssLocation_V1_0& location) override;
    Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
    Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
    Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
@@ -496,7 +553,13 @@ struct GnssCallback : public IGnssCallback {
    // New in 1.1
    Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;

    // New in 2.0
    Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
    Return<void> gnssLocationCb_2_0(const GnssLocation_V2_0& location) override;

    // Templated implementation for gnnsLocationCb and gnnsLocationCb_2_0.
    template <class T>
    Return<void> gnssLocationCbImpl(const T& location);

    // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
    static const char* sNmeaString;
@@ -517,22 +580,30 @@ Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name
const char* GnssCallback::sNmeaString = nullptr;
size_t GnssCallback::sNmeaStringLength = 0;

Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
template<class T>
Return<void> GnssCallback::gnssLocationCbImpl(const T& location) {
    JNIEnv* env = getJniEnv();

    jobject jLocation = translateLocation(env, location);
    bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
            GnssLocationFlags::HAS_LAT_LONG) != 0;
    jobject jLocation = translateGnssLocation(env, location);

    env->CallVoidMethod(mCallbacksObj,
                        method_reportLocation,
                        boolToJbool(hasLatLong),
                        boolToJbool(hasLatLong(location)),
                        jLocation);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    env->DeleteLocalRef(jLocation);
    return Void();
}

Return<void> GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) {
    return gnssLocationCbImpl<GnssLocation_V1_0>(location);
}

Return<void>
GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
    return gnssLocationCbImpl<GnssLocation_V2_0>(location);
}

Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
    JNIEnv* env = getJniEnv();
    env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
@@ -681,12 +752,13 @@ struct GnssGeofenceCallback : public IGnssGeofenceCallback {
    // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
    Return<void> gnssGeofenceTransitionCb(
            int32_t geofenceId,
            const GnssLocation& location,
            const GnssLocation_V1_0& location,
            GeofenceTransition transition,
            hardware::gnss::V1_0::GnssUtcTime timestamp) override;
    Return<void> gnssGeofenceStatusCb(
    Return<void>
    gnssGeofenceStatusCb(
            GeofenceAvailability status,
            const GnssLocation& location) override;
            const GnssLocation_V1_0& location) override;
    Return<void> gnssGeofenceAddCb(int32_t geofenceId,
                                   GeofenceStatus status) override;
    Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
@@ -698,13 +770,12 @@ struct GnssGeofenceCallback : public IGnssGeofenceCallback {
};

Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
        int32_t geofenceId,
        const GnssLocation& location,
        int32_t geofenceId, const GnssLocation_V1_0& location,
        GeofenceTransition transition,
        hardware::gnss::V1_0::GnssUtcTime timestamp) {
    JNIEnv* env = getJniEnv();

    jobject jLocation = translateLocation(env, location);
    jobject jLocation = translateGnssLocation(env, location);

    env->CallVoidMethod(mCallbacksObj,
                        method_reportGeofenceTransition,
@@ -718,16 +789,14 @@ Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
    return Void();
}

Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
        GeofenceAvailability status,
        const GnssLocation& location) {
Return<void>
GnssGeofenceCallback::gnssGeofenceStatusCb(GeofenceAvailability status,
                                           const GnssLocation_V1_0& location) {
    JNIEnv* env = getJniEnv();

    jobject jLocation = translateLocation(env, location);
    jobject jLocation = translateGnssLocation(env, location);

    env->CallVoidMethod(mCallbacksObj,
                        method_reportGeofenceStatus,
                        status,
    env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
                        jLocation);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    env->DeleteLocalRef(jLocation);
@@ -1296,18 +1365,18 @@ struct GnssBatchingCallback : public IGnssBatchingCallback {
    * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
    * follow.
    */
    Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations)
        override;
    Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V1_0>& locations) override;
};

Return<void> GnssBatchingCallback::gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations) {
Return<void> GnssBatchingCallback::gnssLocationBatchCb(
    const hidl_vec<GnssLocation_V1_0>& locations) {
    JNIEnv* env = getJniEnv();

    jobjectArray jLocations = env->NewObjectArray(locations.size(),
            env->FindClass("android/location/Location"), nullptr);

    for (uint16_t i = 0; i < locations.size(); ++i) {
        jobject jLocation = translateLocation(env, locations[i]);
        jobject jLocation = translateGnssLocation(env, locations[i]);
        env->SetObjectArrayElement(jLocations, i, jLocation);
        env->DeleteLocalRef(jLocation);
    }
@@ -1806,9 +1875,34 @@ static void android_location_GnssLocationProvider_inject_best_location(
        jfloat verticalAccuracyMeters,
        jfloat speedAccuracyMetersPerSecond,
        jfloat bearingAccuracyDegrees,
        jlong timestamp) {
        jlong timestamp,
        jint elapsedRealtimeFlags,
        jlong elapsedRealtimeNanos) {
    if (gnssHal_V2_0 != nullptr) {
        GnssLocation_V2_0 location = createGnssLocation_V2_0(
                gnssLocationFlags,
                latitudeDegrees,
                longitudeDegrees,
                altitudeMeters,
                speedMetersPerSec,
                bearingDegrees,
                horizontalAccuracyMeters,
                verticalAccuracyMeters,
                speedAccuracyMetersPerSecond,
                bearingAccuracyDegrees,
                timestamp,
                elapsedRealtimeFlags,
                elapsedRealtimeNanos);
        auto result = gnssHal_V2_0->injectBestLocation_2_0(location);

        if (!result.isOk() || !result) {
            ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
        }
        return;
    }

    if (gnssHal_V1_1 != nullptr) {
        GnssLocation location = createGnssLocation(
        GnssLocation_V1_0 location = createGnssLocation_V1_0(
                gnssLocationFlags,
                latitudeDegrees,
                longitudeDegrees,
@@ -1821,12 +1915,14 @@ static void android_location_GnssLocationProvider_inject_best_location(
                bearingAccuracyDegrees,
                timestamp);
        auto result = gnssHal_V1_1->injectBestLocation(location);

        if (!result.isOk() || !result) {
            ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
        }
    } else {
        ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
        return;
    }

    ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
}

static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
@@ -2695,45 +2791,36 @@ static const JNINativeMethod sMethods[] = {
    {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
    {"native_cleanup", "()V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_cleanup)},
    {"native_set_position_mode",
            "(IIIIIZ)Z",
            reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
    {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
    {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
    {"native_delete_aiding_data",
            "(I)V",
            reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
    {"native_set_position_mode", "(IIIIIZ)Z", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_set_position_mode)},
    {"native_start", "()Z", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_start)},
    {"native_stop", "()Z", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_stop)},
    {"native_delete_aiding_data", "(I)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_delete_aiding_data)},
    {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_read_nmea)},
    {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_inject_time)},
    {"native_inject_best_location",
            "(IDDDFFFFFFJ)V",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
    {"native_inject_location",
            "(DDF)V",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
    {"native_inject_best_location", "(IDDDFFFFFFJIJ)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_inject_best_location)},
    {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_inject_location)},
    {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_supports_xtra)},
    {"native_inject_xtra_data",
            "([BI)V",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
    {"native_agps_set_id",
            "(ILjava/lang/String;)V",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
    {"native_agps_set_ref_location_cellid",
            "(IIIII)V",
            reinterpret_cast<void *>(
    {"native_inject_xtra_data", "([BI)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_inject_xtra_data)},
    {"native_agps_set_id", "(ILjava/lang/String;)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_agps_set_id)},
    {"native_agps_set_ref_location_cellid", "(IIIII)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
    {"native_set_agps_server",
            "(ILjava/lang/String;I)V",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
    {"native_send_ni_response",
            "(II)V",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
    {"native_get_internal_state",
            "()Ljava/lang/String;",
            reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
    {"native_set_agps_server", "(ILjava/lang/String;I)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_set_agps_server)},
    {"native_send_ni_response", "(II)V", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_send_ni_response)},
    {"native_get_internal_state", "()Ljava/lang/String;", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_get_internal_state)},
    {"native_is_gnss_visibility_control_supported", "()Z", reinterpret_cast<void *>(
            android_location_GnssLocationProvider_is_gnss_visibility_control_supported)},
};