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