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

Commit fea938bd authored by Yu-Han Yang's avatar Yu-Han Yang
Browse files

Support GnssMeasurement AIDL in JNI

Bug: 173797017
Test: on cuttlefish
Change-Id: I2b54a861302f015ec9b0feb00d7a312eae789c97
parent 67383ec2
Loading
Loading
Loading
Loading
+12 −2
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/3.0/IGnssPsds.h>
#include <android/hardware/gnss/3.0/IGnssPsds.h>
#include <android/hardware/gnss/BnGnss.h>
#include <android/hardware/gnss/BnGnss.h>
#include <android/hardware/gnss/BnGnssMeasurementCallback.h>
#include <android/hardware/gnss/BnGnssPowerIndicationCallback.h>
#include <android/hardware/gnss/BnGnssPowerIndicationCallback.h>
#include <android/hardware/gnss/BnGnssPsdsCallback.h>
#include <android/hardware/gnss/BnGnssPsdsCallback.h>
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
@@ -1754,7 +1755,15 @@ static void android_location_GnssNative_init_once(JNIEnv* env, jobject obj,
    // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
    // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
    // 1.0@IGnss is paired with 1.0@IGnssMeasurement
    // 1.0@IGnss is paired with 1.0@IGnssMeasurement
    gnssMeasurementIface = nullptr;
    gnssMeasurementIface = nullptr;
    if (gnssHal_V2_1 != nullptr) {
    if (gnssHalAidl != nullptr) {
        sp<hardware::gnss::IGnssMeasurementInterface> gnssMeasurement;
        auto status = gnssHalAidl->getExtensionGnssMeasurement(&gnssMeasurement);
        if (checkAidlStatus(status, "Unable to get a handle to GnssMeasurement AIDL interface.")) {
            gnssMeasurementIface =
                    std::make_unique<android::gnss::GnssMeasurement>(gnssMeasurement);
        }
    }
    if (gnssHal_V2_1 != nullptr && gnssMeasurementIface == nullptr) {
        auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1();
        auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1();
        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) {
        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) {
            gnssMeasurementIface =
            gnssMeasurementIface =
@@ -2696,7 +2705,8 @@ static jboolean android_location_GnssMeasurementsProvider_start_measurement_coll
        return JNI_FALSE;
        return JNI_FALSE;
    }
    }


    return gnssMeasurementIface->setCallback(sp<gnss::GnssMeasurementCallback>::make(mCallbacksObj),
    return gnssMeasurementIface->setCallback(std::make_unique<gnss::GnssMeasurementCallback>(
                                                     mCallbacksObj),
                                             enableFullTracking);
                                             enableFullTracking);
}
}


+25 −8
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@
using android::hardware::hidl_vec;
using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::Return;


