summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/jni/com_android_server_location_GnssLocationProvider.cpp286
-rw-r--r--services/core/jni/gnss/Android.bp2
-rw-r--r--services/core/jni/gnss/GnssBatching.cpp131
-rw-r--r--services/core/jni/gnss/GnssBatching.h86
-rw-r--r--services/core/jni/gnss/GnssBatchingCallback.cpp58
-rw-r--r--services/core/jni/gnss/GnssBatchingCallback.h128
-rw-r--r--services/core/jni/gnss/Utils.cpp122
-rw-r--r--services/core/jni/gnss/Utils.h11
8 files changed, 568 insertions, 256 deletions
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 6be872f9f1ed..0a55003e77fc 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -28,7 +28,6 @@
#include <android/hardware/gnss/2.1/IGnssAntennaInfo.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/BnGnss.h>
-#include <android/hardware/gnss/BnGnssBatchingCallback.h>
#include <android/hardware/gnss/BnGnssCallback.h>
#include <android/hardware/gnss/BnGnssMeasurementCallback.h>
#include <android/hardware/gnss/BnGnssPowerIndicationCallback.h>
@@ -52,6 +51,7 @@
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "gnss/GnssAntennaInfoCallback.h"
+#include "gnss/GnssBatching.h"
#include "gnss/GnssConfiguration.h"
#include "gnss/GnssMeasurement.h"
#include "gnss/Utils.h"
@@ -60,12 +60,9 @@
#include "utils/Log.h"
#include "utils/misc.h"
-static jclass class_location;
static jclass class_gnssNavigationMessage;
static jclass class_gnssPowerStats;
-jobject android::mCallbacksObj = nullptr;
-
static jmethodID method_reportLocation;
static jmethodID method_reportStatus;
static jmethodID method_reportSvStatus;
@@ -87,7 +84,6 @@ static jmethodID method_reportGeofenceRemoveStatus;
static jmethodID method_reportGeofencePauseStatus;
static jmethodID method_reportGeofenceResumeStatus;
static jmethodID method_reportNavigationMessages;
-static jmethodID method_reportLocationBatch;
static jmethodID method_reportGnssServiceDied;
static jmethodID method_reportGnssPowerStats;
static jmethodID method_setSubHalMeasurementCorrectionsCapabilities;
@@ -117,7 +113,6 @@ static jmethodID method_correctionPlaneAltDeg;
static jmethodID method_correctionPlaneAzimDeg;
static jmethodID method_reportNfwNotification;
static jmethodID method_isInEmergencySession;
-static jmethodID method_locationCtor;
static jmethodID method_gnssNavigationMessageCtor;
static jmethodID method_gnssPowerStatsCtor;
static jmethodID method_setSubHalPowerIndicationCapabilities;
@@ -179,10 +174,6 @@ using IAGnss_V1_0 = android::hardware::gnss::V1_0::IAGnss;
using IAGnss_V2_0 = android::hardware::gnss::V2_0::IAGnss;
using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback;
using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
-using IGnssBatching_V1_0 = android::hardware::gnss::V1_0::IGnssBatching;
-using IGnssBatching_V2_0 = android::hardware::gnss::V2_0::IGnssBatching;
-using IGnssBatchingCallback_V1_0 = android::hardware::gnss::V1_0::IGnssBatchingCallback;
-using IGnssBatchingCallback_V2_0 = android::hardware::gnss::V2_0::IGnssBatchingCallback;
using IMeasurementCorrections_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
using IMeasurementCorrections_V1_1 = android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections;
@@ -199,8 +190,6 @@ using android::hardware::gnss::IGnssPowerIndication;
using android::hardware::gnss::IGnssPowerIndicationCallback;
using android::hardware::gnss::PsdsType;
using IGnssAidl = android::hardware::gnss::IGnss;
-using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching;
-using IGnssBatchingCallbackAidl = android::hardware::gnss::IGnssBatchingCallback;
using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback;
using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds;
using IGnssPsdsCallbackAidl = android::hardware::gnss::IGnssPsdsCallback;
@@ -227,7 +216,6 @@ sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
sp<IGnss_V2_1> gnssHal_V2_1 = nullptr;
sp<IGnssAidl> gnssHalAidl = nullptr;
-sp<IGnssBatchingAidl> gnssBatchingAidlIface = nullptr;
sp<IGnssPsdsAidl> gnssPsdsAidlIface = nullptr;
sp<IGnssXtra> gnssXtraIface = nullptr;
sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
@@ -235,8 +223,6 @@ sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
sp<IAGnss_V1_0> agnssIface = nullptr;
sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
-sp<IGnssBatching_V1_0> gnssBatchingIface = nullptr;
-sp<IGnssBatching_V2_0> gnssBatchingIface_V2_0 = nullptr;
sp<IGnssDebug_V1_0> gnssDebugIface = nullptr;
sp<IGnssDebug_V2_0> gnssDebugIface_V2_0 = nullptr;
sp<IGnssNi> gnssNiIface = nullptr;
@@ -249,6 +235,7 @@ sp<IGnssAntennaInfo> gnssAntennaInfoIface = nullptr;
std::unique_ptr<GnssConfigurationInterface> gnssConfigurationIface = nullptr;
std::unique_ptr<android::gnss::GnssMeasurementInterface> gnssMeasurementIface = nullptr;
+std::unique_ptr<android::gnss::GnssBatchingInterface> gnssBatchingIface = nullptr;
#define WAKE_LOCK_NAME "GPS"
@@ -301,103 +288,6 @@ private:
const char* mNativeString;
};
-static jobject translateGnssLocation(JNIEnv* env, const GnssLocationAidl& location) {
- JavaObject object(env, class_location, method_locationCtor, "gps");
-
- uint32_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
- if (flags & GnssLocationAidl::HAS_LAT_LONG) {
- SET(Latitude, location.latitudeDegrees);
- SET(Longitude, location.longitudeDegrees);
- }
- if (flags & GnssLocationAidl::HAS_ALTITUDE) {
- SET(Altitude, location.altitudeMeters);
- }
- if (flags & GnssLocationAidl::HAS_SPEED) {
- SET(Speed, (float)location.speedMetersPerSec);
- }
- if (flags & GnssLocationAidl::HAS_BEARING) {
- SET(Bearing, (float)location.bearingDegrees);
- }
- if (flags & GnssLocationAidl::HAS_HORIZONTAL_ACCURACY) {
- SET(Accuracy, (float)location.horizontalAccuracyMeters);
- }
- if (flags & GnssLocationAidl::HAS_VERTICAL_ACCURACY) {
- SET(VerticalAccuracyMeters, (float)location.verticalAccuracyMeters);
- }
- if (flags & GnssLocationAidl::HAS_SPEED_ACCURACY) {
- SET(SpeedAccuracyMetersPerSecond, (float)location.speedAccuracyMetersPerSecond);
- }
- if (flags & GnssLocationAidl::HAS_BEARING_ACCURACY) {
- SET(BearingAccuracyDegrees, (float)location.bearingAccuracyDegrees);
- }
- SET(Time, location.timestampMillis);
-
- flags = static_cast<uint32_t>(location.elapsedRealtime.flags);
- if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIMESTAMP_NS) {
- SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
- }
- if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) {
- SET(ElapsedRealtimeUncertaintyNanos,
- static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
- }
-
- return object.get();
-}
-
-static jobject translateGnssLocation(JNIEnv* env,
- const GnssLocation_V1_0& location) {
- JavaObject object(env, class_location, method_locationCtor, "gps");
-
- uint16_t flags = static_cast<uint16_t>(location.gnssLocationFlags);
- if (flags & GnssLocationFlags::HAS_LAT_LONG) {
- SET(Latitude, location.latitudeDegrees);
- SET(Longitude, location.longitudeDegrees);
- }
- if (flags & GnssLocationFlags::HAS_ALTITUDE) {
- SET(Altitude, location.altitudeMeters);
- }
- if (flags & GnssLocationFlags::HAS_SPEED) {
- SET(Speed, location.speedMetersPerSec);
- }
- if (flags & GnssLocationFlags::HAS_BEARING) {
- SET(Bearing, location.bearingDegrees);
- }
- if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
- SET(Accuracy, location.horizontalAccuracyMeters);
- }
- if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
- SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
- }
- if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
- SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
- }
- if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
- SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
- }
- SET(Time, location.timestamp);
- SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
-
- return object.get();
-}
-
-static jobject translateGnssLocation(JNIEnv* env,
- const GnssLocation_V2_0& location) {
- JavaObject object(env, class_location, translateGnssLocation(env, location.v1_0));
-
- const uint16_t flags = static_cast<uint16_t>(location.elapsedRealtime.flags);
-
- // Overwrite ElapsedRealtimeNanos when available from HAL.
- if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
- SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
- }
-
- if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
- SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
- }
-
- return object.get();
-}
-
static GnssLocation_V1_0 createGnssLocation_V1_0(
jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
@@ -1219,66 +1109,6 @@ Return<void> AGnssRilCallback::requestRefLocCb() {
return Void();
}
-struct GnssBatchingCallbackUtil {
- template<class T>
- static Return<void> gnssLocationBatchCbImpl(const hidl_vec<T>& locations);
-private:
- GnssBatchingCallbackUtil() = delete;
-};
-
-template<class T>
-Return<void> GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(const hidl_vec<T>& locations) {
- JNIEnv* env = getJniEnv();
-
- jobjectArray jLocations = env->NewObjectArray(locations.size(), class_location, nullptr);
-
- for (uint16_t i = 0; i < locations.size(); ++i) {
- jobject jLocation = translateGnssLocation(env, locations[i]);
- env->SetObjectArrayElement(jLocations, i, jLocation);
- env->DeleteLocalRef(jLocation);
- }
-
- env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-
- env->DeleteLocalRef(jLocations);
-
- return Void();
-}
-
-/*
- * GnssBatchingCallbackAidl class implements the callback methods required by the
- * android::hardware::gnss::IGnssBatching interface.
- */
-struct GnssBatchingCallbackAidl : public android::hardware::gnss::BnGnssBatchingCallback {
- Status gnssLocationBatchCb(const std::vector<GnssLocationAidl>& locations) {
- GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(hidl_vec<GnssLocationAidl>(locations));
- return Status::ok();
- }
-};
-
-/*
- * GnssBatchingCallback_V1_0 class implements the callback methods required by the
- * IGnssBatching 1.0 interface.
- */
-struct GnssBatchingCallback_V1_0 : public IGnssBatchingCallback_V1_0 {
- /** Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback follow. */
- Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V1_0>& locations) override {
- return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
- }
-};
-
-/*
- * GnssBatchingCallback_V2_0 class implements the callback methods required by the
- * IGnssBatching 2.0 interface.
- */
-struct GnssBatchingCallback_V2_0 : public IGnssBatchingCallback_V2_0 {
- /** Methods from ::android::hardware::gps::V2_0::IGnssBatchingCallback follow. */
- Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V2_0>& locations) override {
- return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
- }
-};
-
/* Initializes the GNSS service handle. */
static void android_location_gnss_hal_GnssNative_set_gps_service_handle() {
gnssHalAidl = waitForVintfService<IGnssAidl>();
@@ -1354,10 +1184,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
clazz,
"reportNavigationMessage",
"(Landroid/location/GnssNavigationMessage;)V");
- method_reportLocationBatch = env->GetMethodID(
- clazz,
- "reportLocationBatch",
- "([Landroid/location/Location;)V");
method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
"(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
@@ -1427,17 +1253,15 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
class_gnssPowerStats = (jclass)env->NewGlobalRef(gnssPowerStatsClass);
method_gnssPowerStatsCtor = env->GetMethodID(class_gnssPowerStats, "<init>", "(IJDDDDDD[D)V");
- jclass locationClass = env->FindClass("android/location/Location");
- class_location = (jclass) env->NewGlobalRef(locationClass);
- method_locationCtor = env->GetMethodID(class_location, "<init>", "(Ljava/lang/String;)V");
-
jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass);
method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "<init>", "()V");
+ gnss::GnssAntennaInfo_class_init_once(env, clazz);
+ gnss::GnssBatching_class_init_once(env, clazz);
gnss::GnssConfiguration_class_init_once(env);
gnss::GnssMeasurement_class_init_once(env, clazz);
- gnss::GnssAntennaInfo_class_init_once(env, clazz);
+ gnss::Utils_class_init_once(env);
}
/* Initialization needed at system boot and whenever GNSS service dies. */
@@ -1672,25 +1496,21 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject
}
if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
- sp<IGnssBatchingAidl> gnssBatchingAidl;
+ sp<android::hardware::gnss::IGnssBatching> gnssBatchingAidl;
auto status = gnssHalAidl->getExtensionGnssBatching(&gnssBatchingAidl);
if (checkAidlStatus(status, "Unable to get a handle to GnssBatching interface.")) {
- gnssBatchingAidlIface = gnssBatchingAidl;
+ gnssBatchingIface = std::make_unique<gnss::GnssBatching>(gnssBatchingAidl);
}
} else if (gnssHal_V2_0 != nullptr) {
auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0();
- if (!gnssBatching_V2_0.isOk()) {
- ALOGD("Unable to get a handle to GnssBatching_V2_0");
- } else {
- gnssBatchingIface_V2_0 = gnssBatching_V2_0;
+ if (checkHidlReturn(gnssBatching_V2_0, "Unable to get a handle to GnssBatching_V2_0")) {
+ gnssBatchingIface = std::make_unique<gnss::GnssBatching_V2_0>(gnssBatching_V2_0);
}
}
- if (gnssBatchingIface_V2_0 == nullptr ) {
+ if (gnssBatchingIface == nullptr) {
auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching();
- if (!gnssBatching_V1_0.isOk()) {
- ALOGD("Unable to get a handle to GnssBatching");
- } else {
- gnssBatchingIface = gnssBatching_V1_0;
+ if (checkHidlReturn(gnssBatching_V1_0, "Unable to get a handle to GnssBatching")) {
+ gnssBatchingIface = std::make_unique<gnss::GnssBatching_V1_0>(gnssBatching_V1_0);
}
}
@@ -2786,92 +2606,46 @@ static jboolean android_location_GnssConfiguration_set_es_extension_sec(
}
static jint android_location_gnss_hal_GnssNative_get_batch_size(JNIEnv*) {
- if (gnssBatchingAidlIface != nullptr) {
- int size = 0;
- auto status = gnssBatchingAidlIface->getBatchSize(&size);
- if (!checkAidlStatus(status, "IGnssBatchingAidl getBatchSize() failed")) {
- return 0;
- }
- return size;
- } else if (gnssBatchingIface != nullptr) {
- auto result = gnssBatchingIface->getBatchSize();
- if (!checkHidlReturn(result, "IGnssBatching getBatchSize() failed.")) {
- return 0; // failure in binder, don't support batching
- }
- return static_cast<jint>(result);
+ if (gnssBatchingIface == nullptr) {
+ return 0; // batching not supported, size = 0
}
- return 0; // batching not supported, size = 0
+ return gnssBatchingIface->getBatchSize();
}
static jboolean android_location_gnss_hal_GnssNative_init_batching(JNIEnv*, jclass) {
- if (gnssBatchingAidlIface != nullptr) {
- sp<IGnssBatchingCallbackAidl> gnssBatchingCbIface = new GnssBatchingCallbackAidl();
- auto status = gnssBatchingAidlIface->init(gnssBatchingCbIface);
- return checkAidlStatus(status, "IGnssBatchingAidl init() failed.");
- } else if (gnssBatchingIface_V2_0 != nullptr) {
- sp<IGnssBatchingCallback_V2_0> gnssBatchingCbIface_V2_0 = new GnssBatchingCallback_V2_0();
- auto result = gnssBatchingIface_V2_0->init_2_0(gnssBatchingCbIface_V2_0);
- return checkHidlReturn(result, "IGnssBatching init_2_0() failed.");
- } else if (gnssBatchingIface != nullptr) {
- sp<IGnssBatchingCallback_V1_0> gnssBatchingCbIface_V1_0 = new GnssBatchingCallback_V1_0();
- auto result = gnssBatchingIface->init(gnssBatchingCbIface_V1_0);
- return checkHidlReturn(result, "IGnssBatching init() failed.");
- } else {
+ if (gnssBatchingIface == nullptr) {
return JNI_FALSE; // batching not supported
}
+ return gnssBatchingIface->init(std::make_unique<gnss::GnssBatchingCallback>());
}
static void android_location_gnss_hal_GnssNative_cleanup_batching(JNIEnv*, jclass) {
- if (gnssBatchingAidlIface != nullptr) {
- auto status = gnssBatchingAidlIface->cleanup();
- checkAidlStatus(status, "IGnssBatchingAidl cleanup() failed");
- } else if (gnssBatchingIface != nullptr) {
- auto result = gnssBatchingIface->cleanup();
- checkHidlReturn(result, "IGnssBatching cleanup() failed.");
+ if (gnssBatchingIface == nullptr) {
+ return; // batching not supported
}
- return;
+ gnssBatchingIface->cleanup();
}
static jboolean android_location_gnss_hal_GnssNative_start_batch(JNIEnv*, jclass, jlong periodNanos,
jboolean wakeOnFifoFull) {
- IGnssBatching_V1_0::Options options;
- options.periodNanos = periodNanos;
- if (wakeOnFifoFull) {
- options.flags = static_cast<uint8_t>(IGnssBatching_V1_0::Flag::WAKEUP_ON_FIFO_FULL);
- } else {
- options.flags = 0;
- }
-
- if (gnssBatchingAidlIface != nullptr) {
- auto status = gnssBatchingAidlIface->start(periodNanos, (int)options.flags);
- return checkAidlStatus(status, "IGnssBatchingAidl start() failed.");
- } else if (gnssBatchingIface != nullptr) {
- auto result = gnssBatchingIface->start(options);
- return checkHidlReturn(result, "IGnssBatching start() failed.");
+ if (gnssBatchingIface == nullptr) {
+ return JNI_FALSE; // batching not supported
}
- return JNI_FALSE; // batching not supported
+ return gnssBatchingIface->start(periodNanos, wakeOnFifoFull);
}
static void android_location_gnss_hal_GnssNative_flush_batch(JNIEnv*, jclass) {
- if (gnssBatchingAidlIface != nullptr) {
- auto status = gnssBatchingAidlIface->flush();
- checkAidlStatus(status, "IGnssBatchingAidl flush() failed.");
- } else if (gnssBatchingIface != nullptr) {
- auto result = gnssBatchingIface->flush();
- checkHidlReturn(result, "IGnssBatching flush() failed.");
+ if (gnssBatchingIface == nullptr) {
+ return; // batching not supported
}
- return;
+ gnssBatchingIface->flush();
}
static jboolean android_location_gnss_hal_GnssNative_stop_batch(JNIEnv*, jclass) {
- if (gnssBatchingAidlIface != nullptr) {
- auto status = gnssBatchingAidlIface->stop();
- return checkAidlStatus(status, "IGnssBatchingAidl stop() failed.");
- } else if (gnssBatchingIface != nullptr) {
- auto result = gnssBatchingIface->stop();
- return checkHidlReturn(result, "IGnssBatching stop() failed.");
- }
- return JNI_FALSE; // batching not supported
+ if (gnssBatchingIface == nullptr) {
+ return JNI_FALSE; // batching not supported
+ }
+ return gnssBatchingIface->stop();
}
static jboolean android_location_GnssVisibilityControl_enable_nfw_location_access(
diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp
index 9085fa726c60..090166a0bc1d 100644
--- a/services/core/jni/gnss/Android.bp
+++ b/services/core/jni/gnss/Android.bp
@@ -24,6 +24,8 @@ cc_library_shared {
srcs: [
"GnssAntennaInfoCallback.cpp",
+ "GnssBatching.cpp",
+ "GnssBatchingCallback.cpp",
"GnssConfiguration.cpp",
"GnssMeasurement.cpp",
"GnssMeasurementCallback.cpp",
diff --git a/services/core/jni/gnss/GnssBatching.cpp b/services/core/jni/gnss/GnssBatching.cpp
new file mode 100644
index 000000000000..b66bf21381c7
--- /dev/null
+++ b/services/core/jni/gnss/GnssBatching.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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 "GnssBatchingJni"
+
+#include "GnssBatching.h"
+
+#include "Utils.h"
+
+using android::hardware::gnss::IGnssBatching;
+using IGnssBatching_V1_0 = android::hardware::gnss::V1_0::IGnssBatching;
+using IGnssBatching_V2_0 = android::hardware::gnss::V2_0::IGnssBatching;
+
+namespace android::gnss {
+
+// Implementation of GnssBatching (AIDL HAL)
+
+GnssBatching::GnssBatching(const sp<IGnssBatching>& iGnssBatching) : mIGnssBatching(iGnssBatching) {
+ assert(mIGnssBatching != nullptr);
+}
+
+jboolean GnssBatching::init(const std::unique_ptr<GnssBatchingCallback>& callback) {
+ auto status = mIGnssBatching->init(callback->getAidl());
+ return checkAidlStatus(status, "IGnssBatchingAidl init() failed.");
+}
+
+jint GnssBatching::getBatchSize() {
+ int size = 0;
+ auto status = mIGnssBatching->getBatchSize(&size);
+ if (!checkAidlStatus(status, "IGnssBatchingAidl getBatchSize() failed")) {
+ return 0;
+ }
+ return size;
+}
+
+jboolean GnssBatching::start(long periodNanos, bool wakeOnFifoFull) {
+ int flags = (wakeOnFifoFull) ? IGnssBatching::WAKEUP_ON_FIFO_FULL : 0;
+ auto status = mIGnssBatching->start(periodNanos, flags);
+ return checkAidlStatus(status, "IGnssBatchingAidl start() failed.");
+}
+
+jboolean GnssBatching::stop() {
+ auto status = mIGnssBatching->stop();
+ return checkAidlStatus(status, "IGnssBatchingAidl stop() failed.");
+}
+
+jboolean GnssBatching::flush() {
+ auto status = mIGnssBatching->flush();
+ return checkAidlStatus(status, "IGnssBatchingAidl flush() failed.");
+}
+
+jboolean GnssBatching::cleanup() {
+ auto status = mIGnssBatching->cleanup();
+ return checkAidlStatus(status, "IGnssBatchingAidl cleanup() failed");
+}
+
+// Implementation of GnssBatching_V1_0
+
+GnssBatching_V1_0::GnssBatching_V1_0(const sp<IGnssBatching_V1_0>& iGnssBatching)
+ : mIGnssBatching_V1_0(iGnssBatching) {
+ assert(mIGnssBatching_V1_0 != nullptr);
+}
+
+jboolean GnssBatching_V1_0::init(const std::unique_ptr<GnssBatchingCallback>& callback) {
+ auto result = mIGnssBatching_V1_0->init(callback->getV1_0());
+ return checkHidlReturn(result, "IGnssBatching_V1_0 init() failed.");
+}
+
+jint GnssBatching_V1_0::getBatchSize() {
+ auto result = mIGnssBatching_V1_0->getBatchSize();
+ if (!checkHidlReturn(result, "IGnssBatching getBatchSize() failed.")) {
+ return 0; // failure in binder, don't support batching
+ }
+ return static_cast<jint>(result);
+}
+
+jboolean GnssBatching_V1_0::start(long periodNanos, bool wakeOnFifoFull) {
+ IGnssBatching_V1_0::Options options;
+ options.periodNanos = periodNanos;
+ if (wakeOnFifoFull) {
+ options.flags = static_cast<uint8_t>(IGnssBatching_V1_0::Flag::WAKEUP_ON_FIFO_FULL);
+ } else {
+ options.flags = 0;
+ }
+
+ auto result = mIGnssBatching_V1_0->start(options);
+ return checkHidlReturn(result, "IGnssBatching start() failed.");
+}
+
+jboolean GnssBatching_V1_0::stop() {
+ auto result = mIGnssBatching_V1_0->stop();
+ return checkHidlReturn(result, "IGnssBatching stop() failed.");
+}
+
+jboolean GnssBatching_V1_0::flush() {
+ auto result = mIGnssBatching_V1_0->flush();
+ return checkHidlReturn(result, "IGnssBatching flush() failed.");
+}
+
+jboolean GnssBatching_V1_0::cleanup() {
+ auto result = mIGnssBatching_V1_0->cleanup();
+ return checkHidlReturn(result, "IGnssBatching cleanup() failed.");
+}
+
+// Implementation of GnssBatching_V2_0
+
+GnssBatching_V2_0::GnssBatching_V2_0(const sp<IGnssBatching_V2_0>& iGnssBatching)
+ : GnssBatching_V1_0{iGnssBatching}, mIGnssBatching_V2_0(iGnssBatching) {
+ assert(mIGnssBatching_V2_0 != nullptr);
+}
+
+jboolean GnssBatching_V2_0::init(const std::unique_ptr<GnssBatchingCallback>& callback) {
+ auto result = mIGnssBatching_V2_0->init_2_0(callback->getV2_0());
+ return checkHidlReturn(result, "IGnssBatching_V2_0 init() failed.");
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssBatching.h b/services/core/jni/gnss/GnssBatching.h
new file mode 100644
index 000000000000..a98ca9b0e492
--- /dev/null
+++ b/services/core/jni/gnss/GnssBatching.h
@@ -0,0 +1,86 @@
+/*
+ * 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_GNSSBATCHING_H
+#define _ANDROID_SERVER_GNSS_GNSSBATCHING_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
+#include <android/hardware/gnss/BnGnssBatching.h>
+#include <log/log.h>
+
+#include "GnssBatchingCallback.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+class GnssBatchingInterface {
+public:
+ virtual ~GnssBatchingInterface() {}
+ virtual jboolean init(const std::unique_ptr<GnssBatchingCallback>& callback) = 0;
+ virtual jint getBatchSize() = 0;
+ virtual jboolean start(long periodNanos, bool wakeupOnFifoFull) = 0;
+ virtual jboolean stop() = 0;
+ virtual jboolean flush() = 0;
+ virtual jboolean cleanup() = 0;
+};
+
+class GnssBatching : public GnssBatchingInterface {
+public:
+ GnssBatching(const sp<android::hardware::gnss::IGnssBatching>& iGnssBatching);
+ jboolean init(const std::unique_ptr<GnssBatchingCallback>& callback) override;
+ jint getBatchSize() override;
+ jboolean start(long periodNanos, bool wakeupOnFifoFull) override;
+ jboolean stop() override;
+ jboolean flush() override;
+ jboolean cleanup() override;
+
+private:
+ const sp<android::hardware::gnss::IGnssBatching> mIGnssBatching;
+};
+
+class GnssBatching_V1_0 : public GnssBatchingInterface {
+public:
+ GnssBatching_V1_0(const sp<android::hardware::gnss::V1_0::IGnssBatching>& iGnssBatching);
+ jboolean init(const std::unique_ptr<GnssBatchingCallback>& callback) override;
+ jint getBatchSize() override;
+ jboolean start(long periodNanos, bool wakeupOnFifoFull) override;
+ jboolean stop() override;
+ jboolean flush() override;
+ jboolean cleanup() override;
+
+private:
+ const sp<android::hardware::gnss::V1_0::IGnssBatching> mIGnssBatching_V1_0;
+};
+
+class GnssBatching_V2_0 : public GnssBatching_V1_0 {
+public:
+ GnssBatching_V2_0(const sp<android::hardware::gnss::V2_0::IGnssBatching>& iGnssBatching);
+ jboolean init(const std::unique_ptr<GnssBatchingCallback>& callback) override;
+
+private:
+ const sp<android::hardware::gnss::V2_0::IGnssBatching> mIGnssBatching_V2_0;
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_GNSSBATCHING_H
diff --git a/services/core/jni/gnss/GnssBatchingCallback.cpp b/services/core/jni/gnss/GnssBatchingCallback.cpp
new file mode 100644
index 000000000000..d2a55472b6d4
--- /dev/null
+++ b/services/core/jni/gnss/GnssBatchingCallback.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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 "GnssBatchingCbJni"
+
+#include "GnssBatchingCallback.h"
+
+namespace android::gnss {
+
+namespace {
+
+jmethodID method_reportLocationBatch;
+
+} // anonymous namespace
+
+using android::hardware::hidl_vec;
+using binder::Status;
+using hardware::Return;
+
+using GnssLocationAidl = android::hardware::gnss::GnssLocation;
+using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
+
+void GnssBatching_class_init_once(JNIEnv* env, jclass clazz) {
+ method_reportLocationBatch =
+ env->GetMethodID(clazz, "reportLocationBatch", "([Landroid/location/Location;)V");
+}
+
+Status GnssBatchingCallbackAidl::gnssLocationBatchCb(
+ const std::vector<android::hardware::gnss::GnssLocation>& locations) {
+ GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(hidl_vec<GnssLocationAidl>(locations));
+ return Status::ok();
+}
+
+Return<void> GnssBatchingCallback_V1_0::gnssLocationBatchCb(
+ const hidl_vec<GnssLocation_V1_0>& locations) {
+ return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
+}
+
+Return<void> GnssBatchingCallback_V2_0::gnssLocationBatchCb(
+ const hidl_vec<GnssLocation_V2_0>& locations) {
+ return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssBatchingCallback.h b/services/core/jni/gnss/GnssBatchingCallback.h
new file mode 100644
index 000000000000..a9dd43043162
--- /dev/null
+++ b/services/core/jni/gnss/GnssBatchingCallback.h
@@ -0,0 +1,128 @@
+/*
+ * 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_GNSSBATCHCALLBACK_H
+#define _ANDROID_SERVER_GNSS_GNSSBATCHCALLBACK_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
+#include <android/hardware/gnss/BnGnssBatchingCallback.h>
+#include <log/log.h>
+
+#include <vector>
+
+#include "Utils.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+namespace {
+
+extern jmethodID method_reportLocationBatch;
+
+} // anonymous namespace
+
+void GnssBatching_class_init_once(JNIEnv* env, jclass clazz);
+
+class GnssBatchingCallbackAidl : public hardware::gnss::BnGnssBatchingCallback {
+public:
+ GnssBatchingCallbackAidl() {}
+ android::binder::Status gnssLocationBatchCb(
+ const std::vector<android::hardware::gnss::GnssLocation>& locations) override;
+};
+
+class GnssBatchingCallback_V1_0 : public hardware::gnss::V1_0::IGnssBatchingCallback {
+public:
+ GnssBatchingCallback_V1_0() {}
+ hardware::Return<void> gnssLocationBatchCb(
+ const hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation>& locations) override;
+};
+
+class GnssBatchingCallback_V2_0 : public hardware::gnss::V2_0::IGnssBatchingCallback {
+public:
+ GnssBatchingCallback_V2_0() {}
+ hardware::Return<void> gnssLocationBatchCb(
+ const hardware::hidl_vec<hardware::gnss::V2_0::GnssLocation>& locations) override;
+};
+
+class GnssBatchingCallback {
+public:
+ GnssBatchingCallback() {}
+ sp<GnssBatchingCallbackAidl> getAidl() {
+ if (callbackAidl == nullptr) {
+ callbackAidl = sp<GnssBatchingCallbackAidl>::make();
+ }
+ return callbackAidl;
+ }
+
+ sp<GnssBatchingCallback_V1_0> getV1_0() {
+ if (callbackV1_0 == nullptr) {
+ callbackV1_0 = sp<GnssBatchingCallback_V1_0>::make();
+ }
+ return callbackV1_0;
+ }
+
+ sp<GnssBatchingCallback_V2_0> getV2_0() {
+ if (callbackV2_0 == nullptr) {
+ callbackV2_0 = sp<GnssBatchingCallback_V2_0>::make();
+ }
+ return callbackV2_0;
+ }
+
+private:
+ sp<GnssBatchingCallbackAidl> callbackAidl;
+ sp<GnssBatchingCallback_V1_0> callbackV1_0;
+ sp<GnssBatchingCallback_V2_0> callbackV2_0;
+};
+
+struct GnssBatchingCallbackUtil {
+ template <class T>
+ static hardware::Return<void> gnssLocationBatchCbImpl(const hardware::hidl_vec<T>& locations);
+
+private:
+ GnssBatchingCallbackUtil() = delete;
+};
+
+template <class T>
+hardware::Return<void> GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(
+ const hardware::hidl_vec<T>& locations) {
+ JNIEnv* env = getJniEnv();
+
+ jobjectArray jLocations = env->NewObjectArray(locations.size(), class_location, nullptr);
+
+ for (uint16_t i = 0; i < locations.size(); ++i) {
+ jobject jLocation = translateGnssLocation(env, locations[i]);
+ env->SetObjectArrayElement(jLocations, i, jLocation);
+ env->DeleteLocalRef(jLocation);
+ }
+
+ env->CallVoidMethod(android::getCallbacksObj(), method_reportLocationBatch, jLocations);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+
+ env->DeleteLocalRef(jLocations);
+
+ return hardware::Void();
+}
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_GNSSBATCHCALLBACK_H \ No newline at end of file
diff --git a/services/core/jni/gnss/Utils.cpp b/services/core/jni/gnss/Utils.cpp
index 8cbdfb8d294e..40a94ce62b05 100644
--- a/services/core/jni/gnss/Utils.cpp
+++ b/services/core/jni/gnss/Utils.cpp
@@ -18,6 +18,9 @@
#include "Utils.h"
+#include <android/hardware/gnss/1.0/IGnss.h>
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <utils/SystemClock.h>
/*
* Save a pointer to JavaVm to attach/detach threads executing
* callback methods that need to make JNI calls.
@@ -29,9 +32,29 @@ namespace android {
namespace {
thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
+jmethodID method_locationCtor;
} // anonymous namespace
+jclass class_location;
+
+namespace gnss {
+void Utils_class_init_once(JNIEnv* env) {
+ jclass locationClass = env->FindClass("android/location/Location");
+ class_location = (jclass)env->NewGlobalRef(locationClass);
+ method_locationCtor = env->GetMethodID(class_location, "<init>", "(Ljava/lang/String;)V");
+}
+} // namespace gnss
+
+jobject mCallbacksObj = nullptr;
+
+jobject& getCallbacksObj() {
+ return mCallbacksObj;
+}
+
+using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
+
// Define Java method signatures for all known types.
template <>
const char* const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
@@ -130,4 +153,103 @@ JNIEnv* getJniEnv() {
return env;
}
+template <>
+jobject translateGnssLocation(JNIEnv* env, const android::hardware::gnss::GnssLocation& location) {
+ JavaObject object(env, class_location, method_locationCtor, "gps");
+
+ uint32_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
+ if (flags & android::hardware::gnss::GnssLocation::HAS_LAT_LONG) {
+ SET(Latitude, location.latitudeDegrees);
+ SET(Longitude, location.longitudeDegrees);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_ALTITUDE) {
+ SET(Altitude, location.altitudeMeters);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_SPEED) {
+ SET(Speed, (float)location.speedMetersPerSec);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_BEARING) {
+ SET(Bearing, (float)location.bearingDegrees);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_HORIZONTAL_ACCURACY) {
+ SET(Accuracy, (float)location.horizontalAccuracyMeters);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_VERTICAL_ACCURACY) {
+ SET(VerticalAccuracyMeters, (float)location.verticalAccuracyMeters);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_SPEED_ACCURACY) {
+ SET(SpeedAccuracyMetersPerSecond, (float)location.speedAccuracyMetersPerSecond);
+ }
+ if (flags & android::hardware::gnss::GnssLocation::HAS_BEARING_ACCURACY) {
+ SET(BearingAccuracyDegrees, (float)location.bearingAccuracyDegrees);
+ }
+ SET(Time, location.timestampMillis);
+
+ flags = static_cast<uint32_t>(location.elapsedRealtime.flags);
+ if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIMESTAMP_NS) {
+ SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
+ }
+ if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) {
+ SET(ElapsedRealtimeUncertaintyNanos,
+ static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
+ }
+
+ return object.get();
+}
+
+template <>
+jobject translateGnssLocation(JNIEnv* env, const GnssLocation_V1_0& location) {
+ JavaObject object(env, class_location, method_locationCtor, "gps");
+
+ uint16_t flags = static_cast<uint16_t>(location.gnssLocationFlags);
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) {
+ SET(Latitude, location.latitudeDegrees);
+ SET(Longitude, location.longitudeDegrees);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) {
+ SET(Altitude, location.altitudeMeters);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) {
+ SET(Speed, location.speedMetersPerSec);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) {
+ SET(Bearing, location.bearingDegrees);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
+ SET(Accuracy, location.horizontalAccuracyMeters);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+ SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
+ SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
+ }
+ if (flags & android::hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
+ SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
+ }
+ SET(Time, location.timestamp);
+ SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
+
+ return object.get();
+}
+
+template <>
+jobject translateGnssLocation(JNIEnv* env, const GnssLocation_V2_0& location) {
+ JavaObject object(env, class_location, translateGnssLocation(env, location.v1_0));
+
+ const uint16_t flags = static_cast<uint16_t>(location.elapsedRealtime.flags);
+
+ // Overwrite ElapsedRealtimeNanos when available from HAL.
+ if (flags & android::hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+ SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
+ }
+
+ if (flags & android::hardware::gnss::V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+ SET(ElapsedRealtimeUncertaintyNanos,
+ static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
+ }
+
+ return object.get();
+}
+
} // namespace android
diff --git a/services/core/jni/gnss/Utils.h b/services/core/jni/gnss/Utils.h
index 0938a1b30dc8..1bd69c46527e 100644
--- a/services/core/jni/gnss/Utils.h
+++ b/services/core/jni/gnss/Utils.h
@@ -37,11 +37,19 @@ namespace {
// Must match the value from GnssMeasurement.java
const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1 << 4);
+extern jmethodID method_locationCtor;
} // anonymous namespace
+extern jclass class_location;
extern jobject mCallbacksObj;
+namespace gnss {
+void Utils_class_init_once(JNIEnv* env);
+} // namespace gnss
+
+jobject& getCallbacksObj();
+
jboolean checkHidlReturn(hardware::Return<bool>& result, const char* errorMessage);
jboolean checkAidlStatus(const android::binder::Status& status, const char* errorMessage);
@@ -190,6 +198,9 @@ private:
JNIEnv* getJniEnv();
+template <class T>
+jobject translateGnssLocation(JNIEnv* env, const T& location);
+
} // namespace android
#endif // _ANDROID_SERVER_GNSS_UTILS_H