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_GNSSGEOFENCECALLBACK_H
18 #define _ANDROID_SERVER_GNSS_GNSSGEOFENCECALLBACK_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/1.0/IGnssGeofencing.h>
27 #include <android/hardware/gnss/BnGnssGeofenceCallback.h>
28 #include <log/log.h>
29 
30 #include <vector>
31 
32 #include "Utils.h"
33 #include "jni.h"
34 
35 namespace android::gnss {
36 
37 namespace {
38 extern jmethodID method_reportGeofenceTransition;
39 extern jmethodID method_reportGeofenceStatus;
40 extern jmethodID method_reportGeofenceAddStatus;
41 extern jmethodID method_reportGeofenceRemoveStatus;
42 extern jmethodID method_reportGeofencePauseStatus;
43 extern jmethodID method_reportGeofenceResumeStatus;
44 } // anonymous namespace
45 
46 void GnssGeofence_class_init_once(JNIEnv* env, jclass clazz);
47 
48 class GnssGeofenceCallbackAidl : public hardware::gnss::BnGnssGeofenceCallback {
49 public:
GnssGeofenceCallbackAidl()50     GnssGeofenceCallbackAidl() {}
51     binder::Status gnssGeofenceTransitionCb(int geofenceId,
52                                             const hardware::gnss::GnssLocation& location,
53                                             int transition, int64_t timestampMillis) override;
54     binder::Status gnssGeofenceStatusCb(int availability,
55                                         const hardware::gnss::GnssLocation& lastLocation) override;
56     binder::Status gnssGeofenceAddCb(int geofenceId, int status) override;
57     binder::Status gnssGeofenceRemoveCb(int geofenceId, int status) override;
58     binder::Status gnssGeofencePauseCb(int geofenceId, int status) override;
59     binder::Status gnssGeofenceResumeCb(int geofenceId, int status) override;
60 };
61 
62 class GnssGeofenceCallbackHidl : public hardware::gnss::V1_0::IGnssGeofenceCallback {
63 public:
GnssGeofenceCallbackHidl()64     GnssGeofenceCallbackHidl() {}
65     hardware::Return<void> gnssGeofenceTransitionCb(
66             int32_t geofenceId, const hardware::gnss::V1_0::GnssLocation& location,
67             hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceTransition transition,
68             hardware::gnss::V1_0::GnssUtcTime timestamp) override;
69     hardware::Return<void> gnssGeofenceStatusCb(
70             hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceAvailability status,
71             const hardware::gnss::V1_0::GnssLocation& location) override;
72     hardware::Return<void> gnssGeofenceAddCb(
73             int32_t geofenceId,
74             hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override;
75     hardware::Return<void> gnssGeofenceRemoveCb(
76             int32_t geofenceId,
77             hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override;
78     hardware::Return<void> gnssGeofencePauseCb(
79             int32_t geofenceId,
80             hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override;
81     hardware::Return<void> gnssGeofenceResumeCb(
82             int32_t geofenceId,
83             hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override;
84 };
85 
86 class GnssGeofenceCallback {
87 public:
GnssGeofenceCallback()88     GnssGeofenceCallback() {}
getAidl()89     sp<GnssGeofenceCallbackAidl> getAidl() {
90         if (callbackAidl == nullptr) {
91             callbackAidl = sp<GnssGeofenceCallbackAidl>::make();
92         }
93         return callbackAidl;
94     }
95 
getHidl()96     sp<GnssGeofenceCallbackHidl> getHidl() {
97         if (callbackHidl == nullptr) {
98             callbackHidl = sp<GnssGeofenceCallbackHidl>::make();
99         }
100         return callbackHidl;
101     }
102 
103 private:
104     sp<GnssGeofenceCallbackAidl> callbackAidl;
105     sp<GnssGeofenceCallbackHidl> callbackHidl;
106 };
107 
108 /** Util class for GnssGeofenceCallback methods. */
109 struct GnssGeofenceCallbackUtil {
110     template <class T>
111     static void gnssGeofenceTransitionCb(int geofenceId, const T& location, int transition,
112                                          int64_t timestampMillis);
113     template <class T>
114     static void gnssGeofenceStatusCb(int availability, const T& lastLocation);
115     static void gnssGeofenceAddCb(int geofenceId, int status);
116     static void gnssGeofenceRemoveCb(int geofenceId, int status);
117     static void gnssGeofencePauseCb(int geofenceId, int status);
118     static void gnssGeofenceResumeCb(int geofenceId, int status);
119 
120 private:
121     GnssGeofenceCallbackUtil() = delete;
122 };
123 
124 template <class T>
gnssGeofenceTransitionCb(int geofenceId,const T & location,int transition,int64_t timestamp)125 void GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(int geofenceId, const T& location,
126                                                         int transition, int64_t timestamp) {
127     JNIEnv* env = getJniEnv();
128 
129     jobject jLocation = translateGnssLocation(env, location);
130 
131     env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofenceId, jLocation,
132                         transition, timestamp);
133 
134     checkAndClearExceptionFromCallback(env, __FUNCTION__);
135     env->DeleteLocalRef(jLocation);
136 }
137 
138 template <class T>
gnssGeofenceStatusCb(int availability,const T & lastLocation)139 void GnssGeofenceCallbackUtil::gnssGeofenceStatusCb(int availability, const T& lastLocation) {
140     JNIEnv* env = getJniEnv();
141 
142     jobject jLocation = translateGnssLocation(env, lastLocation);
143 
144     env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, availability, jLocation);
145     checkAndClearExceptionFromCallback(env, __FUNCTION__);
146     env->DeleteLocalRef(jLocation);
147 }
148 
149 } // namespace android::gnss
150 
151 #endif // _ANDROID_SERVER_GNSS_GNSSGEOFENCECALLBACK_H