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