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