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 if (mode == IGnss::GnssPositionMode::STANDALONE)
227 mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
228 else if (mode == IGnss::GnssPositionMode::MS_BASED)
229 mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
230 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
231 mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
232 else {
233 LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
234 retVal = false;
235 }
236 if (GNSS_POWER_MODE_INVALID != powerMode) {
237 mTrackingOptions.powerMode = powerMode;
238 mTrackingOptions.tbm = timeBetweenMeasurement;
239 }
240 locAPIUpdateTrackingOptions(mTrackingOptions);
241 return retVal;
242 }
243
244 // for GpsNiInterface
gnssNiRespond(int32_t notifId,IGnssNiCallback::GnssUserResponseType userResponse)245 void GnssAPIClient::gnssNiRespond(int32_t notifId,
246 IGnssNiCallback::GnssUserResponseType userResponse)
247 {
248 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
249 GnssNiResponse data;
250 switch (userResponse) {
251 case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
252 data = GNSS_NI_RESPONSE_ACCEPT;
253 break;
254 case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
255 data = GNSS_NI_RESPONSE_DENY;
256 break;
257 case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
258 data = GNSS_NI_RESPONSE_NO_RESPONSE;
259 break;
260 default:
261 data = GNSS_NI_RESPONSE_IGNORE;
262 break;
263 }
264
265 locAPIGnssNiResponse(notifId, data);
266 }
267
268 // these apis using LocationAPIControlClient
gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)269 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
270 {
271 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
272 if (mControlClient == nullptr) {
273 return;
274 }
275 GnssAidingData data;
276 memset(&data, 0, sizeof (GnssAidingData));
277 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
278 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
279 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
280 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
281 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT |
282 GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT;
283 data.posEngineMask = STANDARD_POSITIONING_ENGINE;
284
285 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
286 data.deleteAll = true;
287 else {
288 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
289 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
290 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
291 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
292 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
293 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
294 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
295 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
296 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
297 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
298 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
299 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
300 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
301 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
302 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
303 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
304 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
305 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
306 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
307 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
308 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
309 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
310 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
311 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
312 }
313 mControlClient->locAPIGnssDeleteAidingData(data);
314 }
315
gnssEnable(LocationTechnologyType techType)316 void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
317 {
318 LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
319 if (mControlClient == nullptr) {
320 return;
321 }
322 mControlClient->locAPIEnable(techType);
323 }
324
gnssDisable()325 void GnssAPIClient::gnssDisable()
326 {
327 LOC_LOGD("%s]: ()", __FUNCTION__);
328 if (mControlClient == nullptr) {
329 return;
330 }
331 mControlClient->locAPIDisable();
332 }
333
gnssConfigurationUpdate(const GnssConfig & gnssConfig)334 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
335 {
336 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
337 if (mControlClient == nullptr) {
338 return;
339 }
340 mControlClient->locAPIGnssUpdateConfig(gnssConfig);
341 }
342
requestCapabilities()343 void GnssAPIClient::requestCapabilities() {
344 // only send capablities if it's already cached, otherwise the first time LocationAPI
345 // is initialized, capabilities will be sent by LocationAPI
346 if (mLocationCapabilitiesCached) {
347 onCapabilitiesCb(mLocationCapabilitiesMask);
348 }
349 }
350
351 // callbacks
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)352 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
353 {
354 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
355 mLocationCapabilitiesMask = capabilitiesMask;
356 mLocationCapabilitiesCached = true;
357
358 mMutex.lock();
359 auto gnssCbIface(mGnssCbIface);
360 auto gnssCbIface_2_0(mGnssCbIface_2_0);
361 mMutex.unlock();
362
363 if (gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
364 uint32_t data = 0;
365 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
366 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
367 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
368 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
369 data |= IGnssCallback::Capabilities::SCHEDULING;
370 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
371 data |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
372 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
373 data |= V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
374 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
375 data |= IGnssCallback::Capabilities::MSB;
376 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
377 data |= IGnssCallback::Capabilities::MSA;
378 if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
379 data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
380 if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
381 data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
382
383 IGnssCallback::GnssSystemInfo gnssInfo;
384 if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
385 gnssInfo.yearOfHw = 2019;
386 } else if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
387 capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
388 gnssInfo.yearOfHw = 2018;
389 } else if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
390 gnssInfo.yearOfHw = 2017;
391 } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
392 gnssInfo.yearOfHw = 2016;
393 } else {
394 gnssInfo.yearOfHw = 2015;
395 }
396 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
397
398 if (gnssCbIface_2_0 != nullptr) {
399 auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
400 if (!r.isOk()) {
401 LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
402 __func__, r.description().c_str());
403 }
404 r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
405 if (!r.isOk()) {
406 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
407 __func__, r.description().c_str());
408 }
409 } else if (gnssCbIface != nullptr) {
410 auto r = gnssCbIface->gnssSetCapabilitesCb(data);
411 if (!r.isOk()) {
412 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
413 __func__, r.description().c_str());
414 }
415 r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
416 if (!r.isOk()) {
417 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
418 __func__, r.description().c_str());
419 }
420 }
421
422 }
423
424 }
425
onTrackingCb(Location location)426 void GnssAPIClient::onTrackingCb(Location location)
427 {
428 mMutex.lock();
429 auto gnssCbIface(mGnssCbIface);
430 auto gnssCbIface_2_0(mGnssCbIface_2_0);
431 bool isTracking = mTracking;
432 mMutex.unlock();
433
434 LOC_LOGD("%s]: (flags: %02x isTracking: %d)", __FUNCTION__, location.flags, isTracking);
435
436 if (!isTracking) {
437 return;
438 }
439
440 if (gnssCbIface_2_0 != nullptr) {
441 V2_0::GnssLocation gnssLocation;
442 convertGnssLocation(location, gnssLocation);
443 auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
444 if (!r.isOk()) {
445 LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
446 __func__, r.description().c_str());
447 }
448 } else if (gnssCbIface != nullptr) {
449 V1_0::GnssLocation gnssLocation;
450 convertGnssLocation(location, gnssLocation);
451 auto r = gnssCbIface->gnssLocationCb(gnssLocation);
452 if (!r.isOk()) {
453 LOC_LOGE("%s] Error from gnssLocationCb description=%s",
454 __func__, r.description().c_str());
455 }
456 } else {
457 LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
458 }
459
460 }
461
onGnssNiCb(uint32_t id,GnssNiNotification gnssNiNotification)462 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
463 {
464 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
465 mMutex.lock();
466 auto gnssNiCbIface(mGnssNiCbIface);
467 mMutex.unlock();
468
469 if (gnssNiCbIface == nullptr) {
470 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
471 return;
472 }
473
474 IGnssNiCallback::GnssNiNotification notificationGnss = {};
475
476 notificationGnss.notificationId = id;
477
478 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
479 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
480 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
481 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
482 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
483 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
484 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
485 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
486
487 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
488 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
489 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
490 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
491 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
492 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
493
494 notificationGnss.timeoutSec = gnssNiNotification.timeout;
495
496 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
497 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
498 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
499 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
500 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
501 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
502 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
503
504 notificationGnss.requestorId = gnssNiNotification.requestor;
505
506 notificationGnss.notificationMessage = gnssNiNotification.message;
507
508 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
509 notificationGnss.requestorIdEncoding =
510 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
511 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
512 notificationGnss.requestorIdEncoding =
513 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
514 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
515 notificationGnss.requestorIdEncoding =
516 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
517 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
518 notificationGnss.requestorIdEncoding =
519 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
520
521 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
522 notificationGnss.notificationIdEncoding =
523 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
524 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
525 notificationGnss.notificationIdEncoding =
526 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
527 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
528 notificationGnss.notificationIdEncoding =
529 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
530 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
531 notificationGnss.notificationIdEncoding =
532 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
533
534 gnssNiCbIface->niNotifyCb(notificationGnss);
535 }
536
onGnssSvCb(GnssSvNotification gnssSvNotification)537 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
538 {
539 LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
540 mMutex.lock();
541 auto gnssCbIface(mGnssCbIface);
542 auto gnssCbIface_2_0(mGnssCbIface_2_0);
543 mMutex.unlock();
544
545 if (gnssCbIface_2_0 != nullptr) {
546 hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
547 convertGnssSvStatus(gnssSvNotification, svInfoList);
548 auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
549 if (!r.isOk()) {
550 LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
551 __func__, r.description().c_str());
552 }
553 } else if (gnssCbIface != nullptr) {
554 V1_0::IGnssCallback::GnssSvStatus svStatus;
555 convertGnssSvStatus(gnssSvNotification, svStatus);
556 auto r = gnssCbIface->gnssSvStatusCb(svStatus);
557 if (!r.isOk()) {
558 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
559 __func__, r.description().c_str());
560 }
561 }
562 }
563
onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)564 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
565 {
566 mMutex.lock();
567 auto gnssCbIface(mGnssCbIface);
568 auto gnssCbIface_2_0(mGnssCbIface_2_0);
569 mMutex.unlock();
570
571 if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr) {
572 const std::string s(gnssNmeaNotification.nmea);
573 std::stringstream ss(s);
574 std::string each;
575 while(std::getline(ss, each, '\n')) {
576 each += '\n';
577 android::hardware::hidl_string nmeaString;
578 nmeaString.setToExternal(each.c_str(), each.length());
579 if (gnssCbIface_2_0 != nullptr) {
580 auto r = gnssCbIface_2_0->gnssNmeaCb(
581 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
582 if (!r.isOk()) {
583 LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%u description=%s",
584 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
585 r.description().c_str());
586 }
587 } else if (gnssCbIface != nullptr) {
588 auto r = gnssCbIface->gnssNmeaCb(
589 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
590 if (!r.isOk()) {
591 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s",
592 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
593 r.description().c_str());
594 }
595 }
596 }
597 }
598 }
599
onStartTrackingCb(LocationError error)600 void GnssAPIClient::onStartTrackingCb(LocationError error)
601 {
602 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
603 mMutex.lock();
604 auto gnssCbIface(mGnssCbIface);
605 auto gnssCbIface_2_0(mGnssCbIface_2_0);
606 mMutex.unlock();
607
608 if (error == LOCATION_ERROR_SUCCESS) {
609 if (gnssCbIface_2_0 != nullptr) {
610 auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
611 if (!r.isOk()) {
612 LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_ON description=%s",
613 __func__, r.description().c_str());
614 }
615 r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
616 if (!r.isOk()) {
617 LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_BEGIN description=%s",
618 __func__, r.description().c_str());
619 }
620 } else if (gnssCbIface != nullptr) {
621 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
622 if (!r.isOk()) {
623 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
624 __func__, r.description().c_str());
625 }
626 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
627 if (!r.isOk()) {
628 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
629 __func__, r.description().c_str());
630 }
631 }
632 }
633 }
634
onStopTrackingCb(LocationError error)635 void GnssAPIClient::onStopTrackingCb(LocationError error)
636 {
637 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
638 mMutex.lock();
639 auto gnssCbIface(mGnssCbIface);
640 auto gnssCbIface_2_0(mGnssCbIface_2_0);
641 mMutex.unlock();
642
643 if (error == LOCATION_ERROR_SUCCESS) {
644 if (gnssCbIface_2_0 != nullptr) {
645 auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
646 if (!r.isOk()) {
647 LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_END description=%s",
648 __func__, r.description().c_str());
649 }
650 r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
651 if (!r.isOk()) {
652 LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_OFF description=%s",
653 __func__, r.description().c_str());
654 }
655
656 } else if (gnssCbIface != nullptr) {
657 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
658 if (!r.isOk()) {
659 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
660 __func__, r.description().c_str());
661 }
662 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
663 if (!r.isOk()) {
664 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
665 __func__, r.description().c_str());
666 }
667 }
668 }
669 }
670
convertGnssSvStatus(GnssSvNotification & in,V1_0::IGnssCallback::GnssSvStatus & out)671 static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out)
672 {
673 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
674 out.numSvs = in.count;
675 if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
676 LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
677 __FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
678 out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
679 }
680 for (size_t i = 0; i < out.numSvs; i++) {
681 out.gnssSvList[i].svid = in.gnssSvs[i].svId;
682 convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
683 out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
684 out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
685 out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
686 out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
687 out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
688 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
689 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
690 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
691 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
692 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
693 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
694 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
695 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
696 }
697 }
698
convertGnssSvStatus(GnssSvNotification & in,hidl_vec<V2_0::IGnssCallback::GnssSvInfo> & out)699 static void convertGnssSvStatus(GnssSvNotification& in,
700 hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
701 {
702 out.resize(in.count);
703 for (size_t i = 0; i < in.count; i++) {
704 out[i].v1_0.svid = in.gnssSvs[i].svId;
705 out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
706 out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
707 out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
708 out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
709 out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
710 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
711 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
712 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
713 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
714 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
715 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
716 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
717 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
718
719 convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
720 }
721 }
722
723 } // namespace implementation
724 } // namespace V2_0
725 } // namespace gnss
726 } // namespace hardware
727 } // namespace android
728