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