Home | History | Annotate | Download | only in default
      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 
     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 
     66 Gnss::~Gnss() {
     67     sInterfaceExists = false;
     68     sThreadFuncArgsList.clear();
     69 }
     70 
     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 
     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 
    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 %zd. 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  */
    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 %zd. 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 
    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 
    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 
    286 void Gnss::acquireWakelockCb() {
    287     acquireWakelockGnss();
    288 }
    289 
    290 void Gnss::releaseWakelockCb() {
    291     releaseWakelockGnss();
    292 }
    293 
    294 
    295 void Gnss::acquireWakelockGnss() {
    296     sWakelockHeldGnss = true;
    297     updateWakelock();
    298 }
    299 
    300 void Gnss::releaseWakelockGnss() {
    301     sWakelockHeldGnss = false;
    302     updateWakelock();
    303 }
    304 
    305 void Gnss::acquireWakelockFused() {
    306     sWakelockHeldFused = true;
    307     updateWakelock();
    308 }
    309 
    310 void Gnss::releaseWakelockFused() {
    311     sWakelockHeldFused = false;
    312     updateWakelock();
    313 }
    314 
    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 
    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 
    363 pthread_t Gnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
    364     return createPthread(name, start, arg, &sThreadFuncArgsList);
    365 }
    366 
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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             ALOGE("%s GnssRil interface not implemented by GNSS HAL", __func__);
    512         } else {
    513             mGnssRil = new AGnssRil(agpsRilIface);
    514         }
    515     }
    516     return mGnssRil;
    517 }
    518 
    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 GNSS HAL", __func__);
    532         } else {
    533             mGnssConfig = new GnssConfiguration(gnssConfigIface);
    534         }
    535     }
    536     return mGnssConfig;
    537 }
    538 
    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 GNSS HAL", __func__);
    552         } else {
    553             mGnssGeofencingIface = new GnssGeofencing(gpsGeofencingIface);
    554         }
    555     }
    556 
    557     return mGnssGeofencingIface;
    558 }
    559 
    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 GNSS HAL", __func__);
    571         } else {
    572             mAGnssIface = new AGnss(agpsIface);
    573         }
    574     }
    575     return mAGnssIface;
    576 }
    577 
    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             ALOGE("%s GnssNi interface not implemented by GNSS HAL", __func__);
    589         } else {
    590             mGnssNi = new GnssNi(gpsNiIface);
    591         }
    592     }
    593     return mGnssNi;
    594 }
    595 
    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 GNSS HAL", __func__);
    609         } else {
    610             mGnssMeasurement = new GnssMeasurement(gpsMeasurementIface);
    611         }
    612     }
    613     return mGnssMeasurement;
    614 }
    615 
    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             ALOGE("%s GnssNavigationMessage interface not implemented by GNSS HAL",
    629                   __func__);
    630         } else {
    631             mGnssNavigationMessage = new GnssNavigationMessage(gpsNavigationMessageIface);
    632         }
    633     }
    634 
    635     return mGnssNavigationMessage;
    636 }
    637 
    638 Return<sp<IGnssXtra>> Gnss::getExtensionXtra()  {
    639     if (mGnssIface == nullptr) {
    640         ALOGE("%s: Gnss interface is unavailable", __func__);
    641         return nullptr;
    642     }
    643 
    644     if (mGnssXtraIface == nullptr) {
    645         const GpsXtraInterface* gpsXtraIface = static_cast<const GpsXtraInterface*>(
    646                 mGnssIface->get_extension(GPS_XTRA_INTERFACE));
    647 
    648         if (gpsXtraIface == nullptr) {
    649             ALOGE("%s GnssXtra interface not implemented by HAL", __func__);
    650         } else {
    651             mGnssXtraIface = new GnssXtra(gpsXtraIface);
    652         }
    653     }
    654 
    655     return mGnssXtraIface;
    656 }
    657 
    658 Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug()  {
    659     if (mGnssIface == nullptr) {
    660         ALOGE("%s: Gnss interface is unavailable", __func__);
    661         return nullptr;
    662     }
    663 
    664     if (mGnssDebug == nullptr) {
    665         const GpsDebugInterface* gpsDebugIface = static_cast<const GpsDebugInterface*>(
    666                 mGnssIface->get_extension(GPS_DEBUG_INTERFACE));
    667 
    668         if (gpsDebugIface == nullptr) {
    669             ALOGE("%s: GnssDebug interface is not implemented by HAL", __func__);
    670         } else {
    671             mGnssDebug = new GnssDebug(gpsDebugIface);
    672         }
    673     }
    674 
    675     return mGnssDebug;
    676 }
    677 
    678 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching()  {
    679     if (mGnssIface == nullptr) {
    680         ALOGE("%s: Gnss interface is unavailable", __func__);
    681         return nullptr;
    682     }
    683 
    684     if (mGnssBatching == nullptr) {
    685         hw_module_t* module;
    686         const FlpLocationInterface* flpLocationIface = nullptr;
    687         int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    688 
    689         if (err != 0) {
    690             ALOGE("gnss flp hw_get_module failed: %d", err);
    691         } else if (module == nullptr) {
    692             ALOGE("Fused Location hw_get_module returned null module");
    693         } else if (module->methods == nullptr) {
    694             ALOGE("Fused Location hw_get_module returned null methods");
    695         } else {
    696             hw_device_t* device;
    697             err = module->methods->open(module, FUSED_LOCATION_HARDWARE_MODULE_ID, &device);
    698             if (err != 0) {
    699                 ALOGE("flpDevice open failed: %d", err);
    700             } else {
    701                 flp_device_t * flpDevice = reinterpret_cast<flp_device_t*>(device);
    702                 flpLocationIface = flpDevice->get_flp_interface(flpDevice);
    703             }
    704         }
    705 
    706         if (flpLocationIface == nullptr) {
    707             ALOGE("%s: GnssBatching interface is not implemented by HAL", __func__);
    708         } else {
    709             mGnssBatching = new GnssBatching(flpLocationIface);
    710         }
    711     }
    712     return mGnssBatching;
    713 }
    714 
    715 void Gnss::handleHidlDeath() {
    716     ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
    717 
    718     // commands down to the HAL implementation
    719     stop(); // stop ongoing GPS tracking
    720     if (mGnssMeasurement != nullptr) {
    721         mGnssMeasurement->close();
    722     }
    723     if (mGnssNavigationMessage != nullptr) {
    724         mGnssNavigationMessage->close();
    725     }
    726     if (mGnssBatching != nullptr) {
    727         mGnssBatching->stop();
    728         mGnssBatching->cleanup();
    729     }
    730     cleanup();
    731 
    732     /*
    733      * This has died, so close it off in case (race condition) callbacks happen
    734      * before HAL processes above messages.
    735      */
    736     sGnssCbIface = nullptr;
    737 }
    738 
    739 IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
    740     hw_module_t* module;
    741     IGnss* iface = nullptr;
    742     int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    743 
    744     if (err == 0) {
    745         hw_device_t* device;
    746         err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
    747         if (err == 0) {
    748             iface = new Gnss(reinterpret_cast<gps_device_t*>(device));
    749         } else {
    750             ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
    751         }
    752     } else {
    753       ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
    754     }
    755     return iface;
    756 }
    757 
    758 }  // namespace implementation
    759 }  // namespace V1_0
    760 }  // namespace gnss
    761 }  // namespace hardware
    762 }  // namespace android
    763