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