diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 95ef5f76b7651..63f08539bdffe 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -160,7 +160,6 @@ cc_defaults { "android.hardware.gnss@2.0", "android.hardware.gnss@2.1", "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss.visibility_control@1.0", "android.hardware.graphics.bufferqueue@1.0", "android.hardware.graphics.bufferqueue@2.0", "android.hardware.graphics.common@1.2", diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 0da8f7ef0dea0..f24ea38a0e7bb 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -59,6 +58,7 @@ #include "gnss/GnssGeofence.h" #include "gnss/GnssMeasurement.h" #include "gnss/GnssNavigationMessage.h" +#include "gnss/GnssVisibilityControl.h" #include "gnss/Utils.h" #include "hardware_legacy/power.h" #include "jni.h" @@ -162,9 +162,6 @@ using IMeasurementCorrections_V1_1 = android::hardware::gnss::measurement_correc using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback; using android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags; -using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl; -using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback; - using android::hardware::gnss::BlocklistedSource; using android::hardware::gnss::GnssConstellationType; using android::hardware::gnss::GnssPowerStats; @@ -210,7 +207,6 @@ sp gnssNiIface = nullptr; sp gnssPowerIndicationIface = nullptr; sp gnssCorrectionsIface_V1_0 = nullptr; sp gnssCorrectionsIface_V1_1 = nullptr; -sp gnssVisibilityControlIface = nullptr; sp gnssAntennaInfoIface = nullptr; std::unique_ptr gnssConfigurationIface = nullptr; @@ -221,6 +217,7 @@ std::unique_ptr gnssGeofencingIface = null std::unique_ptr agnssIface = nullptr; std::unique_ptr gnssDebugIface = nullptr; std::unique_ptr agnssRilIface = nullptr; +std::unique_ptr gnssVisibilityControlIface = nullptr; #define WAKE_LOCK_NAME "GPS" @@ -858,54 +855,6 @@ Return GnssNiCallback::niNotifyCb( return Void(); } -/* - * GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal. - */ -struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback { - Return nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification) - override; - Return isInEmergencySession() override; -}; - -Return GnssVisibilityControlCallback::nfwNotifyCb( - const IGnssVisibilityControlCallback::NfwNotification& notification) { - JNIEnv* env = getJniEnv(); - jstring proxyAppPackageName = env->NewStringUTF(notification.proxyAppPackageName.c_str()); - jstring otherProtocolStackName = env->NewStringUTF(notification.otherProtocolStackName.c_str()); - jstring requestorId = env->NewStringUTF(notification.requestorId.c_str()); - - if (proxyAppPackageName && otherProtocolStackName && requestorId) { - env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName, - notification.protocolStack, otherProtocolStackName, - notification.requestor, requestorId, notification.responseType, - notification.inEmergencyMode, notification.isCachedLocation); - } else { - ALOGE("%s: OOM Error\n", __func__); - } - - if (requestorId) { - env->DeleteLocalRef(requestorId); - } - - if (otherProtocolStackName) { - env->DeleteLocalRef(otherProtocolStackName); - } - - if (proxyAppPackageName) { - env->DeleteLocalRef(proxyAppPackageName); - } - - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -Return GnssVisibilityControlCallback::isInEmergencySession() { - JNIEnv* env = getJniEnv(); - auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return result; -} - /* Initializes the GNSS service handle. */ static void android_location_gnss_hal_GnssNative_set_gps_service_handle() { gnssHalAidl = waitForVintfService(); @@ -1322,12 +1271,21 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject } } - if (gnssHal_V2_0 != nullptr) { - auto gnssVisibilityControl = gnssHal_V2_0->getExtensionVisibilityControl(); - if (!gnssVisibilityControl.isOk()) { - ALOGD("Unable to get a handle to GnssVisibilityControl interface"); - } else { - gnssVisibilityControlIface = gnssVisibilityControl; + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp + gnssVisibilityControlAidl; + auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl); + if (checkAidlStatus(status, + "Unable to get a handle to GnssVisibilityControl AIDL interface.")) { + gnssVisibilityControlIface = + std::make_unique(gnssVisibilityControlAidl); + } + } else if (gnssHal_V2_0 != nullptr) { + auto gnssVisibilityControlHidl = gnssHal_V2_0->getExtensionVisibilityControl(); + if (checkHidlReturn(gnssVisibilityControlHidl, + "Unable to get a handle to GnssVisibilityControl HIDL interface")) { + gnssVisibilityControlIface = + std::make_unique(gnssVisibilityControlHidl); } } @@ -1452,12 +1410,12 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl ALOGI("Unable to initialize IAGnssRil interface."); } - // Set IGnssVisibilityControl.hal callback. + // Set IGnssVisibilityControl callback. if (gnssVisibilityControlIface != nullptr) { - sp gnssVisibilityControlCbIface = - new GnssVisibilityControlCallback(); - auto result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface); - checkHidlReturn(result, "IGnssVisibilityControl setCallback() failed."); + gnssVisibilityControlIface->setCallback( + std::make_unique()); + } else { + ALOGI("Unable to initialize IGnssVisibilityControl interface."); } // Set IMeasurementCorrections.hal callback. @@ -2301,17 +2259,7 @@ static jboolean android_location_GnssVisibilityControl_enable_nfw_location_acces ALOGI("IGnssVisibilityControl interface not available."); return JNI_FALSE; } - - const jsize length = env->GetArrayLength(proxyApps); - hidl_vec hidlProxyApps(length); - for (int i = 0; i < length; ++i) { - jstring proxyApp = (jstring) (env->GetObjectArrayElement(proxyApps, i)); - ScopedJniString jniProxyApp(env, proxyApp); - hidlProxyApps[i] = jniProxyApp; - } - - auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps); - return checkHidlReturn(result, "IGnssVisibilityControl enableNfwLocationAccess() failed."); + return gnssVisibilityControlIface->enableNfwLocationAccess(env, proxyApps); } static const JNINativeMethod sCoreMethods[] = { diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index d8de5a604b3d0..bed72a8aa87cf 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -38,6 +38,8 @@ cc_library_shared { "GnssMeasurementCallback.cpp", "GnssNavigationMessage.cpp", "GnssNavigationMessageCallback.cpp", + "GnssVisibilityControl.cpp", + "GnssVisibilityControlCallback.cpp", "Utils.cpp", ], } diff --git a/services/core/jni/gnss/GnssVisibilityControl.cpp b/services/core/jni/gnss/GnssVisibilityControl.cpp new file mode 100644 index 0000000000000..a7bab9b1d88de --- /dev/null +++ b/services/core/jni/gnss/GnssVisibilityControl.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Define LOG_TAG before to overwrite the default value. +#define LOG_TAG "GnssVisibilityControlJni" + +#include "GnssVisibilityControl.h" + +#include "Utils.h" + +using IGnssVisibilityControlAidl = + android::hardware::gnss::visibility_control::IGnssVisibilityControl; +using IGnssVisibilityControlHidl = + android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl; + +namespace android::gnss { + +// Implementation of GnssVisibilityControl (AIDL HAL) + +GnssVisibilityControlAidl::GnssVisibilityControlAidl( + const sp& iGnssVisibilityControl) + : mIGnssVisibilityControlAidl(iGnssVisibilityControl) { + assert(mIGnssVisibilityControlAidl != nullptr); +} + +jboolean GnssVisibilityControlAidl::setCallback( + const std::unique_ptr& callback) { + auto status = mIGnssVisibilityControlAidl->setCallback(callback->getAidl()); + return checkAidlStatus(status, "IGnssVisibilityControlAidl setCallback() failed."); +} + +jboolean GnssVisibilityControlAidl::enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) { + int length = env->GetArrayLength(proxyApps); + std::vector aidlProxyApps(length); + for (int i = 0; i < length; ++i) { + jstring proxyApp = (jstring)(env->GetObjectArrayElement(proxyApps, i)); + ScopedJniString jniProxyApp(env, proxyApp); + aidlProxyApps[i] = std::string(jniProxyApp.c_str()); + } + auto status = mIGnssVisibilityControlAidl->enableNfwLocationAccess(aidlProxyApps); + return checkAidlStatus(status, "IGnssVisibilityControlAidl enableNfwLocationAccess() failed"); +} + +// Implementation of GnssVisibilityControlHidl + +GnssVisibilityControlHidl::GnssVisibilityControlHidl( + const sp& iGnssVisibilityControl) + : mIGnssVisibilityControlHidl(iGnssVisibilityControl) { + assert(mIGnssVisibilityControlHidl != nullptr); +} + +jboolean GnssVisibilityControlHidl::setCallback( + const std::unique_ptr& callback) { + auto result = mIGnssVisibilityControlHidl->setCallback(callback->getHidl()); + return checkHidlReturn(result, "IGnssVisibilityControlHidl setCallback() failed."); +} + +jboolean GnssVisibilityControlHidl::enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) { + const jsize length = env->GetArrayLength(proxyApps); + hardware::hidl_vec hidlProxyApps(length); + for (int i = 0; i < length; ++i) { + jstring proxyApp = (jstring)(env->GetObjectArrayElement(proxyApps, i)); + ScopedJniString jniProxyApp(env, proxyApp); + hidlProxyApps[i] = jniProxyApp; + } + + auto result = mIGnssVisibilityControlHidl->enableNfwLocationAccess(hidlProxyApps); + return checkHidlReturn(result, "IGnssVisibilityControlHidl enableNfwLocationAccess() failed."); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssVisibilityControl.h b/services/core/jni/gnss/GnssVisibilityControl.h new file mode 100644 index 0000000000000..e330a459a7a0f --- /dev/null +++ b/services/core/jni/gnss/GnssVisibilityControl.h @@ -0,0 +1,70 @@ +/* + * 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_VISIBILITYCONTROL_H +#define _ANDROID_SERVER_GNSS_VISIBILITYCONTROL_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include + +#include "GnssVisibilityControlCallback.h" +#include "jni.h" + +namespace android::gnss { + +class GnssVisibilityControlInterface { +public: + virtual ~GnssVisibilityControlInterface() {} + virtual jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) = 0; + virtual jboolean setCallback( + const std::unique_ptr& callback) = 0; +}; + +class GnssVisibilityControlAidl : public GnssVisibilityControlInterface { +public: + GnssVisibilityControlAidl( + const sp& + iGnssVisibilityControl); + jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) override; + jboolean setCallback(const std::unique_ptr& callback) override; + +private: + const sp + mIGnssVisibilityControlAidl; +}; + +class GnssVisibilityControlHidl : public GnssVisibilityControlInterface { +public: + GnssVisibilityControlHidl( + const sp& + iGnssVisibilityControl); + jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) override; + jboolean setCallback(const std::unique_ptr& callback) override; + +private: + const sp + mIGnssVisibilityControlHidl; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_VISIBILITYCONTROL_H diff --git a/services/core/jni/gnss/GnssVisibilityControlCallback.cpp b/services/core/jni/gnss/GnssVisibilityControlCallback.cpp new file mode 100644 index 0000000000000..2a9fedd31dfd3 --- /dev/null +++ b/services/core/jni/gnss/GnssVisibilityControlCallback.cpp @@ -0,0 +1,87 @@ +/* + * 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 "GnssVisibilityControlCbJni" + +#include "GnssVisibilityControlCallback.h" + +namespace android::gnss { + +// using android::hardware::hidl_vec; +using binder::Status; +using hardware::Return; + +namespace { +jmethodID method_reportNfwNotification; +jmethodID method_isInEmergencySession; + +} // anonymous namespace + +void GnssVisibilityControl_class_init_once(JNIEnv* env, jclass clazz) { + method_reportNfwNotification = + env->GetMethodID(clazz, "reportNfwNotification", + "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V"); + method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z"); +} + +// Implementation of GnssVisibilityControlCallbackAidl class. + +Status GnssVisibilityControlCallbackAidl::nfwNotifyCb( + const android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback:: + NfwNotification& notification) { + GnssVisibilityControlCallbackUtil::nfwNotifyCb(notification); + return Status::ok(); +} + +Status GnssVisibilityControlCallbackAidl::isInEmergencySession(bool* _aidl_return) { + *_aidl_return = GnssVisibilityControlCallbackUtil::isInEmergencySession(); + return Status::ok(); +} + +// Implementation of GnssVisibilityControlCallbackHidl class. + +Return GnssVisibilityControlCallbackHidl::nfwNotifyCb( + const IGnssVisibilityControlCallback::NfwNotification& notification) { + GnssVisibilityControlCallbackUtil::nfwNotifyCb(notification); + return hardware::Void(); +} + +Return GnssVisibilityControlCallbackHidl::isInEmergencySession() { + return GnssVisibilityControlCallbackUtil::isInEmergencySession(); +} + +// Implementation of GnssVisibilityControlCallbackUtil class. + +bool GnssVisibilityControlCallbackUtil::isInEmergencySession() { + JNIEnv* env = getJniEnv(); + auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return result; +} + +template <> +jstring ToJstring(JNIEnv* env, const String16& value) { + const char16_t* str = value.string(); + size_t len = value.size(); + return env->NewString(reinterpret_cast(str), len); +} + +template <> +jstring ToJstring(JNIEnv* env, const hardware::hidl_string& value) { + return env->NewStringUTF(value.c_str()); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssVisibilityControlCallback.h b/services/core/jni/gnss/GnssVisibilityControlCallback.h new file mode 100644 index 0000000000000..28283efdc40ed --- /dev/null +++ b/services/core/jni/gnss/GnssVisibilityControlCallback.h @@ -0,0 +1,137 @@ +/* + * 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_VISIBILITYCONTROLCALLBACK_H +#define _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +namespace { + +extern jmethodID method_reportNfwNotification; + +} // anonymous namespace + +void GnssNavigationMessage_class_init_once(JNIEnv* env, jclass clazz); + +/* + * GnssVisibilityControlCallbackAidl class implements the callback methods required by the + * android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback interface. + */ +class GnssVisibilityControlCallbackAidl + : public hardware::gnss::visibility_control::BnGnssVisibilityControlCallback { +public: + GnssVisibilityControlCallbackAidl() {} + binder::Status nfwNotifyCb( + const android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback:: + NfwNotification& notification) override; + binder::Status isInEmergencySession(bool* _aidl_return) override; +}; + +/* + * GnssVisibilityControlCallbackHidl implements callback methods of + * IGnssVisibilityControlCallback 1.0 interface. + */ +class GnssVisibilityControlCallbackHidl + : public android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback { +public: + GnssVisibilityControlCallbackHidl() {} + hardware::Return nfwNotifyCb( + const IGnssVisibilityControlCallback::NfwNotification& notification) override; + hardware::Return isInEmergencySession() override; +}; + +class GnssVisibilityControlCallback { +public: + GnssVisibilityControlCallback() {} + 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 GnssVisibilityControlCallbackUtil { + template + static void nfwNotifyCb(const T& notification); + static bool isInEmergencySession(); + +private: + GnssVisibilityControlCallbackUtil() = delete; +}; + +template +static jstring ToJstring(JNIEnv* env, const T& value); + +template +void GnssVisibilityControlCallbackUtil::nfwNotifyCb(const T& notification) { + JNIEnv* env = getJniEnv(); + jstring proxyAppPackageName = ToJstring(env, notification.proxyAppPackageName); + jstring otherProtocolStackName = ToJstring(env, notification.otherProtocolStackName); + jstring requestorId = ToJstring(env, notification.requestorId); + + if (proxyAppPackageName && otherProtocolStackName && requestorId) { + env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName, + notification.protocolStack, otherProtocolStackName, + notification.requestor, requestorId, notification.responseType, + notification.inEmergencyMode, notification.isCachedLocation); + } else { + ALOGE("%s: OOM Error\n", __func__); + } + + if (requestorId) { + env->DeleteLocalRef(requestorId); + } + + if (otherProtocolStackName) { + env->DeleteLocalRef(otherProtocolStackName); + } + + if (proxyAppPackageName) { + env->DeleteLocalRef(proxyAppPackageName); + } + + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H