• 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 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