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