blob: 2e99b2b79d370e9314b2cc02b11a21fc8f52cf7c [file] [log] [blame]
/*
* Copyright (C) 2021 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 before <log/log.h> to overwrite the default value.
#define LOG_TAG "GnssAntInfoCbJni"
#include "GnssAntennaInfoCallback.h"
#include "Utils.h"
namespace android::gnss {
using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::Void;
using binder::Status;
using IGnssAntennaInfoCallbackAidl = android::hardware::gnss::IGnssAntennaInfoCallback;
using IGnssAntennaInfoCallback_V2_1 = android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
namespace {
jclass class_gnssAntennaInfoBuilder;
jclass class_phaseCenterOffset;
jclass class_sphericalCorrections;
jclass class_arrayList;
jclass class_doubleArray;
jmethodID method_reportAntennaInfo;
jmethodID method_gnssAntennaInfoBuilderCtor;
jmethodID method_phaseCenterOffsetCtor;
jmethodID method_sphericalCorrectionsCtor;
jmethodID method_arrayListCtor;
jmethodID method_arrayListAdd;
jmethodID method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz;
jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterOffset;
jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections;
jmethodID method_gnssAntennaInfoBuilderSetSignalGainCorrections;
jmethodID method_gnssAntennaInfoBuilderBuild;
} // anonymous namespace
void GnssAntennaInfo_class_init_once(JNIEnv* env, jclass& clazz) {
method_reportAntennaInfo = env->GetMethodID(clazz, "reportAntennaInfo", "(Ljava/util/List;)V");
jclass gnssAntennaInfoBuilder = env->FindClass("android/location/GnssAntennaInfo$Builder");
class_gnssAntennaInfoBuilder = (jclass)env->NewGlobalRef(gnssAntennaInfoBuilder);
method_gnssAntennaInfoBuilderCtor =
env->GetMethodID(class_gnssAntennaInfoBuilder, "<init>", "()V");
method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz =
env->GetMethodID(class_gnssAntennaInfoBuilder, "setCarrierFrequencyMHz",
"(D)Landroid/location/GnssAntennaInfo$Builder;");
method_gnssAntennaInfoBuilderSetPhaseCenterOffset =
env->GetMethodID(class_gnssAntennaInfoBuilder, "setPhaseCenterOffset",
"(Landroid/location/GnssAntennaInfo$PhaseCenterOffset;)"
"Landroid/location/GnssAntennaInfo$Builder;");
method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections =
env->GetMethodID(class_gnssAntennaInfoBuilder, "setPhaseCenterVariationCorrections",
"(Landroid/location/GnssAntennaInfo$SphericalCorrections;)"
"Landroid/location/GnssAntennaInfo$Builder;");
method_gnssAntennaInfoBuilderSetSignalGainCorrections =
env->GetMethodID(class_gnssAntennaInfoBuilder, "setSignalGainCorrections",
"(Landroid/location/GnssAntennaInfo$SphericalCorrections;)"
"Landroid/location/GnssAntennaInfo$Builder;");
method_gnssAntennaInfoBuilderBuild = env->GetMethodID(class_gnssAntennaInfoBuilder, "build",
"()Landroid/location/GnssAntennaInfo;");
jclass phaseCenterOffsetClass =
env->FindClass("android/location/GnssAntennaInfo$PhaseCenterOffset");
class_phaseCenterOffset = (jclass)env->NewGlobalRef(phaseCenterOffsetClass);
method_phaseCenterOffsetCtor = env->GetMethodID(class_phaseCenterOffset, "<init>", "(DDDDDD)V");
jclass sphericalCorrectionsClass =
env->FindClass("android/location/GnssAntennaInfo$SphericalCorrections");
class_sphericalCorrections = (jclass)env->NewGlobalRef(sphericalCorrectionsClass);
method_sphericalCorrectionsCtor =
env->GetMethodID(class_sphericalCorrections, "<init>", "([[D[[D)V");
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");
jclass doubleArrayClass = env->FindClass("[D");
class_doubleArray = (jclass)env->NewGlobalRef(doubleArrayClass);
}
binder::Status GnssAntennaInfoCallbackAidl::gnssAntennaInfoCb(
const std::vector<IGnssAntennaInfoCallbackAidl::GnssAntennaInfo>& gnssAntennaInfos) {
GnssAntennaInfoCallbackUtil::translateAndReportGnssAntennaInfo(gnssAntennaInfos);
return Status::ok();
}
Return<void> GnssAntennaInfoCallback_V2_1::gnssAntennaInfoCb(
const hidl_vec<IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo>& gnssAntennaInfos) {
GnssAntennaInfoCallbackUtil::translateAndReportGnssAntennaInfo(gnssAntennaInfos);
return Void();
}
template <template <class...> class T_vector, class T_info>
jobjectArray GnssAntennaInfoCallbackUtil::translate2dDoubleArray(JNIEnv* env,
const T_vector<T_info>& array) {
jsize numRows = array.size();
if (numRows == 0) {
// Empty array
return NULL;
}
jsize numCols = array[0].row.size();
if (numCols <= 1) {
// phi angle separation is computed as 180.0 / (numColumns - 1), so can't be < 2.
return NULL;
}
// Allocate array of double arrays
jobjectArray returnArray = env->NewObjectArray(numRows, class_doubleArray, NULL);
// Create each double array
for (uint8_t i = 0; i < numRows; i++) {
jdoubleArray doubleArray = env->NewDoubleArray(numCols);
env->SetDoubleArrayRegion(doubleArray, (jsize)0, numCols, array[i].row.data());
env->SetObjectArrayElement(returnArray, (jsize)i, doubleArray);
env->DeleteLocalRef(doubleArray);
}
return returnArray;
}
template <template <class...> class T_vector, class T_info>
jobject GnssAntennaInfoCallbackUtil::translateAllGnssAntennaInfos(
JNIEnv* env, const T_vector<T_info>& gnssAntennaInfos) {
jobject arrayList = env->NewObject(class_arrayList,
method_arrayListCtor); // Create new ArrayList instance
for (auto gnssAntennaInfo : gnssAntennaInfos) {
jobject gnssAntennaInfoObject = translateSingleGnssAntennaInfo(env, gnssAntennaInfo);
env->CallBooleanMethod(arrayList, method_arrayListAdd,
gnssAntennaInfoObject); // Add the antennaInfo to the ArrayList
// Delete Local Refs
env->DeleteLocalRef(gnssAntennaInfoObject);
}
return arrayList;
}
template <class T>
jobject GnssAntennaInfoCallbackUtil::translatePhaseCenterOffset(JNIEnv* env,
const T& gnssAntennaInfo) {
jobject phaseCenterOffset =
env->NewObject(class_phaseCenterOffset, method_phaseCenterOffsetCtor,
gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.x,
gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.xUncertainty,
gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.y,
gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.yUncertainty,
gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.z,
gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.zUncertainty);
return phaseCenterOffset;
}
template <>
jobject GnssAntennaInfoCallbackUtil::translatePhaseCenterVariationCorrections(
JNIEnv* env, const IGnssAntennaInfoCallbackAidl::GnssAntennaInfo& gnssAntennaInfo) {
if (gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters.empty() ||
gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.empty()) {
return NULL;
}
jobjectArray phaseCenterVariationCorrectionsArray =
translate2dDoubleArray(env, gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters);
jobjectArray phaseCenterVariationCorrectionsUncertaintiesArray =
translate2dDoubleArray(env,
gnssAntennaInfo
.phaseCenterVariationCorrectionUncertaintyMillimeters);
if (phaseCenterVariationCorrectionsArray == NULL ||
phaseCenterVariationCorrectionsUncertaintiesArray == NULL) {
env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
return NULL;
}
jobject phaseCenterVariationCorrections =
env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
phaseCenterVariationCorrectionsArray,
phaseCenterVariationCorrectionsUncertaintiesArray);
env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
return phaseCenterVariationCorrections;
}
template <>
jobject GnssAntennaInfoCallbackUtil::translatePhaseCenterVariationCorrections(
JNIEnv* env, const IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo& gnssAntennaInfo) {
if (gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters == NULL ||
gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters == NULL) {
return NULL;
}
jobjectArray phaseCenterVariationCorrectionsArray =
translate2dDoubleArray(env, gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters);
jobjectArray phaseCenterVariationCorrectionsUncertaintiesArray =
translate2dDoubleArray(env,
gnssAntennaInfo
.phaseCenterVariationCorrectionUncertaintyMillimeters);
if (phaseCenterVariationCorrectionsArray == NULL ||
phaseCenterVariationCorrectionsUncertaintiesArray == NULL) {
env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
return NULL;
}
jobject phaseCenterVariationCorrections =
env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
phaseCenterVariationCorrectionsArray,
phaseCenterVariationCorrectionsUncertaintiesArray);
env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
return phaseCenterVariationCorrections;
}
template <>
jobject GnssAntennaInfoCallbackUtil::translateSignalGainCorrections(
JNIEnv* env, const IGnssAntennaInfoCallbackAidl::GnssAntennaInfo& gnssAntennaInfo) {
if (gnssAntennaInfo.signalGainCorrectionDbi.empty() ||
gnssAntennaInfo.signalGainCorrectionUncertaintyDbi.empty()) {
return NULL;
}
jobjectArray signalGainCorrectionsArray =
translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionDbi);
jobjectArray signalGainCorrectionsUncertaintiesArray =
translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionUncertaintyDbi);
if (signalGainCorrectionsArray == NULL || signalGainCorrectionsUncertaintiesArray == NULL) {
env->DeleteLocalRef(signalGainCorrectionsArray);
env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
return NULL;
}
jobject signalGainCorrections =
env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray);
env->DeleteLocalRef(signalGainCorrectionsArray);
env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
return signalGainCorrections;
}
template <>
jobject GnssAntennaInfoCallbackUtil::translateSignalGainCorrections(
JNIEnv* env, const IGnssAntennaInfoCallback_V2_1::GnssAntennaInfo& gnssAntennaInfo) {
if (gnssAntennaInfo.signalGainCorrectionDbi == NULL ||
gnssAntennaInfo.signalGainCorrectionUncertaintyDbi == NULL) {
return NULL;
}
jobjectArray signalGainCorrectionsArray =
translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionDbi);
jobjectArray signalGainCorrectionsUncertaintiesArray =
translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionUncertaintyDbi);
if (signalGainCorrectionsArray == NULL || signalGainCorrectionsUncertaintiesArray == NULL) {
env->DeleteLocalRef(signalGainCorrectionsArray);
env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
return NULL;
}
jobject signalGainCorrections =
env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray);
env->DeleteLocalRef(signalGainCorrectionsArray);
env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
return signalGainCorrections;
}
template <class T>
jobject GnssAntennaInfoCallbackUtil::translateSingleGnssAntennaInfo(JNIEnv* env,
const T& gnssAntennaInfo) {
jobject phaseCenterOffset = translatePhaseCenterOffset(env, gnssAntennaInfo);
// Nullable
jobject phaseCenterVariationCorrections =
translatePhaseCenterVariationCorrections(env, gnssAntennaInfo);
// Nullable
jobject signalGainCorrections = translateSignalGainCorrections(env, gnssAntennaInfo);
// Get builder
jobject gnssAntennaInfoBuilderObject =
env->NewObject(class_gnssAntennaInfoBuilder, method_gnssAntennaInfoBuilderCtor);
// Set fields
callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz,
getCarrierFrequencyMHz(gnssAntennaInfo));
callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
method_gnssAntennaInfoBuilderSetPhaseCenterOffset,
phaseCenterOffset);
callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections,
phaseCenterVariationCorrections);
callObjectMethodIgnoringResult(env, gnssAntennaInfoBuilderObject,
method_gnssAntennaInfoBuilderSetSignalGainCorrections,
signalGainCorrections);
// build
jobject gnssAntennaInfoObject =
env->CallObjectMethod(gnssAntennaInfoBuilderObject, method_gnssAntennaInfoBuilderBuild);
// Delete Local Refs
env->DeleteLocalRef(phaseCenterOffset);
env->DeleteLocalRef(phaseCenterVariationCorrections);
env->DeleteLocalRef(signalGainCorrections);
return gnssAntennaInfoObject;
}
template <template <class...> class T_vector, class T_info>
void GnssAntennaInfoCallbackUtil::translateAndReportGnssAntennaInfo(
const T_vector<T_info>& gnssAntennaInfos) {
JNIEnv* env = getJniEnv();
jobject arrayList = translateAllGnssAntennaInfos(env, gnssAntennaInfos);
reportAntennaInfo(env, arrayList);
env->DeleteLocalRef(arrayList);
}
void GnssAntennaInfoCallbackUtil::reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray) {
env->CallVoidMethod(mCallbacksObj, method_reportAntennaInfo, antennaInfosArray);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
}
} // namespace android::gnss