1 /*
2 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
3 * Not a Contribution
4 */
5 /*
6 * Copyright (C) 2016 The Android Open Source Project
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #define LOG_TAG "LocSvc_GnssInterface"
22 #define LOG_NDEBUG 0
23
24 #include <fstream>
25 #include <log_util.h>
26 #include <dlfcn.h>
27 #include <cutils/properties.h>
28 #include "Gnss.h"
29 #include "LocationUtil.h"
30 #include "battery_listener.h"
31 #include "loc_misc_utils.h"
32
33 typedef const GnssInterface* (getLocationInterface)();
34
35 #define IMAGES_INFO_FILE "/sys/devices/soc0/images"
36 #define DELIMITER ";"
37
38 namespace android {
39 namespace hardware {
40 namespace gnss {
41 namespace V2_0 {
42 namespace implementation {
43
44 using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
45 static sp<Gnss> sGnss;
getVersionString()46 static std::string getVersionString() {
47 static std::string version;
48 if (!version.empty())
49 return version;
50
51 char value[PROPERTY_VALUE_MAX] = {0};
52 property_get("ro.hardware", value, "unknown");
53 version.append(value).append(DELIMITER);
54
55 std::ifstream in(IMAGES_INFO_FILE);
56 std::string s;
57 while(getline(in, s)) {
58 std::size_t found = s.find("CRM:");
59 if (std::string::npos == found) {
60 continue;
61 }
62
63 // skip over space characters after "CRM:"
64 const char* substr = s.c_str();
65 found += 4;
66 while (0 != substr[found] && isspace(substr[found])) {
67 found++;
68 }
69 if (s.find("11:") != found) {
70 continue;
71 }
72 s.erase(0, found + 3);
73
74 found = s.find_first_of("\r\n");
75 if (std::string::npos != found) {
76 s.erase(s.begin() + found, s.end());
77 }
78 version.append(s).append(DELIMITER);
79 }
80 return version;
81 }
82
serviceDied(uint64_t cookie,const wp<IBase> & who)83 void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
84 LOC_LOGE("%s] service died. cookie: %llu, who: %p",
85 __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
86 if (mGnss != nullptr) {
87 mGnss->cleanup();
88 }
89 }
90
location_on_battery_status_changed(bool charging)91 void location_on_battery_status_changed(bool charging) {
92 LOC_LOGd("battery status changed to %s charging", charging ? "" : "not");
93 if (sGnss != nullptr) {
94 sGnss->getGnssInterface()->updateBatteryStatus(charging);
95 }
96 }
Gnss()97 Gnss::Gnss() {
98 ENTRY_LOG_CALLFLOW();
99 sGnss = this;
100 // initilize gnss interface at first in case needing notify battery status
101 sGnss->getGnssInterface()->initialize();
102 // register health client to listen on battery change
103 loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
104 // clear pending GnssConfig
105 memset(&mPendingConfig, 0, sizeof(GnssConfig));
106 mGnssDeathRecipient = new GnssDeathRecipient(this);
107 }
108
~Gnss()109 Gnss::~Gnss() {
110 ENTRY_LOG_CALLFLOW();
111 if (mApi != nullptr) {
112 delete mApi;
113 mApi = nullptr;
114 }
115 sGnss = nullptr;
116 }
117
getApi()118 GnssAPIClient* Gnss::getApi() {
119 if (mApi != nullptr) {
120 return mApi;
121 }
122
123 if (mGnssCbIface_2_0 != nullptr) {
124 mApi = new GnssAPIClient(mGnssCbIface_2_0);
125 } else if (mGnssCbIface_1_1 != nullptr) {
126 mApi = new GnssAPIClient(mGnssCbIface_1_1, mGnssNiCbIface);
127 } else if (mGnssCbIface != nullptr) {
128 mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
129 } else {
130 LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
131 return mApi;
132 }
133
134 if (mPendingConfig.size == sizeof(GnssConfig)) {
135 // we have pending GnssConfig
136 mApi->gnssConfigurationUpdate(mPendingConfig);
137 // clear size to invalid mPendingConfig
138 mPendingConfig.size = 0;
139 if (mPendingConfig.assistanceServer.hostName != nullptr) {
140 free((void*)mPendingConfig.assistanceServer.hostName);
141 }
142 }
143
144 return mApi;
145 }
146
getGnssInterface()147 const GnssInterface* Gnss::getGnssInterface() {
148 static bool getGnssInterfaceFailed = false;
149
150 if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
151 void * libHandle = nullptr;
152 getLocationInterface* getter = (getLocationInterface*)
153 dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
154
155 if (nullptr == getter) {
156 getGnssInterfaceFailed = true;
157 } else {
158 mGnssInterface = (GnssInterface*)(*getter)();
159 }
160 }
161 return mGnssInterface;
162 }
163
setCallback(const sp<V1_0::IGnssCallback> & callback)164 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
165 ENTRY_LOG_CALLFLOW();
166
167 // In case where previous call to setCallback_1_1 or setCallback_2_0, then
168 // we need to cleanup these interfaces/callbacks here since we no longer
169 // do so in cleanup() function to keep callbacks around after cleanup()
170 if (mApi != nullptr) {
171 mApi->gnssUpdateCallbacks_2_0(nullptr);
172 }
173 if (mGnssCbIface_1_1 != nullptr) {
174 mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
175 mGnssCbIface_1_1 = nullptr;
176 }
177 if (mGnssCbIface_2_0 != nullptr) {
178 mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
179 mGnssCbIface_2_0 = nullptr;
180 }
181
182
183 if (mGnssCbIface != nullptr) {
184 mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
185 }
186 mGnssCbIface = callback;
187 if (mGnssCbIface != nullptr) {
188 mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
189 }
190
191 GnssAPIClient* api = getApi();
192 if (api != nullptr) {
193 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
194 api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
195 api->requestCapabilities();
196 }
197 return true;
198 }
199
setGnssNiCb(const sp<IGnssNiCallback> & callback)200 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
201 ENTRY_LOG_CALLFLOW();
202 mGnssNiCbIface = callback;
203 GnssAPIClient* api = getApi();
204 if (api != nullptr) {
205 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
206 }
207 return true;
208 }
209
updateConfiguration(GnssConfig & gnssConfig)210 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
211 ENTRY_LOG_CALLFLOW();
212 GnssAPIClient* api = getApi();
213 if (api) {
214 api->gnssConfigurationUpdate(gnssConfig);
215 } else if (gnssConfig.flags != 0) {
216 // api is not ready yet, update mPendingConfig with gnssConfig
217 mPendingConfig.size = sizeof(GnssConfig);
218
219 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
220 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
221 mPendingConfig.gpsLock = gnssConfig.gpsLock;
222 }
223 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
224 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
225 mPendingConfig.suplVersion = gnssConfig.suplVersion;
226 }
227 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
228 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
229 mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
230 mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
231 if (mPendingConfig.assistanceServer.hostName != nullptr) {
232 free((void*)mPendingConfig.assistanceServer.hostName);
233 mPendingConfig.assistanceServer.hostName =
234 strdup(gnssConfig.assistanceServer.hostName);
235 }
236 mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
237 }
238 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
239 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
240 mPendingConfig.lppProfile = gnssConfig.lppProfile;
241 }
242 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
243 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
244 mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
245 }
246 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
247 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
248 mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
249 }
250 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
251 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
252 mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
253 }
254 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
255 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
256 mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
257 }
258 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
259 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
260 mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
261 }
262 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
263 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
264 mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
265 }
266 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
267 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
268 mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
269 }
270 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
271 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
272 mPendingConfig.emergencyExtensionSeconds = gnssConfig.emergencyExtensionSeconds;
273 }
274 }
275 return true;
276 }
277
start()278 Return<bool> Gnss::start() {
279 ENTRY_LOG_CALLFLOW();
280 bool retVal = false;
281 GnssAPIClient* api = getApi();
282 if (api) {
283 retVal = api->gnssStart();
284 }
285 return retVal;
286 }
287
stop()288 Return<bool> Gnss::stop() {
289 ENTRY_LOG_CALLFLOW();
290 bool retVal = false;
291 GnssAPIClient* api = getApi();
292 if (api) {
293 retVal = api->gnssStop();
294 }
295 return retVal;
296 }
297
cleanup()298 Return<void> Gnss::cleanup() {
299 ENTRY_LOG_CALLFLOW();
300
301 if (mApi != nullptr) {
302 mApi->gnssStop();
303 mApi->gnssDisable();
304 }
305
306 return Void();
307 }
308
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)309 Return<bool> Gnss::injectLocation(double latitudeDegrees,
310 double longitudeDegrees,
311 float accuracyMeters) {
312 ENTRY_LOG_CALLFLOW();
313 const GnssInterface* gnssInterface = getGnssInterface();
314 if (nullptr != gnssInterface) {
315 gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
316 return true;
317 } else {
318 return false;
319 }
320 }
321
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)322 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
323 int32_t uncertaintyMs) {
324 return true;
325 }
326
deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)327 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) {
328 ENTRY_LOG_CALLFLOW();
329 GnssAPIClient* api = getApi();
330 if (api) {
331 api->gnssDeleteAidingData(aidingDataFlags);
332 }
333 return Void();
334 }
335
setPositionMode(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)336 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
337 V1_0::IGnss::GnssPositionRecurrence recurrence,
338 uint32_t minIntervalMs,
339 uint32_t preferredAccuracyMeters,
340 uint32_t preferredTimeMs) {
341 ENTRY_LOG_CALLFLOW();
342 bool retVal = false;
343 GnssAPIClient* api = getApi();
344 if (api) {
345 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
346 preferredAccuracyMeters, preferredTimeMs);
347 }
348 return retVal;
349 }
350
getExtensionAGnss()351 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
352 ENTRY_LOG_CALLFLOW();
353 // deprecated function. Must return nullptr to pass VTS
354 return nullptr;
355 }
356
getExtensionGnssNi()357 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
358 ENTRY_LOG_CALLFLOW();
359 // deprecated function. Must return nullptr to pass VTS
360 return nullptr;
361 }
362
getExtensionGnssMeasurement()363 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
364 ENTRY_LOG_CALLFLOW();
365 if (mGnssMeasurement == nullptr)
366 mGnssMeasurement = new GnssMeasurement();
367 return mGnssMeasurement;
368 }
369
getExtensionGnssConfiguration()370 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
371 ENTRY_LOG_CALLFLOW();
372 if (mGnssConfig == nullptr) {
373 mGnssConfig = new GnssConfiguration(this);
374 }
375 return mGnssConfig;
376 }
377
getExtensionGnssGeofencing()378 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
379 ENTRY_LOG_CALLFLOW();
380 if (mGnssGeofencingIface == nullptr) {
381 mGnssGeofencingIface = new GnssGeofencing();
382 }
383 return mGnssGeofencingIface;
384 }
385
getExtensionGnssBatching()386 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
387 ENTRY_LOG_CALLFLOW();
388 if (mGnssBatching == nullptr) {
389 mGnssBatching = new GnssBatching();
390 }
391 return mGnssBatching;
392 }
393
getExtensionGnssDebug()394 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
395 ENTRY_LOG_CALLFLOW();
396 if (mGnssDebug == nullptr) {
397 mGnssDebug = new GnssDebug(this);
398 }
399 return mGnssDebug;
400 }
401
getExtensionAGnssRil()402 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
403 ENTRY_LOG_CALLFLOW();
404 if (mGnssRil == nullptr) {
405 mGnssRil = new AGnssRil(this);
406 }
407 return mGnssRil;
408 }
409
410 // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
setCallback_1_1(const sp<V1_1::IGnssCallback> & callback)411 Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
412 ENTRY_LOG_CALLFLOW();
413 auto r = callback->gnssNameCb(getVersionString());
414 if (!r.isOk()) {
415 LOC_LOGE("%s] Error from gnssNameCb description=%s",
416 __func__, r.description().c_str());
417 }
418
419 // In case where previous call to setCallback or setCallback_2_1, then
420 // we need to cleanup these interfaces/callbacks here since we no longer
421 // do so in cleanup() function to keep callbacks around after cleanup()
422 if (mApi != nullptr) {
423 mApi->gnssUpdateCallbacks_2_0(nullptr);
424 }
425 if (mGnssCbIface != nullptr) {
426 mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
427 mGnssCbIface = nullptr;
428 }
429 if (mGnssCbIface_2_0 != nullptr) {
430 mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
431 mGnssCbIface_2_0 = nullptr;
432 }
433
434
435 if (mGnssCbIface_1_1 != nullptr) {
436 mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
437 }
438 mGnssCbIface_1_1 = callback;
439 if (mGnssCbIface_1_1 != nullptr) {
440 mGnssCbIface_1_1->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
441 }
442
443 const GnssInterface* gnssInterface = getGnssInterface();
444 if (nullptr != gnssInterface) {
445 OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
446 odcpiRequestCb(odcpiRequest);
447 };
448 gnssInterface->odcpiInit(cb);
449 }
450
451 GnssAPIClient* api = getApi();
452 if (api != nullptr) {
453 api->gnssUpdateCallbacks(mGnssCbIface_1_1, mGnssNiCbIface);
454 api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
455 api->requestCapabilities();
456 }
457
458 return true;
459 }
460
setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs,bool lowPowerMode)461 Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
462 V1_0::IGnss::GnssPositionRecurrence recurrence,
463 uint32_t minIntervalMs,
464 uint32_t preferredAccuracyMeters,
465 uint32_t preferredTimeMs,
466 bool lowPowerMode) {
467 ENTRY_LOG_CALLFLOW();
468 bool retVal = false;
469 GnssAPIClient* api = getApi();
470 if (api) {
471 GnssPowerMode powerMode = lowPowerMode?
472 GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
473 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
474 preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
475 }
476 return retVal;
477 }
478
getExtensionGnssMeasurement_1_1()479 Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
480 ENTRY_LOG_CALLFLOW();
481 #ifdef GNSS_HIDL_LEGACY_MEASURMENTS
482 return nullptr;
483 #else
484 if (mGnssMeasurement == nullptr)
485 mGnssMeasurement = new GnssMeasurement();
486 return mGnssMeasurement;
487 #endif
488 }
489
getExtensionGnssConfiguration_1_1()490 Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
491 ENTRY_LOG_CALLFLOW();
492 if (mGnssConfig == nullptr)
493 mGnssConfig = new GnssConfiguration(this);
494 return mGnssConfig;
495 }
496
injectBestLocation(const GnssLocation & gnssLocation)497 Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
498 ENTRY_LOG_CALLFLOW();
499 const GnssInterface* gnssInterface = getGnssInterface();
500 if (nullptr != gnssInterface) {
501 Location location = {};
502 convertGnssLocation(gnssLocation, location);
503 gnssInterface->odcpiInject(location);
504 }
505 return true;
506 }
507
odcpiRequestCb(const OdcpiRequestInfo & request)508 void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
509 ENTRY_LOG_CALLFLOW();
510
511 if (mGnssCbIface_2_0 != nullptr) {
512 // For emergency mode, request DBH (Device based hybrid) location
513 // Mark Independent from GNSS flag to false.
514 if (ODCPI_REQUEST_TYPE_START == request.type) {
515 LOC_LOGd("gnssRequestLocationCb_2_0 isUserEmergency = %d", request.isEmergencyMode);
516 auto r = mGnssCbIface_2_0->gnssRequestLocationCb_2_0(!request.isEmergencyMode,
517 request.isEmergencyMode);
518 if (!r.isOk()) {
519 LOC_LOGe("Error invoking gnssRequestLocationCb_2_0 %s", r.description().c_str());
520 }
521 } else {
522 LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
523 }
524 } else if (mGnssCbIface_1_1 != nullptr) {
525 // For emergency mode, request DBH (Device based hybrid) location
526 // Mark Independent from GNSS flag to false.
527 if (ODCPI_REQUEST_TYPE_START == request.type) {
528 auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
529 if (!r.isOk()) {
530 LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
531 }
532 } else {
533 LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
534 }
535 } else {
536 LOC_LOGe("ODCPI request not supported.");
537 }
538 }
539
540 // Methods from ::android::hardware::gnss::V2_0::IGnss follow.
setCallback_2_0(const sp<V2_0::IGnssCallback> & callback)541 Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
542 ENTRY_LOG_CALLFLOW();
543 auto r = callback->gnssNameCb(getVersionString());
544 if (!r.isOk()) {
545 LOC_LOGE("%s] Error from gnssNameCb description=%s",
546 __func__, r.description().c_str());
547 }
548
549 // In case where previous call to setCallback or setCallback_1_1, then
550 // we need to cleanup these interfaces/callbacks here since we no longer
551 // do so in cleanup() function to keep callbacks around after cleanup()
552 if (mApi != nullptr) {
553 mApi->gnssUpdateCallbacks(nullptr, nullptr);
554 }
555 mGnssNiCbIface = nullptr;
556 if (mGnssCbIface != nullptr) {
557 mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
558 mGnssCbIface = nullptr;
559 }
560 if (mGnssCbIface_1_1 != nullptr) {
561 mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
562 mGnssCbIface_1_1 = nullptr;
563 }
564
565 if (mGnssCbIface_2_0 != nullptr) {
566 mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
567 }
568 mGnssCbIface_2_0 = callback;
569 if (mGnssCbIface_2_0 != nullptr) {
570 mGnssCbIface_2_0->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
571 }
572
573 const GnssInterface* gnssInterface = getGnssInterface();
574 if (nullptr != gnssInterface) {
575 OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
576 odcpiRequestCb(odcpiRequest);
577 };
578 gnssInterface->odcpiInit(cb);
579 }
580
581 GnssAPIClient* api = getApi();
582 if (api != nullptr) {
583 api->gnssUpdateCallbacks_2_0(mGnssCbIface_2_0);
584 api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
585 api->requestCapabilities();
586 }
587
588 return true;
589 }
590
getExtensionAGnss_2_0()591 Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
592 ENTRY_LOG_CALLFLOW();
593 if (mAGnssIface_2_0 == nullptr) {
594 mAGnssIface_2_0 = new AGnss(this);
595 }
596 return mAGnssIface_2_0;
597 }
getExtensionAGnssRil_2_0()598 Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
599 if (mGnssRil == nullptr) {
600 mGnssRil = new AGnssRil(this);
601 }
602 return mGnssRil;
603 }
604
getExtensionGnssConfiguration_2_0()605 Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
606 ENTRY_LOG_CALLFLOW();
607 if (mGnssConfig == nullptr) {
608 mGnssConfig = new GnssConfiguration(this);
609 }
610 return mGnssConfig;
611 }
getExtensionGnssMeasurement_2_0()612 Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
613 ENTRY_LOG_CALLFLOW();
614 #ifdef GNSS_HIDL_LEGACY_MEASURMENTS
615 return nullptr;
616 #else
617 if (mGnssMeasurement == nullptr)
618 mGnssMeasurement = new GnssMeasurement();
619 return mGnssMeasurement;
620 #endif
621 }
622 Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
getExtensionMeasurementCorrections()623 Gnss::getExtensionMeasurementCorrections() {
624 // We do not support, so return nullptr to pass VTS
625 return nullptr;
626 }
627 Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
getExtensionVisibilityControl()628 Gnss::getExtensionVisibilityControl() {
629 ENTRY_LOG_CALLFLOW();
630 if (mVisibCtrl == nullptr) {
631 mVisibCtrl = new GnssVisibilityControl(this);
632 }
633 return mVisibCtrl;
634 }
635
injectBestLocation_2_0(const V2_0::GnssLocation & gnssLocation)636 Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation& gnssLocation) {
637 ENTRY_LOG_CALLFLOW();
638 const GnssInterface* gnssInterface = getGnssInterface();
639 if (nullptr != gnssInterface) {
640 Location location = {};
641 convertGnssLocation(gnssLocation, location);
642 gnssInterface->odcpiInject(location);
643 }
644 return true;
645 }
646
getExtensionGnssDebug_2_0()647 Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
648 ENTRY_LOG_CALLFLOW();
649 if (mGnssDebug == nullptr) {
650 mGnssDebug = new GnssDebug(this);
651 }
652 return mGnssDebug;
653 }
654
getExtensionGnssBatching_2_0()655 Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
656 ENTRY_LOG_CALLFLOW();
657 if (mGnssBatching == nullptr) {
658 mGnssBatching = new GnssBatching();
659 }
660 return mGnssBatching;
661 }
662
HIDL_FETCH_IGnss(const char * hal)663 V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
664 ENTRY_LOG_CALLFLOW();
665 V1_0::IGnss* iface = nullptr;
666 iface = new Gnss();
667 if (iface == nullptr) {
668 LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
669 }
670 return iface;
671 }
672
673 } // namespace implementation
674 } // namespace V2_0
675 } // namespace gnss
676 } // namespace hardware
677 } // namespace android
678