1 /*
2 * Copyright (C) 2016 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 #define LOG_TAG "GnssHAL_GnssInterface"
18
19 #include "Gnss.h"
20 #include <GnssUtils.h>
21
22 namespace android {
23 namespace hardware {
24 namespace gnss {
25 namespace V1_0 {
26 namespace implementation {
27
28 std::vector<std::unique_ptr<ThreadFuncArgs>> Gnss::sThreadFuncArgsList;
29 sp<IGnssCallback> Gnss::sGnssCbIface = nullptr;
30 bool Gnss::sInterfaceExists = false;
31 bool Gnss::sWakelockHeldGnss = false;
32 bool Gnss::sWakelockHeldFused = false;
33
34 GpsCallbacks Gnss::sGnssCb = {
35 .size = sizeof(GpsCallbacks),
36 .location_cb = locationCb,
37 .status_cb = statusCb,
38 .sv_status_cb = gpsSvStatusCb,
39 .nmea_cb = nmeaCb,
40 .set_capabilities_cb = setCapabilitiesCb,
41 .acquire_wakelock_cb = acquireWakelockCb,
42 .release_wakelock_cb = releaseWakelockCb,
43 .create_thread_cb = createThreadCb,
44 .request_utc_time_cb = requestUtcTimeCb,
45 .set_system_info_cb = setSystemInfoCb,
46 .gnss_sv_status_cb = gnssSvStatusCb,
47 };
48
49 uint32_t Gnss::sCapabilitiesCached = 0;
50 uint16_t Gnss::sYearOfHwCached = 0;
51
Gnss(gps_device_t * gnssDevice)52 Gnss::Gnss(gps_device_t* gnssDevice) :
53 mDeathRecipient(new GnssHidlDeathRecipient(this)) {
54 /* Error out if an instance of the interface already exists. */
55 LOG_ALWAYS_FATAL_IF(sInterfaceExists);
56 sInterfaceExists = true;
57
58 if (gnssDevice == nullptr) {
59 ALOGE("%s: Invalid device_t handle", __func__);
60 return;
61 }
62
63 mGnssIface = gnssDevice->get_gps_interface(gnssDevice);
64 }
65
~Gnss()66 Gnss::~Gnss() {
67 sInterfaceExists = false;
68 sThreadFuncArgsList.clear();
69 }
70
locationCb(GpsLocation * location)71 void Gnss::locationCb(GpsLocation* location) {
72 if (sGnssCbIface == nullptr) {
73 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
74 return;
75 }
76
77 if (location == nullptr) {
78 ALOGE("%s: Invalid location from GNSS HAL", __func__);
79 return;
80 }
81
82 android::hardware::gnss::V1_0::GnssLocation gnssLocation = convertToGnssLocation(location);
83 auto ret = sGnssCbIface->gnssLocationCb(gnssLocation);
84 if (!ret.isOk()) {
85 ALOGE("%s: Unable to invoke callback", __func__);
86 }
87 }
88
statusCb(GpsStatus * gnssStatus)89 void Gnss::statusCb(GpsStatus* gnssStatus) {
90 if (sGnssCbIface == nullptr) {
91 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
92 return;
93 }
94
95 if (gnssStatus == nullptr) {
96 ALOGE("%s: Invalid GpsStatus from GNSS HAL", __func__);
97 return;
98 }
99
100 IGnssCallback::GnssStatusValue status =
101 static_cast<IGnssCallback::GnssStatusValue>(gnssStatus->status);
102
103 auto ret = sGnssCbIface->gnssStatusCb(status);
104 if (!ret.isOk()) {
105 ALOGE("%s: Unable to invoke callback", __func__);
106 }
107 }
108
gnssSvStatusCb(GnssSvStatus * status)109 void Gnss::gnssSvStatusCb(GnssSvStatus* status) {
110 if (sGnssCbIface == nullptr) {
111 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
112 return;
113 }
114
115 if (status == nullptr) {
116 ALOGE("Invalid status from GNSS HAL %s", __func__);
117 return;
118 }
119
120 IGnssCallback::GnssSvStatus svStatus;
121 svStatus.numSvs = status->num_svs;
122
123 if (svStatus.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
124 ALOGW("Too many satellites %u. Clamps to %d.", svStatus.numSvs, GnssMax::SVS_COUNT);
125 svStatus.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
126 }
127
128 for (size_t i = 0; i < svStatus.numSvs; i++) {
129 auto svInfo = status->gnss_sv_list[i];
130 IGnssCallback::GnssSvInfo gnssSvInfo = {
131 .svid = svInfo.svid,
132 .constellation = static_cast<
133 android::hardware::gnss::V1_0::GnssConstellationType>(
134 svInfo.constellation),
135 .cN0Dbhz = svInfo.c_n0_dbhz,
136 .elevationDegrees = svInfo.elevation,
137 .azimuthDegrees = svInfo.azimuth,
138 // Older chipsets do not provide carrier frequency, hence
139 // HAS_CARRIER_FREQUENCY flag and the carrierFrequencyHz fields
140 // are not set. So we are resetting both fields here.
141 .svFlag = static_cast<uint8_t>(
142 svInfo.flags &= ~(static_cast<uint8_t>(
143 IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY))),
144 .carrierFrequencyHz = 0};
145 svStatus.gnssSvList[i] = gnssSvInfo;
146 }
147
148 auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
149 if (!ret.isOk()) {
150 ALOGE("%s: Unable to invoke callback", __func__);
151 }
152 }
153
154 /*
155 * This enum is used by gpsSvStatusCb() method below to convert GpsSvStatus
156 * to GnssSvStatus for backward compatibility. It is only used by the default
157 * implementation and is not part of the GNSS interface.
158 */
159 enum SvidValues : uint16_t {
160 GLONASS_SVID_OFFSET = 64,
161 GLONASS_SVID_COUNT = 24,
162 BEIDOU_SVID_OFFSET = 200,
163 BEIDOU_SVID_COUNT = 35,
164 SBAS_SVID_MIN = 33,
165 SBAS_SVID_MAX = 64,
166 SBAS_SVID_ADD = 87,
167 QZSS_SVID_MIN = 193,
168 QZSS_SVID_MAX = 200
169 };
170
171 /*
172 * The following code that converts GpsSvStatus to GnssSvStatus is moved here from
173 * GnssLocationProvider. GnssLocationProvider does not require it anymore since GpsSvStatus is
174 * being deprecated and is no longer part of the GNSS interface.
175 */
gpsSvStatusCb(GpsSvStatus * svInfo)176 void Gnss::gpsSvStatusCb(GpsSvStatus* svInfo) {
177 if (sGnssCbIface == nullptr) {
178 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
179 return;
180 }
181
182 if (svInfo == nullptr) {
183 ALOGE("Invalid status from GNSS HAL %s", __func__);
184 return;
185 }
186
187 IGnssCallback::GnssSvStatus svStatus;
188 svStatus.numSvs = svInfo->num_svs;
189 /*
190 * Clamp the list size since GnssSvStatus can support a maximum of
191 * GnssMax::SVS_COUNT entries.
192 */
193 if (svStatus.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
194 ALOGW("Too many satellites %u. Clamps to %d.", svStatus.numSvs, GnssMax::SVS_COUNT);
195 svStatus.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
196 }
197
198 uint32_t ephemerisMask = svInfo->ephemeris_mask;
199 uint32_t almanacMask = svInfo->almanac_mask;
200 uint32_t usedInFixMask = svInfo->used_in_fix_mask;
201 /*
202 * Conversion from GpsSvInfo to IGnssCallback::GnssSvInfo happens below.
203 */
204 for (size_t i = 0; i < svStatus.numSvs; i++) {
205 IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList[i];
206 info.svid = svInfo->sv_list[i].prn;
207 if (info.svid >= 1 && info.svid <= 32) {
208 info.constellation = GnssConstellationType::GPS;
209 } else if (info.svid > GLONASS_SVID_OFFSET &&
210 info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
211 info.constellation = GnssConstellationType::GLONASS;
212 info.svid -= GLONASS_SVID_OFFSET;
213 } else if (info.svid > BEIDOU_SVID_OFFSET &&
214 info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
215 info.constellation = GnssConstellationType::BEIDOU;
216 info.svid -= BEIDOU_SVID_OFFSET;
217 } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
218 info.constellation = GnssConstellationType::SBAS;
219 info.svid += SBAS_SVID_ADD;
220 } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
221 info.constellation = GnssConstellationType::QZSS;
222 } else {
223 ALOGD("Unknown constellation type with Svid = %d.", info.svid);
224 info.constellation = GnssConstellationType::UNKNOWN;
225 }
226
227 info.cN0Dbhz = svInfo->sv_list[i].snr;
228 info.elevationDegrees = svInfo->sv_list[i].elevation;
229 info.azimuthDegrees = svInfo->sv_list[i].azimuth;
230 // TODO: b/31702236
231 info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
232
233 /*
234 * Only GPS info is valid for these fields, as these masks are just 32
235 * bits, by GPS prn.
236 */
237 if (info.constellation == GnssConstellationType::GPS) {
238 int32_t svidMask = (1 << (info.svid - 1));
239 if ((ephemerisMask & svidMask) != 0) {
240 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
241 }
242 if ((almanacMask & svidMask) != 0) {
243 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
244 }
245 if ((usedInFixMask & svidMask) != 0) {
246 info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
247 }
248 }
249 }
250
251 auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
252 if (!ret.isOk()) {
253 ALOGE("%s: Unable to invoke callback", __func__);
254 }
255 }
256
nmeaCb(GpsUtcTime timestamp,const char * nmea,int length)257 void Gnss::nmeaCb(GpsUtcTime timestamp, const char* nmea, int length) {
258 if (sGnssCbIface == nullptr) {
259 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
260 return;
261 }
262
263 android::hardware::hidl_string nmeaString;
264 nmeaString.setToExternal(nmea, length);
265 auto ret = sGnssCbIface->gnssNmeaCb(timestamp, nmeaString);
266 if (!ret.isOk()) {
267 ALOGE("%s: Unable to invoke callback", __func__);
268 }
269 }
270
setCapabilitiesCb(uint32_t capabilities)271 void Gnss::setCapabilitiesCb(uint32_t capabilities) {
272 if (sGnssCbIface == nullptr) {
273 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
274 return;
275 }
276
277 auto ret = sGnssCbIface->gnssSetCapabilitesCb(capabilities);
278 if (!ret.isOk()) {
279 ALOGE("%s: Unable to invoke callback", __func__);
280 }
281
282 // Save for reconnection when some legacy hal's don't resend this info
283 sCapabilitiesCached = capabilities;
284 }
285
acquireWakelockCb()286 void Gnss::acquireWakelockCb() {
287 acquireWakelockGnss();
288 }
289
releaseWakelockCb()290 void Gnss::releaseWakelockCb() {
291 releaseWakelockGnss();
292 }
293
294
acquireWakelockGnss()295 void Gnss::acquireWakelockGnss() {
296 sWakelockHeldGnss = true;
297 updateWakelock();
298 }
299
releaseWakelockGnss()300 void Gnss::releaseWakelockGnss() {
301 sWakelockHeldGnss = false;
302 updateWakelock();
303 }
304
acquireWakelockFused()305 void Gnss::acquireWakelockFused() {
306 sWakelockHeldFused = true;
307 updateWakelock();
308 }
309
releaseWakelockFused()310 void Gnss::releaseWakelockFused() {
311 sWakelockHeldFused = false;
312 updateWakelock();
313 }
314
updateWakelock()315 void Gnss::updateWakelock() {
316 // Track the state of the last request - in case the wake lock in the layer above is reference
317 // counted.
318 static bool sWakelockHeld = false;
319
320 if (sGnssCbIface == nullptr) {
321 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
322 return;
323 }
324
325 if (sWakelockHeldGnss || sWakelockHeldFused) {
326 if (!sWakelockHeld) {
327 ALOGI("%s: GNSS HAL Wakelock acquired due to gps: %d, fused: %d", __func__,
328 sWakelockHeldGnss, sWakelockHeldFused);
329 sWakelockHeld = true;
330 auto ret = sGnssCbIface->gnssAcquireWakelockCb();
331 if (!ret.isOk()) {
332 ALOGE("%s: Unable to invoke callback", __func__);
333 }
334 }
335 } else {
336 if (sWakelockHeld) {
337 ALOGI("%s: GNSS HAL Wakelock released", __func__);
338 } else {
339 // To avoid burning power, always release, even if logic got here with sWakelock false
340 // which it shouldn't, unless underlying *.h implementation makes duplicate requests.
341 ALOGW("%s: GNSS HAL Wakelock released, duplicate request", __func__);
342 }
343 sWakelockHeld = false;
344 auto ret = sGnssCbIface->gnssReleaseWakelockCb();
345 if (!ret.isOk()) {
346 ALOGE("%s: Unable to invoke callback", __func__);
347 }
348 }
349 }
350
requestUtcTimeCb()351 void Gnss::requestUtcTimeCb() {
352 if (sGnssCbIface == nullptr) {
353 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
354 return;
355 }
356
357 auto ret = sGnssCbIface->gnssRequestTimeCb();
358 if (!ret.isOk()) {
359 ALOGE("%s: Unable to invoke callback", __func__);
360 }
361 }
362
createThreadCb(const char * name,void (* start)(void *),void * arg)363 pthread_t Gnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
364 return createPthread(name, start, arg, &sThreadFuncArgsList);
365 }
366
setSystemInfoCb(const LegacyGnssSystemInfo * info)367 void Gnss::setSystemInfoCb(const LegacyGnssSystemInfo* info) {
368 if (sGnssCbIface == nullptr) {
369 ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
370 return;
371 }
372
373 if (info == nullptr) {
374 ALOGE("Invalid GnssSystemInfo from GNSS HAL %s", __func__);
375 return;
376 }
377
378 IGnssCallback::GnssSystemInfo gnssInfo = {
379 .yearOfHw = info->year_of_hw
380 };
381
382 auto ret = sGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
383 if (!ret.isOk()) {
384 ALOGE("%s: Unable to invoke callback", __func__);
385 }
386
387 // Save for reconnection when some legacy hal's don't resend this info
388 sYearOfHwCached = info->year_of_hw;
389 }
390
391
392 // Methods from ::android::hardware::gnss::V1_0::IGnss follow.
setCallback(const sp<IGnssCallback> & callback)393 Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback) {
394 if (mGnssIface == nullptr) {
395 ALOGE("%s: Gnss interface is unavailable", __func__);
396 return false;
397 }
398
399 if (callback == nullptr) {
400 ALOGE("%s: Null callback ignored", __func__);
401 return false;
402 }
403
404 if (sGnssCbIface != NULL) {
405 ALOGW("%s called more than once. Unexpected unless test.", __func__);
406 sGnssCbIface->unlinkToDeath(mDeathRecipient);
407 }
408
409 sGnssCbIface = callback;
410 callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
411
412 // If this was received in the past, send it up again to refresh caller.
413 // mGnssIface will override after init() is called below, if needed
414 // (though it's unlikely the gps.h capabilities or system info will change.)
415 if (sCapabilitiesCached != 0) {
416 setCapabilitiesCb(sCapabilitiesCached);
417 }
418 if (sYearOfHwCached != 0) {
419 LegacyGnssSystemInfo info;
420 info.year_of_hw = sYearOfHwCached;
421 setSystemInfoCb(&info);
422 }
423
424 return (mGnssIface->init(&sGnssCb) == 0);
425 }
426
start()427 Return<bool> Gnss::start() {
428 if (mGnssIface == nullptr) {
429 ALOGE("%s: Gnss interface is unavailable", __func__);
430 return false;
431 }
432
433 return (mGnssIface->start() == 0);
434 }
435
stop()436 Return<bool> Gnss::stop() {
437 if (mGnssIface == nullptr) {
438 ALOGE("%s: Gnss interface is unavailable", __func__);
439 return false;
440 }
441
442 return (mGnssIface->stop() == 0);
443 }
444
cleanup()445 Return<void> Gnss::cleanup() {
446 if (mGnssIface == nullptr) {
447 ALOGE("%s: Gnss interface is unavailable", __func__);
448 } else {
449 mGnssIface->cleanup();
450 }
451 return Void();
452 }
453
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)454 Return<bool> Gnss::injectLocation(double latitudeDegrees,
455 double longitudeDegrees,
456 float accuracyMeters) {
457 if (mGnssIface == nullptr) {
458 ALOGE("%s: Gnss interface is unavailable", __func__);
459 return false;
460 }
461
462 return (mGnssIface->inject_location(latitudeDegrees, longitudeDegrees, accuracyMeters) == 0);
463 }
464
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)465 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
466 int32_t uncertaintyMs) {
467 if (mGnssIface == nullptr) {
468 ALOGE("%s: Gnss interface is unavailable", __func__);
469 return false;
470 }
471
472 return (mGnssIface->inject_time(timeMs, timeReferenceMs, uncertaintyMs) == 0);
473 }
474
deleteAidingData(IGnss::GnssAidingData aidingDataFlags)475 Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) {
476 if (mGnssIface == nullptr) {
477 ALOGE("%s: Gnss interface is unavailable", __func__);
478 } else {
479 mGnssIface->delete_aiding_data(static_cast<GpsAidingData>(aidingDataFlags));
480 }
481 return Void();
482 }
483
setPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)484 Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
485 IGnss::GnssPositionRecurrence recurrence,
486 uint32_t minIntervalMs,
487 uint32_t preferredAccuracyMeters,
488 uint32_t preferredTimeMs) {
489 if (mGnssIface == nullptr) {
490 ALOGE("%s: Gnss interface is unavailable", __func__);
491 return false;
492 }
493
494 return (mGnssIface->set_position_mode(static_cast<GpsPositionMode>(mode),
495 static_cast<GpsPositionRecurrence>(recurrence),
496 minIntervalMs,
497 preferredAccuracyMeters,
498 preferredTimeMs) == 0);
499 }
500
getExtensionAGnssRil()501 Return<sp<IAGnssRil>> Gnss::getExtensionAGnssRil() {
502 if (mGnssIface == nullptr) {
503 ALOGE("%s: Gnss interface is unavailable", __func__);
504 return nullptr;
505 }
506
507 if (mGnssRil == nullptr) {
508 const AGpsRilInterface* agpsRilIface = static_cast<const AGpsRilInterface*>(
509 mGnssIface->get_extension(AGPS_RIL_INTERFACE));
510 if (agpsRilIface == nullptr) {
511 ALOGI("%s: GnssRil interface not implemented by HAL", __func__);
512 } else {
513 mGnssRil = new AGnssRil(agpsRilIface);
514 }
515 }
516 return mGnssRil;
517 }
518
getExtensionGnssConfiguration()519 Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
520 if (mGnssIface == nullptr) {
521 ALOGE("%s: Gnss interface is unavailable", __func__);
522 return nullptr;
523 }
524
525 if (mGnssConfig == nullptr) {
526 const GnssConfigurationInterface* gnssConfigIface =
527 static_cast<const GnssConfigurationInterface*>(
528 mGnssIface->get_extension(GNSS_CONFIGURATION_INTERFACE));
529
530 if (gnssConfigIface == nullptr) {
531 ALOGE("%s: GnssConfiguration interface not implemented by HAL", __func__);
532 } else {
533 mGnssConfig = new GnssConfiguration(gnssConfigIface);
534 }
535 }
536 return mGnssConfig;
537 }
538
getExtensionGnssGeofencing()539 Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
540 if (mGnssIface == nullptr) {
541 ALOGE("%s: Gnss interface is unavailable", __func__);
542 return nullptr;
543 }
544
545 if (mGnssGeofencingIface == nullptr) {
546 const GpsGeofencingInterface* gpsGeofencingIface =
547 static_cast<const GpsGeofencingInterface*>(
548 mGnssIface->get_extension(GPS_GEOFENCING_INTERFACE));
549
550 if (gpsGeofencingIface == nullptr) {
551 ALOGE("%s: GnssGeofencing interface not implemented by HAL", __func__);
552 } else {
553 mGnssGeofencingIface = new GnssGeofencing(gpsGeofencingIface);
554 }
555 }
556
557 return mGnssGeofencingIface;
558 }
559
getExtensionAGnss()560 Return<sp<IAGnss>> Gnss::getExtensionAGnss() {
561 if (mGnssIface == nullptr) {
562 ALOGE("%s: Gnss interface is unavailable", __func__);
563 return nullptr;
564 }
565
566 if (mAGnssIface == nullptr) {
567 const AGpsInterface* agpsIface = static_cast<const AGpsInterface*>(
568 mGnssIface->get_extension(AGPS_INTERFACE));
569 if (agpsIface == nullptr) {
570 ALOGE("%s: AGnss interface not implemented by HAL", __func__);
571 } else {
572 mAGnssIface = new AGnss(agpsIface);
573 }
574 }
575 return mAGnssIface;
576 }
577
getExtensionGnssNi()578 Return<sp<IGnssNi>> Gnss::getExtensionGnssNi() {
579 if (mGnssIface == nullptr) {
580 ALOGE("%s: Gnss interface is unavailable", __func__);
581 return nullptr;
582 }
583
584 if (mGnssNi == nullptr) {
585 const GpsNiInterface* gpsNiIface = static_cast<const GpsNiInterface*>(
586 mGnssIface->get_extension(GPS_NI_INTERFACE));
587 if (gpsNiIface == nullptr) {
588 ALOGI("%s: GnssNi interface not implemented by HAL", __func__);
589 } else {
590 mGnssNi = new GnssNi(gpsNiIface);
591 }
592 }
593 return mGnssNi;
594 }
595
getExtensionGnssMeasurement()596 Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
597 if (mGnssIface == nullptr) {
598 ALOGE("%s: Gnss interface is unavailable", __func__);
599 return nullptr;
600 }
601
602 if (mGnssMeasurement == nullptr) {
603 const GpsMeasurementInterface* gpsMeasurementIface =
604 static_cast<const GpsMeasurementInterface*>(
605 mGnssIface->get_extension(GPS_MEASUREMENT_INTERFACE));
606
607 if (gpsMeasurementIface == nullptr) {
608 ALOGE("%s: GnssMeasurement interface not implemented by HAL", __func__);
609 } else {
610 mGnssMeasurement = new GnssMeasurement(gpsMeasurementIface);
611 }
612 }
613 return mGnssMeasurement;
614 }
615
getExtensionGnssNavigationMessage()616 Return<sp<IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
617 if (mGnssIface == nullptr) {
618 ALOGE("%s: Gnss interface is unavailable", __func__);
619 return nullptr;
620 }
621
622 if (mGnssNavigationMessage == nullptr) {
623 const GpsNavigationMessageInterface* gpsNavigationMessageIface =
624 static_cast<const GpsNavigationMessageInterface*>(
625 mGnssIface->get_extension(GPS_NAVIGATION_MESSAGE_INTERFACE));
626
627 if (gpsNavigationMessageIface == nullptr) {
628 ALOGI("%s: GnssNavigationMessage interface not implemented by HAL", __func__);
629 } else {
630 mGnssNavigationMessage = new GnssNavigationMessage(gpsNavigationMessageIface);
631 }
632 }
633
634 return mGnssNavigationMessage;
635 }
636
getExtensionXtra()637 Return<sp<IGnssXtra>> Gnss::getExtensionXtra() {
638 if (mGnssIface == nullptr) {
639 ALOGE("%s: Gnss interface is unavailable", __func__);
640 return nullptr;
641 }
642
643 if (mGnssXtraIface == nullptr) {
644 const GpsXtraInterface* gpsXtraIface = static_cast<const GpsXtraInterface*>(
645 mGnssIface->get_extension(GPS_XTRA_INTERFACE));
646
647 if (gpsXtraIface == nullptr) {
648 ALOGI("%s: GnssXtra interface not implemented by HAL", __func__);
649 } else {
650 mGnssXtraIface = new GnssXtra(gpsXtraIface);
651 }
652 }
653
654 return mGnssXtraIface;
655 }
656
getExtensionGnssDebug()657 Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() {
658 if (mGnssIface == nullptr) {
659 ALOGE("%s: Gnss interface is unavailable", __func__);
660 return nullptr;
661 }
662
663 if (mGnssDebug == nullptr) {
664 const GpsDebugInterface* gpsDebugIface = static_cast<const GpsDebugInterface*>(
665 mGnssIface->get_extension(GPS_DEBUG_INTERFACE));
666
667 if (gpsDebugIface == nullptr) {
668 ALOGI("%s: GnssDebug interface not implemented by HAL", __func__);
669 } else {
670 mGnssDebug = new GnssDebug(gpsDebugIface);
671 }
672 }
673
674 return mGnssDebug;
675 }
676
getExtensionGnssBatching()677 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching() {
678 if (mGnssIface == nullptr) {
679 ALOGE("%s: Gnss interface is unavailable", __func__);
680 return nullptr;
681 }
682
683 if (mGnssBatching == nullptr) {
684 hw_module_t* module;
685 const FlpLocationInterface* flpLocationIface = nullptr;
686 int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
687
688 if (err != 0) {
689 ALOGE("gnss flp hw_get_module failed: %d", err);
690 } else if (module == nullptr) {
691 ALOGE("Fused Location hw_get_module returned null module");
692 } else if (module->methods == nullptr) {
693 ALOGE("Fused Location hw_get_module returned null methods");
694 } else {
695 hw_device_t* device;
696 err = module->methods->open(module, FUSED_LOCATION_HARDWARE_MODULE_ID, &device);
697 if (err != 0) {
698 ALOGE("flpDevice open failed: %d", err);
699 } else {
700 flp_device_t * flpDevice = reinterpret_cast<flp_device_t*>(device);
701 flpLocationIface = flpDevice->get_flp_interface(flpDevice);
702 }
703 }
704
705 if (flpLocationIface == nullptr) {
706 ALOGE("%s: GnssBatching interface is not implemented by HAL", __func__);
707 } else {
708 mGnssBatching = new GnssBatching(flpLocationIface);
709 }
710 }
711 return mGnssBatching;
712 }
713
handleHidlDeath()714 void Gnss::handleHidlDeath() {
715 ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
716
717 // commands down to the HAL implementation
718 stop(); // stop ongoing GPS tracking
719 if (mGnssMeasurement != nullptr) {
720 mGnssMeasurement->close();
721 }
722 if (mGnssNavigationMessage != nullptr) {
723 mGnssNavigationMessage->close();
724 }
725 if (mGnssBatching != nullptr) {
726 mGnssBatching->stop();
727 mGnssBatching->cleanup();
728 }
729 cleanup();
730
731 /*
732 * This has died, so close it off in case (race condition) callbacks happen
733 * before HAL processes above messages.
734 */
735 sGnssCbIface = nullptr;
736 }
737
HIDL_FETCH_IGnss(const char *)738 IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
739 hw_module_t* module;
740 IGnss* iface = nullptr;
741 int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
742
743 if (err == 0) {
744 hw_device_t* device;
745 err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
746 if (err == 0) {
747 iface = new Gnss(reinterpret_cast<gps_device_t*>(device));
748 } else {
749 ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
750 }
751 } else {
752 ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
753 }
754 return iface;
755 }
756
757 } // namespace implementation
758 } // namespace V1_0
759 } // namespace gnss
760 } // namespace hardware
761 } // namespace android
762