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