diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 0ec8b3a7fee2e..066dbce89ca6e 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -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.0@IGnss is paired with 1.0@IGnssMeasurement gnssMeasurementIface = nullptr; - if (gnssHal_V2_1 != nullptr) { + if (gnssHalAidl != nullptr) { + sp gnssMeasurement; + auto status = gnssHalAidl->getExtensionGnssMeasurement(&gnssMeasurement); + if (checkAidlStatus(status, "Unable to get a handle to GnssMeasurement AIDL interface.")) { + gnssMeasurementIface = + std::make_unique(gnssMeasurement); + } + } + if (gnssHal_V2_1 != nullptr && gnssMeasurementIface == nullptr) { auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1(); if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) { gnssMeasurementIface = @@ -2696,7 +2705,8 @@ static jboolean android_location_GnssMeasurementsProvider_start_measurement_coll return JNI_FALSE; } - return gnssMeasurementIface->setCallback(sp::make(mCallbacksObj), + return gnssMeasurementIface->setCallback(std::make_unique( + mCallbacksObj), enableFullTracking); } diff --git a/services/core/jni/gnss/GnssMeasurement.cpp b/services/core/jni/gnss/GnssMeasurement.cpp index efa8ce7402237..2261c38fb185b 100644 --- a/services/core/jni/gnss/GnssMeasurement.cpp +++ b/services/core/jni/gnss/GnssMeasurement.cpp @@ -23,6 +23,7 @@ using android::hardware::hidl_vec; using android::hardware::Return; +using IGnssMeasurementInterface = android::hardware::gnss::IGnssMeasurementInterface; using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement; using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::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 { +// Implementation of GnssMeasurement + +GnssMeasurement::GnssMeasurement(const sp& iGnssMeasurement) + : mIGnssMeasurement(iGnssMeasurement) {} + +jboolean GnssMeasurement::setCallback(const std::unique_ptr& 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 GnssMeasurement_V1_0::GnssMeasurement_V1_0(const sp& iGnssMeasurement) : mIGnssMeasurement_V1_0(iGnssMeasurement) {} -jboolean GnssMeasurement_V1_0::setCallback(const sp& callback, +jboolean GnssMeasurement_V1_0::setCallback(const std::unique_ptr& callback, bool enableFullTracking) { if (enableFullTracking == true) { 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.")) { return JNI_FALSE; } @@ -71,9 +88,9 @@ jboolean GnssMeasurement_V1_0::close() { GnssMeasurement_V1_1::GnssMeasurement_V1_1(const sp& iGnssMeasurement) : GnssMeasurement_V1_0{iGnssMeasurement}, mIGnssMeasurement_V1_1(iGnssMeasurement) {} -jboolean GnssMeasurement_V1_1::setCallback(const sp& callback, +jboolean GnssMeasurement_V1_1::setCallback(const std::unique_ptr& callback, 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.")) { return JNI_FALSE; } @@ -86,9 +103,9 @@ jboolean GnssMeasurement_V1_1::setCallback(const sp& ca GnssMeasurement_V2_0::GnssMeasurement_V2_0(const sp& iGnssMeasurement) : GnssMeasurement_V1_1{iGnssMeasurement}, mIGnssMeasurement_V2_0(iGnssMeasurement) {} -jboolean GnssMeasurement_V2_0::setCallback(const sp& callback, +jboolean GnssMeasurement_V2_0::setCallback(const std::unique_ptr& callback, 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.")) { return JNI_FALSE; } @@ -101,9 +118,9 @@ jboolean GnssMeasurement_V2_0::setCallback(const sp& ca GnssMeasurement_V2_1::GnssMeasurement_V2_1(const sp& iGnssMeasurement) : GnssMeasurement_V2_0{iGnssMeasurement}, mIGnssMeasurement_V2_1(iGnssMeasurement) {} -jboolean GnssMeasurement_V2_1::setCallback(const sp& callback, +jboolean GnssMeasurement_V2_1::setCallback(const std::unique_ptr& callback, 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.")) { return JNI_FALSE; } diff --git a/services/core/jni/gnss/GnssMeasurement.h b/services/core/jni/gnss/GnssMeasurement.h index 0e41abb304436..e64336fb67ac7 100644 --- a/services/core/jni/gnss/GnssMeasurement.h +++ b/services/core/jni/gnss/GnssMeasurement.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "GnssMeasurementCallback.h" #include "jni.h" @@ -36,16 +37,27 @@ namespace android::gnss { class GnssMeasurementInterface { public: virtual ~GnssMeasurementInterface() {} - virtual jboolean setCallback(const sp& callback, + virtual jboolean setCallback(const std::unique_ptr& callback, bool enableFullTracking) = 0; virtual jboolean close() = 0; }; +class GnssMeasurement : public GnssMeasurementInterface { +public: + GnssMeasurement(const sp& iGnssMeasurement); + jboolean setCallback(const std::unique_ptr& callback, + bool enableFullTracking) override; + jboolean close() override; + +private: + const sp mIGnssMeasurement; +}; + class GnssMeasurement_V1_0 : public GnssMeasurementInterface { public: GnssMeasurement_V1_0( const sp& iGnssMeasurement); - jboolean setCallback(const sp& callback, + jboolean setCallback(const std::unique_ptr& callback, bool enableFullTracking) override; jboolean close() override; @@ -57,7 +69,7 @@ class GnssMeasurement_V1_1 : public GnssMeasurement_V1_0 { public: GnssMeasurement_V1_1( const sp& iGnssMeasurement); - jboolean setCallback(const sp& callback, + jboolean setCallback(const std::unique_ptr& callback, bool enableFullTracking) override; private: @@ -68,7 +80,7 @@ class GnssMeasurement_V2_0 : public GnssMeasurement_V1_1 { public: GnssMeasurement_V2_0( const sp& iGnssMeasurement); - jboolean setCallback(const sp& callback, + jboolean setCallback(const std::unique_ptr& callback, bool enableFullTracking) override; private: @@ -79,7 +91,7 @@ class GnssMeasurement_V2_1 : public GnssMeasurement_V2_0 { public: GnssMeasurement_V2_1( const sp& iGnssMeasurement); - jboolean setCallback(const sp& callback, + jboolean setCallback(const std::unique_ptr& callback, bool enableFullTracking) override; private: diff --git a/services/core/jni/gnss/GnssMeasurementCallback.cpp b/services/core/jni/gnss/GnssMeasurementCallback.cpp index 9f1826cc2290c..bb020f30f27a8 100644 --- a/services/core/jni/gnss/GnssMeasurementCallback.cpp +++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp @@ -20,6 +20,12 @@ namespace android::gnss { +using binder::Status; +using hardware::gnss::ElapsedRealtime; +using hardware::gnss::GnssClock; +using hardware::gnss::GnssData; +using hardware::gnss::GnssMeasurement; + jclass class_gnssMeasurementsEvent; jclass class_gnssMeasurement; jclass class_gnssClock; @@ -47,174 +53,98 @@ void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz) { method_gnssClockCtor = env->GetMethodID(class_gnssClock, "", "()V"); } -hardware::Return GnssMeasurementCallback::gnssMeasurementCb_2_1( - const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) { - translateAndSetGnssData(data); - return hardware::Void(); +void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock, + jobjectArray measurementArray) { + jobject gnssMeasurementsEvent = + env->NewObject(class_gnssMeasurementsEvent, method_gnssMeasurementsEventCtor, clock, + measurementArray); + + env->CallVoidMethod(callbacksObj, method_reportMeasurementData, gnssMeasurementsEvent); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(gnssMeasurementsEvent); } -hardware::Return GnssMeasurementCallback::gnssMeasurementCb_2_0( - const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) { - translateAndSetGnssData(data); - return hardware::Void(); -} +template +void setMeasurementFields_V1_0(const T_Measurement& measurement, JavaObject& object) { + uint32_t flags = static_cast(measurement.flags); -hardware::Return GnssMeasurementCallback::gnssMeasurementCb( - const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) { - translateAndSetGnssData(data); - return hardware::Void(); -} - -hardware::Return GnssMeasurementCallback::GnssMeasurementCb( - const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) { - translateAndSetGnssData(data); - return hardware::Void(); -} - -template <> -size_t GnssMeasurementCallback::getMeasurementCount< - hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>( - const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) { - return data.measurementCount; -} - -// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); -template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< - hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>( - const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement* measurement, - JavaObject& object) { - uint32_t flags = static_cast(measurement->flags); - - SET(Svid, static_cast(measurement->svid)); - SET(ConstellationType, static_cast(measurement->constellation)); - SET(TimeOffsetNanos, measurement->timeOffsetNs); - SET(State, static_cast(measurement->state)); - SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs); - SET(ReceivedSvTimeUncertaintyNanos, measurement->receivedSvTimeUncertaintyInNs); - SET(Cn0DbHz, measurement->cN0DbHz); - SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps); - SET(PseudorangeRateUncertaintyMetersPerSecond, measurement->pseudorangeRateUncertaintyMps); + SET(Svid, static_cast(measurement.svid)); + SET(TimeOffsetNanos, measurement.timeOffsetNs); + SET(State, static_cast(measurement.state)); + SET(ReceivedSvTimeNanos, measurement.receivedSvTimeInNs); + SET(ReceivedSvTimeUncertaintyNanos, measurement.receivedSvTimeUncertaintyInNs); + SET(PseudorangeRateMetersPerSecond, measurement.pseudorangeRateMps); + SET(PseudorangeRateUncertaintyMetersPerSecond, measurement.pseudorangeRateUncertaintyMps); SET(AccumulatedDeltaRangeState, - (static_cast(measurement->accumulatedDeltaRangeState) & + (static_cast(measurement.accumulatedDeltaRangeState) & ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0 - SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM); - SET(AccumulatedDeltaRangeUncertaintyMeters, measurement->accumulatedDeltaRangeUncertaintyM); - - if (flags & static_cast(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) { - SET(CarrierFrequencyHz, measurement->carrierFrequencyHz); - } + SET(AccumulatedDeltaRangeMeters, measurement.accumulatedDeltaRangeM); + SET(AccumulatedDeltaRangeUncertaintyMeters, measurement.accumulatedDeltaRangeUncertaintyM); // Intentionally not copying deprecated fields of carrierCycles, // carrierPhase, carrierPhaseUncertainty - SET(MultipathIndicator, static_cast(measurement->multipathIndicator)); + SET(MultipathIndicator, static_cast(measurement.multipathIndicator)); - if (flags & static_cast(GnssMeasurementFlags::HAS_SNR)) { - SET(SnrInDb, measurement->snrDb); + if (flags & static_cast(T_Flags::HAS_SNR)) { + SET(SnrInDb, measurement.snrDb); } - if (flags & static_cast(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) { - SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb); + if (flags & static_cast(T_Flags::HAS_AUTOMATIC_GAIN_CONTROL)) { + SET(AutomaticGainControlLevelInDb, measurement.agcLevelDb); } } -// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); -template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< - hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>( - const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement* measurement_V1_1, - JavaObject& object) { - translateSingleGnssMeasurement(&(measurement_V1_1->v1_0), object); +template +void setMeasurementFields_V2_1(const T_Measurement& measurement, JavaObject& object) { + SET(BasebandCn0DbHz, measurement.basebandCN0DbHz); - // Set the V1_1 flag, and mark that new field has valid information for Java Layer - SET(AccumulatedDeltaRangeState, - (static_cast(measurement_V1_1->accumulatedDeltaRangeState) | - ADR_STATE_HALF_CYCLE_REPORTED)); -} - -// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); -template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< - hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>( - const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement* measurement_V2_0, - JavaObject& object) { - JNIEnv* env = getJniEnv(); - translateSingleGnssMeasurement(&(measurement_V2_0->v1_1), object); - - jstring codeType = env->NewStringUTF(measurement_V2_0->codeType.c_str()); - SET(CodeType, codeType); - - // Overwrite with v2_0.state since v2_0->v1_1->v1_0.state is deprecated. - SET(State, static_cast(measurement_V2_0->state)); - - // Overwrite with v2_0.constellation since v2_0->v1_1->v1_0.constellation is deprecated. - SET(ConstellationType, static_cast(measurement_V2_0->constellation)); - - if (codeType) { - env->DeleteLocalRef(codeType); - } -} - -// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); -template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< - hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>( - const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement* measurement_V2_1, - JavaObject& object) { - translateSingleGnssMeasurement(&(measurement_V2_1->v2_0), object); - - SET(BasebandCn0DbHz, measurement_V2_1->basebandCN0DbHz); - - if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_FULL_ISB) { - SET(FullInterSignalBiasNanos, measurement_V2_1->fullInterSignalBiasNs); + if (measurement.flags & T_Flags::HAS_FULL_ISB) { + SET(FullInterSignalBiasNanos, measurement.fullInterSignalBiasNs); } - if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_FULL_ISB_UNCERTAINTY) { - SET(FullInterSignalBiasUncertaintyNanos, - measurement_V2_1->fullInterSignalBiasUncertaintyNs); + if (measurement.flags & T_Flags::HAS_FULL_ISB_UNCERTAINTY) { + SET(FullInterSignalBiasUncertaintyNanos, measurement.fullInterSignalBiasUncertaintyNs); } - if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB) { - SET(SatelliteInterSignalBiasNanos, measurement_V2_1->satelliteInterSignalBiasNs); + if (measurement.flags & T_Flags::HAS_SATELLITE_ISB) { + SET(SatelliteInterSignalBiasNanos, measurement.satelliteInterSignalBiasNs); } - if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB_UNCERTAINTY) { + if (measurement.flags & T_Flags::HAS_SATELLITE_ISB_UNCERTAINTY) { SET(SatelliteInterSignalBiasUncertaintyNanos, - measurement_V2_1->satelliteInterSignalBiasUncertaintyNs); + measurement.satelliteInterSignalBiasUncertaintyNs); } } -template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, - const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock) { +template +void setClockFields_V1_0(const T_Clock& clock, JavaObject& object) { uint32_t flags = static_cast(clock.gnssClockFlags); - if (flags & static_cast(GnssClockFlags::HAS_LEAP_SECOND)) { + if (flags & static_cast(T_Flags::HAS_LEAP_SECOND)) { SET(LeapSecond, static_cast(clock.leapSecond)); } - if (flags & static_cast(GnssClockFlags::HAS_TIME_UNCERTAINTY)) { + if (flags & static_cast(T_Flags::HAS_TIME_UNCERTAINTY)) { SET(TimeUncertaintyNanos, clock.timeUncertaintyNs); } - if (flags & static_cast(GnssClockFlags::HAS_FULL_BIAS)) { + if (flags & static_cast(T_Flags::HAS_FULL_BIAS)) { SET(FullBiasNanos, clock.fullBiasNs); } - if (flags & static_cast(GnssClockFlags::HAS_BIAS)) { + if (flags & static_cast(T_Flags::HAS_BIAS)) { SET(BiasNanos, clock.biasNs); } - if (flags & static_cast(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) { + if (flags & static_cast(T_Flags::HAS_BIAS_UNCERTAINTY)) { SET(BiasUncertaintyNanos, clock.biasUncertaintyNs); } - if (flags & static_cast(GnssClockFlags::HAS_DRIFT)) { + if (flags & static_cast(T_Flags::HAS_DRIFT)) { SET(DriftNanosPerSecond, clock.driftNsps); } - if (flags & static_cast(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) { + if (flags & static_cast(T_Flags::HAS_DRIFT_UNCERTAINTY)) { SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps); } @@ -222,10 +152,8 @@ void GnssMeasurementCallback::translateGnssClock( SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount); } -template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, - const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock) { +template +void setClockFields_V2_1(const T_Clock& clock, JavaObject& object) { JNIEnv* env = getJniEnv(); SET(ReferenceConstellationTypeForIsb, static_cast(clock.referenceSignalTypeForIsb.constellation)); @@ -234,17 +162,216 @@ void GnssMeasurementCallback::translateGnssClock( jstring referenceCodeTypeForIsb = env->NewStringUTF(clock.referenceSignalTypeForIsb.codeType.c_str()); SET(ReferenceCodeTypeForIsb, referenceCodeTypeForIsb); + env->DeleteLocalRef(referenceCodeTypeForIsb); +} - translateGnssClock(object, clock.v1_0); - - if (referenceCodeTypeForIsb) { - env->DeleteLocalRef(referenceCodeTypeForIsb); +template +void setElapsedRealtimeFields(const T_ElapsedRealtime& elapsedRealtime, JavaObject& object) { + uint32_t flags = static_cast(elapsedRealtime.flags); + if (flags & T_Flags::HAS_TIMESTAMP_NS) { + SET(ElapsedRealtimeNanos, static_cast(elapsedRealtime.timestampNs)); + } + if (flags & T_Flags::HAS_TIME_UNCERTAINTY_NS) { + SET(ElapsedRealtimeUncertaintyNanos, + static_cast(elapsedRealtime.timeUncertaintyNs)); } } +// Implementation of GnssMeasurementCallbackAidl class. + +Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& data) { + ALOGD("%s", __func__); + translateAndSetGnssData(data); + return Status::ok(); +} + +void GnssMeasurementCallbackAidl::translateAndSetGnssData(const GnssData& data) { + JNIEnv* env = getJniEnv(); + + JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor); + translateGnssClock(env, data, gnssClockJavaObject); + jobject clock = gnssClockJavaObject.get(); + + jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements); + setMeasurementData(env, mCallbacksObj, clock, measurementArray); + + env->DeleteLocalRef(clock); + env->DeleteLocalRef(measurementArray); +} + +void GnssMeasurementCallbackAidl::translateSingleGnssMeasurement(JNIEnv* env, + const GnssMeasurement& measurement, + JavaObject& object) { + setMeasurementFields_V1_0(measurement, object); + setMeasurementFields_V2_1(measurement, object); + + SET(Cn0DbHz, measurement.antennaCN0DbHz); + SET(ConstellationType, static_cast(measurement.signalType.constellation)); + + if (measurement.flags & static_cast(GnssMeasurement::HAS_CARRIER_FREQUENCY)) { + SET(CarrierFrequencyHz, static_cast(measurement.signalType.carrierFrequencyHz)); + } + + jstring codeType = env->NewStringUTF(measurement.signalType.codeType.c_str()); + SET(CodeType, codeType); + env->DeleteLocalRef(codeType); +} + +jobjectArray GnssMeasurementCallbackAidl::translateAllGnssMeasurements( + JNIEnv* env, const std::vector& measurements) { + if (measurements.size() == 0) { + return nullptr; + } + + jobjectArray gnssMeasurementArray = + env->NewObjectArray(measurements.size(), class_gnssMeasurement, + nullptr /* initialElement */); + + for (uint16_t i = 0; i < measurements.size(); ++i) { + JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor); + translateSingleGnssMeasurement(env, measurements[i], object); + jobject gnssMeasurement = object.get(); + env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement); + env->DeleteLocalRef(gnssMeasurement); + } + + return gnssMeasurementArray; +} + +void GnssMeasurementCallbackAidl::translateGnssClock(JNIEnv* env, const GnssData& data, + JavaObject& object) { + setElapsedRealtimeFields(data.elapsedRealtime, object); + setClockFields_V1_0(data.clock, object); + setClockFields_V2_1(data.clock, object); +} + +// Implementation of GnssMeasurementCallbackHidl class. + +hardware::Return GnssMeasurementCallbackHidl::gnssMeasurementCb_2_1( + const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) { + translateAndSetGnssData(data); + return hardware::Void(); +} + +hardware::Return GnssMeasurementCallbackHidl::gnssMeasurementCb_2_0( + const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) { + translateAndSetGnssData(data); + return hardware::Void(); +} + +hardware::Return GnssMeasurementCallbackHidl::gnssMeasurementCb( + const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) { + translateAndSetGnssData(data); + return hardware::Void(); +} + +hardware::Return GnssMeasurementCallbackHidl::GnssMeasurementCb( + const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) { + translateAndSetGnssData(data); + return hardware::Void(); +} + template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) { +size_t GnssMeasurementCallbackHidl::getMeasurementCount< + hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>( + const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) { + return data.measurementCount; +} + +// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); +template <> +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< + hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>( + const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement& measurement, + JavaObject& object) { + setMeasurementFields_V1_0(measurement, object); + + SET(ConstellationType, static_cast(measurement.constellation)); + SET(Cn0DbHz, measurement.cN0DbHz); + if (measurement.flags & static_cast(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) { + SET(CarrierFrequencyHz, measurement.carrierFrequencyHz); + } +} + +// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); +template <> +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< + hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>( + const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V1_1, + JavaObject& object) { + translateSingleGnssMeasurement(measurement_V1_1.v1_0, object); + + // Set the V1_1 flag, and mark that new field has valid information for Java Layer + SET(AccumulatedDeltaRangeState, + (static_cast(measurement_V1_1.accumulatedDeltaRangeState) | + ADR_STATE_HALF_CYCLE_REPORTED)); +} + +// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); +template <> +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< + hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>( + const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_0, + JavaObject& object) { + JNIEnv* env = getJniEnv(); + translateSingleGnssMeasurement(measurement_V2_0.v1_1, object); + + jstring codeType = env->NewStringUTF(measurement_V2_0.codeType.c_str()); + SET(CodeType, codeType); + + // Overwrite with v2_0.state since V2_0.v1_1.v1_0.state is deprecated. + SET(State, static_cast(measurement_V2_0.state)); + + // Overwrite with v2_0.constellation since V2_0.v1_1.v1_0.constellation is deprecated. + SET(ConstellationType, static_cast(measurement_V2_0.constellation)); + + if (codeType) { + env->DeleteLocalRef(codeType); + } +} + +// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); +template <> +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< + hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>( + const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_1, + JavaObject& object) { + translateSingleGnssMeasurement(measurement_V2_1.v2_0, object); + + setMeasurementFields_V2_1(measurement_V2_1, object); +} + +template <> +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock, + JavaObject& object) { + setClockFields_V1_0(clock, object); +} + +template <> +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock, + JavaObject& object) { + setClockFields_V2_1(clock, object); + translateGnssClock(clock.v1_0, object); +} + +template <> +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object) { + setElapsedRealtimeFields(data.elapsedRealtime, + object); + translateGnssClock(data.clock, object); +} + +template <> +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data, JavaObject& object) { auto elapsedRealtime = data.elapsedRealtime; uint16_t flags = static_cast(elapsedRealtime.flags); if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) { @@ -254,33 +381,7 @@ void GnssMeasurementCallback::translateGnssClock( SET(ElapsedRealtimeUncertaintyNanos, static_cast(elapsedRealtime.timeUncertaintyNs)); } - translateGnssClock(object, data.clock); -} - -template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) { - auto elapsedRealtime = data.elapsedRealtime; - uint16_t flags = static_cast(elapsedRealtime.flags); - if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) { - SET(ElapsedRealtimeNanos, static_cast(elapsedRealtime.timestampNs)); - } - if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) { - SET(ElapsedRealtimeUncertaintyNanos, - static_cast(elapsedRealtime.timeUncertaintyNs)); - } - translateGnssClock(object, data.clock); -} - -void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock, - jobjectArray measurementArray) { - jobject gnssMeasurementsEvent = - env->NewObject(class_gnssMeasurementsEvent, method_gnssMeasurementsEventCtor, clock, - measurementArray); - - env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, gnssMeasurementsEvent); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(gnssMeasurementsEvent); + translateGnssClock(data.clock, object); } } // namespace android::gnss diff --git a/services/core/jni/gnss/GnssMeasurementCallback.h b/services/core/jni/gnss/GnssMeasurementCallback.h index 71c33a7e7dbb7..26f12437a2175 100644 --- a/services/core/jni/gnss/GnssMeasurementCallback.h +++ b/services/core/jni/gnss/GnssMeasurementCallback.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "Utils.h" #include "jni.h" @@ -44,12 +45,36 @@ extern jmethodID method_reportMeasurementData; 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& 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 * GnssMeasurement interface. */ -struct GnssMeasurementCallback : public hardware::gnss::V2_1::IGnssMeasurementCallback { - GnssMeasurementCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {} +class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback { +public: + GnssMeasurementCallbackHidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {} hardware::Return gnssMeasurementCb_2_1( const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override; hardware::Return gnssMeasurementCb_2_0( @@ -61,7 +86,7 @@ struct GnssMeasurementCallback : public hardware::gnss::V2_1::IGnssMeasurementCa private: template - void translateSingleGnssMeasurement(const T* measurement, JavaObject& object); + void translateSingleGnssMeasurement(const T& measurement, JavaObject& object); template jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count); @@ -73,93 +98,114 @@ private: size_t getMeasurementCount(const T& data); template - void translateGnssClock(JavaObject& object, const T& data); - - void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray); + void translateGnssClock(const T& data, JavaObject& object); jobject& mCallbacksObj; }; +class GnssMeasurementCallback { +public: + GnssMeasurementCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {} + sp getAidl() { + if (callbackAidl == nullptr) { + callbackAidl = sp::make(mCallbacksObj); + } + return callbackAidl; + } + + sp getHidl() { + if (callbackHidl == nullptr) { + callbackHidl = sp::make(mCallbacksObj); + } + return callbackHidl; + } + +private: + jobject& mCallbacksObj; + sp callbackAidl; + sp callbackHidl; +}; + template -void GnssMeasurementCallback::translateAndSetGnssData(const T& data) { +void GnssMeasurementCallbackHidl::translateAndSetGnssData(const T& data) { JNIEnv* env = getJniEnv(); JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor); - translateGnssClock(gnssClockJavaObject, data); + translateGnssClock(data, gnssClockJavaObject); jobject clock = gnssClockJavaObject.get(); size_t count = getMeasurementCount(data); jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count); - setMeasurementData(env, clock, measurementArray); + setMeasurementData(env, mCallbacksObj, clock, measurementArray); env->DeleteLocalRef(clock); env->DeleteLocalRef(measurementArray); } template <> -size_t GnssMeasurementCallback::getMeasurementCount< +size_t GnssMeasurementCallbackHidl::getMeasurementCount< hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>( const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data); template -size_t GnssMeasurementCallback::getMeasurementCount(const T& data) { +size_t GnssMeasurementCallbackHidl::getMeasurementCount(const T& data) { return data.measurements.size(); } // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>( - const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement* measurement, + const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement& measurement, JavaObject& object); // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< 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); // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< 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); // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement"); template <> -void GnssMeasurementCallback::translateSingleGnssMeasurement< +void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement< 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); template -void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) { - translateGnssClock(object, data.clock); +void GnssMeasurementCallbackHidl::translateGnssClock(const T& data, JavaObject& object) { + translateGnssClock(data.clock, object); } template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock); +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object); template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock); +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object); template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data); +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object); template <> -void GnssMeasurementCallback::translateGnssClock( - JavaObject& object, const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data); +void GnssMeasurementCallbackHidl::translateGnssClock( + const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data, JavaObject& object); template -jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env, - const T* measurements, - size_t count) { +jobjectArray GnssMeasurementCallbackHidl::translateAllGnssMeasurements(JNIEnv* env, + const T* measurements, + size_t count) { if (count == 0) { return nullptr; } @@ -169,7 +215,7 @@ jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env, for (uint16_t i = 0; i < count; ++i) { JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor); - translateSingleGnssMeasurement(&(measurements[i]), object); + translateSingleGnssMeasurement(measurements[i], object); jobject gnssMeasurement = object.get(); env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement); env->DeleteLocalRef(gnssMeasurement);