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 39namespace android { 40namespace hardware { 41namespace gnss { 42namespace V1_0 { 43namespace implementation { 44 45static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out); 46 47GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb, 48 const sp<IGnssNiCallback>& niCb) : 49 LocationAPIClientBase(), 50 mGnssCbIface(nullptr), 51 mGnssNiCbIface(nullptr), 52 mLocationCapabilitiesMask(0), 53 mLocationCapabilitiesCached(false) 54{ 55 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); 56 57 // set default LocationOptions. 58 memset(&mLocationOptions, 0, sizeof(LocationOptions)); 59 mLocationOptions.size = sizeof(LocationOptions); 60 mLocationOptions.minInterval = 1000; 61 mLocationOptions.minDistance = 0; 62 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; 63 64 gnssUpdateCallbacks(gpsCb, niCb); 65} 66 67GnssAPIClient::~GnssAPIClient() 68{ 69 LOC_LOGD("%s]: ()", __FUNCTION__); 70} 71 72// for GpsInterface 73void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb, 74 const sp<IGnssNiCallback>& niCb) 75{ 76 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); 77 78 mGnssCbIface = gpsCb; 79 mGnssNiCbIface = niCb; 80 81 LocationCallbacks locationCallbacks; 82 locationCallbacks.size = sizeof(LocationCallbacks); 83 84 locationCallbacks.trackingCb = nullptr; 85 if (mGnssCbIface != nullptr) { 86 locationCallbacks.trackingCb = [this](Location location) { 87 onTrackingCb(location); 88 }; 89 } 90 91 locationCallbacks.batchingCb = nullptr; 92 locationCallbacks.geofenceBreachCb = nullptr; 93 locationCallbacks.geofenceStatusCb = nullptr; 94 locationCallbacks.gnssLocationInfoCb = nullptr; 95 96 locationCallbacks.gnssNiCb = nullptr; 97 if (mGnssNiCbIface != nullptr) { 98 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) { 99 onGnssNiCb(id, gnssNiNotification); 100 }; 101 } 102 103 locationCallbacks.gnssSvCb = nullptr; 104 if (mGnssCbIface != nullptr) { 105 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) { 106 onGnssSvCb(gnssSvNotification); 107 }; 108 } 109 110 locationCallbacks.gnssNmeaCb = nullptr; 111 if (mGnssCbIface != nullptr) { 112 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) { 113 onGnssNmeaCb(gnssNmeaNotification); 114 }; 115 } 116 117 locationCallbacks.gnssMeasurementsCb = nullptr; 118 119 locAPISetCallbacks(locationCallbacks); 120} 121 122bool GnssAPIClient::gnssStart() 123{ 124 LOC_LOGD("%s]: ()", __FUNCTION__); 125 bool retVal = true; 126 locAPIStartTracking(mLocationOptions); 127 return retVal; 128} 129 130bool GnssAPIClient::gnssStop() 131{ 132 LOC_LOGD("%s]: ()", __FUNCTION__); 133 bool retVal = true; 134 locAPIStopTracking(); 135 return retVal; 136} 137 138void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags) 139{ 140 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags); 141 GnssAidingData data; 142 memset(&data, 0, sizeof (GnssAidingData)); 143 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT | 144 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT | 145 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT | 146 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT | 147 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT; 148 149 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL) 150 data.deleteAll = true; 151 else { 152 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS) 153 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT; 154 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC) 155 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT; 156 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION) 157 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT; 158 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME) 159 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT; 160 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO) 161 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT; 162 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC) 163 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT; 164 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH) 165 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT; 166 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR) 167 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT; 168 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER) 169 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT; 170 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA) 171 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT; 172 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI) 173 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT; 174 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO) 175 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT; 176 } 177 locAPIGnssDeleteAidingData(data); 178} 179 180bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, 181 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, 182 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs) 183{ 184 LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__, 185 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs); 186 bool retVal = true; 187 memset(&mLocationOptions, 0, sizeof(LocationOptions)); 188 mLocationOptions.size = sizeof(LocationOptions); 189 mLocationOptions.minInterval = minIntervalMs; 190 mLocationOptions.minDistance = preferredAccuracyMeters; 191 if (mode == IGnss::GnssPositionMode::STANDALONE) 192 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; 193 else if (mode == IGnss::GnssPositionMode::MS_BASED) 194 mLocationOptions.mode = GNSS_SUPL_MODE_MSB; 195 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED) 196 mLocationOptions.mode = GNSS_SUPL_MODE_MSA; 197 locAPIUpdateTrackingOptions(mLocationOptions); 198 return retVal; 199} 200 201// for GpsNiInterface 202void GnssAPIClient::gnssNiRespond(int32_t notifId, 203 IGnssNiCallback::GnssUserResponseType userResponse) 204{ 205 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse)); 206 GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE; 207 if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT) 208 data = GNSS_NI_RESPONSE_ACCEPT; 209 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY) 210 data = GNSS_NI_RESPONSE_DENY; 211 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP) 212 data = GNSS_NI_RESPONSE_NO_RESPONSE; 213 locAPIGnssNiResponse(notifId, data); 214} 215 216// for GnssConfigurationInterface 217void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig) 218{ 219 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags); 220 locAPIGnssUpdateConfig(gnssConfig); 221} 222 223void GnssAPIClient::requestCapabilities() { 224 // only send capablities if it's already cached, otherwise the first time LocationAPI 225 // is initialized, capabilities will be sent by LocationAPI 226 if (mLocationCapabilitiesCached) { 227 onCapabilitiesCb(mLocationCapabilitiesMask); 228 } 229} 230 231// callbacks 232void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) 233{ 234 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); 235 mLocationCapabilitiesMask = capabilitiesMask; 236 mLocationCapabilitiesCached = true; 237 if (mGnssCbIface != nullptr) { 238 uint32_t data = 0; 239 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || 240 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || 241 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) || 242 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT)) 243 data |= IGnssCallback::Capabilities::SCHEDULING; 244 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT) 245 data |= IGnssCallback::Capabilities::GEOFENCING; 246 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) 247 data |= IGnssCallback::Capabilities::MEASUREMENTS; 248 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) 249 data |= IGnssCallback::Capabilities::MSB; 250 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) 251 data |= IGnssCallback::Capabilities::MSA; 252 auto r = mGnssCbIface->gnssSetCapabilitesCb(data); 253 if (!r.isOk()) { 254 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s", 255 __func__, r.description().c_str()); 256 } 257 } 258 if (mGnssCbIface != nullptr) { 259 IGnssCallback::GnssSystemInfo gnssInfo; 260 gnssInfo.yearOfHw = 2015; 261 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) { 262 gnssInfo.yearOfHw = 2017; 263 } 264 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw); 265 auto r = mGnssCbIface->gnssSetSystemInfoCb(gnssInfo); 266 if (!r.isOk()) { 267 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s", 268 __func__, r.description().c_str()); 269 } 270 } 271} 272 273void GnssAPIClient::onTrackingCb(Location location) 274{ 275 LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags); 276 if (mGnssCbIface != nullptr) { 277 GnssLocation gnssLocation; 278 convertGnssLocation(location, gnssLocation); 279 auto r = mGnssCbIface->gnssLocationCb(gnssLocation); 280 if (!r.isOk()) { 281 LOC_LOGE("%s] Error from gnssLocationCb description=%s", 282 __func__, r.description().c_str()); 283 } 284 } 285} 286 287void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) 288{ 289 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id); 290 291 if (mGnssNiCbIface == nullptr) { 292 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__); 293 return; 294 } 295 296 IGnssNiCallback::GnssNiNotification notificationGnss = {}; 297 298 notificationGnss.notificationId = id; 299 300 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE) 301 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE; 302 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL) 303 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL; 304 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE) 305 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE; 306 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL) 307 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL; 308 309 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT) 310 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY; 311 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT) 312 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY; 313 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT) 314 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE; 315 316 notificationGnss.timeoutSec = gnssNiNotification.timeout; 317 318 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT) 319 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT; 320 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY) 321 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY; 322 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE || 323 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE) 324 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP; 325 326 notificationGnss.requestorId = gnssNiNotification.requestor; 327 328 notificationGnss.notificationMessage = gnssNiNotification.message; 329 330 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE) 331 notificationGnss.requestorIdEncoding = 332 IGnssNiCallback::GnssNiEncodingType::ENC_NONE; 333 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) 334 notificationGnss.requestorIdEncoding = 335 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; 336 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8) 337 notificationGnss.requestorIdEncoding = 338 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; 339 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2) 340 notificationGnss.requestorIdEncoding = 341 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; 342 343 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE) 344 notificationGnss.notificationIdEncoding = 345 IGnssNiCallback::GnssNiEncodingType::ENC_NONE; 346 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) 347 notificationGnss.notificationIdEncoding = 348 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; 349 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8) 350 notificationGnss.notificationIdEncoding = 351 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; 352 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2) 353 notificationGnss.notificationIdEncoding = 354 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; 355 356 mGnssNiCbIface->niNotifyCb(notificationGnss); 357} 358 359void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) 360{ 361 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count); 362 if (mGnssCbIface != nullptr) { 363 IGnssCallback::GnssSvStatus svStatus; 364 convertGnssSvStatus(gnssSvNotification, svStatus); 365 auto r = mGnssCbIface->gnssSvStatusCb(svStatus); 366 if (!r.isOk()) { 367 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s", 368 __func__, r.description().c_str()); 369 } 370 } 371} 372 373void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) 374{ 375 if (mGnssCbIface != nullptr) { 376 android::hardware::hidl_string nmeaString; 377 nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length); 378 auto r = mGnssCbIface->gnssNmeaCb( 379 static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString); 380 if (!r.isOk()) { 381 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s", __func__, 382 gnssNmeaNotification.nmea, gnssNmeaNotification.length, r.description().c_str()); 383 } 384 } 385} 386 387void GnssAPIClient::onStartTrackingCb(LocationError error) 388{ 389 LOC_LOGD("%s]: (%d)", __FUNCTION__, error); 390 if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { 391 auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); 392 if (!r.isOk()) { 393 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s", 394 __func__, r.description().c_str()); 395 } 396 r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); 397 if (!r.isOk()) { 398 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s", 399 __func__, r.description().c_str()); 400 } 401 } 402} 403 404void GnssAPIClient::onStopTrackingCb(LocationError error) 405{ 406 LOC_LOGD("%s]: (%d)", __FUNCTION__, error); 407 if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { 408 auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); 409 if (!r.isOk()) { 410 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s", 411 __func__, r.description().c_str()); 412 } 413 r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); 414 if (!r.isOk()) { 415 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s", 416 __func__, r.description().c_str()); 417 } 418 } 419} 420 421static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out) 422{ 423 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus)); 424 out.numSvs = in.count; 425 if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) { 426 LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.", 427 __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT); 428 out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT); 429 } 430 for (size_t i = 0; i < out.numSvs; i++) { 431 IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; 432 info.svid = in.gnssSvs[i].svId; 433 convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); 434 info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; 435 info.elevationDegrees = in.gnssSvs[i].elevation; 436 info.azimuthDegrees = in.gnssSvs[i].azimuth; 437 info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE); 438 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) 439 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA; 440 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) 441 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA; 442 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) 443 info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX; 444 } 445} 446 447} // namespace implementation 448} // namespace V1_0 449} // namespace gnss 450} // namespace hardware 451} // namespace android 452