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