1 /*
2  * Copyright (C) 2019 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 #pragma once
18 
19 #include <android/hardware/gnss/2.1/IGnss.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <hidl/MQDescriptor.h>
23 #include <hidl/Status.h>
24 #include <log/log.h>
25 #include <sys/epoll.h>
26 #include <atomic>
27 #include <mutex>
28 #include <string>
29 #include <thread>
30 
31 #include <cutils/properties.h>
32 
33 #include "GnssAntennaInfo.h"
34 #include "GnssConfiguration.h"
35 #include "GnssDebug.h"
36 #include "GnssMeasurement.h"
37 #include "GnssMeasurementCorrections.h"
38 #include "MockLocation.h"
39 #include "NmeaFixInfo.h"
40 #include "Utils.h"
41 
42 namespace android::hardware::gnss::common::implementation {
43 
44 constexpr int INPUT_BUFFER_SIZE = 128;
45 constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION";
46 constexpr char GNSS_PATH[] = "/dev/gnss0";
47 
48 template <class T_IGnss>
49 struct GnssTemplate : public T_IGnss {
50     GnssTemplate();
51     ~GnssTemplate();
52     // Methods from V1_0::IGnss follow.
53     Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
54     Return<bool> start() override;
55     Return<bool> stop() override;
56     Return<void> cleanup() override;
57     Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs,
58                             int32_t uncertaintyMs) override;
59     Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees,
60                                 float accuracyMeters) override;
61     Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
62     Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
63                                  V1_0::IGnss::GnssPositionRecurrence recurrence,
64                                  uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
65                                  uint32_t preferredTimeMs) override;
66     Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
67     Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
68     Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
69     Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
70     Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
71     Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override;
72     Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override;
73     Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
74     Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
75     Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
76 
77     // Methods from V1_1::IGnss follow.
78     Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
79     Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
80                                      V1_0::IGnss::GnssPositionRecurrence recurrence,
81                                      uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
82                                      uint32_t preferredTimeMs, bool lowPowerMode) override;
83     Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
84     Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
85     Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
86 
87     // Methods from V2_0::IGnss follow.
88     Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
89     Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
90     Return<sp<V2_0::IGnssDebug>> getExtensionGnssDebug_2_0() override;
91     Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
92     Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
93     Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
94     Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
95     getExtensionMeasurementCorrections() override;
96     Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
97             override;
98     Return<sp<V2_0::IGnssBatching>> getExtensionGnssBatching_2_0() override;
99     Return<bool> injectBestLocation_2_0(const V2_0::GnssLocation& location) override;
100 
101     // Methods from V2_1::IGnss follow.
102     Return<bool> setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) override;
103     Return<sp<V2_1::IGnssMeasurement>> getExtensionGnssMeasurement_2_1() override;
104     Return<sp<V2_1::IGnssConfiguration>> getExtensionGnssConfiguration_2_1() override;
105     Return<sp<measurement_corrections::V1_1::IMeasurementCorrections>>
106     getExtensionMeasurementCorrections_1_1() override;
107     Return<sp<V2_1::IGnssAntennaInfo>> getExtensionGnssAntennaInfo() override;
108 
109     Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
110 
111   private:
112     std::unique_ptr<V2_0::GnssLocation> getLocationFromHW();
113     void reportLocation(const V2_0::GnssLocation&) const;
114     void reportLocation(const V1_0::GnssLocation&) const;
115     void reportSvStatus(const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>&) const;
116     void reportGnssStatusValue(const V1_0::IGnssCallback::GnssStatusValue) const;
117 
118     Return<void> help(const hidl_handle& fd);
119     Return<void> setLocation(const hidl_handle& fd, const hidl_vec<hidl_string>& options);
120 
121     static sp<V2_1::IGnssCallback> sGnssCallback_2_1;
122     static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
123     static sp<V1_1::IGnssCallback> sGnssCallback_1_1;
124     static sp<V1_0::IGnssCallback> sGnssCallback_1_0;
125 
126     std::atomic<long> mMinIntervalMs;
127     sp<V2_1::implementation::GnssConfiguration> mGnssConfiguration;
128     std::atomic<bool> mIsActive;
129     std::atomic<bool> mHardwareModeChecked;
130     std::atomic<int> mGnssFd;
131     std::thread mThread;
132 
133     mutable std::mutex mMutex;
134     virtual hidl_vec<V2_1::IGnssCallback::GnssSvInfo> filterBlocklistedSatellitesV2_1(
135             hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList);
136     virtual void notePowerConsumption();
137 };
138 
139 template <class T_IGnss>
140 sp<V2_1::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_2_1 = nullptr;
141 template <class T_IGnss>
142 sp<V2_0::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_2_0 = nullptr;
143 template <class T_IGnss>
144 sp<V1_1::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_1_1 = nullptr;
145 template <class T_IGnss>
146 sp<V1_0::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_1_0 = nullptr;
147 
148 template <class T_IGnss>
GnssTemplate()149 GnssTemplate<T_IGnss>::GnssTemplate()
150     : mMinIntervalMs(1000),
151       mGnssConfiguration{new V2_1::implementation::GnssConfiguration()},
152       mHardwareModeChecked(false),
153       mGnssFd(-1) {}
154 
155 template <class T_IGnss>
~GnssTemplate()156 GnssTemplate<T_IGnss>::~GnssTemplate() {
157     stop();
158 }
159 
160 template <class T_IGnss>
getLocationFromHW()161 std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
162     char inputBuffer[INPUT_BUFFER_SIZE];
163     if (!mHardwareModeChecked) {
164         // default using gnss0
165         const char * gnss_dev_path = GNSS_PATH;
166         char devname_value[PROPERTY_VALUE_MAX] = "";
167         if (property_get("debug.location.gnss.devname", devname_value, NULL) > 0) {
168             gnss_dev_path = devname_value;
169             ALOGD("using %s instead of the default %s", gnss_dev_path, GNSS_PATH);
170         }
171 
172         mGnssFd = open(gnss_dev_path, O_RDWR | O_NONBLOCK);
173         if (mGnssFd == -1) {
174             ALOGW("Failed to open %s errno: %d", gnss_dev_path, errno);
175         }
176         mHardwareModeChecked = true;
177     }
178 
179     if (mGnssFd == -1) {
180         return nullptr;
181     }
182 
183     int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION));
184     if (bytes_write <= 0) {
185         return nullptr;
186     }
187 
188     struct epoll_event ev, events[1];
189     ev.data.fd = mGnssFd;
190     ev.events = EPOLLIN;
191     int epoll_fd = epoll_create1(0);
192     epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
193     int bytes_read = -1;
194     std::string inputStr = "";
195     int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
196 
197     if (epoll_ret == -1) {
198         return nullptr;
199     }
200     while (true) {
201         memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
202         bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
203         if (bytes_read <= 0) {
204             break;
205         }
206         inputStr += std::string(inputBuffer, bytes_read);
207     }
208     return NmeaFixInfo::getLocationFromInputStr(inputStr);
209 }
210 
211 template <class T_IGnss>
start()212 Return<bool> GnssTemplate<T_IGnss>::start() {
213     if (mIsActive) {
214         ALOGW("Gnss has started. Restarting...");
215         stop();
216     }
217 
218     mIsActive = true;
219     this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_BEGIN);
220     mThread = std::thread([this]() {
221         while (mIsActive == true) {
222             auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
223             this->reportSvStatus(svStatus);
224             auto currentLocation = getLocationFromHW();
225             notePowerConsumption();
226             if (mGnssFd != -1) {
227                 // Only report location if the return from hardware is valid
228                 // note that we can not merge these two "if" together, if didn't
229                 // get location from hardware, we shouldn't report location, not
230                 // report the "default" one.
231                 if (currentLocation != nullptr) {
232                     this->reportLocation(*currentLocation);
233                 }
234             } else {
235                 if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) {
236                     const auto location = Utils::getMockLocationV2_0();
237                     this->reportLocation(location);
238                 } else {
239                     const auto location = Utils::getMockLocationV1_0();
240                     this->reportLocation(location);
241                 }
242             }
243             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
244         }
245     });
246     return true;
247 }
248 
249 template <class T_IGnss>
filterBlocklistedSatellitesV2_1(hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList)250 hidl_vec<V2_1::IGnssCallback::GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
251         hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList) {
252     ALOGD("GnssTemplate::filterBlocklistedSatellitesV2_1");
253     for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
254         if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
255             gnssSvInfoList[i].v2_0.v1_0.svFlag &=
256                     ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
257         }
258     }
259     return gnssSvInfoList;
260 }
261 
262 template <class T_IGnss>
notePowerConsumption()263 void GnssTemplate<T_IGnss>::notePowerConsumption() {
264     ALOGD("GnssTemplate::notePowerConsumption");
265 }
266 
267 template <class T_IGnss>
stop()268 Return<bool> GnssTemplate<T_IGnss>::stop() {
269     ALOGD("stop");
270     mIsActive = false;
271     this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_END);
272     if (mThread.joinable()) {
273         mThread.join();
274     }
275     if (mGnssFd != -1) {
276         close(mGnssFd);
277         mGnssFd = -1;
278         mHardwareModeChecked = false;
279     }
280     return true;
281 }
282 
283 // Methods from V1_0::IGnss follow.
284 template <class T_IGnss>
setCallback(const sp<V1_0::IGnssCallback> & callback)285 Return<bool> GnssTemplate<T_IGnss>::setCallback(const sp<V1_0::IGnssCallback>& callback) {
286     if (callback == nullptr) {
287         ALOGE("%s: Null callback ignored", __func__);
288         return false;
289     }
290 
291     sGnssCallback_1_0 = callback;
292 
293     uint32_t capabilities = 0x0 | V1_0::IGnssCallback::Capabilities::MEASUREMENTS |
294                             V1_0::IGnssCallback::Capabilities::SCHEDULING;
295     auto ret = sGnssCallback_1_0->gnssSetCapabilitesCb(capabilities);
296     if (!ret.isOk()) {
297         ALOGE("%s: Unable to invoke callback", __func__);
298     }
299 
300     V2_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
301 
302     ret = sGnssCallback_1_0->gnssSetSystemInfoCb(gnssInfo);
303     if (!ret.isOk()) {
304         ALOGE("%s: Unable to invoke callback", __func__);
305     }
306 
307     return true;
308 }
309 
310 template <class T_IGnss>
cleanup()311 Return<void> GnssTemplate<T_IGnss>::cleanup() {
312     sGnssCallback_2_1 = nullptr;
313     sGnssCallback_2_0 = nullptr;
314     return Void();
315 }
316 
317 template <class T_IGnss>
injectTime(int64_t,int64_t,int32_t)318 Return<bool> GnssTemplate<T_IGnss>::injectTime(int64_t, int64_t, int32_t) {
319     return true;
320 }
321 
322 template <class T_IGnss>
injectLocation(double,double,float)323 Return<bool> GnssTemplate<T_IGnss>::injectLocation(double, double, float) {
324     return true;
325 }
326 
327 template <class T_IGnss>
deleteAidingData(V1_0::IGnss::GnssAidingData)328 Return<void> GnssTemplate<T_IGnss>::deleteAidingData(V1_0::IGnss::GnssAidingData) {
329     // TODO implement
330     return Void();
331 }
332 
333 template <class T_IGnss>
setPositionMode(V1_0::IGnss::GnssPositionMode,V1_0::IGnss::GnssPositionRecurrence,uint32_t minIntervalMs,uint32_t,uint32_t)334 Return<bool> GnssTemplate<T_IGnss>::setPositionMode(V1_0::IGnss::GnssPositionMode,
335                                                     V1_0::IGnss::GnssPositionRecurrence,
336                                                     uint32_t minIntervalMs, uint32_t, uint32_t) {
337     mMinIntervalMs = minIntervalMs;
338     return true;
339 }
340 
341 template <class T_IGnss>
getExtensionAGnssRil()342 Return<sp<V1_0::IAGnssRil>> GnssTemplate<T_IGnss>::getExtensionAGnssRil() {
343     // TODO implement
344     return ::android::sp<V1_0::IAGnssRil>{};
345 }
346 
347 template <class T_IGnss>
getExtensionGnssGeofencing()348 Return<sp<V1_0::IGnssGeofencing>> GnssTemplate<T_IGnss>::getExtensionGnssGeofencing() {
349     // TODO implement
350     return ::android::sp<V1_0::IGnssGeofencing>{};
351 }
352 
353 template <class T_IGnss>
getExtensionAGnss()354 Return<sp<V1_0::IAGnss>> GnssTemplate<T_IGnss>::getExtensionAGnss() {
355     // TODO implement
356     return ::android::sp<V1_0::IAGnss>{};
357 }
358 
359 template <class T_IGnss>
getExtensionGnssNi()360 Return<sp<V1_0::IGnssNi>> GnssTemplate<T_IGnss>::getExtensionGnssNi() {
361     // TODO implement
362     return ::android::sp<V1_0::IGnssNi>{};
363 }
364 
365 template <class T_IGnss>
getExtensionGnssMeasurement()366 Return<sp<V1_0::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement() {
367     ALOGD("Gnss::getExtensionGnssMeasurement");
368     return new V2_1::implementation::GnssMeasurement();
369 }
370 
371 template <class T_IGnss>
372 Return<sp<V1_0::IGnssNavigationMessage>>
getExtensionGnssNavigationMessage()373 GnssTemplate<T_IGnss>::getExtensionGnssNavigationMessage() {
374     // TODO implement
375     return ::android::sp<V1_0::IGnssNavigationMessage>{};
376 }
377 
378 template <class T_IGnss>
getExtensionXtra()379 Return<sp<V1_0::IGnssXtra>> GnssTemplate<T_IGnss>::getExtensionXtra() {
380     // TODO implement
381     return ::android::sp<V1_0::IGnssXtra>{};
382 }
383 
384 template <class T_IGnss>
getExtensionGnssConfiguration()385 Return<sp<V1_0::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration() {
386     // TODO implement
387     return ::android::sp<V1_0::IGnssConfiguration>{};
388 }
389 
390 template <class T_IGnss>
getExtensionGnssDebug()391 Return<sp<V1_0::IGnssDebug>> GnssTemplate<T_IGnss>::getExtensionGnssDebug() {
392     return new V1_1::implementation::GnssDebug();
393 }
394 
395 template <class T_IGnss>
getExtensionGnssBatching()396 Return<sp<V1_0::IGnssBatching>> GnssTemplate<T_IGnss>::getExtensionGnssBatching() {
397     // TODO implement
398     return ::android::sp<V1_0::IGnssBatching>{};
399 }
400 
401 // Methods from V1_1::IGnss follow.
402 template <class T_IGnss>
setCallback_1_1(const sp<V1_1::IGnssCallback> & callback)403 Return<bool> GnssTemplate<T_IGnss>::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
404     if (callback == nullptr) {
405         ALOGE("%s: Null callback ignored", __func__);
406         return false;
407     }
408 
409     sGnssCallback_1_1 = callback;
410 
411     uint32_t capabilities = 0x0;
412     auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities);
413     if (!ret.isOk()) {
414         ALOGE("%s: Unable to invoke callback", __func__);
415     }
416 
417     V2_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
418 
419     ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo);
420     if (!ret.isOk()) {
421         ALOGE("%s: Unable to invoke callback", __func__);
422     }
423 
424     auto gnssName = "Google Mock GNSS Implementation v2.1";
425     ret = sGnssCallback_1_1->gnssNameCb(gnssName);
426     if (!ret.isOk()) {
427         ALOGE("%s: Unable to invoke callback", __func__);
428     }
429 
430     return true;
431 }
432 
433 template <class T_IGnss>
setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,V1_0::IGnss::GnssPositionRecurrence,uint32_t minIntervalMs,uint32_t,uint32_t,bool)434 Return<bool> GnssTemplate<T_IGnss>::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
435                                                         V1_0::IGnss::GnssPositionRecurrence,
436                                                         uint32_t minIntervalMs, uint32_t, uint32_t,
437                                                         bool) {
438     mMinIntervalMs = minIntervalMs;
439     return true;
440 }
441 
442 template <class T_IGnss>
getExtensionGnssConfiguration_1_1()443 Return<sp<V1_1::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration_1_1() {
444     // TODO implement
445     return ::android::sp<V1_1::IGnssConfiguration>{};
446 }
447 
448 template <class T_IGnss>
getExtensionGnssMeasurement_1_1()449 Return<sp<V1_1::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_1_1() {
450     // TODO implement
451     return ::android::sp<V1_1::IGnssMeasurement>{};
452 }
453 
454 template <class T_IGnss>
injectBestLocation(const V1_0::GnssLocation &)455 Return<bool> GnssTemplate<T_IGnss>::injectBestLocation(const V1_0::GnssLocation&) {
456     return true;
457 }
458 
459 // Methods from V2_0::IGnss follow.
460 template <class T_IGnss>
setCallback_2_0(const sp<V2_0::IGnssCallback> & callback)461 Return<bool> GnssTemplate<T_IGnss>::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
462     ALOGD("Gnss::setCallback_2_0");
463     if (callback == nullptr) {
464         ALOGE("%s: Null callback ignored", __func__);
465         return false;
466     }
467 
468     sGnssCallback_2_0 = callback;
469 
470     using Capabilities = V2_0::IGnssCallback::Capabilities;
471     const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
472                               Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
473     auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
474     if (!ret.isOk()) {
475         ALOGE("%s: Unable to invoke callback", __func__);
476     }
477 
478     V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
479 
480     ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
481     if (!ret.isOk()) {
482         ALOGE("%s: Unable to invoke callback", __func__);
483     }
484 
485     auto gnssName = "Google Mock GNSS Implementation v2.1";
486     ret = sGnssCallback_2_0->gnssNameCb(gnssName);
487     if (!ret.isOk()) {
488         ALOGE("%s: Unable to invoke callback", __func__);
489     }
490 
491     return true;
492 }
493 
494 template <class T_IGnss>
getExtensionGnssConfiguration_2_0()495 Return<sp<V2_0::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration_2_0() {
496     ALOGD("Gnss::getExtensionGnssConfiguration_2_0");
497     return mGnssConfiguration;
498 }
499 
500 template <class T_IGnss>
getExtensionGnssDebug_2_0()501 Return<sp<V2_0::IGnssDebug>> GnssTemplate<T_IGnss>::getExtensionGnssDebug_2_0() {
502     // TODO implement
503     return ::android::sp<V2_0::IGnssDebug>{};
504 }
505 
506 template <class T_IGnss>
getExtensionAGnss_2_0()507 Return<sp<V2_0::IAGnss>> GnssTemplate<T_IGnss>::getExtensionAGnss_2_0() {
508     // TODO implement
509     return ::android::sp<V2_0::IAGnss>{};
510 }
511 
512 template <class T_IGnss>
getExtensionAGnssRil_2_0()513 Return<sp<V2_0::IAGnssRil>> GnssTemplate<T_IGnss>::getExtensionAGnssRil_2_0() {
514     // TODO implement
515     return ::android::sp<V2_0::IAGnssRil>{};
516 }
517 
518 template <class T_IGnss>
getExtensionGnssMeasurement_2_0()519 Return<sp<V2_0::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_2_0() {
520     ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
521     return new V2_1::implementation::GnssMeasurement();
522 }
523 
524 template <class T_IGnss>
525 Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
getExtensionMeasurementCorrections()526 GnssTemplate<T_IGnss>::getExtensionMeasurementCorrections() {
527     ALOGD("Gnss::getExtensionMeasurementCorrections()");
528     return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections();
529 }
530 
531 template <class T_IGnss>
532 Return<sp<visibility_control::V1_0::IGnssVisibilityControl>>
getExtensionVisibilityControl()533 GnssTemplate<T_IGnss>::getExtensionVisibilityControl() {
534     // TODO implement
535     return ::android::sp<visibility_control::V1_0::IGnssVisibilityControl>{};
536 }
537 
538 template <class T_IGnss>
getExtensionGnssBatching_2_0()539 Return<sp<V2_0::IGnssBatching>> GnssTemplate<T_IGnss>::getExtensionGnssBatching_2_0() {
540     // TODO implement
541     return ::android::sp<V2_0::IGnssBatching>{};
542 }
543 
544 template <class T_IGnss>
injectBestLocation_2_0(const V2_0::GnssLocation &)545 Return<bool> GnssTemplate<T_IGnss>::injectBestLocation_2_0(const V2_0::GnssLocation&) {
546     // TODO(b/124012850): Implement function.
547     return bool{};
548 }
549 
550 // Methods from V2_1::IGnss follow.
551 template <class T_IGnss>
setCallback_2_1(const sp<V2_1::IGnssCallback> & callback)552 Return<bool> GnssTemplate<T_IGnss>::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
553     ALOGD("Gnss::setCallback_2_1");
554     if (callback == nullptr) {
555         ALOGE("%s: Null callback ignored", __func__);
556         return false;
557     }
558 
559     sGnssCallback_2_1 = callback;
560 
561     using Capabilities = V2_1::IGnssCallback::Capabilities;
562     const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
563                               Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST |
564                               Capabilities::ANTENNA_INFO;
565     auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_1(capabilities);
566     if (!ret.isOk()) {
567         ALOGE("%s: Unable to invoke callback", __func__);
568     }
569 
570     V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020};
571 
572     ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo);
573     if (!ret.isOk()) {
574         ALOGE("%s: Unable to invoke callback", __func__);
575     }
576 
577     auto gnssName = "Android Mock GNSS Implementation v2.1";
578     ret = sGnssCallback_2_1->gnssNameCb(gnssName);
579     if (!ret.isOk()) {
580         ALOGE("%s: Unable to invoke callback", __func__);
581     }
582 
583     return true;
584 }
585 
586 template <class T_IGnss>
getExtensionGnssMeasurement_2_1()587 Return<sp<V2_1::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_2_1() {
588     ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
589     return new V2_1::implementation::GnssMeasurement();
590 }
591 
592 template <class T_IGnss>
getExtensionGnssConfiguration_2_1()593 Return<sp<V2_1::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration_2_1() {
594     ALOGD("Gnss::getExtensionGnssConfiguration_2_1");
595     return mGnssConfiguration;
596 }
597 
598 template <class T_IGnss>
599 Return<sp<measurement_corrections::V1_1::IMeasurementCorrections>>
getExtensionMeasurementCorrections_1_1()600 GnssTemplate<T_IGnss>::getExtensionMeasurementCorrections_1_1() {
601     ALOGD("Gnss::getExtensionMeasurementCorrections_1_1()");
602     return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections();
603 }
604 
605 template <class T_IGnss>
getExtensionGnssAntennaInfo()606 Return<sp<V2_1::IGnssAntennaInfo>> GnssTemplate<T_IGnss>::getExtensionGnssAntennaInfo() {
607     ALOGD("Gnss::getExtensionGnssAntennaInfo");
608     return new V2_1::implementation::GnssAntennaInfo();
609 }
610 
611 template <class T_IGnss>
reportGnssStatusValue(const V1_0::IGnssCallback::GnssStatusValue gnssStatusValue)612 void GnssTemplate<T_IGnss>::reportGnssStatusValue(
613         const V1_0::IGnssCallback::GnssStatusValue gnssStatusValue) const {
614     std::unique_lock<std::mutex> lock(mMutex);
615     if (sGnssCallback_2_1 == nullptr) {
616         ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
617         return;
618     }
619     auto ret = sGnssCallback_2_1->gnssStatusCb(gnssStatusValue);
620     if (!ret.isOk()) {
621         ALOGE("%s: Unable to invoke callback", __func__);
622     }
623 }
624 
625 template <class T_IGnss>
reportSvStatus(const hidl_vec<V2_1::IGnssCallback::GnssSvInfo> & svInfoList)626 void GnssTemplate<T_IGnss>::reportSvStatus(
627         const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& svInfoList) const {
628     std::unique_lock<std::mutex> lock(mMutex);
629     // TODO(skz): update this to call 2_0 callback if non-null
630     if (sGnssCallback_2_1 == nullptr) {
631         ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
632         return;
633     }
634     auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList);
635     if (!ret.isOk()) {
636         ALOGE("%s: Unable to invoke callback", __func__);
637     }
638 }
639 
640 template <class T_IGnss>
reportLocation(const V1_0::GnssLocation & location)641 void GnssTemplate<T_IGnss>::reportLocation(const V1_0::GnssLocation& location) const {
642     std::unique_lock<std::mutex> lock(mMutex);
643     if (sGnssCallback_1_1 != nullptr) {
644         auto ret = sGnssCallback_1_1->gnssLocationCb(location);
645         if (!ret.isOk()) {
646             ALOGE("%s: Unable to invoke callback v1.1", __func__);
647         }
648         return;
649     }
650     if (sGnssCallback_1_0 == nullptr) {
651         ALOGE("%s: No non-null callback", __func__);
652         return;
653     }
654     auto ret = sGnssCallback_1_0->gnssLocationCb(location);
655     if (!ret.isOk()) {
656         ALOGE("%s: Unable to invoke callback v1.0", __func__);
657     }
658 }
659 
660 template <class T_IGnss>
reportLocation(const V2_0::GnssLocation & location)661 void GnssTemplate<T_IGnss>::reportLocation(const V2_0::GnssLocation& location) const {
662     std::unique_lock<std::mutex> lock(mMutex);
663     if (sGnssCallback_2_1 != nullptr) {
664         auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
665         if (!ret.isOk()) {
666             ALOGE("%s: Unable to invoke callback v2.1", __func__);
667         }
668         return;
669     }
670     if (sGnssCallback_2_0 == nullptr) {
671         ALOGE("%s: No non-null callback", __func__);
672         return;
673     }
674     auto ret = sGnssCallback_2_0->gnssLocationCb_2_0(location);
675     if (!ret.isOk()) {
676         ALOGE("%s: Unable to invoke callback v2.0", __func__);
677     }
678 }
679 
680 template <class T_IGnss>
setLocation(const hidl_handle & fd,const hidl_vec<hidl_string> & options)681 Return<void> GnssTemplate<T_IGnss>::setLocation(const hidl_handle& fd,
682                                                 const hidl_vec<hidl_string>& options) {
683     auto lat = gMockLatitudeDegrees;
684     auto lon = gMockLongitudeDegrees;
685     auto ele = gMockAltitudeMeters;
686     auto bea = gMockBearingDegrees;
687     auto spd = gMockSpeedMetersPerSec;
688 
689     for (size_t i = 1; i < options.size(); ++i) {
690         std::string option = options[i];
691         if (option.rfind("lat=", 0) == 0) {
692             option = option.substr(4);
693             lat = stof(option);
694         } else if (option.rfind("lon=", 0) == 0) {
695             option = option.substr(4);
696             lon = stof(option);
697         } else if (option.rfind("ele=", 0) == 0) {
698             option = option.substr(4);
699             ele = stof(option);
700         } else if (option.rfind("bea=", 0) == 0) {
701             option = option.substr(4);
702             bea = stof(option);
703         } else if (option.rfind("spd=", 0) == 0) {
704             option = option.substr(4);
705             spd = stof(option);
706         } else {
707             dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str());
708         }
709     }
710 
711     gMockLatitudeDegrees = lat;
712     gMockLongitudeDegrees = lon;
713     gMockAltitudeMeters = ele;
714     gMockBearingDegrees = bea;
715     gMockSpeedMetersPerSec = spd;
716 
717     dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f bea=%f spd=%f\n",
718             gMockLatitudeDegrees, gMockLongitudeDegrees, gMockAltitudeMeters, gMockBearingDegrees,
719             gMockSpeedMetersPerSec);
720 
721     return Void();
722 }
723 
724 template <class T_IGnss>
help(const hidl_handle & fd)725 Return<void> GnssTemplate<T_IGnss>::help(const hidl_handle& fd) {
726     dprintf(fd->data[0],
727             "invalid option for Gnss HAL; valid options are:\n"
728             "location [lat=..] [lon=..] [ele=..] [bea=..] [spd=..]\n");
729     return Void();
730 }
731 
732 template <class T_IGnss>
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & options)733 Return<void> GnssTemplate<T_IGnss>::debug(const hidl_handle& fd,
734                                           const hidl_vec<hidl_string>& options) {
735     if (fd == nullptr || fd->numFds == 0) {
736         return Void();
737     }
738 
739     if (options.size() == 0) {
740         return help(fd);
741     } else if (options[0] == "location") {
742         return setLocation(fd, options);
743     } else {
744         return help(fd);
745     }
746 
747     return Void();
748 }
749 
750 }  // namespace android::hardware::gnss::common::implementation
751