• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 #include "battery_listener.h"
32 #include "loc_misc_utils.h"
33 
34 typedef const GnssInterface* (getLocationInterface)();
35 
36 #define IMAGES_INFO_FILE "/sys/devices/soc0/images"
37 #define DELIMITER ";"
38 
39 namespace android {
40 namespace hardware {
41 namespace gnss {
42 namespace V1_1 {
43 namespace implementation {
44 
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->getGnssInterface()->resetNetworkInfo();
88         mGnss->stop();
89         mGnss->cleanup();
90     }
91 }
92 
location_on_battery_status_changed(bool charging)93 void location_on_battery_status_changed(bool charging) {
94     LOC_LOGd("battery status changed to %s charging", charging ? "" : "not");
95     if (sGnss != nullptr) {
96         sGnss->getGnssInterface()->updateBatteryStatus(charging);
97     }
98 }
Gnss()99 Gnss::Gnss() {
100     ENTRY_LOG_CALLFLOW();
101     sGnss = this;
102     // initilize gnss interface at first in case needing notify battery status
103     sGnss->getGnssInterface()->initialize();
104     // register health client to listen on battery change
105     loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
106     // clear pending GnssConfig
107     memset(&mPendingConfig, 0, sizeof(GnssConfig));
108 
109     mGnssDeathRecipient = new GnssDeathRecipient(this);
110 }
111 
~Gnss()112 Gnss::~Gnss() {
113     ENTRY_LOG_CALLFLOW();
114     if (mApi != nullptr) {
115         mApi->destroy();
116         mApi = nullptr;
117     }
118     sGnss = nullptr;
119 }
120 
getApi()121 GnssAPIClient* Gnss::getApi() {
122     if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
123         mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
124         if (mApi == nullptr) {
125             LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
126             return mApi;
127         }
128 
129         if (mPendingConfig.size == sizeof(GnssConfig)) {
130             // we have pending GnssConfig
131             mApi->gnssConfigurationUpdate(mPendingConfig);
132             // clear size to invalid mPendingConfig
133             mPendingConfig.size = 0;
134             if (mPendingConfig.assistanceServer.hostName != nullptr) {
135                 free((void*)mPendingConfig.assistanceServer.hostName);
136             }
137         }
138     }
139     if (mApi == nullptr) {
140         LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
141     }
142     return mApi;
143 }
144 
getGnssInterface()145 const GnssInterface* Gnss::getGnssInterface() {
146     static bool getGnssInterfaceFailed = false;
147     if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
148         void * libHandle = nullptr;
149         getLocationInterface* getter = (getLocationInterface*)
150                 dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
151 
152         if (nullptr == getter) {
153             getGnssInterfaceFailed = true;
154         } else {
155             mGnssInterface = (const GnssInterface*)(*getter)();
156         }
157     }
158     return mGnssInterface;
159 }
160 
setCallback(const sp<V1_0::IGnssCallback> & callback)161 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback)  {
162     ENTRY_LOG_CALLFLOW();
163     if (mGnssCbIface != nullptr) {
164         mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
165     }
166     mGnssCbIface = callback;
167     if (mGnssCbIface != nullptr) {
168         mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
169     }
170 
171     GnssAPIClient* api = getApi();
172     if (api != nullptr) {
173         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
174         api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
175         api->requestCapabilities();
176     }
177     return true;
178 }
179 
setGnssNiCb(const sp<IGnssNiCallback> & callback)180 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
181     ENTRY_LOG_CALLFLOW();
182     mGnssNiCbIface = callback;
183     GnssAPIClient* api = getApi();
184     if (api != nullptr) {
185         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
186     }
187     return true;
188 }
189 
updateConfiguration(GnssConfig & gnssConfig)190 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
191     ENTRY_LOG_CALLFLOW();
192     GnssAPIClient* api = getApi();
193     if (api) {
194         api->gnssConfigurationUpdate(gnssConfig);
195     } else if (gnssConfig.flags != 0) {
196         // api is not ready yet, update mPendingConfig with gnssConfig
197         mPendingConfig.size = sizeof(GnssConfig);
198 
199         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
200             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
201             mPendingConfig.gpsLock = gnssConfig.gpsLock;
202         }
203         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
204             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
205             mPendingConfig.suplVersion = gnssConfig.suplVersion;
206         }
207         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
208             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
209             mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
210             mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
211             if (mPendingConfig.assistanceServer.hostName != nullptr) {
212                 free((void*)mPendingConfig.assistanceServer.hostName);
213                 mPendingConfig.assistanceServer.hostName =
214                     strdup(gnssConfig.assistanceServer.hostName);
215             }
216             mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
217         }
218         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
219             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
220             mPendingConfig.lppProfileMask = gnssConfig.lppProfileMask;
221         }
222         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
223             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
224             mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
225         }
226         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
227             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
228             mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
229         }
230         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
231             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
232             mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
233         }
234         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
235             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
236             mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
237         }
238         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
239             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
240             mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
241         }
242         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
243             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
244             mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
245         }
246         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
247             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
248             mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
249         }
250     }
251     return true;
252 }
253 
start()254 Return<bool> Gnss::start()  {
255     ENTRY_LOG_CALLFLOW();
256     bool retVal = false;
257     GnssAPIClient* api = getApi();
258     if (api) {
259         retVal = api->gnssStart();
260     }
261     return retVal;
262 }
263 
stop()264 Return<bool> Gnss::stop()  {
265     ENTRY_LOG_CALLFLOW();
266     bool retVal = false;
267     GnssAPIClient* api = getApi();
268     if (api) {
269         retVal = api->gnssStop();
270     }
271     return retVal;
272 }
273 
cleanup()274 Return<void> Gnss::cleanup()  {
275     ENTRY_LOG_CALLFLOW();
276 
277     if (mApi != nullptr) {
278         mApi->gnssDisable();
279     }
280 
281     return Void();
282 }
283 
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)284 Return<bool> Gnss::injectLocation(double latitudeDegrees,
285                                   double longitudeDegrees,
286                                   float accuracyMeters)  {
287     ENTRY_LOG_CALLFLOW();
288     const GnssInterface* gnssInterface = getGnssInterface();
289     if (nullptr != gnssInterface) {
290         gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
291         return true;
292     } else {
293         return false;
294     }
295 }
296 
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)297 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
298                               int32_t uncertaintyMs) {
299     return true;
300 }
301 
deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)302 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)  {
303     ENTRY_LOG_CALLFLOW();
304     GnssAPIClient* api = getApi();
305     if (api) {
306         api->gnssDeleteAidingData(aidingDataFlags);
307     }
308     return Void();
309 }
310 
setPositionMode(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)311 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
312                                    V1_0::IGnss::GnssPositionRecurrence recurrence,
313                                    uint32_t minIntervalMs,
314                                    uint32_t preferredAccuracyMeters,
315                                    uint32_t preferredTimeMs)  {
316     ENTRY_LOG_CALLFLOW();
317     bool retVal = false;
318     GnssAPIClient* api = getApi();
319     if (api) {
320         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
321                 preferredAccuracyMeters, preferredTimeMs);
322     }
323     return retVal;
324 }
325 
getExtensionAGnss()326 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss()  {
327     ENTRY_LOG_CALLFLOW();
328     mAGnssIface = new AGnss(this);
329     return mAGnssIface;
330 }
331 
getExtensionGnssNi()332 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
333     ENTRY_LOG_CALLFLOW();
334     mGnssNi = new GnssNi(this);
335     return mGnssNi;
336 }
337 
getExtensionGnssMeasurement()338 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
339     ENTRY_LOG_CALLFLOW();
340     if (mGnssMeasurement == nullptr)
341         mGnssMeasurement = new GnssMeasurement();
342     return mGnssMeasurement;
343 }
344 
getExtensionGnssConfiguration()345 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
346     ENTRY_LOG_CALLFLOW();
347     mGnssConfig = new GnssConfiguration(this);
348     return mGnssConfig;
349 }
350 
getExtensionGnssGeofencing()351 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
352     ENTRY_LOG_CALLFLOW();
353     mGnssGeofencingIface = new GnssGeofencing();
354     return mGnssGeofencingIface;
355 }
356 
getExtensionGnssBatching()357 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching()  {
358     mGnssBatching = new GnssBatching();
359     return mGnssBatching;
360 }
361 
getExtensionGnssDebug()362 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
363     ENTRY_LOG_CALLFLOW();
364     mGnssDebug = new GnssDebug(this);
365     return mGnssDebug;
366 }
367 
getExtensionAGnssRil()368 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
369     mGnssRil = new AGnssRil(this);
370     return mGnssRil;
371 }
372 
373 // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
setCallback_1_1(const sp<V1_1::IGnssCallback> & callback)374 Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
375     ENTRY_LOG_CALLFLOW();
376     callback->gnssNameCb(getVersionString());
377     mGnssCbIface_1_1 = callback;
378     const GnssInterface* gnssInterface = getGnssInterface();
379     if (nullptr != gnssInterface) {
380         OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
381             odcpiRequestCb(odcpiRequest);
382         };
383         gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
384     }
385     return setCallback(callback);
386 }
387 
setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs,bool lowPowerMode)388 Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
389         V1_0::IGnss::GnssPositionRecurrence recurrence,
390         uint32_t minIntervalMs,
391         uint32_t preferredAccuracyMeters,
392         uint32_t preferredTimeMs,
393         bool lowPowerMode) {
394     ENTRY_LOG_CALLFLOW();
395     bool retVal = false;
396     GnssAPIClient* api = getApi();
397     if (api) {
398         GnssPowerMode powerMode = lowPowerMode?
399                 GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
400         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
401                 preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
402     }
403     return retVal;
404 }
405 
getExtensionGnssMeasurement_1_1()406 Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
407     ENTRY_LOG_CALLFLOW();
408     if (mGnssMeasurement == nullptr)
409         mGnssMeasurement = new GnssMeasurement();
410     return mGnssMeasurement;
411 }
412 
getExtensionGnssConfiguration_1_1()413 Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
414     ENTRY_LOG_CALLFLOW();
415     if (mGnssConfig == nullptr)
416         mGnssConfig = new GnssConfiguration(this);
417     return mGnssConfig;
418 }
419 
injectBestLocation(const GnssLocation & gnssLocation)420 Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
421     ENTRY_LOG_CALLFLOW();
422     const GnssInterface* gnssInterface = getGnssInterface();
423     if (nullptr != gnssInterface) {
424         Location location = {};
425         convertGnssLocation(gnssLocation, location);
426         gnssInterface->odcpiInject(location);
427     }
428     return true;
429 }
430 
odcpiRequestCb(const OdcpiRequestInfo & request)431 void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
432     ENTRY_LOG_CALLFLOW();
433     if (ODCPI_REQUEST_TYPE_STOP == request.type) {
434         return;
435     }
436     if (mGnssCbIface_1_1 != nullptr) {
437         // For emergency mode, request DBH (Device based hybrid) location
438         // Mark Independent from GNSS flag to false.
439         if (ODCPI_REQUEST_TYPE_START == request.type) {
440             auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
441             if (!r.isOk()) {
442                 LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
443             }
444         } else {
445             LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
446         }
447     } else {
448         LOC_LOGe("ODCPI request not supported.");
449     }
450 }
451 
HIDL_FETCH_IGnss(const char * hal)452 V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
453     ENTRY_LOG_CALLFLOW();
454     V1_0::IGnss* iface = nullptr;
455     iface = new Gnss();
456     if (iface == nullptr) {
457         LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
458     }
459     return iface;
460 }
461 
462 }  // namespace implementation
463 }  // namespace V1_1
464 }  // namespace gnss
465 }  // namespace hardware
466 }  // namespace android
467