blob: 2982546bfa470dd3d7c22906bb2deac1f8d4d4a1 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "GnssMeasCbJni"
#include "GnssMeasurementCallback.h"
namespace android::gnss {
using binder::Status;
using hardware::gnss::CorrelationVector;
using hardware::gnss::ElapsedRealtime;
using hardware::gnss::GnssClock;
using hardware::gnss::GnssData;
using hardware::gnss::GnssMeasurement;
using hardware::gnss::SatellitePvt;
using GnssAgc = hardware::gnss::GnssData::GnssAgc;
namespace {
jclass class_arrayList;
jclass class_clockInfo;
jclass class_correlationVectorBuilder;
jclass class_gnssAgc;
jclass class_gnssAgcBuilder;
jclass class_gnssMeasurementsEvent;
jclass class_gnssMeasurementsEventBuilder;
jclass class_gnssMeasurement;
jclass class_gnssClock;
jclass class_positionEcef;
jclass class_satellitePvtBuilder;
jclass class_velocityEcef;
jmethodID method_arrayListAdd;
jmethodID method_arrayListCtor;
jmethodID method_correlationVectorBuilderBuild;
jmethodID method_correlationVectorBuilderCtor;
jmethodID method_correlationVectorBuilderSetFrequencyOffsetMetersPerSecond;
jmethodID method_correlationVectorBuilderSetMagnitude;
jmethodID method_correlationVectorBuilderSetSamplingStartMeters;
jmethodID method_correlationVectorBuilderSetSamplingWidthMeters;
jmethodID method_gnssAgcBuilderCtor;
jmethodID method_gnssAgcBuilderSetLevelDb;
jmethodID method_gnssAgcBuilderSetConstellationType;
jmethodID method_gnssAgcBuilderSetCarrierFrequencyHz;
jmethodID method_gnssAgcBuilderBuild;
jmethodID method_gnssMeasurementsEventBuilderCtor;
jmethodID method_gnssMeasurementsEventBuilderSetClock;
jmethodID method_gnssMeasurementsEventBuilderSetIsFullTracking;
jmethodID method_gnssMeasurementsEventBuilderSetMeasurements;
jmethodID method_gnssMeasurementsEventBuilderSetGnssAutomaticGainControls;
jmethodID method_gnssMeasurementsEventBuilderBuild;
jmethodID method_gnssMeasurementsSetCorrelationVectors;
jmethodID method_gnssMeasurementsSetSatellitePvt;
jmethodID method_gnssClockCtor;
jmethodID method_gnssMeasurementCtor;
jmethodID method_reportMeasurementData;
jmethodID method_satellitePvtBuilderBuild;
jmethodID method_satellitePvtBuilderCtor;
jmethodID method_satellitePvtBuilderSetPositionEcef;
jmethodID method_satellitePvtBuilderSetVelocityEcef;
jmethodID method_satellitePvtBuilderSetClockInfo;
jmethodID method_satellitePvtBuilderSetIonoDelayMeters;
jmethodID method_satellitePvtBuilderSetTropoDelayMeters;
jmethodID method_satellitePvtBuilderSetTimeOfClock;
jmethodID method_satellitePvtBuilderSetTimeOfEphemeris;
jmethodID method_satellitePvtBuilderSetIssueOfDataClock;
jmethodID method_satellitePvtBuilderSetIssueOfDataEphemeris;
jmethodID method_satellitePvtBuilderSetEphemerisSource;
jmethodID method_positionEcef;
jmethodID method_velocityEcef;
jmethodID method_clockInfo;
} // anonymous namespace
void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz) {
method_reportMeasurementData = env->GetMethodID(clazz, "reportMeasurementData",
"(Landroid/location/GnssMeasurementsEvent;)V");
// Initialize GnssMeasurement related classes and methods
jclass gnssMeasurementsEventClass = env->FindClass("android/location/GnssMeasurementsEvent");
class_gnssMeasurementsEvent = (jclass)env->NewGlobalRef(gnssMeasurementsEventClass);
jclass gnssMeasurementsEventBuilderClass =
env->FindClass("android/location/GnssMeasurementsEvent$Builder");
class_gnssMeasurementsEventBuilder =
(jclass)env->NewGlobalRef(gnssMeasurementsEventBuilderClass);
method_gnssMeasurementsEventBuilderCtor =
env->GetMethodID(class_gnssMeasurementsEventBuilder, "<init>", "()V");
method_gnssMeasurementsEventBuilderSetClock =
env->GetMethodID(class_gnssMeasurementsEventBuilder, "setClock",
"(Landroid/location/GnssClock;)"
"Landroid/location/GnssMeasurementsEvent$Builder;");
method_gnssMeasurementsEventBuilderSetMeasurements =
env->GetMethodID(class_gnssMeasurementsEventBuilder, "setMeasurements",
"([Landroid/location/GnssMeasurement;)"
"Landroid/location/GnssMeasurementsEvent$Builder;");
method_gnssMeasurementsEventBuilderSetGnssAutomaticGainControls =
env->GetMethodID(class_gnssMeasurementsEventBuilder, "setGnssAutomaticGainControls",
"([Landroid/location/GnssAutomaticGainControl;)"
"Landroid/location/GnssMeasurementsEvent$Builder;");
method_gnssMeasurementsEventBuilderSetIsFullTracking =
env->GetMethodID(class_gnssMeasurementsEventBuilder, "setIsFullTracking",
"(Z)"
"Landroid/location/GnssMeasurementsEvent$Builder;");
method_gnssMeasurementsEventBuilderBuild =
env->GetMethodID(class_gnssMeasurementsEventBuilder, "build",
"()Landroid/location/GnssMeasurementsEvent;");
// Initialize GnssAgc related classes and methods
jclass gnssAgcClass = env->FindClass("android/location/GnssAutomaticGainControl");
class_gnssAgc = (jclass)env->NewGlobalRef(gnssAgcClass);
jclass gnssAgcBuilderClass =
env->FindClass("android/location/GnssAutomaticGainControl$Builder");
class_gnssAgcBuilder = (jclass)env->NewGlobalRef(gnssAgcBuilderClass);
method_gnssAgcBuilderCtor = env->GetMethodID(class_gnssAgcBuilder, "<init>", "()V");
method_gnssAgcBuilderSetLevelDb =
env->GetMethodID(class_gnssAgcBuilder, "setLevelDb",
"(D)"
"Landroid/location/GnssAutomaticGainControl$Builder;");
method_gnssAgcBuilderSetConstellationType =
env->GetMethodID(class_gnssAgcBuilder, "setConstellationType",
"(I)"
"Landroid/location/GnssAutomaticGainControl$Builder;");
method_gnssAgcBuilderSetCarrierFrequencyHz =
env->GetMethodID(class_gnssAgcBuilder, "setCarrierFrequencyHz",
"(J)"
"Landroid/location/GnssAutomaticGainControl$Builder;");
method_gnssAgcBuilderBuild = env->GetMethodID(class_gnssAgcBuilder, "build",
"()Landroid/location/GnssAutomaticGainControl;");
// Initialize GnssMeasurement related classes and methods
jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
class_gnssMeasurement = (jclass)env->NewGlobalRef(gnssMeasurementClass);
method_gnssMeasurementCtor = env->GetMethodID(class_gnssMeasurement, "<init>", "()V");
method_gnssMeasurementsSetSatellitePvt =
env->GetMethodID(class_gnssMeasurement, "setSatellitePvt",
"(Landroid/location/SatellitePvt;)V");
method_gnssMeasurementsSetCorrelationVectors =
env->GetMethodID(class_gnssMeasurement, "setCorrelationVectors",
"(Ljava/util/Collection;)V");
jclass gnssClockClass = env->FindClass("android/location/GnssClock");
class_gnssClock = (jclass)env->NewGlobalRef(gnssClockClass);
method_gnssClockCtor = env->GetMethodID(class_gnssClock, "<init>", "()V");
jclass satellitePvtBuilder = env->FindClass("android/location/SatellitePvt$Builder");
class_satellitePvtBuilder = (jclass)env->NewGlobalRef(satellitePvtBuilder);
method_satellitePvtBuilderCtor = env->GetMethodID(class_satellitePvtBuilder, "<init>", "()V");
method_satellitePvtBuilderSetPositionEcef =
env->GetMethodID(class_satellitePvtBuilder, "setPositionEcef",
"(Landroid/location/SatellitePvt$PositionEcef;)"
"Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetVelocityEcef =
env->GetMethodID(class_satellitePvtBuilder, "setVelocityEcef",
"(Landroid/location/SatellitePvt$VelocityEcef;)"
"Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetClockInfo =
env->GetMethodID(class_satellitePvtBuilder, "setClockInfo",
"(Landroid/location/SatellitePvt$ClockInfo;)"
"Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetIonoDelayMeters =
env->GetMethodID(class_satellitePvtBuilder, "setIonoDelayMeters",
"(D)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetTropoDelayMeters =
env->GetMethodID(class_satellitePvtBuilder, "setTropoDelayMeters",
"(D)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetTimeOfClock =
env->GetMethodID(class_satellitePvtBuilder, "setTimeOfClockSeconds",
"(J)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetTimeOfEphemeris =
env->GetMethodID(class_satellitePvtBuilder, "setTimeOfEphemerisSeconds",
"(J)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetIssueOfDataClock =
env->GetMethodID(class_satellitePvtBuilder, "setIssueOfDataClock",
"(I)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetIssueOfDataEphemeris =
env->GetMethodID(class_satellitePvtBuilder, "setIssueOfDataEphemeris",
"(I)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetEphemerisSource =
env->GetMethodID(class_satellitePvtBuilder, "setEphemerisSource",
"(I)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderBuild = env->GetMethodID(class_satellitePvtBuilder, "build",
"()Landroid/location/SatellitePvt;");
jclass positionEcefClass = env->FindClass("android/location/SatellitePvt$PositionEcef");
class_positionEcef = (jclass)env->NewGlobalRef(positionEcefClass);
method_positionEcef = env->GetMethodID(class_positionEcef, "<init>", "(DDDD)V");
jclass velocityEcefClass = env->FindClass("android/location/SatellitePvt$VelocityEcef");
class_velocityEcef = (jclass)env->NewGlobalRef(velocityEcefClass);
method_velocityEcef = env->GetMethodID(class_velocityEcef, "<init>", "(DDDD)V");
jclass clockInfoClass = env->FindClass("android/location/SatellitePvt$ClockInfo");
class_clockInfo = (jclass)env->NewGlobalRef(clockInfoClass);
method_clockInfo = env->GetMethodID(class_clockInfo, "<init>", "(DDD)V");
jclass correlationVectorBuilder = env->FindClass("android/location/CorrelationVector$Builder");
class_correlationVectorBuilder = (jclass)env->NewGlobalRef(correlationVectorBuilder);
method_correlationVectorBuilderCtor =
env->GetMethodID(class_correlationVectorBuilder, "<init>", "()V");
method_correlationVectorBuilderSetMagnitude =
env->GetMethodID(class_correlationVectorBuilder, "setMagnitude",
"([I)Landroid/location/CorrelationVector$Builder;");
method_correlationVectorBuilderSetFrequencyOffsetMetersPerSecond =
env->GetMethodID(class_correlationVectorBuilder, "setFrequencyOffsetMetersPerSecond",
"(D)Landroid/location/CorrelationVector$Builder;");
method_correlationVectorBuilderSetSamplingStartMeters =
env->GetMethodID(class_correlationVectorBuilder, "setSamplingStartMeters",
"(D)Landroid/location/CorrelationVector$Builder;");
method_correlationVectorBuilderSetSamplingWidthMeters =
env->GetMethodID(class_correlationVectorBuilder, "setSamplingWidthMeters",
"(D)Landroid/location/CorrelationVector$Builder;");
method_correlationVectorBuilderBuild =
env->GetMethodID(class_correlationVectorBuilder, "build",
"()Landroid/location/CorrelationVector;");
jclass arrayListClass = env->FindClass("java/util/ArrayList");
class_arrayList = (jclass)env->NewGlobalRef(arrayListClass);
method_arrayListCtor = env->GetMethodID(class_arrayList, "<init>", "()V");
method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z");
}
void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock,
jobjectArray measurementArray, jobjectArray gnssAgcArray,
bool hasIsFullTracking, jboolean isFullTracking) {
jobject gnssMeasurementsEventBuilderObject =
env->NewObject(class_gnssMeasurementsEventBuilder,
method_gnssMeasurementsEventBuilderCtor);
callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject,
method_gnssMeasurementsEventBuilderSetClock, clock);
callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject,
method_gnssMeasurementsEventBuilderSetMeasurements,
measurementArray);
callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject,
method_gnssMeasurementsEventBuilderSetGnssAutomaticGainControls,
gnssAgcArray);
if (hasIsFullTracking) {
callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject,
method_gnssMeasurementsEventBuilderSetIsFullTracking,
isFullTracking);
}
jobject gnssMeasurementsEventObject =
env->CallObjectMethod(gnssMeasurementsEventBuilderObject,
method_gnssMeasurementsEventBuilderBuild);
env->CallVoidMethod(callbacksObj, method_reportMeasurementData, gnssMeasurementsEventObject);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
env->DeleteLocalRef(gnssMeasurementsEventBuilderObject);
env->DeleteLocalRef(gnssMeasurementsEventObject);
}
template <class T_Measurement, class T_Flags>
void setMeasurementFields_V1_0(const T_Measurement& measurement, JavaObject& object) {
uint32_t flags = static_cast<uint32_t>(measurement.flags);
SET(Svid, static_cast<int32_t>(measurement.svid));
SET(TimeOffsetNanos, measurement.timeOffsetNs);
SET(State, static_cast<int32_t>(measurement.state));
SET(ReceivedSvTimeNanos, measurement.receivedSvTimeInNs);
SET(ReceivedSvTimeUncertaintyNanos, measurement.receivedSvTimeUncertaintyInNs);
SET(PseudorangeRateMetersPerSecond, measurement.pseudorangeRateMps);
SET(PseudorangeRateUncertaintyMetersPerSecond, measurement.pseudorangeRateUncertaintyMps);
SET(AccumulatedDeltaRangeState,
(static_cast<int32_t>(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);
// Intentionally not copying deprecated fields of carrierCycles,
// carrierPhase, carrierPhaseUncertainty
SET(MultipathIndicator, static_cast<int32_t>(measurement.multipathIndicator));
if (flags & static_cast<uint32_t>(T_Flags::HAS_SNR)) {
SET(SnrInDb, measurement.snrDb);
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_AUTOMATIC_GAIN_CONTROL)) {
SET(AutomaticGainControlLevelInDb, measurement.agcLevelDb);
}
}
template <class T_Measurement, class T_Flags>
void setMeasurementFields_V2_1(const T_Measurement& measurement, JavaObject& object) {
SET(BasebandCn0DbHz, measurement.basebandCN0DbHz);
if (measurement.flags & T_Flags::HAS_FULL_ISB) {
SET(FullInterSignalBiasNanos, measurement.fullInterSignalBiasNs);
}
if (measurement.flags & T_Flags::HAS_FULL_ISB_UNCERTAINTY) {
SET(FullInterSignalBiasUncertaintyNanos, measurement.fullInterSignalBiasUncertaintyNs);
}
if (measurement.flags & T_Flags::HAS_SATELLITE_ISB) {
SET(SatelliteInterSignalBiasNanos, measurement.satelliteInterSignalBiasNs);
}
if (measurement.flags & T_Flags::HAS_SATELLITE_ISB_UNCERTAINTY) {
SET(SatelliteInterSignalBiasUncertaintyNanos,
measurement.satelliteInterSignalBiasUncertaintyNs);
}
}
template <class T_Clock, class T_Flags>
void setClockFields_V1_0(const T_Clock& clock, JavaObject& object) {
uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags);
if (flags & static_cast<uint32_t>(T_Flags::HAS_LEAP_SECOND)) {
SET(LeapSecond, static_cast<int32_t>(clock.leapSecond));
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_TIME_UNCERTAINTY)) {
SET(TimeUncertaintyNanos, clock.timeUncertaintyNs);
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_FULL_BIAS)) {
SET(FullBiasNanos, clock.fullBiasNs);
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_BIAS)) {
SET(BiasNanos, clock.biasNs);
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_BIAS_UNCERTAINTY)) {
SET(BiasUncertaintyNanos, clock.biasUncertaintyNs);
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_DRIFT)) {
SET(DriftNanosPerSecond, clock.driftNsps);
}
if (flags & static_cast<uint32_t>(T_Flags::HAS_DRIFT_UNCERTAINTY)) {
SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps);
}
SET(TimeNanos, clock.timeNs);
SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount);
}
template <class T_Clock, class T_Flags>
void setClockFields_V2_1(const T_Clock& clock, JavaObject& object) {
JNIEnv* env = getJniEnv();
SET(ReferenceConstellationTypeForIsb,
static_cast<int32_t>(clock.referenceSignalTypeForIsb.constellation));
SET(ReferenceCarrierFrequencyHzForIsb, clock.referenceSignalTypeForIsb.carrierFrequencyHz);
jstring referenceCodeTypeForIsb =
env->NewStringUTF(clock.referenceSignalTypeForIsb.codeType.c_str());
SET(ReferenceCodeTypeForIsb, referenceCodeTypeForIsb);
env->DeleteLocalRef(referenceCodeTypeForIsb);
}
template <class T_ElapsedRealtime, class T_Flags>
void setElapsedRealtimeFields(const T_ElapsedRealtime& elapsedRealtime, JavaObject& object) {
uint32_t flags = static_cast<uint32_t>(elapsedRealtime.flags);
if (flags & T_Flags::HAS_TIMESTAMP_NS) {
SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
}
if (flags & T_Flags::HAS_TIME_UNCERTAINTY_NS) {
SET(ElapsedRealtimeUncertaintyNanos,
static_cast<double>(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);
jobjectArray gnssAgcArray = nullptr;
gnssAgcArray = translateAllGnssAgcs(env, data.gnssAgcs);
if (this->getInterfaceVersion() >= 3) {
setMeasurementData(env, mCallbacksObj, clock, measurementArray, gnssAgcArray,
/*hasIsFullTracking=*/true, data.isFullTracking);
} else {
setMeasurementData(env, mCallbacksObj, clock, measurementArray, gnssAgcArray,
/*hasIsFullTracking=*/false,
/*isFullTracking=*/JNI_FALSE);
}
env->DeleteLocalRef(clock);
env->DeleteLocalRef(measurementArray);
env->DeleteLocalRef(gnssAgcArray);
}
void GnssMeasurementCallbackAidl::translateSingleGnssMeasurement(JNIEnv* env,
const GnssMeasurement& measurement,
JavaObject& object) {
setMeasurementFields_V1_0<GnssMeasurement, GnssMeasurement>(measurement, object);
setMeasurementFields_V2_1<GnssMeasurement, GnssMeasurement>(measurement, object);
SET(Cn0DbHz, measurement.antennaCN0DbHz);
SET(ConstellationType, static_cast<int32_t>(measurement.signalType.constellation));
// Half cycle state is reported in the AIDL version of GnssMeasurement
SET(AccumulatedDeltaRangeState,
(static_cast<int32_t>(measurement.accumulatedDeltaRangeState) |
ADR_STATE_HALF_CYCLE_REPORTED));
if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_CARRIER_FREQUENCY)) {
SET(CarrierFrequencyHz, static_cast<float>(measurement.signalType.carrierFrequencyHz));
}
if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_SATELLITE_PVT)) {
const SatellitePvt& satellitePvt = measurement.satellitePvt;
uint16_t satFlags = static_cast<uint16_t>(satellitePvt.flags);
jobject positionEcef = nullptr;
jobject velocityEcef = nullptr;
jobject clockInfo = nullptr;
jobject satellitePvtBuilderObject =
env->NewObject(class_satellitePvtBuilder, method_satellitePvtBuilderCtor);
if (satFlags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) {
positionEcef = env->NewObject(class_positionEcef, method_positionEcef,
satellitePvt.satPosEcef.posXMeters,
satellitePvt.satPosEcef.posYMeters,
satellitePvt.satPosEcef.posZMeters,
satellitePvt.satPosEcef.ureMeters);
velocityEcef =
env->NewObject(class_velocityEcef, method_velocityEcef,
satellitePvt.satVelEcef.velXMps, satellitePvt.satVelEcef.velYMps,
satellitePvt.satVelEcef.velZMps,
satellitePvt.satVelEcef.ureRateMps);
clockInfo = env->NewObject(class_clockInfo, method_clockInfo,
satellitePvt.satClockInfo.satHardwareCodeBiasMeters,
satellitePvt.satClockInfo.satTimeCorrectionMeters,
satellitePvt.satClockInfo.satClkDriftMps);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetPositionEcef, positionEcef);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetVelocityEcef, velocityEcef);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetClockInfo, clockInfo);
}
if (satFlags & SatellitePvt::HAS_IONO) {
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetIonoDelayMeters,
satellitePvt.ionoDelayMeters);
}
if (satFlags & SatellitePvt::HAS_TROPO) {
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetTropoDelayMeters,
satellitePvt.tropoDelayMeters);
}
if (this->getInterfaceVersion() >= 2) {
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetTimeOfClock,
satellitePvt.timeOfClockSeconds);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetTimeOfEphemeris,
satellitePvt.timeOfEphemerisSeconds);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetIssueOfDataClock,
satellitePvt.issueOfDataClock);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetIssueOfDataEphemeris,
satellitePvt.issueOfDataEphemeris);
callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
method_satellitePvtBuilderSetEphemerisSource,
static_cast<int>(satellitePvt.ephemerisSource));
}
jobject satellitePvtObject =
env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderBuild);
env->CallVoidMethod(object.get(), method_gnssMeasurementsSetSatellitePvt,
satellitePvtObject);
env->DeleteLocalRef(positionEcef);
env->DeleteLocalRef(velocityEcef);
env->DeleteLocalRef(clockInfo);
env->DeleteLocalRef(satellitePvtBuilderObject);
env->DeleteLocalRef(satellitePvtObject);
}
if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_CORRELATION_VECTOR)) {
jobject correlationVectorList = env->NewObject(class_arrayList, method_arrayListCtor);
for (uint16_t i = 0; i < measurement.correlationVectors.size(); ++i) {
const CorrelationVector& correlationVector = measurement.correlationVectors[i];
const std::vector<int32_t>& magnitudeVector = correlationVector.magnitude;
jsize numMagnitude = magnitudeVector.size();
jintArray magnitudeArray = env->NewIntArray(numMagnitude);
env->SetIntArrayRegion(magnitudeArray, 0, numMagnitude,
reinterpret_cast<const jint*>(magnitudeVector.data()));
jobject correlationVectorBuilderObject =
env->NewObject(class_correlationVectorBuilder,
method_correlationVectorBuilderCtor);
callObjectMethodIgnoringResult(env, correlationVectorBuilderObject,
method_correlationVectorBuilderSetMagnitude,
magnitudeArray);
callObjectMethodIgnoringResult(
env, correlationVectorBuilderObject,
method_correlationVectorBuilderSetFrequencyOffsetMetersPerSecond,
correlationVector.frequencyOffsetMps);
callObjectMethodIgnoringResult(env, correlationVectorBuilderObject,
method_correlationVectorBuilderSetSamplingStartMeters,
correlationVector.samplingStartM);
callObjectMethodIgnoringResult(env, correlationVectorBuilderObject,
method_correlationVectorBuilderSetSamplingWidthMeters,
correlationVector.samplingWidthM);
jobject correlationVectorObject =
env->CallObjectMethod(correlationVectorBuilderObject,
method_correlationVectorBuilderBuild);
env->CallBooleanMethod(correlationVectorList, method_arrayListAdd,
correlationVectorObject);
env->DeleteLocalRef(magnitudeArray);
env->DeleteLocalRef(correlationVectorBuilderObject);
env->DeleteLocalRef(correlationVectorObject);
}
env->CallVoidMethod(object.get(), method_gnssMeasurementsSetCorrelationVectors,
correlationVectorList);
env->DeleteLocalRef(correlationVectorList);
}
jstring codeType = env->NewStringUTF(measurement.signalType.codeType.c_str());
SET(CodeType, codeType);
env->DeleteLocalRef(codeType);
}
jobjectArray GnssMeasurementCallbackAidl::translateAllGnssMeasurements(
JNIEnv* env, const std::vector<GnssMeasurement>& 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;
}
jobjectArray GnssMeasurementCallbackAidl::translateAllGnssAgcs(JNIEnv* env,
const std::vector<GnssAgc>& agcs) {
if (agcs.size() == 0) {
return nullptr;
}
jobjectArray gnssAgcArray =
env->NewObjectArray(agcs.size(), class_gnssAgc, nullptr /* initialElement */);
for (uint16_t i = 0; i < agcs.size(); ++i) {
const GnssAgc& gnssAgc = agcs[i];
jobject agcBuilderObject = env->NewObject(class_gnssAgcBuilder, method_gnssAgcBuilderCtor);
callObjectMethodIgnoringResult(env, agcBuilderObject, method_gnssAgcBuilderSetLevelDb,
gnssAgc.agcLevelDb);
callObjectMethodIgnoringResult(env, agcBuilderObject,
method_gnssAgcBuilderSetConstellationType,
(int)gnssAgc.constellation);
callObjectMethodIgnoringResult(env, agcBuilderObject,
method_gnssAgcBuilderSetCarrierFrequencyHz,
gnssAgc.carrierFrequencyHz);
jobject agcObject = env->CallObjectMethod(agcBuilderObject, method_gnssAgcBuilderBuild);
env->SetObjectArrayElement(gnssAgcArray, i, agcObject);
env->DeleteLocalRef(agcBuilderObject);
env->DeleteLocalRef(agcObject);
}
return gnssAgcArray;
}
void GnssMeasurementCallbackAidl::translateGnssClock(JNIEnv* env, const GnssData& data,
JavaObject& object) {
setElapsedRealtimeFields<ElapsedRealtime, ElapsedRealtime>(data.elapsedRealtime, object);
setClockFields_V1_0<GnssClock, GnssClock>(data.clock, object);
setClockFields_V2_1<GnssClock, GnssClock>(data.clock, object);
}
// Implementation of GnssMeasurementCallbackHidl class.
hardware::Return<void> GnssMeasurementCallbackHidl::gnssMeasurementCb_2_1(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) {
translateAndSetGnssData(data);
return hardware::Void();
}
hardware::Return<void> GnssMeasurementCallbackHidl::gnssMeasurementCb_2_0(
const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) {
translateAndSetGnssData(data);
return hardware::Void();
}
hardware::Return<void> GnssMeasurementCallbackHidl::gnssMeasurementCb(
const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) {
translateAndSetGnssData(data);
return hardware::Void();
}
hardware::Return<void> GnssMeasurementCallbackHidl::GnssMeasurementCb(
const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) {
translateAndSetGnssData(data);
return hardware::Void();
}
template <>
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<hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement,
GnssMeasurementFlags>(measurement, object);
SET(ConstellationType, static_cast<int32_t>(measurement.constellation));
SET(Cn0DbHz, measurement.cN0DbHz);
if (measurement.flags & static_cast<uint32_t>(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);
// Half cycle state is reported in HIDL v1.1 or newer.
SET(AccumulatedDeltaRangeState,
(static_cast<int32_t>(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<int32_t>(measurement_V2_0.state));
// Overwrite with v2_0.constellation since V2_0.v1_1.v1_0.constellation is deprecated.
SET(ConstellationType, static_cast<int32_t>(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<hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement,
GnssMeasurementFlags>(measurement_V2_1, object);
}
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock,
JavaObject& object) {
setClockFields_V1_0<hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock,
GnssClockFlags>(clock, object);
}
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock,
JavaObject& object) {
setClockFields_V2_1<hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock,
GnssClockFlags>(clock, object);
translateGnssClock(clock.v1_0, object);
}
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object) {
setElapsedRealtimeFields<hardware::gnss::V2_0::ElapsedRealtime,
hardware::gnss::V2_0::ElapsedRealtimeFlags>(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<uint16_t>(elapsedRealtime.flags);
if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
}
if (flags & hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
SET(ElapsedRealtimeUncertaintyNanos,
static_cast<double>(elapsedRealtime.timeUncertaintyNs));
}
translateGnssClock(data.clock, object);
}
} // namespace android::gnss