1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation, nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_NDEBUG 0 31 #define LOG_TAG "LocSvc_GnssAPIClient" 32 33 #include <log_util.h> 34 #include <loc_cfg.h> 35 36 #include "LocationUtil.h" 37 #include "GnssAPIClient.h" 38 #include <LocDualContext.h> 39 40 namespace android { 41 namespace hardware { 42 namespace gnss { 43 namespace V1_0 { 44 namespace implementation { 45 46 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out); 47 48 GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb, 49 const sp<IGnssNiCallback>& niCb) : 50 LocationAPIClientBase(), 51 mGnssCbIface(nullptr), 52 mGnssNiCbIface(nullptr), 53 mControlClient(new LocationAPIControlClient()), 54 mLocationCapabilitiesMask(0), 55 mLocationCapabilitiesCached(false) 56 { 57 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); 58 59 // set default LocationOptions. 60 memset(&mLocationOptions, 0, sizeof(LocationOptions)); 61 mLocationOptions.size = sizeof(LocationOptions); 62 mLocationOptions.minInterval = 1000; 63 mLocationOptions.minDistance = 0; 64 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; 65 66 gnssUpdateCallbacks(gpsCb, niCb); 67 } 68 69 GnssAPIClient::~GnssAPIClient() 70 { 71 LOC_LOGD("%s]: ()", __FUNCTION__); 72 if (mControlClient) { 73 delete mControlClient; 74 mControlClient = nullptr; 75 } 76 } 77 78 // for GpsInterface 79 void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb, 80 const sp<IGnssNiCallback>& niCb) 81 { 82 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); 83 84 mMutex.lock(); 85 mGnssCbIface = gpsCb; 86 mGnssNiCbIface = niCb; 87 mMutex.unlock(); 88 89 LocationCallbacks locationCallbacks; 90 memset(&locationCallbacks, 0, sizeof(LocationCallbacks)); 91 locationCallbacks.size = sizeof(LocationCallbacks); 92 93 locationCallbacks.trackingCb = nullptr; 94 if (mGnssCbIface != nullptr) { 95 locationCallbacks.trackingCb = [this](Location location) { 96 onTrackingCb(location); 97 }; 98 } 99 100 locationCallbacks.batchingCb = nullptr; 101 locationCallbacks.geofenceBreachCb = nullptr; 102 locationCallbacks.geofenceStatusCb = nullptr; 103 locationCallbacks.gnssLocationInfoCb = nullptr; 104 105 locationCallbacks.gnssNiCb = nullptr; 106 loc_core::ContextBase* context = 107 loc_core::LocDualContext::getLocFgContext( 108 NULL, NULL, 109 loc_core::LocDualContext::mLocationHalName, false); 110 if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) { 111 LOC_LOGD("Registering NI CB"); 112 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) { 113 onGnssNiCb(id, gnssNiNotification); 114 }; 115 } 116 117 locationCallbacks.gnssSvCb = nullptr; 118 if (mGnssCbIface != nullptr) { 119 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) { 120 onGnssSvCb(gnssSvNotification); 121 }; 122 } 123 124 locationCallbacks.gnssNmeaCb = nullptr; 125 if (mGnssCbIface != nullptr) { 126 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) { 127 onGnssNmeaCb(gnssNmeaNotification); 128 }; 129 } 130 131 locationCallbacks.gnssMeasurementsCb = nullptr; 132 133 locAPISetCallbacks(locationCallbacks); 134 } 135 136 bool GnssAPIClient::gnssStart() 137 { 138 LOC_LOGD("%s]: ()", __FUNCTION__); 139 bool retVal = true; 140 locAPIStartTracking(mLocationOptions); 141 return retVal; 142 } 143 144 bool GnssAPIClient::gnssStop() 145 { 146 LOC_LOGD("%s]: ()", __FUNCTION__); 147 bool retVal = true; 148 locAPIStopTracking(); 149 return retVal; 150 } 151 152 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, 153 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, 154 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs) 155 { 156 LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__, 157 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs); 158 bool retVal = true; 159 memset(&mLocationOptions, 0, sizeof(LocationOptions)); 160 mLocationOptions.size = sizeof(LocationOptions); 161 mLocationOptions.minInterval = minIntervalMs; 162 mLocationOptions.minDistance = preferredAccuracyMeters; 163 if (mode == IGnss::GnssPositionMode::STANDALONE) 164 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; 165 else if (mode == IGnss::GnssPositionMode::MS_BASED) 166 mLocationOptions.mode = GNSS_SUPL_MODE_MSB; 167 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED) 168 mLocationOptions.mode = GNSS_SUPL_MODE_MSA; 169 else { 170 LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode); 171 retVal = false; 172 } 173 locAPIUpdateTrackingOptions(mLocationOptions); 174 return retVal; 175 } 176 177 // for GpsNiInterface 178 void GnssAPIClient::gnssNiRespond(int32_t notifId, 179 IGnssNiCallback::GnssUserResponseType userResponse) 180 { 181 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse)); 182 GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE; 183 if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT) 184 data = GNSS_NI_RESPONSE_ACCEPT; 185 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY) 186 data = GNSS_NI_RESPONSE_DENY; 187 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP) 188 data = GNSS_NI_RESPONSE_NO_RESPONSE; 189 else { 190 LOC_LOGD("%s]: invalid GnssUserResponseType: %d", __FUNCTION__, (int)userResponse); 191 return; 192 } 193 locAPIGnssNiResponse(notifId, data); 194 } 195 196 // these apis using LocationAPIControlClient 197 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags) 198 { 199 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags); 200 if (mControlClient == nullptr) { 201 return; 202 } 203 GnssAidingData data; 204 memset(&data, 0, sizeof (GnssAidingData)); 205 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT | 206 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT | 207 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT | 208 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT | 209 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT; 210 211 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL) 212 data.deleteAll = true; 213 else { 214 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS) 215 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT; 216 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC) 217 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT; 218 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION) 219 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT; 220 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME) 221 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT; 222 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO) 223 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT; 224 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC) 225 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT; 226 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH) 227 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT; 228 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR) 229 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT; 230 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER) 231 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT; 232 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA) 233 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT; 234 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI) 235 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT; 236 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO) 237 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT; 238 } 239 mControlClient->locAPIGnssDeleteAidingData(data); 240 } 241 242 void GnssAPIClient::gnssEnable(LocationTechnologyType techType) 243 { 244 LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType); 245 if (mControlClient == nullptr) { 246 return; 247 } 248 mControlClient->locAPIEnable(techType); 249 } 250 251 void GnssAPIClient::gnssDisable() 252 { 253 LOC_LOGD("%s]: ()", __FUNCTION__); 254 if (mControlClient == nullptr) { 255 return; 256 } 257 mControlClient->locAPIDisable(); 258 } 259 260 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig) 261 { 262 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags); 263 if (mControlClient == nullptr) { 264 return; 265 } 266 mControlClient->locAPIGnssUpdateConfig(gnssConfig); 267 } 268 269 void GnssAPIClient::requestCapabilities() { 270 // only send capablities if it's already cached, otherwise the first time LocationAPI 271 // is initialized, capabilities will be sent by LocationAPI 272 if (mLocationCapabilitiesCached) { 273 onCapabilitiesCb(mLocationCapabilitiesMask); 274 } 275 } 276 277 // callbacks 278 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) 279 { 280 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); 281 mLocationCapabilitiesMask = capabilitiesMask; 282 mLocationCapabilitiesCached = true; 283 284 mMutex.lock(); 285 auto gnssCbIface(mGnssCbIface); 286 mMutex.unlock(); 287 288 if (gnssCbIface != nullptr) { 289 uint32_t data = 0; 290 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || 291 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || 292 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) || 293 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT)) 294 data |= IGnssCallback::Capabilities::SCHEDULING; 295 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT) 296 data |= IGnssCallback::Capabilities::GEOFENCING; 297 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) 298 data |= IGnssCallback::Capabilities::MEASUREMENTS; 299 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) 300 data |= IGnssCallback::Capabilities::MSB; 301 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) 302 data |= IGnssCallback::Capabilities::MSA; 303 auto r = gnssCbIface->gnssSetCapabilitesCb(data); 304 if (!r.isOk()) { 305 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s", 306 __func__, r.description().c_str()); 307 } 308 } 309 if (gnssCbIface != nullptr) { 310 IGnssCallback::GnssSystemInfo gnssInfo; 311 if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) { 312 gnssInfo.yearOfHw = 2017; 313 } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) { 314 gnssInfo.yearOfHw = 2016; 315 } else { 316 gnssInfo.yearOfHw = 2015; 317 } 318 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw); 319 auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo); 320 if (!r.isOk()) { 321 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s", 322 __func__, r.description().c_str()); 323 } 324 } 325 } 326 327 void GnssAPIClient::onTrackingCb(Location location) 328 { 329 LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags); 330 mMutex.lock(); 331 auto gnssCbIface(mGnssCbIface); 332 mMutex.unlock(); 333 334 if (gnssCbIface != nullptr) { 335 GnssLocation gnssLocation; 336 convertGnssLocation(location, gnssLocation); 337 auto r = gnssCbIface->gnssLocationCb(gnssLocation); 338 if (!r.isOk()) { 339 LOC_LOGE("%s] Error from gnssLocationCb description=%s", 340 __func__, r.description().c_str()); 341 } 342 } 343 } 344 345 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) 346 { 347 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id); 348 mMutex.lock(); 349 auto gnssNiCbIface(mGnssNiCbIface); 350 mMutex.unlock(); 351 352 if (gnssNiCbIface == nullptr) { 353 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__); 354 return; 355 } 356 357 IGnssNiCallback::GnssNiNotification notificationGnss = {}; 358 359 notificationGnss.notificationId = id; 360 361 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE) 362 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE; 363 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL) 364 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL; 365 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE) 366 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE; 367 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL) 368 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL; 369 370 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT) 371 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY; 372 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT) 373 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY; 374 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT) 375 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE; 376 377 notificationGnss.timeoutSec = gnssNiNotification.timeout; 378 379 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT) 380 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT; 381 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY) 382 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY; 383 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE || 384 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE) 385 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP; 386 387 notificationGnss.requestorId = gnssNiNotification.requestor; 388 389 notificationGnss.notificationMessage = gnssNiNotification.message; 390 391 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE) 392 notificationGnss.requestorIdEncoding = 393 IGnssNiCallback::GnssNiEncodingType::ENC_NONE; 394 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) 395 notificationGnss.requestorIdEncoding = 396 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; 397 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8) 398 notificationGnss.requestorIdEncoding = 399 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; 400 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2) 401 notificationGnss.requestorIdEncoding = 402 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; 403 404 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE) 405 notificationGnss.notificationIdEncoding = 406 IGnssNiCallback::GnssNiEncodingType::ENC_NONE; 407 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) 408 notificationGnss.notificationIdEncoding = 409 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; 410 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8) 411 notificationGnss.notificationIdEncoding = 412 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; 413 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2) 414 notificationGnss.notificationIdEncoding = 415 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; 416 417 gnssNiCbIface->niNotifyCb(notificationGnss); 418 } 419 420 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) 421 { 422 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count); 423 mMutex.lock(); 424 auto gnssCbIface(mGnssCbIface); 425 mMutex.unlock(); 426 427 if (gnssCbIface != nullptr) { 428 IGnssCallback::GnssSvStatus svStatus; 429 convertGnssSvStatus(gnssSvNotification, svStatus); 430 auto r = gnssCbIface->gnssSvStatusCb(svStatus); 431 if (!r.isOk()) { 432 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s", 433 __func__, r.description().c_str()); 434 } 435 } 436 } 437 438 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) 439 { 440 mMutex.lock(); 441 auto gnssCbIface(mGnssCbIface); 442 mMutex.unlock(); 443 444 if (gnssCbIface != nullptr) { 445 android::hardware::hidl_string nmeaString; 446 nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length); 447 auto r = gnssCbIface->gnssNmeaCb( 448 static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString); 449 if (!r.isOk()) { 450 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__, 451 gnssNmeaNotification.nmea, gnssNmeaNotification.length, r.description().c_str()); 452 } 453 } 454 } 455 456 void GnssAPIClient::onStartTrackingCb(LocationError error) 457 { 458 LOC_LOGD("%s]: (%d)", __FUNCTION__, error); 459 mMutex.lock(); 460 auto gnssCbIface(mGnssCbIface); 461 mMutex.unlock(); 462 463 if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) { 464 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); 465 if (!r.isOk()) { 466 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s", 467 __func__, r.description().c_str()); 468 } 469 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); 470 if (!r.isOk()) { 471 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s", 472 __func__, r.description().c_str()); 473 } 474 } 475 } 476 477 void GnssAPIClient::onStopTrackingCb(LocationError error) 478 { 479 LOC_LOGD("%s]: (%d)", __FUNCTION__, error); 480 mMutex.lock(); 481 auto gnssCbIface(mGnssCbIface); 482 mMutex.unlock(); 483 484 if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) { 485 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); 486 if (!r.isOk()) { 487 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s", 488 __func__, r.description().c_str()); 489 } 490 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); 491 if (!r.isOk()) { 492 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s", 493 __func__, r.description().c_str()); 494 } 495 } 496 } 497 498 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out) 499 { 500 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus)); 501 out.numSvs = in.count; 502 if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) { 503 LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.", 504 __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT); 505 out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT); 506 } 507 for (size_t i = 0; i < out.numSvs; i++) { 508 IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; 509 info.svid = in.gnssSvs[i].svId; 510 convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); 511 info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; 512 info.elevationDegrees = in.gnssSvs[i].elevation; 513 info.azimuthDegrees = in.gnssSvs[i].azimuth; 514 info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE); 515 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) 516 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA; 517 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) 518 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA; 519 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) 520 info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX; 521 } 522 } 523 524 } // namespace implementation 525 } // namespace V1_0 526 } // namespace gnss 527 } // namespace hardware 528 } // namespace android 529