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