1 /*
2  * Copyright (C) 2020 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_GNSSMEASUREMENTCALLBACK_H
18 #define _ANDROID_SERVER_GNSS_GNSSMEASUREMENTCALLBACK_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/IGnssMeasurement.h>
27 #include <android/hardware/gnss/1.1/IGnssMeasurement.h>
28 #include <android/hardware/gnss/2.0/IGnssMeasurement.h>
29 #include <android/hardware/gnss/2.1/IGnssMeasurement.h>
30 #include <android/hardware/gnss/BnGnssMeasurementCallback.h>
31 #include <log/log.h>
32 #include "Utils.h"
33 #include "jni.h"
34 
35 namespace android::gnss {
36 
37 namespace {
38 extern jclass class_gnssMeasurementsEvent;
39 extern jclass class_gnssMeasurement;
40 extern jclass class_gnssClock;
41 
42 extern jmethodID method_gnssMeasurementsEventCtor;
43 extern jmethodID method_gnssClockCtor;
44 extern jmethodID method_gnssMeasurementCtor;
45 extern jmethodID method_reportMeasurementData;
46 } // anonymous namespace
47 
48 void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz);
49 
50 void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock,
51                         jobjectArray measurementArray, jobjectArray gnssAgcArray,
52                         bool hasIsFullTracking, jboolean isFullTracking);
53 
54 class GnssMeasurementCallbackAidl : public hardware::gnss::BnGnssMeasurementCallback {
55 public:
GnssMeasurementCallbackAidl()56     GnssMeasurementCallbackAidl() : mCallbacksObj(getCallbacksObj()) {}
57     android::binder::Status gnssMeasurementCb(const hardware::gnss::GnssData& data) override;
58 
59 private:
60     void translateSingleGnssMeasurement(JNIEnv* env,
61                                         const hardware::gnss::GnssMeasurement& measurement,
62                                         JavaObject& object);
63 
64     jobjectArray translateAllGnssMeasurements(
65             JNIEnv* env, const std::vector<hardware::gnss::GnssMeasurement>& measurements);
66     jobjectArray translateAllGnssAgcs(JNIEnv* env,
67                                       const std::vector<hardware::gnss::GnssData::GnssAgc>& agcs);
68 
69     void translateAndSetGnssData(const hardware::gnss::GnssData& data);
70 
71     void translateGnssClock(JNIEnv* env, const hardware::gnss::GnssData& data, JavaObject& object);
72 
73     jobject& mCallbacksObj;
74 };
75 
76 /*
77  * GnssMeasurementCallback implements the callback methods required for the
78  * GnssMeasurement interface.
79  */
80 class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback {
81 public:
GnssMeasurementCallbackHidl()82     GnssMeasurementCallbackHidl() : mCallbacksObj(getCallbacksObj()) {}
83     hardware::Return<void> gnssMeasurementCb_2_1(
84             const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override;
85     hardware::Return<void> gnssMeasurementCb_2_0(
86             const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) override;
87     hardware::Return<void> gnssMeasurementCb(
88             const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) override;
89     hardware::Return<void> GnssMeasurementCb(
90             const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) override;
91 
92 private:
93     template <class T>
94     void translateSingleGnssMeasurement(const T& measurement, JavaObject& object);
95 
96     template <class T>
97     jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
98 
99     template <class T>
100     void translateAndSetGnssData(const T& data);
101 
102     template <class T>
103     size_t getMeasurementCount(const T& data);
104 
105     template <class T>
106     void translateGnssClock(const T& data, JavaObject& object);
107 
108     jobject& mCallbacksObj;
109 };
110 
111 class GnssMeasurementCallback {
112 public:
GnssMeasurementCallback()113     GnssMeasurementCallback() {}
getAidl()114     sp<GnssMeasurementCallbackAidl> getAidl() {
115         if (callbackAidl == nullptr) {
116             callbackAidl = sp<GnssMeasurementCallbackAidl>::make();
117         }
118         return callbackAidl;
119     }
120 
getHidl()121     sp<GnssMeasurementCallbackHidl> getHidl() {
122         if (callbackHidl == nullptr) {
123             callbackHidl = sp<GnssMeasurementCallbackHidl>::make();
124         }
125         return callbackHidl;
126     }
127 
128 private:
129     sp<GnssMeasurementCallbackAidl> callbackAidl;
130     sp<GnssMeasurementCallbackHidl> callbackHidl;
131 };
132 
133 template <class T>
translateAndSetGnssData(const T & data)134 void GnssMeasurementCallbackHidl::translateAndSetGnssData(const T& data) {
135     JNIEnv* env = getJniEnv();
136 
137     JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
138     translateGnssClock(data, gnssClockJavaObject);
139     jobject clock = gnssClockJavaObject.get();
140 
141     size_t count = getMeasurementCount(data);
142     jobjectArray measurementArray =
143             translateAllGnssMeasurements(env, data.measurements.data(), count);
144     setMeasurementData(env, mCallbacksObj, clock, measurementArray, /*gnssAgcArray=*/nullptr,
145                        /*hasIsFullTracking=*/false,
146                        /*isFullTracking=*/JNI_FALSE);
147 
148     env->DeleteLocalRef(clock);
149     env->DeleteLocalRef(measurementArray);
150 }
151 
152 template <>
153 size_t GnssMeasurementCallbackHidl::getMeasurementCount<
154         hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>(
155         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data);
156 
157 template <class T>
getMeasurementCount(const T & data)158 size_t GnssMeasurementCallbackHidl::getMeasurementCount(const T& data) {
159     return data.measurements.size();
160 }
161 
162 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
163 template <>
164 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
165         hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>(
166         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement& measurement,
167         JavaObject& object);
168 
169 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
170 template <>
171 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
172         hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>(
173         const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V1_1,
174         JavaObject& object);
175 
176 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
177 template <>
178 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
179         hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>(
180         const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_0,
181         JavaObject& object);
182 
183 // Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
184 template <>
185 void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
186         hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>(
187         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_1,
188         JavaObject& object);
189 
190 template <class T>
translateGnssClock(const T & data,JavaObject & object)191 void GnssMeasurementCallbackHidl::translateGnssClock(const T& data, JavaObject& object) {
192     translateGnssClock(data.clock, object);
193 }
194 
195 template <>
196 void GnssMeasurementCallbackHidl::translateGnssClock(
197         const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object);
198 
199 template <>
200 void GnssMeasurementCallbackHidl::translateGnssClock(
201         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object);
202 
203 template <>
204 void GnssMeasurementCallbackHidl::translateGnssClock(
205         const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object);
206 
207 template <>
208 void GnssMeasurementCallbackHidl::translateGnssClock(
209         const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data, JavaObject& object);
210 
211 template <class T>
translateAllGnssMeasurements(JNIEnv * env,const T * measurements,size_t count)212 jobjectArray GnssMeasurementCallbackHidl::translateAllGnssMeasurements(JNIEnv* env,
213                                                                        const T* measurements,
214                                                                        size_t count) {
215     if (count == 0) {
216         return nullptr;
217     }
218 
219     jobjectArray gnssMeasurementArray =
220             env->NewObjectArray(count, class_gnssMeasurement, nullptr /* initialElement */);
221 
222     for (uint16_t i = 0; i < count; ++i) {
223         JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
224         translateSingleGnssMeasurement(measurements[i], object);
225         jobject gnssMeasurement = object.get();
226         env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
227         env->DeleteLocalRef(gnssMeasurement);
228     }
229 
230     return gnssMeasurementArray;
231 }
232 
233 } // namespace android::gnss
234 
235 #endif // _ANDROID_SERVER_GNSS_GNSSMEASUREMENTCALLBACK_H