using IGnssMeasurementInterface = android::hardware::gnss::IGnssMeasurementInterface;
using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
@@ -43,17 +44,33 @@ jboolean checkGnssMeasurementStatus(const IGnssMeasurement_V1_0::GnssMeasurement


namespace android::gnss {
namespace android::gnss {


// Implementation of GnssMeasurement

GnssMeasurement::GnssMeasurement(const sp<IGnssMeasurementInterface>& iGnssMeasurement)
      : mIGnssMeasurement(iGnssMeasurement) {}

jboolean GnssMeasurement::setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                                      bool enableFullTracking) {
    auto status = mIGnssMeasurement->setCallback(callback->getAidl(), enableFullTracking);
    return checkAidlStatus(status, "IGnssMeasurement setCallback() failed.");
}

jboolean GnssMeasurement::close() {
    auto status = mIGnssMeasurement->close();
    return checkAidlStatus(status, "IGnssMeasurement close() failed.");
}

// Implementation of GnssMeasurement_V1_0
// Implementation of GnssMeasurement_V1_0


GnssMeasurement_V1_0::GnssMeasurement_V1_0(const sp<IGnssMeasurement_V1_0>& iGnssMeasurement)
GnssMeasurement_V1_0::GnssMeasurement_V1_0(const sp<IGnssMeasurement_V1_0>& iGnssMeasurement)
      : mIGnssMeasurement_V1_0(iGnssMeasurement) {}
      : mIGnssMeasurement_V1_0(iGnssMeasurement) {}


jboolean GnssMeasurement_V1_0::setCallback(const sp<GnssMeasurementCallback>& callback,
jboolean GnssMeasurement_V1_0::setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                                           bool enableFullTracking) {
                                           bool enableFullTracking) {
    if (enableFullTracking == true) {
    if (enableFullTracking == true) {
        ALOGW("Full tracking is mode not supported in 1.0 GNSS HAL.");
        ALOGW("Full tracking is mode not supported in 1.0 GNSS HAL.");
    }
    }
    auto status = mIGnssMeasurement_V1_0->setCallback(callback);
    auto status = mIGnssMeasurement_V1_0->setCallback(callback->getHidl());
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback() failed.")) {
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback() failed.")) {
        return JNI_FALSE;
        return JNI_FALSE;
    }
    }
@@ -71,9 +88,9 @@ jboolean GnssMeasurement_V1_0::close() {
GnssMeasurement_V1_1::GnssMeasurement_V1_1(const sp<IGnssMeasurement_V1_1>& iGnssMeasurement)
GnssMeasurement_V1_1::GnssMeasurement_V1_1(const sp<IGnssMeasurement_V1_1>& iGnssMeasurement)
      : GnssMeasurement_V1_0{iGnssMeasurement}, mIGnssMeasurement_V1_1(iGnssMeasurement) {}
      : GnssMeasurement_V1_0{iGnssMeasurement}, mIGnssMeasurement_V1_1(iGnssMeasurement) {}


jboolean GnssMeasurement_V1_1::setCallback(const sp<GnssMeasurementCallback>& callback,
jboolean GnssMeasurement_V1_1::setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                                           bool enableFullTracking) {
                                           bool enableFullTracking) {
    auto status = mIGnssMeasurement_V1_1->setCallback_1_1(callback, enableFullTracking);
    auto status = mIGnssMeasurement_V1_1->setCallback_1_1(callback->getHidl(), enableFullTracking);
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback_V1_1() failed.")) {
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback_V1_1() failed.")) {
        return JNI_FALSE;
        return JNI_FALSE;
    }
    }
@@ -86,9 +103,9 @@ jboolean GnssMeasurement_V1_1::setCallback(const sp<GnssMeasurementCallback>& ca
GnssMeasurement_V2_0::GnssMeasurement_V2_0(const sp<IGnssMeasurement_V2_0>& iGnssMeasurement)
GnssMeasurement_V2_0::GnssMeasurement_V2_0(const sp<IGnssMeasurement_V2_0>& iGnssMeasurement)
      : GnssMeasurement_V1_1{iGnssMeasurement}, mIGnssMeasurement_V2_0(iGnssMeasurement) {}
      : GnssMeasurement_V1_1{iGnssMeasurement}, mIGnssMeasurement_V2_0(iGnssMeasurement) {}


jboolean GnssMeasurement_V2_0::setCallback(const sp<GnssMeasurementCallback>& callback,
jboolean GnssMeasurement_V2_0::setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                                           bool enableFullTracking) {
                                           bool enableFullTracking) {
    auto status = mIGnssMeasurement_V2_0->setCallback_2_0(callback, enableFullTracking);
    auto status = mIGnssMeasurement_V2_0->setCallback_2_0(callback->getHidl(), enableFullTracking);
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback_2_0() failed.")) {
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback_2_0() failed.")) {
        return JNI_FALSE;
        return JNI_FALSE;
    }
    }
@@ -101,9 +118,9 @@ jboolean GnssMeasurement_V2_0::setCallback(const sp<GnssMeasurementCallback>& ca
GnssMeasurement_V2_1::GnssMeasurement_V2_1(const sp<IGnssMeasurement_V2_1>& iGnssMeasurement)
GnssMeasurement_V2_1::GnssMeasurement_V2_1(const sp<IGnssMeasurement_V2_1>& iGnssMeasurement)
      : GnssMeasurement_V2_0{iGnssMeasurement}, mIGnssMeasurement_V2_1(iGnssMeasurement) {}
      : GnssMeasurement_V2_0{iGnssMeasurement}, mIGnssMeasurement_V2_1(iGnssMeasurement) {}


jboolean GnssMeasurement_V2_1::setCallback(const sp<GnssMeasurementCallback>& callback,
jboolean GnssMeasurement_V2_1::setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                                           bool enableFullTracking) {
                                           bool enableFullTracking) {
    auto status = mIGnssMeasurement_V2_1->setCallback_2_1(callback, enableFullTracking);
    auto status = mIGnssMeasurement_V2_1->setCallback_2_1(callback->getHidl(), enableFullTracking);
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback_2_1() failed.")) {
    if (!checkHidlReturn(status, "IGnssMeasurement setCallback_2_1() failed.")) {
        return JNI_FALSE;
        return JNI_FALSE;
    }
    }
+17 −5
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <log/log.h>
#include <log/log.h>
#include "GnssMeasurementCallback.h"
#include "GnssMeasurementCallback.h"
#include "jni.h"
#include "jni.h"
@@ -36,16 +37,27 @@ namespace android::gnss {
class GnssMeasurementInterface {
class GnssMeasurementInterface {
public:
public:
    virtual ~GnssMeasurementInterface() {}
    virtual ~GnssMeasurementInterface() {}
    virtual jboolean setCallback(const sp<GnssMeasurementCallback>& callback,
    virtual jboolean setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                                 bool enableFullTracking) = 0;
                                 bool enableFullTracking) = 0;
    virtual jboolean close() = 0;
    virtual jboolean close() = 0;
};
};


class GnssMeasurement : public GnssMeasurementInterface {
public:
    GnssMeasurement(const sp<android::hardware::gnss::IGnssMeasurementInterface>& iGnssMeasurement);
    jboolean setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                         bool enableFullTracking) override;
    jboolean close() override;

private:
    const sp<android::hardware::gnss::IGnssMeasurementInterface> mIGnssMeasurement;
};

class GnssMeasurement_V1_0 : public GnssMeasurementInterface {
class GnssMeasurement_V1_0 : public GnssMeasurementInterface {
public:
public:
    GnssMeasurement_V1_0(
    GnssMeasurement_V1_0(
            const sp<android::hardware::gnss::V1_0::IGnssMeasurement>& iGnssMeasurement);
            const sp<android::hardware::gnss::V1_0::IGnssMeasurement>& iGnssMeasurement);
    jboolean setCallback(const sp<GnssMeasurementCallback>& callback,
    jboolean setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                         bool enableFullTracking) override;
                         bool enableFullTracking) override;
    jboolean close() override;
    jboolean close() override;


@@ -57,7 +69,7 @@ class GnssMeasurement_V1_1 : public GnssMeasurement_V1_0 {
public:
public:
    GnssMeasurement_V1_1(
    GnssMeasurement_V1_1(
            const sp<android::hardware::gnss::V1_1::IGnssMeasurement>& iGnssMeasurement);
            const sp<android::hardware::gnss::V1_1::IGnssMeasurement>& iGnssMeasurement);
    jboolean setCallback(const sp<GnssMeasurementCallback>& callback,
    jboolean setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                         bool enableFullTracking) override;
                         bool enableFullTracking) override;


private:
private:
@@ -68,7 +80,7 @@ class GnssMeasurement_V2_0 : public GnssMeasurement_V1_1 {
public:
public:
    GnssMeasurement_V2_0(
    GnssMeasurement_V2_0(
            const sp<android::hardware::gnss::V2_0::IGnssMeasurement>& iGnssMeasurement);
            const sp<android::hardware::gnss::V2_0::IGnssMeasurement>& iGnssMeasurement);
    jboolean setCallback(const sp<GnssMeasurementCallback>& callback,
    jboolean setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                         bool enableFullTracking) override;
                         bool enableFullTracking) override;


private:
private:
@@ -79,7 +91,7 @@ class GnssMeasurement_V2_1 : public GnssMeasurement_V2_0 {
public:
public:
    GnssMeasurement_V2_1(
    GnssMeasurement_V2_1(
            const sp<android::hardware::gnss::V2_1::IGnssMeasurement>& iGnssMeasurement);
            const sp<android::hardware::gnss::V2_1::IGnssMeasurement>& iGnssMeasurement);
    jboolean setCallback(const sp<GnssMeasurementCallback>& callback,
    jboolean setCallback(const std::unique_ptr<GnssMeasurementCallback>& callback,
                         bool enableFullTracking) override;
                         bool enableFullTracking) override;


private:
private:
+250 −149

File changed.

Preview size limit exceeded, changes collapsed.

+78 −32
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/BnGnssMeasurementCallback.h>
#include <log/log.h>
#include <log/log.h>
#include "Utils.h"
#include "Utils.h"
#include "jni.h"
#include "jni.h"
@@ -44,12 +45,36 @@ extern jmethodID method_reportMeasurementData;


void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz);
void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz);


void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock,
                        jobjectArray measurementArray);

