1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H
18 #define _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H
19 
20 #pragma once
21 
22 #ifndef LOG_TAG
23 #error LOG_TAG must be defined before including this file.
24 #endif
25 
26 #include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
27 #include <android/hardware/gnss/visibility_control/BnGnssVisibilityControlCallback.h>
28 #include <log/log.h>
29 
30 #include "Utils.h"
31 #include "jni.h"
32 
33 namespace android::gnss {
34 
35 namespace {
36 extern jmethodID method_reportNfwNotification;
37 extern jmethodID method_isInEmergencySession;
38 } // anonymous namespace
39 
40 void GnssVisibilityControl_class_init_once(JNIEnv* env, jclass clazz);
41 
42 /*
43  * GnssVisibilityControlCallbackAidl class implements the callback methods required by the
44  * android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback interface.
45  */
46 class GnssVisibilityControlCallbackAidl
47       : public hardware::gnss::visibility_control::BnGnssVisibilityControlCallback {
48 public:
GnssVisibilityControlCallbackAidl()49     GnssVisibilityControlCallbackAidl() {}
50     binder::Status nfwNotifyCb(
51             const android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback::
52                     NfwNotification& notification) override;
53     binder::Status isInEmergencySession(bool* _aidl_return) override;
54 };
55 
56 /*
57  * GnssVisibilityControlCallbackHidl implements callback methods of
58  * IGnssVisibilityControlCallback 1.0 interface.
59  */
60 class GnssVisibilityControlCallbackHidl
61       : public android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback {
62 public:
GnssVisibilityControlCallbackHidl()63     GnssVisibilityControlCallbackHidl() {}
64     hardware::Return<void> nfwNotifyCb(
65             const IGnssVisibilityControlCallback::NfwNotification& notification) override;
66     hardware::Return<bool> isInEmergencySession() override;
67 };
68 
69 class GnssVisibilityControlCallback {
70 public:
GnssVisibilityControlCallback()71     GnssVisibilityControlCallback() {}
getAidl()72     sp<GnssVisibilityControlCallbackAidl> getAidl() {
73         if (callbackAidl == nullptr) {
74             callbackAidl = sp<GnssVisibilityControlCallbackAidl>::make();
75         }
76         return callbackAidl;
77     }
78 
getHidl()79     sp<GnssVisibilityControlCallbackHidl> getHidl() {
80         if (callbackHidl == nullptr) {
81             callbackHidl = sp<GnssVisibilityControlCallbackHidl>::make();
82         }
83         return callbackHidl;
84     }
85 
86 private:
87     sp<GnssVisibilityControlCallbackAidl> callbackAidl;
88     sp<GnssVisibilityControlCallbackHidl> callbackHidl;
89 };
90 
91 struct GnssVisibilityControlCallbackUtil {
92     template <class T>
93     static void nfwNotifyCb(const T& notification);
94     static bool isInEmergencySession();
95 
96 private:
97     GnssVisibilityControlCallbackUtil() = delete;
98 };
99 
100 template <class T>
101 static jstring ToJstring(JNIEnv* env, const T& value);
102 
103 template <class T>
nfwNotifyCb(const T & notification)104 void GnssVisibilityControlCallbackUtil::nfwNotifyCb(const T& notification) {
105     JNIEnv* env = getJniEnv();
106     jstring proxyAppPackageName = ToJstring(env, notification.proxyAppPackageName);
107     jstring otherProtocolStackName = ToJstring(env, notification.otherProtocolStackName);
108     jstring requestorId = ToJstring(env, notification.requestorId);
109 
110     if (proxyAppPackageName && otherProtocolStackName && requestorId) {
111         env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
112                             notification.protocolStack, otherProtocolStackName,
113                             notification.requestor, requestorId, notification.responseType,
114                             notification.inEmergencyMode, notification.isCachedLocation);
115     } else {
116         ALOGE("%s: OOM Error\n", __func__);
117     }
118 
119     if (requestorId) {
120         env->DeleteLocalRef(requestorId);
121     }
122 
123     if (otherProtocolStackName) {
124         env->DeleteLocalRef(otherProtocolStackName);
125     }
126 
127     if (proxyAppPackageName) {
128         env->DeleteLocalRef(proxyAppPackageName);
129     }
130 
131     checkAndClearExceptionFromCallback(env, __FUNCTION__);
132 }
133 
134 } // namespace android::gnss
135 
136 #endif // _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H
137