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