1 /* Copyright (c) 2017-2020, 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 #define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
33
34 #include <inttypes.h>
35 #include <log_util.h>
36 #include <loc_cfg.h>
37
38 #include "LocationUtil.h"
39 #include "GnssAPIClient.h"
40 #include <LocContext.h>
41
42 namespace android {
43 namespace hardware {
44 namespace gnss {
45 namespace V2_0 {
46 namespace implementation {
47
48 using ::android::hardware::gnss::V2_0::IGnss;
49 using ::android::hardware::gnss::V2_0::IGnssCallback;
50 using ::android::hardware::gnss::V1_0::IGnssNiCallback;
51 using ::android::hardware::gnss::V2_0::GnssLocation;
52
53 static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out);
54 static void convertGnssSvStatus(GnssSvNotification& in,
55 hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out);
56
GnssAPIClient(const sp<V1_0::IGnssCallback> & gpsCb,const sp<V1_0::IGnssNiCallback> & niCb)57 GnssAPIClient::GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
58 const sp<V1_0::IGnssNiCallback>& niCb) :
59 LocationAPIClientBase(),
60 mGnssCbIface(nullptr),
61 mGnssNiCbIface(nullptr),
62 mControlClient(new LocationAPIControlClient()),
63 mLocationCapabilitiesMask(0),
64 mLocationCapabilitiesCached(false),
65 mTracking(false),
66 mGnssCbIface_2_0(nullptr)
67 {
68 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
69
70 initLocationOptions();
71 gnssUpdateCallbacks(gpsCb, niCb);
72 }
73
GnssAPIClient(const sp<V2_0::IGnssCallback> & gpsCb)74 GnssAPIClient::GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb) :
75 LocationAPIClientBase(),
76 mGnssCbIface(nullptr),
77 mGnssNiCbIface(nullptr),
78 mControlClient(new LocationAPIControlClient()),
79 mLocationCapabilitiesMask(0),
80 mLocationCapabilitiesCached(false),
81 mTracking(false),
82 mGnssCbIface_2_0(nullptr)
83 {
84 LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
85
86 initLocationOptions();
87 gnssUpdateCallbacks_2_0(gpsCb);
88 }
89
~GnssAPIClient()90 GnssAPIClient::~GnssAPIClient()
91 {
92 LOC_LOGD("%s]: ()", __FUNCTION__);
93 if (mControlClient) {
94 delete mControlClient;
95 mControlClient = nullptr;
96 }
97 }
98
initLocationOptions()99 void GnssAPIClient::initLocationOptions()
100 {
101 // set default LocationOptions.
102 memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
103 mTrackingOptions.size = sizeof(TrackingOptions);
104 mTrackingOptions.minInterval = 1000;
105 mTrackingOptions.minDistance = 0;
106 mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
107 }
108
setCallbacks()109 void GnssAPIClient::setCallbacks()
110 {
111 LocationCallbacks locationCallbacks;
112 memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
113 locationCallbacks.size = sizeof(LocationCallbacks);
114
115 locationCallbacks.trackingCb = nullptr;
116 locationCallbacks.trackingCb = [this](Location location) {
117 onTrackingCb(location);
118 };
119
120 locationCallbacks.batchingCb = nullptr;
121 locationCallbacks.geofenceBreachCb = nullptr;
122 locationCallbacks.geofenceStatusCb = nullptr;
123 locationCallbacks.gnssLocationInfoCb = nullptr;
124 locationCallbacks.gnssNiCb = nullptr;
125 if (mGnssNiCbIface != nullptr) {
126 loc_core::ContextBase* context =
127 loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
128 if (!context->hasAgpsExtendedCapabilities()) {
129 LOC_LOGD("Registering NI CB");
130 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
131 onGnssNiCb(id, gnssNiNotification);
132 };
133 }
134 }
135
136 locationCallbacks.gnssSvCb = nullptr;
137 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
138 onGnssSvCb(gnssSvNotification);
139 };
140
141 locationCallbacks.gnssNmeaCb = nullptr;
142 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
143 onGnssNmeaCb(gnssNmeaNotification);
144 };
145
146 locationCallbacks.gnssMeasurementsCb = nullptr;
147
148 locAPISetCallbacks(locationCallbacks);
149 }
150
151 // for GpsInterface
gnssUpdateCallbacks(const sp<V1_0::IGnssCallback> & gpsCb,const sp<IGnssNiCallback> & niCb)152 void GnssAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
153 const sp<IGnssNiCallback>& niCb)
154 {
155 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
156
157 mMutex.lock();
158 mGnssCbIface = gpsCb;
159 mGnssNiCbIface = niCb;
160 mMutex.unlock();
161
162 if (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr) {
163 setCallbacks();
164 }
165 }
166
gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback> & gpsCb)167 void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb)
168 {
169 LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
170
171 mMutex.lock();
172 mGnssCbIface_2_0 = gpsCb;
173 mMutex.unlock();
174
175 if (mGnssCbIface_2_0 != nullptr) {
176 setCallbacks();
177 }
178 }
179
gnssStart()180 bool GnssAPIClient::gnssStart()
181 {
182 LOC_LOGD("%s]: ()", __FUNCTION__);
183
184 mMutex.lock();
185 mTracking = true;
186 mMutex.unlock();
187
188 bool retVal = true;
189 locAPIStartTracking(mTrackingOptions);
190 return retVal;
191 }
192
gnssStop()193 bool GnssAPIClient::gnssStop()
194 {
195 LOC_LOGD("%s]: ()", __FUNCTION__);
196
197 mMutex.lock();
198 mTracking = false;
199 mMutex.unlock();
200
201 bool retVal = true;
202 locAPIStopTracking();
203 return retVal;
204 }
205
gnssSetPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs,GnssPowerMode powerMode,uint32_t timeBetweenMeasurement)206 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
207 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
208 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
209 GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
210 {
211 LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
212 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
213 preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
214 bool retVal = true;
215 memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
216 mTrackingOptions.size = sizeof(TrackingOptions);
217 mTrackingOptions.minInterval = minIntervalMs;
218 if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
219 IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
220 // We set a very large interval to simulate SINGLE mode. Once we report a fix,
221 // the caller should take the responsibility to stop the session.
222 // For MSA, we always treat it as SINGLE mode.
223 mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
224 }
225 if (mode == IGnss::GnssPositionMode::STANDALONE)
226 mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
227 else if (mode == IGnss::GnssPositionMode::MS_BASED)
228 mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
229 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
230 mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
231 else {
232 LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
233 retVal = false;
234 }
235 if (GNSS_POWER_MODE_INVALID != powerMode) {
236 mTrackingOptions.powerMode = powerMode;
237 mTrackingOptions.tbm = timeBetweenMeasurement;
238 }
239 locAPIUpdateTrackingOptions(mTrackingOptions);
240 return retVal;
241 }
242
243 // for GpsNiInterface
gnssNiRespond(int32_t notifId,IGnssNiCallback::GnssUserResponseType userResponse)244 void GnssAPIClient::gnssNiRespond(int32_t notifId,
245 IGnssNiCallback::GnssUserResponseType userResponse)
246 {
247 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
248 GnssNiResponse data;
249 switch (userResponse) {
250 case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
251 data = GNSS_NI_RESPONSE_ACCEPT;
252 break;
253 case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
254 data = GNSS_NI_RESPONSE_DENY;
255 break;
256 case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
257 data = GNSS_NI_RESPONSE_NO_RESPONSE;
258 break;
259 default:
260 data = GNSS_NI_RESPONSE_IGNORE;
261 break;
262 }
263
264 locAPIGnssNiResponse(notifId, data);
265 }
266
267 // these apis using LocationAPIControlClient
gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)268 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
269 {
270 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
271 if (mControlClient == nullptr) {
272 return;
273 }
274 GnssAidingData data;
275 memset(&data, 0, sizeof (GnssAidingData));
276 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
277 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
278 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
279 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
280 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT |
281 GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT;
282 data.posEngineMask = STANDARD_POSITIONING_ENGINE;
283
284 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
285 data.deleteAll = true;
286 else {
287 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
288 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
289 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
290 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
291 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
292 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
293 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
294 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
295 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
296 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
297 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
298 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
299 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
300 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
301 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
302 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
303 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
304 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
305 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
306 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
307 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
308 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
309 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
310 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
311 }
312 mControlClient->locAPIGnssDeleteAidingData(data);
313 }
314
gnssEnable(LocationTechnologyType techType)315 void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
316 {
317 LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
318 if (mControlClient == nullptr) {
319 return;
320 }
321 mControlClient->locAPIEnable(techType);
322 }
323
gnssDisable()324 void GnssAPIClient::gnssDisable()
325 {
326 LOC_LOGD("%s]: ()", __FUNCTION__);
327 if (mControlClient == nullptr) {
328 return;
329 }
330 mControlClient->locAPIDisable();
331 }
332
gnssConfigurationUpdate(const GnssConfig & gnssConfig)333 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
334 {
335 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
336 if (mControlClient == nullptr) {
337 return;
338 }
339 mControlClient->locAPIGnssUpdateConfig(gnssConfig);
340 }
341
requestCapabilities()342 void GnssAPIClient::requestCapabilities() {
343 // only send capablities if it's already cached, otherwise the first time LocationAPI
344 // is initialized, capabilities will be sent by LocationAPI
345 if (mLocationCapabilitiesCached) {
346 onCapabilitiesCb(mLocationCapabilitiesMask);
347 }
348 }
349
350 // callbacks
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)351 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
352 {
353 LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
354 mLocationCapabilitiesMask = capabilitiesMask;
355 mLocationCapabilitiesCached = true;
356
357 mMutex.lock();
358 auto gnssCbIface(mGnssCbIface);
359 auto gnssCbIface_2_0(mGnssCbIface_2_0);
360 mMutex.unlock();
361
362 if (gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
363 uint32_t data = 0;
364 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
365 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
366 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
367 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
368 data |= IGnssCallback::Capabilities::SCHEDULING;
369 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
370 data |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
371 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
372 data |= V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
373 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
374 data |= IGnssCallback::Capabilities::MSB;
375 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
376 data |= IGnssCallback::Capabilities::MSA;
377 if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
378 data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
379 if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
380 data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
381
382 IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
383
384 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
385 gnssInfo.yearOfHw++; // 2016
386 if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
387 gnssInfo.yearOfHw++; // 2017
388 if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
389 capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
390 gnssInfo.yearOfHw++; // 2018
391 if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
392 gnssInfo.yearOfHw++; // 2019
393 }
394 }
395 }
396 }
397 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
398
399 if (gnssCbIface_2_0 != nullptr) {
400 auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
401 if (!r.isOk()) {
402 LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
403 __func__, r.description().c_str());
404 }
405 r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
406 if (!r.isOk()) {
407 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
408 __func__, r.description().c_str());
409 }
410 } else if (gnssCbIface != nullptr) {
411 auto r = gnssCbIface->gnssSetCapabilitesCb(data);
412 if (!r.isOk()) {
413 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
414 __func__, r.description().c_str());
415 }
416 r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
417 if (!r.isOk()) {
418 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
419 __func__, r.description().c_str());
420 }
421 }
422
423 }
424
425 }
426
onTrackingCb(Location location)427 void GnssAPIClient::onTrackingCb(Location location)
428 {
429 mMutex.lock();
430 auto gnssCbIface(mGnssCbIface);
431 auto gnssCbIface_2_0(mGnssCbIface_2_0);
432 bool isTracking = mTracking;
433 mMutex.unlock();
434
435 LOC_LOGD("%s]: (flags: %02x isTracking: %d)", __FUNCTION__, location.flags, isTracking);
436
437 if (!isTracking) {
438 return;
439 }
440
441 if (gnssCbIface_2_0 != nullptr) {
442 V2_0::GnssLocation gnssLocation;
443 convertGnssLocation(location, gnssLocation);
444 auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
445 if (!r.isOk()) {
446 LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
447 __func__, r.description().c_str());
448 }
449 } else if (gnssCbIface != nullptr) {
450 V1_0::GnssLocation gnssLocation;
451 convertGnssLocation(location, gnssLocation);
452 auto r = gnssCbIface->gnssLocationCb(gnssLocation);
453 if (!r.isOk()) {
454 LOC_LOGE("%s] Error from gnssLocationCb description=%s",
455 __func__, r.description().c_str());
456 }
457 } else {
458 LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
459 }
460
461 }
462
onGnssNiCb(uint32_t id,GnssNiNotification gnssNiNotification)463 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
464 {
465 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
466 mMutex.lock();
467 auto gnssNiCbIface(mGnssNiCbIface);
468 mMutex.unlock();
469
470 if (gnssNiCbIface == nullptr) {
471 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
472 return;
473 }
474
475 IGnssNiCallback::GnssNiNotification notificationGnss = {};
476
477 notificationGnss.notificationId = id;
478
479 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
480 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
481 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
482 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
483 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
484 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
485 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
486 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
487
488 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
489 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
490 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
491 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
492 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
493 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
494
495 notificationGnss.timeoutSec = gnssNiNotification.timeout;
496
497 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
498 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
499 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
500 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
501 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
502 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
503 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
504
505 notificationGnss.requestorId = gnssNiNotification.requestor;
506
507 notificationGnss.notificationMessage = gnssNiNotification.message;
508
509 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
510 notificationGnss.requestorIdEncoding =
511 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
512 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
513 notificationGnss.requestorIdEncoding =
514 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
515 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
516 notificationGnss.requestorIdEncoding =
517 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
518 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
519 notificationGnss.requestorIdEncoding =
520 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
521
522 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
523 notificationGnss.notificationIdEncoding =
524 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
525 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
526 notificationGnss.notificationIdEncoding =
527 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
528 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
529 notificationGnss.notificationIdEncoding =
530 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
531 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
532 notificationGnss.notificationIdEncoding =
533 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
534
535 gnssNiCbIface->niNotifyCb(notificationGnss);
536 }
537
onGnssSvCb(GnssSvNotification gnssSvNotification)538 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
539 {
540 LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
541 mMutex.lock();
542 auto gnssCbIface(mGnssCbIface);
543 auto gnssCbIface_2_0(mGnssCbIface_2_0);
544 mMutex.unlock();
545
546 if (gnssCbIface_2_0 != nullptr) {
547 hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
548 convertGnssSvStatus(gnssSvNotification, svInfoList);
549 auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
550 if (!r.isOk()) {
551 LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
552 __func__, r.description().c_str());
553 }
554 } else if (gnssCbIface != nullptr) {
555 V1_0::IGnssCallback::GnssSvStatus svStatus;
556 convertGnssSvStatus(gnssSvNotification, svStatus);
557 auto r = gnssCbIface->gnssSvStatusCb(svStatus);
558 if (!r.isOk()) {
559 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
560 __func__, r.description().c_str());
561 }
562 }
563 }
564
onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)565 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
566 {
567 mMutex.lock();
568 auto gnssCbIface(mGnssCbIface);
569 auto gnssCbIface_2_0(mGnssCbIface_2_0);
570 mMutex.unlock();
571
572 if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr) {
573 const std::string s(gnssNmeaNotification.nmea);
574 std::stringstream ss(s);
575 std::string each;
576 while(std::getline(ss, each, '\n')) {
577 each += '\n';
578 android::hardware::hidl_string nmeaString;
579 nmeaString.setToExternal(each.c_str(), each.length());
580 if (gnssCbIface_2_0 != nullptr) {
581 auto r = gnssCbIface_2_0->gnssNmeaCb(
582 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
583 if (!r.isOk()) {
584 LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%u description=%s",
585 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
586 r.description().c_str());
587 }
588 } else if (gnssCbIface != nullptr) {
589 auto r = gnssCbIface->gnssNmeaCb(
590 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
591 if (!r.isOk()) {
592 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s",
593 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
594 r.description().c_str());
595 }
596 }
597 }
598 }
599 }
600
onStartTrackingCb(LocationError error)601 void GnssAPIClient::onStartTrackingCb(LocationError error)
602 {
603 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
604 mMutex.lock();
605 auto gnssCbIface(mGnssCbIface);
606 auto gnssCbIface_2_0(mGnssCbIface_2_0);
607 mMutex.unlock();
608
609 if (error == LOCATION_ERROR_SUCCESS) {
610 if (gnssCbIface_2_0 != nullptr) {
611 auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
612 if (!r.isOk()) {
613 LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_ON description=%s",
614 __func__, r.description().c_str());
615 }
616 r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
617 if (!r.isOk()) {
618 LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_BEGIN description=%s",
619 __func__, r.description().c_str());
620 }
621 } else if (gnssCbIface != nullptr) {
622 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
623 if (!r.isOk()) {
624 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
625 __func__, r.description().c_str());
626 }
627 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
628 if (!r.isOk()) {
629 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
630 __func__, r.description().c_str());
631 }
632 }
633 }
634 }
635
onStopTrackingCb(LocationError error)636 void GnssAPIClient::onStopTrackingCb(LocationError error)
637 {
638 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
639 mMutex.lock();
640 auto gnssCbIface(mGnssCbIface);
641 auto gnssCbIface_2_0(mGnssCbIface_2_0);
642 mMutex.unlock();
643
644 if (error == LOCATION_ERROR_SUCCESS) {
645 if (gnssCbIface_2_0 != nullptr) {
646 auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
647 if (!r.isOk()) {
648 LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_END description=%s",
649 __func__, r.description().c_str());
650 }
651 r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
652 if (!r.isOk()) {
653 LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_OFF description=%s",
654 __func__, r.description().c_str());
655 }
656
657 } else if (gnssCbIface != nullptr) {
658 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
659 if (!r.isOk()) {
660 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
661 __func__, r.description().c_str());
662 }
663 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
664 if (!r.isOk()) {
665 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
666 __func__, r.description().c_str());
667 }
668 }
669 }
670 }
671
convertGnssSvStatus(GnssSvNotification & in,V1_0::IGnssCallback::GnssSvStatus & out)672 static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out)
673 {
674 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
675 out.numSvs = in.count;
676 if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
677 LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
678 __FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
679 out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
680 }
681 for (size_t i = 0; i < out.numSvs; i++) {
682 convertGnssSvid(in.gnssSvs[i], out.gnssSvList[i].svid);
683 convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
684 out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
685 out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
686 out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
687 out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
688 out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
689 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
690 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
691 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
692 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
693 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
694 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
695 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
696 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
697 }
698 }
699
convertGnssSvStatus(GnssSvNotification & in,hidl_vec<V2_0::IGnssCallback::GnssSvInfo> & out)700 static void convertGnssSvStatus(GnssSvNotification& in,
701 hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
702 {
703 out.resize(in.count);
704 for (size_t i = 0; i < in.count; i++) {
705 convertGnssSvid(in.gnssSvs[i], out[i].v1_0.svid);
706 out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
707 out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
708 out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
709 out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
710 out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
711 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
712 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
713 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
714 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
715 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
716 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
717 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
718 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
719
720 convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
721 }
722 }
723
724 } // namespace implementation
725 } // namespace V2_0
726 } // namespace gnss
727 } // namespace hardware
728 } // namespace android
729