Add GnssVisibilityControl AIDL HAL (frameworks/base)

Bug: 208728105
Test: atest VtsHalGnssTargetTest
Change-Id: Id05a7462762779b54afbfbf573d9b64874b806d9
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 95ef5f7..63f0853 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -160,7 +160,6 @@
         "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 0da8f7e..f24ea38 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 <android/hardware/gnss/BnGnssPsdsCallback.h>
 #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 <binder/IServiceManager.h>
 #include <nativehelper/JNIHelp.h>
 #include <pthread.h>
@@ -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 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<IGnssPowerIndication> gnssPowerIndicationIface = nullptr;
 sp<IMeasurementCorrections_V1_0> gnssCorrectionsIface_V1_0 = nullptr;
 sp<IMeasurementCorrections_V1_1> gnssCorrectionsIface_V1_1 = nullptr;
-sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
 sp<IGnssAntennaInfo> gnssAntennaInfoIface = nullptr;
 
 std::unique_ptr<GnssConfigurationInterface> gnssConfigurationIface = nullptr;
@@ -221,6 +217,7 @@
 std::unique_ptr<android::gnss::AGnssInterface> agnssIface = nullptr;
 std::unique_ptr<android::gnss::GnssDebugInterface> gnssDebugIface = nullptr;
 std::unique_ptr<android::gnss::AGnssRilInterface> agnssRilIface = nullptr;
+std::unique_ptr<android::gnss::GnssVisibilityControlInterface> gnssVisibilityControlIface = nullptr;
 
 #define WAKE_LOCK_NAME  "GPS"
 
@@ -858,54 +855,6 @@
     return Void();
 }
 
-/*
- * GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal.
- */
-struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback {
-    Return<void> nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification)
-            override;
-    Return<bool> isInEmergencySession() override;
-};
-
-Return<void> 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<bool> 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<IGnssAidl>();
@@ -1322,12 +1271,21 @@
         }
     }
 
-    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<android::hardware::gnss::visibility_control::IGnssVisibilityControl>
+                gnssVisibilityControlAidl;
+        auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl);
+        if (checkAidlStatus(status,
+                            "Unable to get a handle to GnssVisibilityControl AIDL interface.")) {
+            gnssVisibilityControlIface =
+                    std::make_unique<gnss::GnssVisibilityControlAidl>(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<gnss::GnssVisibilityControlHidl>(gnssVisibilityControlHidl);
         }
     }
 
@@ -1452,12 +1410,12 @@
         ALOGI("Unable to initialize IAGnssRil interface.");
     }
 
-    // Set IGnssVisibilityControl.hal callback.
+    // Set IGnssVisibilityControl callback.
     if (gnssVisibilityControlIface != nullptr) {
-        sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
-                new GnssVisibilityControlCallback();
-        auto result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
-        checkHidlReturn(result, "IGnssVisibilityControl setCallback() failed.");
+        gnssVisibilityControlIface->setCallback(
+                std::make_unique<gnss::GnssVisibilityControlCallback>());
+    } else {
+        ALOGI("Unable to initialize IGnssVisibilityControl interface.");
     }
 
     // Set IMeasurementCorrections.hal callback.
@@ -2301,17 +2259,7 @@
         ALOGI("IGnssVisibilityControl interface not available.");
         return JNI_FALSE;
     }
-
-    const jsize length = env->GetArrayLength(proxyApps);
-    hidl_vec<hidl_string> 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 d8de5a6..bed72a8 100644
--- a/services/core/jni/gnss/Android.bp
+++ b/services/core/jni/gnss/Android.bp
@@ -38,6 +38,8 @@
         "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 0000000..a7bab9b
--- /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 <log/log.h> 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<IGnssVisibilityControlAidl>& iGnssVisibilityControl)
+      : mIGnssVisibilityControlAidl(iGnssVisibilityControl) {
+    assert(mIGnssVisibilityControlAidl != nullptr);
+}
+
+jboolean GnssVisibilityControlAidl::setCallback(
+        const std::unique_ptr<GnssVisibilityControlCallback>& 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<std::string> 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<IGnssVisibilityControlHidl>& iGnssVisibilityControl)
+      : mIGnssVisibilityControlHidl(iGnssVisibilityControl) {
+    assert(mIGnssVisibilityControlHidl != nullptr);
+}
+
+jboolean GnssVisibilityControlHidl::setCallback(
+        const std::unique_ptr<GnssVisibilityControlCallback>& 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<hardware::hidl_string> 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 0000000..e330a45
--- /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 <android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
+#include <log/log.h>
+
+#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<GnssVisibilityControlCallback>& callback) = 0;
+};
+
+class GnssVisibilityControlAidl : public GnssVisibilityControlInterface {
+public:
+    GnssVisibilityControlAidl(
+            const sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>&
+                    iGnssVisibilityControl);
+    jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) override;
+    jboolean setCallback(const std::unique_ptr<GnssVisibilityControlCallback>& callback) override;
+
+private:
+    const sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>
+            mIGnssVisibilityControlAidl;
+};
+
+class GnssVisibilityControlHidl : public GnssVisibilityControlInterface {
+public:
+    GnssVisibilityControlHidl(
+            const sp<android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>&
+                    iGnssVisibilityControl);
+    jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) override;
+    jboolean setCallback(const std::unique_ptr<GnssVisibilityControlCallback>& callback) override;
+
+private:
+    const sp<android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>
+            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 0000000..2a9fedd
--- /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<void> GnssVisibilityControlCallbackHidl::nfwNotifyCb(
+        const IGnssVisibilityControlCallback::NfwNotification& notification) {
+    GnssVisibilityControlCallbackUtil::nfwNotifyCb(notification);
+    return hardware::Void();
+}
+
+Return<bool> 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<const jchar*>(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 0000000..28283efd
--- /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 <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <android/hardware/gnss/visibility_control/BnGnssVisibilityControlCallback.h>
+#include <log/log.h>
+
+#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<void> nfwNotifyCb(
+            const IGnssVisibilityControlCallback::NfwNotification& notification) override;
+    hardware::Return<bool> isInEmergencySession() override;
+};
+
+class GnssVisibilityControlCallback {
+public:
+    GnssVisibilityControlCallback() {}
+    sp<GnssVisibilityControlCallbackAidl> getAidl() {
+        if (callbackAidl == nullptr) {
+            callbackAidl = sp<GnssVisibilityControlCallbackAidl>::make();
+        }
+        return callbackAidl;
+    }
+
+    sp<GnssVisibilityControlCallbackHidl> getHidl() {
+        if (callbackHidl == nullptr) {
+            callbackHidl = sp<GnssVisibilityControlCallbackHidl>::make();
+        }
+        return callbackHidl;
+    }
+
+private:
+    sp<GnssVisibilityControlCallbackAidl> callbackAidl;
+    sp<GnssVisibilityControlCallbackHidl> callbackHidl;
+};
+
+struct GnssVisibilityControlCallbackUtil {
+    template <class T>
+    static void nfwNotifyCb(const T& notification);
+    static bool isInEmergencySession();
+
+private:
+    GnssVisibilityControlCallbackUtil() = delete;
+};
+
+template <class T>
+static jstring ToJstring(JNIEnv* env, const T& value);
+
+template <class T>
+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