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<android::hardware::gnss::V1_0::GnssConstellationType>(
133                         svInfo.constellation),
134                 .cN0Dbhz = svInfo.c_n0_dbhz,
135                 .elevationDegrees = svInfo.elevation,
136                 .azimuthDegrees = svInfo.azimuth,
137                 .carrierFrequencyHz = 0,
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 &=
143                         ~(static_cast<uint8_t>(IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY))),
144         };
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