From 26f6450381cdd9d2db029a4466a8f2699edc4c66 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Fri, 25 Jun 2021 15:03:16 -0700 Subject: [PATCH] Refactor GnssAntennaInfo JNI Create Android.bp for the gnss sub-folder. Bug: 171245259 Test: atest LocationManagerFineTest#testGetGnssAntennaInfos Change-Id: Ie9530e1a6a7807770e67fa5646be39559cef2b34 --- services/core/jni/Android.bp | 5 +- ...d_server_location_GnssLocationProvider.cpp | 271 +----------------- services/core/jni/gnss/Android.bp | 51 ++++ .../core/jni/gnss/GnssAntennaInfoCallback.cpp | 269 +++++++++++++++++ .../core/jni/gnss/GnssAntennaInfoCallback.h | 84 ++++++ .../core/jni/gnss/GnssMeasurementCallback.cpp | 3 + .../core/jni/gnss/GnssMeasurementCallback.h | 2 + services/core/jni/gnss/Utils.cpp | 6 + 8 files changed, 419 insertions(+), 272 deletions(-) create mode 100644 services/core/jni/gnss/Android.bp create mode 100644 services/core/jni/gnss/GnssAntennaInfoCallback.cpp create mode 100644 services/core/jni/gnss/GnssAntennaInfoCallback.h diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 53401fd471786..ab4f1f6fee2f0 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -30,10 +30,6 @@ cc_library_static { "BroadcastRadio/TunerCallback.cpp", "BroadcastRadio/convert.cpp", "BroadcastRadio/regions.cpp", - "gnss/GnssConfiguration.cpp", - "gnss/GnssMeasurement.cpp", - "gnss/GnssMeasurementCallback.cpp", - "gnss/Utils.cpp", "stats/SurfaceFlingerPuller.cpp", "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", @@ -122,6 +118,7 @@ cc_defaults { "libinputflinger", "libinputflinger_base", "libinputservice", + "libservices.core-gnss", "libstatshidl", "libstatspull", "libstatssocket", diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index a87b513491f61..1639d82f78757 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -40,6 +40,7 @@ #include #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" +#include "gnss/GnssAntennaInfoCallback.h" #include "gnss/GnssConfiguration.h" #include "gnss/GnssMeasurement.h" #include "gnss/Utils.h" @@ -60,12 +61,7 @@ static jclass class_location; static jclass class_gnssNavigationMessage; -static jclass class_gnssAntennaInfoBuilder; static jclass class_gnssPowerStats; -static jclass class_phaseCenterOffset; -static jclass class_sphericalCorrections; -static jclass class_arrayList; -static jclass class_doubleArray; jobject android::mCallbacksObj = nullptr; @@ -89,7 +85,6 @@ static jmethodID method_reportGeofenceAddStatus; static jmethodID method_reportGeofenceRemoveStatus; static jmethodID method_reportGeofencePauseStatus; static jmethodID method_reportGeofenceResumeStatus; -static jmethodID method_reportAntennaInfo; static jmethodID method_reportNavigationMessages; static jmethodID method_reportLocationBatch; static jmethodID method_reportGnssServiceDied; @@ -123,25 +118,9 @@ static jmethodID method_reportNfwNotification; static jmethodID method_isInEmergencySession; static jmethodID method_locationCtor; static jmethodID method_gnssNavigationMessageCtor; -static jmethodID method_gnssAntennaInfoBuilderCtor; static jmethodID method_gnssPowerStatsCtor; -static jmethodID method_phaseCenterOffsetCtor; -static jmethodID method_sphericalCorrectionsCtor; -static jmethodID method_arrayListCtor; -static jmethodID method_arrayListAdd; -static jmethodID method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz; -static jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterOffset; -static jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections; -static jmethodID method_gnssAntennaInfoBuilderSetSignalGainCorrections; -static jmethodID method_gnssAntennaInfoBuilderBuild; static jmethodID method_setSubHalPowerIndicationCapabilities; -/* - * Save a pointer to JavaVm to attach/detach threads executing - * callback methods that need to make JNI calls. - */ -JavaVM* android::ScopedJniThreadAttach::sJvm; - using android::OK; using android::sp; using android::status_t; @@ -193,7 +172,6 @@ using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback; using IGnssDebug_V1_0 = android::hardware::gnss::V1_0::IGnssDebug; using IGnssDebug_V2_0 = android::hardware::gnss::V2_0::IGnssDebug; using IGnssAntennaInfo = android::hardware::gnss::V2_1::IGnssAntennaInfo; -using IGnssAntennaInfoCallback = android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil; using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil; using IAGnss_V1_0 = android::hardware::gnss::V1_0::IAGnss; @@ -953,208 +931,6 @@ Return GnssNavigationMessageCallback::gnssNavigationMessageCb( return Void(); } -/* - * GnssAntennaInfoCallback implements the callback methods required for the - * GnssAntennaInfo interface. - */ -struct GnssAntennaInfoCallback : public IGnssAntennaInfoCallback { - // Methods from V2_1::GnssAntennaInfoCallback follow. - Return gnssAntennaInfoCb( - const hidl_vec& gnssAntennaInfos); - -private: - jobject translateAllGnssAntennaInfos( - JNIEnv* env, - const hidl_vec& gnssAntennaInfos); - jobject translateSingleGnssAntennaInfo( - JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo); - jobject translatePhaseCenterOffset( - JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo); - jobject translatePhaseCenterVariationCorrections( - JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo); - jobject translateSignalGainCorrections( - JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo); - jobjectArray translate2dDoubleArray(JNIEnv* env, - const hidl_vec& array); - void translateAndReportGnssAntennaInfo( - const hidl_vec& gnssAntennaInfos); - void reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray); -}; - -Return GnssAntennaInfoCallback::gnssAntennaInfoCb( - const hidl_vec& gnssAntennaInfos) { - translateAndReportGnssAntennaInfo(gnssAntennaInfos); - return Void(); -} - -jobjectArray GnssAntennaInfoCallback::translate2dDoubleArray( - JNIEnv* env, const hidl_vec& 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; -} - -jobject GnssAntennaInfoCallback::translateAllGnssAntennaInfos( - JNIEnv* env, const hidl_vec& 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; -} - -jobject GnssAntennaInfoCallback::translatePhaseCenterOffset( - JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& 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; -} - -jobject GnssAntennaInfoCallback::translatePhaseCenterVariationCorrections( - JNIEnv* env, const IGnssAntennaInfoCallback::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) { - return NULL; - } - - jobject phaseCenterVariationCorrections = - env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor, - phaseCenterVariationCorrectionsArray, - phaseCenterVariationCorrectionsUncertaintiesArray); - - env->DeleteLocalRef(phaseCenterVariationCorrectionsArray); - env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray); - - return phaseCenterVariationCorrections; -} - -jobject GnssAntennaInfoCallback::translateSignalGainCorrections( - JNIEnv* env, const IGnssAntennaInfoCallback::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) { - return NULL; - } - - jobject signalGainCorrections = - env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor, - signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray); - - env->DeleteLocalRef(signalGainCorrectionsArray); - env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray); - - return signalGainCorrections; -} - -jobject GnssAntennaInfoCallback::translateSingleGnssAntennaInfo( - JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& 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 - env->CallObjectMethod(gnssAntennaInfoBuilderObject, - method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz, - gnssAntennaInfo.carrierFrequencyMHz); - env->CallObjectMethod(gnssAntennaInfoBuilderObject, - method_gnssAntennaInfoBuilderSetPhaseCenterOffset, phaseCenterOffset); - env->CallObjectMethod(gnssAntennaInfoBuilderObject, - method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections, - phaseCenterVariationCorrections); - env->CallObjectMethod(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; -} - -void GnssAntennaInfoCallback::translateAndReportGnssAntennaInfo( - const hidl_vec& gnssAntennaInfos) { - JNIEnv* env = getJniEnv(); - - jobject arrayList = translateAllGnssAntennaInfos(env, gnssAntennaInfos); - - reportAntennaInfo(env, arrayList); - - env->DeleteLocalRef(arrayList); -} - -void GnssAntennaInfoCallback::reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray) { - env->CallVoidMethod(mCallbacksObj, method_reportAntennaInfo, antennaInfosArray); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - /* * MeasurementCorrectionsCallback implements callback methods of interface * IMeasurementCorrectionsCallback.hal. @@ -1515,7 +1291,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc "(II)V"); method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus", "(II)V"); - method_reportAntennaInfo = env->GetMethodID(clazz, "reportAntennaInfo", "(Ljava/util/List;)V"); method_reportNavigationMessages = env->GetMethodID( clazz, "reportNavigationMessage", @@ -1589,39 +1364,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D"); method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D"); - jclass gnssAntennaInfoBuilder = env->FindClass("android/location/GnssAntennaInfo$Builder"); - class_gnssAntennaInfoBuilder = (jclass)env->NewGlobalRef(gnssAntennaInfoBuilder); - method_gnssAntennaInfoBuilderCtor = - env->GetMethodID(class_gnssAntennaInfoBuilder, "", "()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, "", "(DDDDDD)V"); - - jclass sphericalCorrectionsClass = - env->FindClass("android/location/GnssAntennaInfo$SphericalCorrections"); - class_sphericalCorrections = (jclass)env->NewGlobalRef(sphericalCorrectionsClass); - method_sphericalCorrectionsCtor = - env->GetMethodID(class_sphericalCorrections, "", "([[D[[D)V"); - jclass gnssPowerStatsClass = env->FindClass("com/android/server/location/gnss/GnssPowerStats"); class_gnssPowerStats = (jclass)env->NewGlobalRef(gnssPowerStatsClass); method_gnssPowerStatsCtor = env->GetMethodID(class_gnssPowerStats, "", "(IJDDDDDD[D)V"); @@ -1634,16 +1376,9 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass); method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "", "()V"); - jclass arrayListClass = env->FindClass("java/util/ArrayList"); - class_arrayList = (jclass)env->NewGlobalRef(arrayListClass); - method_arrayListCtor = env->GetMethodID(class_arrayList, "", "()V"); - method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z"); - - jclass doubleArrayClass = env->FindClass("[D"); - class_doubleArray = (jclass)env->NewGlobalRef(doubleArrayClass); - gnss::GnssConfiguration_class_init_once(env); gnss::GnssMeasurement_class_init_once(env, clazz); + gnss::GnssAntennaInfo_class_init_once(env, clazz); } /* Initialization needed at system boot and whenever GNSS service dies. */ @@ -2626,7 +2361,7 @@ static jboolean android_location_gnss_hal_GnssNative_start_antenna_info_listenin return JNI_FALSE; } - sp cbIface = new GnssAntennaInfoCallback(); + sp cbIface = new gnss::GnssAntennaInfoCallback(mCallbacksObj); auto result = gnssAntennaInfoIface->setCallback(cbIface); diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp new file mode 100644 index 0000000000000..444cb8b7e9550 --- /dev/null +++ b/services/core/jni/gnss/Android.bp @@ -0,0 +1,51 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +cc_library_shared { + name: "libservices.core-gnss", + defaults: ["libservices.core-gnss-libs"], + + cpp_std: "c++2a", + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + "-Wthread-safety", + + "-DEGL_EGLEXT_PROTOTYPES", + "-DGL_GLEXT_PROTOTYPES", + ], + + srcs: [ + "GnssAntennaInfoCallback.cpp", + "GnssConfiguration.cpp", + "GnssMeasurement.cpp", + "GnssMeasurementCallback.cpp", + "Utils.cpp", + ], +} + +cc_defaults { + name: "libservices.core-gnss-libs", + shared_libs: [ + "libandroid_runtime", + "libbinder", + "libhidlbase", + "liblog", + "libnativehelper", + "libutils", + "android.hardware.gnss-V1-cpp", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.visibility_control@1.0", + ], +} diff --git a/services/core/jni/gnss/GnssAntennaInfoCallback.cpp b/services/core/jni/gnss/GnssAntennaInfoCallback.cpp new file mode 100644 index 0000000000000..fbc000b25d26d --- /dev/null +++ b/services/core/jni/gnss/GnssAntennaInfoCallback.cpp @@ -0,0 +1,269 @@ +/* + * 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 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 IGnssAntennaInfoCallback = 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, "", "()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, "", "(DDDDDD)V"); + + jclass sphericalCorrectionsClass = + env->FindClass("android/location/GnssAntennaInfo$SphericalCorrections"); + class_sphericalCorrections = (jclass)env->NewGlobalRef(sphericalCorrectionsClass); + method_sphericalCorrectionsCtor = + env->GetMethodID(class_sphericalCorrections, "", "([[D[[D)V"); + + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + class_arrayList = (jclass)env->NewGlobalRef(arrayListClass); + method_arrayListCtor = env->GetMethodID(class_arrayList, "", "()V"); + method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z"); + + jclass doubleArrayClass = env->FindClass("[D"); + class_doubleArray = (jclass)env->NewGlobalRef(doubleArrayClass); +} + +Return GnssAntennaInfoCallback::gnssAntennaInfoCb( + const hidl_vec& gnssAntennaInfos) { + translateAndReportGnssAntennaInfo(gnssAntennaInfos); + return Void(); +} + +jobjectArray GnssAntennaInfoCallback::translate2dDoubleArray( + JNIEnv* env, const hidl_vec& 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; +} + +jobject GnssAntennaInfoCallback::translateAllGnssAntennaInfos( + JNIEnv* env, const hidl_vec& 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; +} + +jobject GnssAntennaInfoCallback::translatePhaseCenterOffset( + JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& 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; +} + +jobject GnssAntennaInfoCallback::translatePhaseCenterVariationCorrections( + JNIEnv* env, const IGnssAntennaInfoCallback::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) { + return NULL; + } + + jobject phaseCenterVariationCorrections = + env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor, + phaseCenterVariationCorrectionsArray, + phaseCenterVariationCorrectionsUncertaintiesArray); + + env->DeleteLocalRef(phaseCenterVariationCorrectionsArray); + env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray); + + return phaseCenterVariationCorrections; +} + +jobject GnssAntennaInfoCallback::translateSignalGainCorrections( + JNIEnv* env, const IGnssAntennaInfoCallback::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) { + return NULL; + } + + jobject signalGainCorrections = + env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor, + signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray); + + env->DeleteLocalRef(signalGainCorrectionsArray); + env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray); + + return signalGainCorrections; +} + +jobject GnssAntennaInfoCallback::translateSingleGnssAntennaInfo( + JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& 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 + env->CallObjectMethod(gnssAntennaInfoBuilderObject, + method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz, + gnssAntennaInfo.carrierFrequencyMHz); + env->CallObjectMethod(gnssAntennaInfoBuilderObject, + method_gnssAntennaInfoBuilderSetPhaseCenterOffset, phaseCenterOffset); + env->CallObjectMethod(gnssAntennaInfoBuilderObject, + method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections, + phaseCenterVariationCorrections); + env->CallObjectMethod(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; +} + +void GnssAntennaInfoCallback::translateAndReportGnssAntennaInfo( + const hidl_vec& gnssAntennaInfos) { + JNIEnv* env = getJniEnv(); + + jobject arrayList = translateAllGnssAntennaInfos(env, gnssAntennaInfos); + + reportAntennaInfo(env, arrayList); + + env->DeleteLocalRef(arrayList); +} + +void GnssAntennaInfoCallback::reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray) { + env->CallVoidMethod(mCallbacksObj, method_reportAntennaInfo, antennaInfosArray); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssAntennaInfoCallback.h b/services/core/jni/gnss/GnssAntennaInfoCallback.h new file mode 100644 index 0000000000000..0fc763336077e --- /dev/null +++ b/services/core/jni/gnss/GnssAntennaInfoCallback.h @@ -0,0 +1,84 @@ +/* + * 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. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSSANTENNAINFOCALLBACK_H +#define _ANDROID_SERVER_GNSS_GNSSANTENNAINFOCALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +void GnssAntennaInfo_class_init_once(JNIEnv* env, jclass& clazz); + +/* + * GnssAntennaInfoCallback implements the callback methods required for the + * GnssAntennaInfo interface. + */ +struct GnssAntennaInfoCallback : public android::hardware::gnss::V2_1::IGnssAntennaInfoCallback { + GnssAntennaInfoCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {} + // Methods from V2_1::GnssAntennaInfoCallback follow. + hardware::Return gnssAntennaInfoCb( + const hardware::hidl_vec< + android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>& + gnssAntennaInfos); + +private: + jobject translateAllGnssAntennaInfos( + JNIEnv* env, + const hardware::hidl_vec< + android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>& + gnssAntennaInfos); + jobject translateSingleGnssAntennaInfo( + JNIEnv* env, + const android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo& + gnssAntennaInfo); + jobject translatePhaseCenterOffset( + JNIEnv* env, + const android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo& + gnssAntennaInfo); + jobject translatePhaseCenterVariationCorrections( + JNIEnv* env, + const android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo& + gnssAntennaInfo); + jobject translateSignalGainCorrections( + JNIEnv* env, + const android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo& + gnssAntennaInfo); + jobjectArray translate2dDoubleArray( + JNIEnv* env, + const hardware::hidl_vec& + array); + void translateAndReportGnssAntennaInfo( + const hardware::hidl_vec< + android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>& + gnssAntennaInfos); + void reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray); + + jobject& mCallbacksObj; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSANTENNAINFOCALLBACK_H diff --git a/services/core/jni/gnss/GnssMeasurementCallback.cpp b/services/core/jni/gnss/GnssMeasurementCallback.cpp index 8c6c673fb5b25..34ae4690e0ea3 100644 --- a/services/core/jni/gnss/GnssMeasurementCallback.cpp +++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp @@ -28,6 +28,7 @@ using hardware::gnss::GnssData; using hardware::gnss::GnssMeasurement; using hardware::gnss::SatellitePvt; +namespace { jclass class_arrayList; jclass class_clockInfo; jclass class_correlationVectorBuilder; @@ -63,6 +64,8 @@ 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"); diff --git a/services/core/jni/gnss/GnssMeasurementCallback.h b/services/core/jni/gnss/GnssMeasurementCallback.h index 26f12437a2175..32200fdf904e9 100644 --- a/services/core/jni/gnss/GnssMeasurementCallback.h +++ b/services/core/jni/gnss/GnssMeasurementCallback.h @@ -34,6 +34,7 @@ namespace android::gnss { +namespace { extern jclass class_gnssMeasurementsEvent; extern jclass class_gnssMeasurement; extern jclass class_gnssClock; @@ -42,6 +43,7 @@ extern jmethodID method_gnssMeasurementsEventCtor; extern jmethodID method_gnssClockCtor; extern jmethodID method_gnssMeasurementCtor; extern jmethodID method_reportMeasurementData; +} // anonymous namespace void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz); diff --git a/services/core/jni/gnss/Utils.cpp b/services/core/jni/gnss/Utils.cpp index 20e14a919fce4..8cbdfb8d294e5 100644 --- a/services/core/jni/gnss/Utils.cpp +++ b/services/core/jni/gnss/Utils.cpp @@ -18,6 +18,12 @@ #include "Utils.h" +/* + * Save a pointer to JavaVm to attach/detach threads executing + * callback methods that need to make JNI calls. + */ +JavaVM* android::ScopedJniThreadAttach::sJvm; + namespace android { namespace {