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