From 52b4581fe37bc515130e61951fac93c91711da3e Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 22 Nov 2021 09:48:49 -0800 Subject: [PATCH] Add GnssNavigationMessage AIDL HAL (frameworks/base) Bug: 205185251 Test: atest GnssNavigationMessageRegistrationTest Change-Id: I5d0cb8ba583a1161125fb07a105ade7d6495e985 --- ...d_server_location_GnssLocationProvider.cpp | 97 +++----------- services/core/jni/gnss/Android.bp | 2 + .../core/jni/gnss/GnssNavigationMessage.cpp | 73 ++++++++++ .../core/jni/gnss/GnssNavigationMessage.h | 67 ++++++++++ .../gnss/GnssNavigationMessageCallback.cpp | 63 +++++++++ .../jni/gnss/GnssNavigationMessageCallback.h | 125 ++++++++++++++++++ 6 files changed, 349 insertions(+), 78 deletions(-) create mode 100644 services/core/jni/gnss/GnssNavigationMessage.cpp create mode 100644 services/core/jni/gnss/GnssNavigationMessage.h create mode 100644 services/core/jni/gnss/GnssNavigationMessageCallback.cpp create mode 100644 services/core/jni/gnss/GnssNavigationMessageCallback.h diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index e4c8871e6f8d4..2ccef9a61ffb8 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -56,13 +56,13 @@ #include "gnss/GnssBatching.h" #include "gnss/GnssConfiguration.h" #include "gnss/GnssMeasurement.h" +#include "gnss/GnssNavigationMessage.h" #include "gnss/Utils.h" #include "hardware_legacy/power.h" #include "jni.h" #include "utils/Log.h" #include "utils/misc.h" -static jclass class_gnssNavigationMessage; static jclass class_gnssPowerStats; static jmethodID method_reportLocation; @@ -85,7 +85,6 @@ static jmethodID method_reportGeofenceAddStatus; static jmethodID method_reportGeofenceRemoveStatus; static jmethodID method_reportGeofencePauseStatus; static jmethodID method_reportGeofenceResumeStatus; -static jmethodID method_reportNavigationMessages; static jmethodID method_reportGnssServiceDied; static jmethodID method_reportGnssPowerStats; static jmethodID method_setSubHalMeasurementCorrectionsCapabilities; @@ -115,7 +114,6 @@ static jmethodID method_correctionPlaneAltDeg; static jmethodID method_correctionPlaneAzimDeg; static jmethodID method_reportNfwNotification; static jmethodID method_isInEmergencySession; -static jmethodID method_gnssNavigationMessageCtor; static jmethodID method_gnssPowerStatsCtor; static jmethodID method_setSubHalPowerIndicationCapabilities; @@ -233,7 +231,6 @@ sp agnssIface_V2_0 = nullptr; sp gnssDebugIface = nullptr; sp gnssDebugIface_V2_0 = nullptr; sp gnssNiIface = nullptr; -sp gnssNavigationMessageIface = nullptr; sp gnssPowerIndicationIface = nullptr; sp gnssCorrectionsIface_V1_0 = nullptr; sp gnssCorrectionsIface_V1_1 = nullptr; @@ -242,6 +239,7 @@ sp gnssAntennaInfoIface = nullptr; std::unique_ptr gnssConfigurationIface = nullptr; std::unique_ptr gnssMeasurementIface = nullptr; +std::unique_ptr gnssNavigationMessageIface = nullptr; std::unique_ptr gnssBatchingIface = nullptr; #define WAKE_LOCK_NAME "GPS" @@ -909,50 +907,6 @@ Return GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId, Geof return Void(); } -/* - * GnssNavigationMessageCallback interface implements the callback methods - * required by the IGnssNavigationMessage interface. - */ -struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback { - /* - * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback - * follow. - */ - Return gnssNavigationMessageCb( - const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override; -}; - -Return GnssNavigationMessageCallback::gnssNavigationMessageCb( - const IGnssNavigationMessageCallback::GnssNavigationMessage& message) { - JNIEnv* env = getJniEnv(); - - size_t dataLength = message.data.size(); - - std::vector navigationData = message.data; - uint8_t* data = &(navigationData[0]); - if (dataLength == 0 || data == nullptr) { - ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, - dataLength); - return Void(); - } - - JavaObject object(env, class_gnssNavigationMessage, method_gnssNavigationMessageCtor); - SET(Type, static_cast(message.type)); - SET(Svid, static_cast(message.svid)); - SET(MessageId, static_cast(message.messageId)); - SET(SubmessageId, static_cast(message.submessageId)); - object.callSetter("setData", data, dataLength); - SET(Status, static_cast(message.status)); - - jobject navigationMessage = object.get(); - env->CallVoidMethod(mCallbacksObj, - method_reportNavigationMessages, - navigationMessage); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(navigationMessage); - return Void(); -} - /* * MeasurementCorrectionsCallback implements callback methods of interface * IMeasurementCorrectionsCallback.hal. @@ -1264,10 +1218,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_reportNavigationMessages = env->GetMethodID( - clazz, - "reportNavigationMessage", - "(Landroid/location/GnssNavigationMessage;)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"); @@ -1337,14 +1287,11 @@ 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, "", "(IJDDDDDD[D)V"); - jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage"); - class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass); - method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "", "()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::GnssNavigationMessage_class_init_once(env, clazz); gnss::Utils_class_init_once(env); } @@ -1431,12 +1378,20 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject } } - if (gnssHal != nullptr) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp gnssNavigationMessage; + auto status = gnssHalAidl->getExtensionGnssNavigationMessage(&gnssNavigationMessage); + if (checkAidlStatus(status, + "Unable to get a handle to GnssNavigationMessage AIDL interface.")) { + gnssNavigationMessageIface = + std::make_unique(gnssNavigationMessage); + } + } else if (gnssHal != nullptr) { auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage(); - if (!gnssNavigationMessage.isOk()) { - ALOGD("Unable to get a handle to GnssNavigationMessage"); - } else { - gnssNavigationMessageIface = gnssNavigationMessage; + if (checkHidlReturn(gnssNavigationMessage, + "Unable to get a handle to GnssNavigationMessage interface.")) { + gnssNavigationMessageIface = + std::make_unique(gnssNavigationMessage); } } @@ -2624,20 +2579,8 @@ static jboolean android_location_gnss_hal_GnssNative_start_navigation_message_co return JNI_FALSE; } - sp gnssNavigationMessageCbIface = - new GnssNavigationMessageCallback(); - auto result = gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface); - if (!checkHidlReturn(result, "IGnssNavigationMessage setCallback() failed.")) { - return JNI_FALSE; - } - - IGnssNavigationMessage::GnssNavigationMessageStatus initRet = result; - if (initRet != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) { - ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast(initRet)); - return JNI_FALSE; - } - - return JNI_TRUE; + return gnssNavigationMessageIface->setCallback( + std::make_unique()); } static jboolean android_location_gnss_hal_GnssNative_stop_navigation_message_collection(JNIEnv* env, @@ -2646,9 +2589,7 @@ static jboolean android_location_gnss_hal_GnssNative_stop_navigation_message_col ALOGE("%s: IGnssNavigationMessage interface not available.", __func__); return JNI_FALSE; } - - auto result = gnssNavigationMessageIface->close(); - return checkHidlReturn(result, "IGnssNavigationMessage close() failed."); + return gnssNavigationMessageIface->close(); } static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*, diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index 090166a0bc1d2..6c6b30405ab37 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -29,6 +29,8 @@ cc_library_shared { "GnssConfiguration.cpp", "GnssMeasurement.cpp", "GnssMeasurementCallback.cpp", + "GnssNavigationMessage.cpp", + "GnssNavigationMessageCallback.cpp", "Utils.cpp", ], } diff --git a/services/core/jni/gnss/GnssNavigationMessage.cpp b/services/core/jni/gnss/GnssNavigationMessage.cpp new file mode 100644 index 0000000000000..75aee74380a77 --- /dev/null +++ b/services/core/jni/gnss/GnssNavigationMessage.cpp @@ -0,0 +1,73 @@ +/* + * 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 "GnssNavigationMessageJni" + +#include "GnssNavigationMessage.h" + +#include "Utils.h" + +namespace android::gnss { + +using hardware::gnss::IGnssNavigationMessageInterface; +using IGnssNavigationMessageHidl = hardware::gnss::V1_0::IGnssNavigationMessage; + +// Implementation of GnssNavigationMessage (AIDL HAL) + +GnssNavigationMessageAidl::GnssNavigationMessageAidl( + const sp& iGnssNavigationMessage) + : mIGnssNavigationMessage(iGnssNavigationMessage) { + assert(mIGnssNavigationMessage != nullptr); +} + +jboolean GnssNavigationMessageAidl::setCallback( + const std::unique_ptr& callback) { + auto status = mIGnssNavigationMessage->setCallback(callback->getAidl()); + return checkAidlStatus(status, "IGnssNavigationMessageAidl setCallback() failed."); +} + +jboolean GnssNavigationMessageAidl::close() { + auto status = mIGnssNavigationMessage->close(); + return checkAidlStatus(status, "IGnssNavigationMessageAidl close() failed"); +} + +// Implementation of GnssNavigationMessageHidl + +GnssNavigationMessageHidl::GnssNavigationMessageHidl( + const sp& iGnssNavigationMessage) + : mIGnssNavigationMessageHidl(iGnssNavigationMessage) { + assert(mIGnssNavigationMessageHidl != nullptr); +} + +jboolean GnssNavigationMessageHidl::setCallback( + const std::unique_ptr& callback) { + auto result = mIGnssNavigationMessageHidl->setCallback(callback->getHidl()); + + IGnssNavigationMessageHidl::GnssNavigationMessageStatus initRet = result; + if (initRet != IGnssNavigationMessageHidl::GnssNavigationMessageStatus::SUCCESS) { + ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast(initRet)); + return JNI_FALSE; + } + return JNI_TRUE; +} + +jboolean GnssNavigationMessageHidl::close() { + auto result = mIGnssNavigationMessageHidl->close(); + return checkHidlReturn(result, "IGnssNavigationMessage close() failed."); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssNavigationMessage.h b/services/core/jni/gnss/GnssNavigationMessage.h new file mode 100644 index 0000000000000..e3a1e4a49ab17 --- /dev/null +++ b/services/core/jni/gnss/GnssNavigationMessage.h @@ -0,0 +1,67 @@ +/* + * 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_GNSSNAVIGATIONMESSAGE_H +#define _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGE_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include "GnssNavigationMessageCallback.h" +#include "jni.h" + +namespace android::gnss { + +class GnssNavigationMessageInterface { +public: + virtual ~GnssNavigationMessageInterface() {} + virtual jboolean setCallback( + const std::unique_ptr& callback) = 0; + virtual jboolean close() = 0; +}; + +class GnssNavigationMessageAidl : public GnssNavigationMessageInterface { +public: + GnssNavigationMessageAidl(const sp& + iGnssNavigationMessage); + jboolean setCallback(const std::unique_ptr& callback) override; + jboolean close() override; + +private: + const sp mIGnssNavigationMessage; +}; + +class GnssNavigationMessageHidl : public GnssNavigationMessageInterface { +public: + GnssNavigationMessageHidl(const sp& + iGnssNavigationMessage); + jboolean setCallback(const std::unique_ptr& callback) override; + jboolean close() override; + +private: + const sp mIGnssNavigationMessageHidl; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGE_H diff --git a/services/core/jni/gnss/GnssNavigationMessageCallback.cpp b/services/core/jni/gnss/GnssNavigationMessageCallback.cpp new file mode 100644 index 0000000000000..1779c95d12f36 --- /dev/null +++ b/services/core/jni/gnss/GnssNavigationMessageCallback.cpp @@ -0,0 +1,63 @@ +/* + * 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 "GnssNavMsgCbJni" + +#include "GnssNavigationMessageCallback.h" + +namespace android::gnss { + +namespace { + +jclass class_gnssNavigationMessage; +jmethodID method_reportNavigationMessages; +jmethodID method_gnssNavigationMessageCtor; + +} // anonymous namespace + +using binder::Status; +using hardware::Return; +using hardware::Void; + +using GnssNavigationMessageAidl = + android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage; +using GnssNavigationMessageHidl = + android::hardware::gnss::V1_0::IGnssNavigationMessageCallback::GnssNavigationMessage; + +void GnssNavigationMessage_class_init_once(JNIEnv* env, jclass clazz) { + method_reportNavigationMessages = + env->GetMethodID(clazz, "reportNavigationMessage", + "(Landroid/location/GnssNavigationMessage;)V"); + + jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage"); + class_gnssNavigationMessage = (jclass)env->NewGlobalRef(gnssNavigationMessageClass); + method_gnssNavigationMessageCtor = + env->GetMethodID(class_gnssNavigationMessage, "", "()V"); +} + +Status GnssNavigationMessageCallbackAidl::gnssNavigationMessageCb( + const GnssNavigationMessageAidl& message) { + GnssNavigationMessageCallbackUtil::gnssNavigationMessageCbImpl(message); + return Status::ok(); +} + +Return GnssNavigationMessageCallbackHidl::gnssNavigationMessageCb( + const GnssNavigationMessageHidl& message) { + GnssNavigationMessageCallbackUtil::gnssNavigationMessageCbImpl(message); + return Void(); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssNavigationMessageCallback.h b/services/core/jni/gnss/GnssNavigationMessageCallback.h new file mode 100644 index 0000000000000..fe76fc75bd394 --- /dev/null +++ b/services/core/jni/gnss/GnssNavigationMessageCallback.h @@ -0,0 +1,125 @@ +/* + * 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_GNSSNAVIGATIONMESSAGECALLBACK_H +#define _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGECALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include + +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +namespace { + +extern jclass class_gnssNavigationMessage; +extern jmethodID method_reportNavigationMessages; +extern jmethodID method_gnssNavigationMessageCtor; + +} // anonymous namespace + +void GnssNavigationMessage_class_init_once(JNIEnv* env, jclass clazz); + +class GnssNavigationMessageCallbackAidl : public hardware::gnss::BnGnssNavigationMessageCallback { +public: + GnssNavigationMessageCallbackAidl() {} + android::binder::Status gnssNavigationMessageCb( + const hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage& message) + override; +}; + +class GnssNavigationMessageCallbackHidl + : public hardware::gnss::V1_0::IGnssNavigationMessageCallback { +public: + GnssNavigationMessageCallbackHidl() {} + + hardware::Return gnssNavigationMessageCb( + const hardware::gnss::V1_0::IGnssNavigationMessageCallback::GnssNavigationMessage& + message) override; +}; + +class GnssNavigationMessageCallback { +public: + GnssNavigationMessageCallback() {} + sp getAidl() { + if (callbackAidl == nullptr) { + callbackAidl = sp::make(); + } + return callbackAidl; + } + + sp getHidl() { + if (callbackHidl == nullptr) { + callbackHidl = sp::make(); + } + return callbackHidl; + } + +private: + sp callbackAidl; + sp callbackHidl; +}; + +struct GnssNavigationMessageCallbackUtil { + template + static void gnssNavigationMessageCbImpl(const T& message); + +private: + GnssNavigationMessageCallbackUtil() = delete; +}; + +template +void GnssNavigationMessageCallbackUtil::gnssNavigationMessageCbImpl(const T& message) { + JNIEnv* env = getJniEnv(); + + size_t dataLength = message.data.size(); + + std::vector navigationData = message.data; + uint8_t* data = &(navigationData[0]); + if (dataLength == 0 || data == nullptr) { + ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength); + return; + } + + JavaObject object(env, class_gnssNavigationMessage, method_gnssNavigationMessageCtor); + SET(Type, static_cast(message.type)); + SET(Svid, static_cast(message.svid)); + SET(MessageId, static_cast(message.messageId)); + SET(SubmessageId, static_cast(message.submessageId)); + object.callSetter("setData", data, dataLength); + SET(Status, static_cast(message.status)); + + jobject navigationMessage = object.get(); + env->CallVoidMethod(mCallbacksObj, method_reportNavigationMessages, navigationMessage); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(navigationMessage); + return; +} + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGECALLBACK_H \ No newline at end of file