Merge "Add AGnss AIDL HAL (frameworks/base)"
This commit is contained in:
committed by
Android (Google) Code Review
commit
6f0f3d81bc
@@ -37,10 +37,7 @@
|
||||
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
|
||||
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
|
||||
#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
@@ -52,6 +49,7 @@
|
||||
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
#include "android_runtime/Log.h"
|
||||
#include "gnss/AGnss.h"
|
||||
#include "gnss/GnssAntennaInfoCallback.h"
|
||||
#include "gnss/GnssBatching.h"
|
||||
#include "gnss/GnssConfiguration.h"
|
||||
@@ -69,7 +67,6 @@ static jclass class_gnssPowerStats;
|
||||
static jmethodID method_reportLocation;
|
||||
static jmethodID method_reportStatus;
|
||||
static jmethodID method_reportSvStatus;
|
||||
static jmethodID method_reportAGpsStatus;
|
||||
static jmethodID method_reportNmea;
|
||||
static jmethodID method_setTopHalCapabilities;
|
||||
static jmethodID method_setGnssYearOfHardware;
|
||||
@@ -163,10 +160,6 @@ using IGnssDebug_V2_0 = android::hardware::gnss::V2_0::IGnssDebug;
|
||||
using IGnssAntennaInfo = android::hardware::gnss::V2_1::IGnssAntennaInfo;
|
||||
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;
|
||||
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 IMeasurementCorrections_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
|
||||
using IMeasurementCorrections_V1_1 = android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections;
|
||||
@@ -182,6 +175,7 @@ using android::hardware::gnss::GnssPowerStats;
|
||||
using android::hardware::gnss::IGnssPowerIndication;
|
||||
using android::hardware::gnss::IGnssPowerIndicationCallback;
|
||||
using android::hardware::gnss::PsdsType;
|
||||
using IAGnssAidl = android::hardware::gnss::IAGnss;
|
||||
using IGnssAidl = android::hardware::gnss::IGnss;
|
||||
using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback;
|
||||
using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching;
|
||||
@@ -215,8 +209,6 @@ sp<IGnssPsdsAidl> gnssPsdsAidlIface = nullptr;
|
||||
sp<IGnssXtra> gnssXtraIface = nullptr;
|
||||
sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
|
||||
sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
|
||||
sp<IAGnss_V1_0> agnssIface = nullptr;
|
||||
sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
|
||||
sp<IGnssDebug_V1_0> gnssDebugIface = nullptr;
|
||||
sp<IGnssDebug_V2_0> gnssDebugIface_V2_0 = nullptr;
|
||||
sp<IGnssNi> gnssNiIface = nullptr;
|
||||
@@ -231,6 +223,7 @@ std::unique_ptr<android::gnss::GnssMeasurementInterface> gnssMeasurementIface =
|
||||
std::unique_ptr<android::gnss::GnssNavigationMessageInterface> gnssNavigationMessageIface = nullptr;
|
||||
std::unique_ptr<android::gnss::GnssBatchingInterface> gnssBatchingIface = nullptr;
|
||||
std::unique_ptr<android::gnss::GnssGeofenceInterface> gnssGeofencingIface = nullptr;
|
||||
std::unique_ptr<android::gnss::AGnssInterface> agnssIface = nullptr;
|
||||
|
||||
#define WAKE_LOCK_NAME "GPS"
|
||||
|
||||
@@ -255,34 +248,6 @@ static inline jboolean boolToJbool(bool value) {
|
||||
return value ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
struct ScopedJniString {
|
||||
ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) {
|
||||
mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr);
|
||||
}
|
||||
|
||||
~ScopedJniString() {
|
||||
if (mNativeString != nullptr) {
|
||||
mEnv->ReleaseStringUTFChars(mJavaString, mNativeString);
|
||||
}
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return mNativeString;
|
||||
}
|
||||
|
||||
operator hidl_string() const {
|
||||
return hidl_string(mNativeString);
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedJniString(const ScopedJniString&) = delete;
|
||||
ScopedJniString& operator=(const ScopedJniString&) = delete;
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jstring mJavaString;
|
||||
const char* mNativeString;
|
||||
};
|
||||
|
||||
static GnssLocation_V1_0 createGnssLocation_V1_0(
|
||||
jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
|
||||
jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
|
||||
@@ -805,122 +770,6 @@ Return<bool> GnssVisibilityControlCallback::isInEmergencySession() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface.
|
||||
*/
|
||||
struct AGnssCallback_V1_0 : public IAGnssCallback_V1_0 {
|
||||
// Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
|
||||
Return<void> agnssStatusIpV6Cb(
|
||||
const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) override;
|
||||
|
||||
Return<void> agnssStatusIpV4Cb(
|
||||
const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) override;
|
||||
private:
|
||||
jbyteArray convertToIpV4(uint32_t ip);
|
||||
};
|
||||
|
||||
Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb(
|
||||
const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) {
|
||||
JNIEnv* env = getJniEnv();
|
||||
jbyteArray byteArray = nullptr;
|
||||
|
||||
byteArray = env->NewByteArray(16);
|
||||
if (byteArray != nullptr) {
|
||||
env->SetByteArrayRegion(byteArray, 0, 16,
|
||||
(const jbyte*)(agps_status.ipV6Addr.data()));
|
||||
} else {
|
||||
ALOGE("Unable to allocate byte array for IPv6 address.");
|
||||
}
|
||||
|
||||
IF_ALOGD() {
|
||||
// log the IP for reference in case there is a bogus value pushed by HAL
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
|
||||
ALOGD("AGPS IP is v6: %s", str);
|
||||
}
|
||||
|
||||
jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
|
||||
ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
|
||||
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
|
||||
agps_status.type, agps_status.status, byteArray);
|
||||
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
|
||||
if (byteArray) {
|
||||
env->DeleteLocalRef(byteArray);
|
||||
}
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb(
|
||||
const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) {
|
||||
JNIEnv* env = getJniEnv();
|
||||
jbyteArray byteArray = nullptr;
|
||||
|
||||
uint32_t ipAddr = agps_status.ipV4Addr;
|
||||
byteArray = convertToIpV4(ipAddr);
|
||||
|
||||
IF_ALOGD() {
|
||||
/*
|
||||
* log the IP for reference in case there is a bogus value pushed by
|
||||
* HAL.
|
||||
*/
|
||||
char str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
|
||||
ALOGD("AGPS IP is v4: %s", str);
|
||||
}
|
||||
|
||||
jsize byteArrayLength =
|
||||
byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
|
||||
ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
|
||||
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
|
||||
agps_status.type, agps_status.status, byteArray);
|
||||
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
|
||||
if (byteArray) {
|
||||
env->DeleteLocalRef(byteArray);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) {
|
||||
if (INADDR_NONE == ip) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JNIEnv* env = getJniEnv();
|
||||
jbyteArray byteArray = env->NewByteArray(4);
|
||||
if (byteArray == nullptr) {
|
||||
ALOGE("Unable to allocate byte array for IPv4 address");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jbyte ipv4[4];
|
||||
ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
|
||||
memcpy(ipv4, &ip, sizeof(ipv4));
|
||||
env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface.
|
||||
*/
|
||||
struct AGnssCallback_V2_0 : public IAGnssCallback_V2_0 {
|
||||
// Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow.
|
||||
Return<void> agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
|
||||
IAGnssCallback_V2_0::AGnssStatusValue status) override;
|
||||
};
|
||||
|
||||
Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
|
||||
IAGnssCallback_V2_0::AGnssStatusValue status) {
|
||||
JNIEnv* env = getJniEnv();
|
||||
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr);
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
return Void();
|
||||
}
|
||||
|
||||
/*
|
||||
* AGnssRilCallback implements the callback methods required by the AGnssRil
|
||||
* interface.
|
||||
@@ -990,7 +839,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
|
||||
"(ZLandroid/location/Location;)V");
|
||||
method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
|
||||
method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V");
|
||||
method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
|
||||
method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
|
||||
method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");
|
||||
method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
|
||||
@@ -1077,6 +925,7 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
|
||||
gnss::GnssConfiguration_class_init_once(env);
|
||||
gnss::GnssMeasurement_class_init_once(env, clazz);
|
||||
gnss::GnssNavigationMessage_class_init_once(env, clazz);
|
||||
gnss::AGnss_class_init_once(env, clazz);
|
||||
gnss::Utils_class_init_once(env);
|
||||
}
|
||||
|
||||
@@ -1147,19 +996,21 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject
|
||||
}
|
||||
}
|
||||
|
||||
if (gnssHal_V2_0 != nullptr) {
|
||||
if (gnssHalAidl != nullptr) {
|
||||
sp<IAGnssAidl> agnssAidl;
|
||||
auto status = gnssHalAidl->getExtensionAGnss(&agnssAidl);
|
||||
if (checkAidlStatus(status, "Unable to get a handle to AGnss interface.")) {
|
||||
agnssIface = std::make_unique<gnss::AGnss>(agnssAidl);
|
||||
}
|
||||
} else if (gnssHal_V2_0 != nullptr) {
|
||||
auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
|
||||
if (!agnss_V2_0.isOk()) {
|
||||
ALOGD("Unable to get a handle to AGnss_V2_0");
|
||||
} else {
|
||||
agnssIface_V2_0 = agnss_V2_0;
|
||||
if (checkHidlReturn(agnss_V2_0, "Unable to get a handle to AGnss_V2_0")) {
|
||||
agnssIface = std::make_unique<gnss::AGnss_V2_0>(agnss_V2_0);
|
||||
}
|
||||
} else if (gnssHal != nullptr) {
|
||||
auto agnss_V1_0 = gnssHal->getExtensionAGnss();
|
||||
if (!agnss_V1_0.isOk()) {
|
||||
ALOGD("Unable to get a handle to AGnss");
|
||||
} else {
|
||||
agnssIface = agnss_V1_0;
|
||||
if (checkHidlReturn(agnss_V1_0, "Unable to get a handle to AGnss_V1_0")) {
|
||||
agnssIface = std::make_unique<gnss::AGnss_V1_0>(agnss_V1_0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1452,16 +1303,9 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl
|
||||
}
|
||||
}
|
||||
|
||||
// Set IAGnss.hal callback.
|
||||
if (agnssIface_V2_0 != nullptr) {
|
||||
sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
|
||||
auto agnssStatus = agnssIface_V2_0->setCallback(aGnssCbIface);
|
||||
checkHidlReturn(agnssStatus, "IAGnss 2.0 setCallback() failed.");
|
||||
} else if (agnssIface != nullptr) {
|
||||
sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
|
||||
auto agnssStatus = agnssIface->setCallback(aGnssCbIface);
|
||||
checkHidlReturn(agnssStatus, "IAGnss setCallback() failed.");
|
||||
} else {
|
||||
// Set IAGnss callback.
|
||||
if (agnssIface == nullptr ||
|
||||
!agnssIface->setCallback(std::make_unique<gnss::AGnssCallback>())) {
|
||||
ALOGI("Unable to initialize IAGnss interface.");
|
||||
}
|
||||
|
||||
@@ -1737,61 +1581,6 @@ static void android_location_gnss_hal_GnssNative_inject_psds_data(JNIEnv* env, j
|
||||
env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
|
||||
}
|
||||
|
||||
struct AGnssDispatcher {
|
||||
static void dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, jint apnIpType);
|
||||
static void dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, jlong networkHandle,
|
||||
jstring apn, jint apnIpType);
|
||||
|
||||
template <class T>
|
||||
static void dataConnClosed(sp<T> agnssIface);
|
||||
|
||||
template <class T>
|
||||
static void dataConnFailed(sp<T> agnssIface);
|
||||
|
||||
template <class T, class U>
|
||||
static void setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, jint port);
|
||||
|
||||
private:
|
||||
AGnssDispatcher() = delete;
|
||||
};
|
||||
|
||||
void AGnssDispatcher::dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn,
|
||||
jint apnIpType) {
|
||||
ScopedJniString jniApn{env, apn};
|
||||
auto result = agnssIface->dataConnOpen(jniApn,
|
||||
static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
|
||||
checkHidlReturn(result, "IAGnss dataConnOpen() failed. APN and its IP type not set.");
|
||||
}
|
||||
|
||||
void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env,
|
||||
jlong networkHandle, jstring apn, jint apnIpType) {
|
||||
ScopedJniString jniApn{env, apn};
|
||||
auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
|
||||
static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
|
||||
checkHidlReturn(result, "IAGnss 2.0 dataConnOpen() failed. APN and its IP type not set.");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) {
|
||||
auto result = agnssIface->dataConnClosed();
|
||||
checkHidlReturn(result, "IAGnss dataConnClosed() failed.");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) {
|
||||
auto result = agnssIface->dataConnFailed();
|
||||
checkHidlReturn(result, "IAGnss dataConnFailed() failed.");
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
void AGnssDispatcher::setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname,
|
||||
jint port) {
|
||||
ScopedJniString jniHostName{env, hostname};
|
||||
auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type),
|
||||
jniHostName, port);
|
||||
checkHidlReturn(result, "IAGnss setServer() failed. Host name and port not set.");
|
||||
}
|
||||
|
||||
static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
|
||||
JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
|
||||
if (apn == nullptr) {
|
||||
@@ -1799,10 +1588,8 @@ static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
|
||||
return;
|
||||
}
|
||||
|
||||
if (agnssIface_V2_0 != nullptr) {
|
||||
AGnssDispatcher::dataConnOpen(agnssIface_V2_0, env, networkHandle, apn, apnIpType);
|
||||
} else if (agnssIface != nullptr) {
|
||||
AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType);
|
||||
if (agnssIface != nullptr) {
|
||||
agnssIface->dataConnOpen(env, networkHandle, apn, apnIpType);
|
||||
} else {
|
||||
ALOGE("%s: IAGnss interface not available.", __func__);
|
||||
return;
|
||||
@@ -1811,10 +1598,8 @@ static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
|
||||
|
||||
static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
|
||||
jobject /* obj */) {
|
||||
if (agnssIface_V2_0 != nullptr) {
|
||||
AGnssDispatcher::dataConnClosed(agnssIface_V2_0);
|
||||
} else if (agnssIface != nullptr) {
|
||||
AGnssDispatcher::dataConnClosed(agnssIface);
|
||||
if (agnssIface != nullptr) {
|
||||
agnssIface->dataConnClosed();
|
||||
} else {
|
||||
ALOGE("%s: IAGnss interface not available.", __func__);
|
||||
return;
|
||||
@@ -1823,10 +1608,8 @@ static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_close
|
||||
|
||||
static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
|
||||
jobject /* obj */) {
|
||||
if (agnssIface_V2_0 != nullptr) {
|
||||
AGnssDispatcher::dataConnFailed(agnssIface_V2_0);
|
||||
} else if (agnssIface != nullptr) {
|
||||
AGnssDispatcher::dataConnFailed(agnssIface);
|
||||
if (agnssIface != nullptr) {
|
||||
agnssIface->dataConnFailed();
|
||||
} else {
|
||||
ALOGE("%s: IAGnss interface not available.", __func__);
|
||||
return;
|
||||
@@ -1835,12 +1618,8 @@ static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_faile
|
||||
|
||||
static void android_location_gnss_hal_GnssNative_set_agps_server(JNIEnv* env, jclass, jint type,
|
||||
jstring hostname, jint port) {
|
||||
if (agnssIface_V2_0 != nullptr) {
|
||||
AGnssDispatcher::setServer<IAGnss_V2_0, IAGnssCallback_V2_0>(agnssIface_V2_0, env, type,
|
||||
hostname, port);
|
||||
} else if (agnssIface != nullptr) {
|
||||
AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type,
|
||||
hostname, port);
|
||||
if (agnssIface != nullptr) {
|
||||
agnssIface->setServer(env, type, hostname, port);
|
||||
} else {
|
||||
ALOGE("%s: IAGnss interface not available.", __func__);
|
||||
return;
|
||||
|
||||
141
services/core/jni/gnss/AGnss.cpp
Normal file
141
services/core/jni/gnss/AGnss.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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 "AGnssJni"
|
||||
|
||||
#include "AGnss.h"
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
using android::hardware::gnss::IAGnss;
|
||||
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 AGnssType = android::hardware::gnss::IAGnssCallback::AGnssType;
|
||||
|
||||
namespace android::gnss {
|
||||
|
||||
// Implementation of AGnss (AIDL HAL)
|
||||
|
||||
AGnss::AGnss(const sp<IAGnss>& iAGnss) : mIAGnss(iAGnss) {
|
||||
assert(mIAGnss != nullptr);
|
||||
}
|
||||
|
||||
jboolean AGnss::setCallback(const std::unique_ptr<AGnssCallback>& callback) {
|
||||
auto status = mIAGnss->setCallback(callback->getAidl());
|
||||
return checkAidlStatus(status, "IAGnssAidl setCallback() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss::dataConnOpen(JNIEnv* env, jlong networkHandle, jstring apn, jint apnIpType) {
|
||||
ScopedJniString jniApn{env, apn};
|
||||
auto status = mIAGnss->dataConnOpen(networkHandle, String16(jniApn.c_str()),
|
||||
static_cast<IAGnss::ApnIpType>(apnIpType));
|
||||
return checkAidlStatus(status,
|
||||
"IAGnssAidl dataConnOpen() failed. APN and its IP type not set.");
|
||||
}
|
||||
|
||||
jboolean AGnss::dataConnClosed() {
|
||||
auto status = mIAGnss->dataConnClosed();
|
||||
return checkAidlStatus(status, "IAGnssAidl dataConnClosed() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss::dataConnFailed() {
|
||||
auto status = mIAGnss->dataConnFailed();
|
||||
return checkAidlStatus(status, "IAGnssAidl dataConnFailed() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss::setServer(JNIEnv* env, jint type, jstring hostname, jint port) {
|
||||
ScopedJniString jniHostName{env, hostname};
|
||||
auto status =
|
||||
mIAGnss->setServer(static_cast<AGnssType>(type), String16(jniHostName.c_str()), port);
|
||||
return checkAidlStatus(status, "IAGnssAidl setServer() failed. Host name and port not set.");
|
||||
}
|
||||
|
||||
// Implementation of AGnss_V1_0
|
||||
|
||||
AGnss_V1_0::AGnss_V1_0(const sp<IAGnss_V1_0>& iAGnss) : mIAGnss_V1_0(iAGnss) {
|
||||
assert(mIAGnss_V1_0 != nullptr);
|
||||
}
|
||||
|
||||
jboolean AGnss_V1_0::setCallback(const std::unique_ptr<AGnssCallback>& callback) {
|
||||
auto result = mIAGnss_V1_0->setCallback(callback->getV1_0());
|
||||
return checkHidlReturn(result, "IAGnss_V1_0 setCallback() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V1_0::dataConnOpen(JNIEnv* env, jlong, jstring apn, jint apnIpType) {
|
||||
ScopedJniString jniApn{env, apn};
|
||||
auto result =
|
||||
mIAGnss_V1_0->dataConnOpen(jniApn, static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
|
||||
return checkHidlReturn(result,
|
||||
"IAGnss_V1_0 dataConnOpen() failed. APN and its IP type not set.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V1_0::dataConnClosed() {
|
||||
auto result = mIAGnss_V1_0->dataConnClosed();
|
||||
return checkHidlReturn(result, "IAGnss_V1_0 dataConnClosed() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V1_0::dataConnFailed() {
|
||||
auto result = mIAGnss_V1_0->dataConnFailed();
|
||||
return checkHidlReturn(result, "IAGnss_V1_0 dataConnFailed() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V1_0::setServer(JNIEnv* env, jint type, jstring hostname, jint port) {
|
||||
ScopedJniString jniHostName{env, hostname};
|
||||
auto result = mIAGnss_V1_0->setServer(static_cast<IAGnssCallback_V1_0::AGnssType>(type),
|
||||
jniHostName, port);
|
||||
return checkHidlReturn(result, "IAGnss_V1_0 setServer() failed. Host name and port not set.");
|
||||
}
|
||||
|
||||
// Implementation of AGnss_V2_0
|
||||
|
||||
AGnss_V2_0::AGnss_V2_0(const sp<IAGnss_V2_0>& iAGnss) : mIAGnss_V2_0(iAGnss) {
|
||||
assert(mIAGnss_V2_0 != nullptr);
|
||||
}
|
||||
|
||||
jboolean AGnss_V2_0::setCallback(const std::unique_ptr<AGnssCallback>& callback) {
|
||||
auto result = mIAGnss_V2_0->setCallback(callback->getV2_0());
|
||||
return checkHidlReturn(result, "IAGnss_V2_0 setCallback() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V2_0::dataConnOpen(JNIEnv* env, jlong networkHandle, jstring apn, jint apnIpType) {
|
||||
ScopedJniString jniApn{env, apn};
|
||||
auto result = mIAGnss_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
|
||||
static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
|
||||
return checkHidlReturn(result,
|
||||
"IAGnss_V2_0 dataConnOpen() failed. APN and its IP type not set.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V2_0::dataConnClosed() {
|
||||
auto result = mIAGnss_V2_0->dataConnClosed();
|
||||
return checkHidlReturn(result, "IAGnss_V2_0 dataConnClosed() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V2_0::dataConnFailed() {
|
||||
auto result = mIAGnss_V2_0->dataConnFailed();
|
||||
return checkHidlReturn(result, "IAGnss_V2_0 dataConnFailed() failed.");
|
||||
}
|
||||
|
||||
jboolean AGnss_V2_0::setServer(JNIEnv* env, jint type, jstring hostname, jint port) {
|
||||
ScopedJniString jniHostName{env, hostname};
|
||||
auto result = mIAGnss_V2_0->setServer(static_cast<IAGnssCallback_V2_0::AGnssType>(type),
|
||||
jniHostName, port);
|
||||
return checkHidlReturn(result, "IAGnss_V2_0 setServer() failed. Host name and port not set.");
|
||||
}
|
||||
|
||||
} // namespace android::gnss
|
||||
86
services/core/jni/gnss/AGnss.h
Normal file
86
services/core/jni/gnss/AGnss.h
Normal file
@@ -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_AGNSS_H
|
||||
#define _ANDROID_SERVER_GNSS_AGNSS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#error LOG_TAG must be defined before including this file.
|
||||
#endif
|
||||
|
||||
#include <android/hardware/gnss/BnAGnss.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include "AGnssCallback.h"
|
||||
#include "jni.h"
|
||||
|
||||
namespace android::gnss {
|
||||
|
||||
class AGnssInterface {
|
||||
public:
|
||||
virtual ~AGnssInterface() {}
|
||||
virtual jboolean setCallback(const std::unique_ptr<AGnssCallback>& callback) = 0;
|
||||
virtual jboolean dataConnOpen(JNIEnv* env, jlong networkHandle, jstring apn,
|
||||
jint apnIpType) = 0;
|
||||
virtual jboolean dataConnClosed() = 0;
|
||||
virtual jboolean dataConnFailed() = 0;
|
||||
virtual jboolean setServer(JNIEnv* env, jint type, jstring hostname, jint port) = 0;
|
||||
};
|
||||
|
||||
class AGnss : public AGnssInterface {
|
||||
public:
|
||||
AGnss(const sp<android::hardware::gnss::IAGnss>& iAGnss);
|
||||
jboolean setCallback(const std::unique_ptr<AGnssCallback>& callback) override;
|
||||
jboolean dataConnOpen(JNIEnv* env, jlong networkHandle, jstring apn, jint apnIpType) override;
|
||||
jboolean dataConnClosed() override;
|
||||
jboolean dataConnFailed() override;
|
||||
jboolean setServer(JNIEnv* env, jint type, jstring hostname, jint port) override;
|
||||
|
||||
private:
|
||||
const sp<android::hardware::gnss::IAGnss> mIAGnss;
|
||||
};
|
||||
|
||||
class AGnss_V1_0 : public AGnssInterface {
|
||||
public:
|
||||
AGnss_V1_0(const sp<android::hardware::gnss::V1_0::IAGnss>& iAGnss);
|
||||
jboolean setCallback(const std::unique_ptr<AGnssCallback>& callback) override;
|
||||
jboolean dataConnOpen(JNIEnv* env, jlong, jstring apn, jint apnIpType) override;
|
||||
jboolean dataConnClosed() override;
|
||||
jboolean dataConnFailed() override;
|
||||
jboolean setServer(JNIEnv* env, jint type, jstring hostname, jint port) override;
|
||||
|
||||
private:
|
||||
const sp<android::hardware::gnss::V1_0::IAGnss> mIAGnss_V1_0;
|
||||
};
|
||||
|
||||
class AGnss_V2_0 : public AGnssInterface {
|
||||
public:
|
||||
AGnss_V2_0(const sp<android::hardware::gnss::V2_0::IAGnss>& iAGnss);
|
||||
jboolean setCallback(const std::unique_ptr<AGnssCallback>& callback) override;
|
||||
jboolean dataConnOpen(JNIEnv* env, jlong networkHandle, jstring apn, jint apnIpType) override;
|
||||
jboolean dataConnClosed() override;
|
||||
jboolean dataConnFailed() override;
|
||||
jboolean setServer(JNIEnv* env, jint type, jstring hostname, jint port) override;
|
||||
|
||||
private:
|
||||
const sp<android::hardware::gnss::V2_0::IAGnss> mIAGnss_V2_0;
|
||||
};
|
||||
|
||||
} // namespace android::gnss
|
||||
|
||||
#endif // _ANDROID_SERVER_GNSS_AGNSS_H
|
||||
133
services/core/jni/gnss/AGnssCallback.cpp
Normal file
133
services/core/jni/gnss/AGnssCallback.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 "AGnssCbJni"
|
||||
|
||||
#include "AGnssCallback.h"
|
||||
|
||||
namespace android::gnss {
|
||||
|
||||
using binder::Status;
|
||||
using hardware::Return;
|
||||
using hardware::Void;
|
||||
using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback;
|
||||
using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
|
||||
|
||||
namespace {
|
||||
|
||||
jmethodID method_reportAGpsStatus;
|
||||
|
||||
}
|
||||
|
||||
void AGnss_class_init_once(JNIEnv* env, jclass clazz) {
|
||||
method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
|
||||
}
|
||||
|
||||
Status AGnssCallbackAidl::agnssStatusCb(AGnssType type, AGnssStatusValue status) {
|
||||
AGnssCallbackUtil::agnssStatusCbImpl(type, status);
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb(
|
||||
const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) {
|
||||
JNIEnv* env = getJniEnv();
|
||||
jbyteArray byteArray = nullptr;
|
||||
|
||||
byteArray = env->NewByteArray(16);
|
||||
if (byteArray != nullptr) {
|
||||
env->SetByteArrayRegion(byteArray, 0, 16, (const jbyte*)(agps_status.ipV6Addr.data()));
|
||||
} else {
|
||||
ALOGE("Unable to allocate byte array for IPv6 address.");
|
||||
}
|
||||
|
||||
IF_ALOGD() {
|
||||
// log the IP for reference in case there is a bogus value pushed by HAL
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
|
||||
ALOGD("AGPS IP is v6: %s", str);
|
||||
}
|
||||
|
||||
jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
|
||||
ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
|
||||
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, agps_status.type,
|
||||
agps_status.status, byteArray);
|
||||
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
|
||||
if (byteArray) {
|
||||
env->DeleteLocalRef(byteArray);
|
||||
}
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb(
|
||||
const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) {
|
||||
JNIEnv* env = getJniEnv();
|
||||
jbyteArray byteArray = nullptr;
|
||||
|
||||
uint32_t ipAddr = agps_status.ipV4Addr;
|
||||
byteArray = convertToIpV4(ipAddr);
|
||||
|
||||
IF_ALOGD() {
|
||||
/*
|
||||
* log the IP for reference in case there is a bogus value pushed by
|
||||
* HAL.
|
||||
*/
|
||||
char str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
|
||||
ALOGD("AGPS IP is v4: %s", str);
|
||||
}
|
||||
|
||||
jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
|
||||
ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
|
||||
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, agps_status.type,
|
||||
agps_status.status, byteArray);
|
||||
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
|
||||
if (byteArray) {
|
||||
env->DeleteLocalRef(byteArray);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) {
|
||||
if (INADDR_NONE == ip) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JNIEnv* env = getJniEnv();
|
||||
jbyteArray byteArray = env->NewByteArray(4);
|
||||
if (byteArray == nullptr) {
|
||||
ALOGE("Unable to allocate byte array for IPv4 address");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jbyte ipv4[4];
|
||||
ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
|
||||
memcpy(ipv4, &ip, sizeof(ipv4));
|
||||
env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
|
||||
IAGnssCallback_V2_0::AGnssStatusValue status) {
|
||||
AGnssCallbackUtil::agnssStatusCbImpl(type, status);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace android::gnss
|
||||
134
services/core/jni/gnss/AGnssCallback.h
Normal file
134
services/core/jni/gnss/AGnssCallback.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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_AGNSSCALLBACK_H
|
||||
#define _ANDROID_SERVER_GNSS_AGNSSCALLBACK_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#error LOG_TAG must be defined before including this file.
|
||||
#endif
|
||||
|
||||
#include <android/hardware/gnss/1.0/IAGnss.h>
|
||||
#include <android/hardware/gnss/2.0/IAGnss.h>
|
||||
#include <android/hardware/gnss/BnAGnssCallback.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "jni.h"
|
||||
|
||||
namespace android::gnss {
|
||||
|
||||
namespace {
|
||||
|
||||
extern jmethodID method_reportAGpsStatus;
|
||||
|
||||
}
|
||||
|
||||
void AGnss_class_init_once(JNIEnv* env, jclass clazz);
|
||||
|
||||
/*
|
||||
* AGnssCallbackAidl class implements the callback methods required by the
|
||||
* android::hardware::gnss::IAGnss interface.
|
||||
*/
|
||||
class AGnssCallbackAidl : public android::hardware::gnss::BnAGnssCallback {
|
||||
public:
|
||||
binder::Status agnssStatusCb(AGnssType type, AGnssStatusValue status) override;
|
||||
};
|
||||
|
||||
/*
|
||||
* AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface.
|
||||
*/
|
||||
class AGnssCallback_V1_0 : public android::hardware::gnss::V1_0::IAGnssCallback {
|
||||
public:
|
||||
// Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
|
||||
hardware::Return<void> agnssStatusIpV6Cb(
|
||||
const android::hardware::gnss::V1_0::IAGnssCallback::AGnssStatusIpV6& agps_status)
|
||||
override;
|
||||
|
||||
hardware::Return<void> agnssStatusIpV4Cb(
|
||||
const android::hardware::gnss::V1_0::IAGnssCallback::AGnssStatusIpV4& agps_status)
|
||||
override;
|
||||
|
||||
private:
|
||||
jbyteArray convertToIpV4(uint32_t ip);
|
||||
};
|
||||
|
||||
/*
|
||||
* AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface.
|
||||
*/
|
||||
class AGnssCallback_V2_0 : public android::hardware::gnss::V2_0::IAGnssCallback {
|
||||
public:
|
||||
// Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow.
|
||||
hardware::Return<void> agnssStatusCb(
|
||||
android::hardware::gnss::V2_0::IAGnssCallback::AGnssType type,
|
||||
android::hardware::gnss::V2_0::IAGnssCallback::AGnssStatusValue status) override;
|
||||
};
|
||||
|
||||
class AGnssCallback {
|
||||
public:
|
||||
AGnssCallback() {}
|
||||
sp<AGnssCallbackAidl> getAidl() {
|
||||
if (callbackAidl == nullptr) {
|
||||
callbackAidl = sp<AGnssCallbackAidl>::make();
|
||||
}
|
||||
return callbackAidl;
|
||||
}
|
||||
|
||||
sp<AGnssCallback_V1_0> getV1_0() {
|
||||
if (callbackV1_0 == nullptr) {
|
||||
callbackV1_0 = sp<AGnssCallback_V1_0>::make();
|
||||
}
|
||||
return callbackV1_0;
|
||||
}
|
||||
|
||||
sp<AGnssCallback_V2_0> getV2_0() {
|
||||
if (callbackV2_0 == nullptr) {
|
||||
callbackV2_0 = sp<AGnssCallback_V2_0>::make();
|
||||
}
|
||||
return callbackV2_0;
|
||||
}
|
||||
|
||||
private:
|
||||
sp<AGnssCallbackAidl> callbackAidl;
|
||||
sp<AGnssCallback_V1_0> callbackV1_0;
|
||||
sp<AGnssCallback_V2_0> callbackV2_0;
|
||||
};
|
||||
|
||||
struct AGnssCallbackUtil {
|
||||
template <class T, class U>
|
||||
static void agnssStatusCbImpl(const T& type, const U& status);
|
||||
|
||||
private:
|
||||
AGnssCallbackUtil() = delete;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
void AGnssCallbackUtil::agnssStatusCbImpl(const T& type, const U& status) {
|
||||
ALOGD("%s. type: %d, status:%d", __func__, static_cast<int32_t>(type),
|
||||
static_cast<int32_t>(status));
|
||||
JNIEnv* env = getJniEnv();
|
||||
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr);
|
||||
checkAndClearExceptionFromCallback(env, __FUNCTION__);
|
||||
}
|
||||
|
||||
} // namespace android::gnss
|
||||
|
||||
#endif // _ANDROID_SERVER_GNSS_AGNSSCALLBACK_H
|
||||
@@ -23,6 +23,8 @@ cc_library_shared {
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"AGnss.cpp",
|
||||
"AGnssCallback.cpp",
|
||||
"GnssAntennaInfoCallback.cpp",
|
||||
"GnssBatching.cpp",
|
||||
"GnssBatchingCallback.cpp",
|
||||
|
||||
@@ -196,6 +196,30 @@ private:
|
||||
JNIEnv* mEnv = nullptr;
|
||||
};
|
||||
|
||||
struct ScopedJniString {
|
||||
ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) {
|
||||
mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr);
|
||||
}
|
||||
|
||||
~ScopedJniString() {
|
||||
if (mNativeString != nullptr) {
|
||||
mEnv->ReleaseStringUTFChars(mJavaString, mNativeString);
|
||||
}
|
||||
}
|
||||
|
||||
const char* c_str() const { return mNativeString; }
|
||||
|
||||
operator hardware::hidl_string() const { return hardware::hidl_string(mNativeString); }
|
||||
|
||||
private:
|
||||
ScopedJniString(const ScopedJniString&) = delete;
|
||||
ScopedJniString& operator=(const ScopedJniString&) = delete;
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jstring mJavaString;
|
||||
const char* mNativeString;
|
||||
};
|
||||
|
||||
JNIEnv* getJniEnv();
|
||||
|
||||
template <class T>
|
||||
|
||||
Reference in New Issue
Block a user