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