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