class GnssMeasurementCallbackAidl : public hardware::gnss::BnGnssMeasurementCallback {
public:
    GnssMeasurementCallbackAidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
    android::binder::Status gnssMeasurementCb(const hardware::gnss::GnssData& data) override;

private:
    void translateSingleGnssMeasurement(JNIEnv* env,
                                        const hardware::gnss::GnssMeasurement& measurement,
                                        JavaObject& object);

    jobjectArray translateAllGnssMeasurements(
            JNIEnv* env, const std::vector<hardware::gnss::GnssMeasurement>& measurements);

    void translateAndSetGnssData(const hardware::gnss::GnssData& data);

    void translateGnssClock(JNIEnv* env, const hardware::gnss::GnssData& data, JavaObject& object);

    jobject& mCallbacksObj;
};

/*
/*
 * GnssMeasurementCallback implements the callback methods required for the
 * GnssMeasurementCallback implements the callback methods required for the
 * GnssMeasurement interface.
 * GnssMeasurement interface.
 */
 */
struct GnssMeasurementCallback : public hardware::gnss::V2_1::IGnssMeasurementCallback {
class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback {
    GnssMeasurementCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
public:
    GnssMeasurementCallbackHidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
    hardware::Return<void> gnssMeasurementCb_2_1(
    hardware::Return<void> gnssMeasurementCb_2_1(
            const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override;
            const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override;
    hardware::Return<void> gnssMeasurementCb_2_0(
    hardware::Return<void> gnssMeasurementCb_2_0(
@@ -61,7 +86,7 @@ struct GnssMeasurementCallback : public hardware::gnss::V2_1::IGnssMeasurementCa


private:
private:
    template <class T>
    template <class T>
    void translateSingleGnssMeasurement(const T* measurement, JavaObject& object);
    void translateSingleGnssMeasurement(const T& measurement, JavaObject& object);


    template <class T>
    template <class T>
    jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
    jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
@@ -73,91 +98,112 @@ private:
    size_t getMeasurementCount(const T& data);
    size_t getMeasurementCount(const T& data);


    template <class T>
    template <class T>
    void translateGnssClock(JavaObject& object, const T& data);
    void translateGnssClock(const T& data, JavaObject& object);


    void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
    jobject& mCallbacksObj;
};


class GnssMeasurementCallback {
public:
    GnssMeasurementCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
    sp<GnssMeasurementCallbackAidl> getAidl() {
        if (callbackAidl == nullptr) {
            callbackAidl = sp<GnssMeasurementCallbackAidl>::make(mCallbacksObj);
        }
        return callbackAidl;
    }

    sp<GnssMeasurementCallbackHidl> getHidl() {
        if (callbackHidl == nullptr) {
            callbackHidl = sp<GnssMeasurementCallbackHidl>::make(mCallbacksObj);
        }
        return callbackHidl;
    }

private:
    jobject& mCallbacksObj;
    jobject& mCallbacksObj;
    sp<GnssMeasurementCallbackAidl> callbackAidl;
    sp<GnssMeasurementCallbackHidl> callbackHidl;
};
};


template <class T>
template <class T>
void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
void GnssMeasurementCallbackHidl::translateAndSetGnssData(const T& data) {
    JNIEnv* env = getJniEnv();
    JNIEnv* env = getJniEnv();


    JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
    JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
    translateGnssClock(gnssClockJavaObject, data);
    translateGnssClock(data, gnssClockJavaObject);
    jobject clock = gnssClockJavaObject.get();
    jobject clock = gnssClockJavaObject.get();


    size_t count = getMeasurementCount(data);
    size_t count = getMeasurementCount(data);
    jobjectArray measurementArray =
    jobjectArray measurementArray =
            translateAllGnssMeasurements(env, data.measurements.data(), count);
            translateAllGnssMeasurements(env, data.measurements.data(), count);
    setMeasurementData(env, clock, measurementArray);
    setMeasurementData(env, mCallbacksObj, clock, measurementArray);


    env->DeleteLocalRef(clock);
    env->DeleteLocalRef(clock);
    env->DeleteLocalRef(measurementArray);
    env->DeleteLocalRef(measurementArray);
}
}


template <>
template <>
size_t GnssMeasurementCallback::getMeasurementCount<
size_t GnssMeasurementCallbackHidl::getMeasurementCount<
        hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>(
        hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>(
        const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data);
        const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data);


template <class T>
template <class T>
size_t GnssMeasurementCallback::getMeasurementCount(const T& data) {
size_t GnssMeasurementCallbackHidl::getMeasurementCount(const T& data) {
    return data.measurements.size();
    return data.measurements.size();
}
}


// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
template <>
void GnssMeasurementCallback::translateSingleGnssMeasurement<
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
        hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>(
        hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>(
        const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement* measurement,
        const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement& measurement,
        JavaObject& object);
        JavaObject& object);


// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
template <>
void GnssMeasurementCallback::translateSingleGnssMeasurement<
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
        hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>(
        hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>(
        const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement* measurement_V1_1,
        const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V1_1,
        JavaObject& object);
        JavaObject& object);


// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
template <>
void GnssMeasurementCallback::translateSingleGnssMeasurement<
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
        hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>(
        hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>(
        const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement* measurement_V2_0,
        const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_0,
        JavaObject& object);
        JavaObject& object);


// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
template <>
void GnssMeasurementCallback::translateSingleGnssMeasurement<
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
        hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>(
        hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>(
        const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement* measurement_V2_1,
        const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_1,
        JavaObject& object);
        JavaObject& object);


template <class T>
template <class T>
void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) {
void GnssMeasurementCallbackHidl::translateGnssClock(const T& data, JavaObject& object) {
    translateGnssClock(object, data.clock);
    translateGnssClock(data.clock, object);
}
}


template <>
template <>
void GnssMeasurementCallback::translateGnssClock(
void GnssMeasurementCallbackHidl::translateGnssClock(
        JavaObject& object, const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock);
        const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object);


template <>
template <>
void GnssMeasurementCallback::translateGnssClock(
void GnssMeasurementCallbackHidl::translateGnssClock(
        JavaObject& object, const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock);
        const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object);


template <>
template <>
void GnssMeasurementCallback::translateGnssClock(
void GnssMeasurementCallbackHidl::translateGnssClock(
        JavaObject& object, const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data);
        const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object);


template <>
template <>
void GnssMeasurementCallback::translateGnssClock(
void GnssMeasurementCallbackHidl::translateGnssClock(
        JavaObject& object, const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data);
        const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data, JavaObject& object);


template <class T>
template <class T>
jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,
jobjectArray GnssMeasurementCallbackHidl::translateAllGnssMeasurements(JNIEnv* env,
                                                                       const T* measurements,
                                                                       const T* measurements,
                                                                       size_t count) {
                                                                       size_t count) {
    if (count == 0) {
    if (count == 0) {
@@ -169,7 +215,7 @@ jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,


    for (uint16_t i = 0; i < count; ++i) {
    for (uint16_t i = 0; i < count; ++i) {
        JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
        JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
        translateSingleGnssMeasurement(&(measurements[i]), object);
        translateSingleGnssMeasurement(measurements[i], object);
        jobject gnssMeasurement = object.get();
        jobject gnssMeasurement = object.get();
        env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
        env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
        env->DeleteLocalRef(gnssMeasurement);
        env->DeleteLocalRef(gnssMeasurement);