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