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