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