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