• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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