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