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 #include "battery_listener.h"
31 #include "loc_misc_utils.h"
32 
33 typedef const GnssInterface* (getLocationInterface)();
34 
35 namespace android {
36 namespace hardware {
37 namespace gnss {
38 namespace V1_0 {
39 namespace implementation {
40 
41 static sp<Gnss> sGnss;
serviceDied(uint64_t cookie,const wp<IBase> & who)42 void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
43     LOC_LOGE("%s] service died. cookie: %llu, who: %p",
44             __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
45     if (mGnss != nullptr) {
46         mGnss->stop();
47         mGnss->cleanup();
48     }
49 }
50 
location_on_battery_status_changed(bool charging)51 void location_on_battery_status_changed(bool charging) {
52     LOC_LOGd("battery status changed to %s charging", charging ? "" : "not ");
53     if (sGnss != nullptr) {
54         sGnss->getGnssInterface()->updateBatteryStatus(charging);
55     }
56 }
Gnss()57 Gnss::Gnss() {
58     ENTRY_LOG_CALLFLOW();
59     sGnss = this;
60     // initilize gnss interface at first in case needing notify battery status
61     sGnss->getGnssInterface()->initialize();
62     // register health client to listen on battery change
63     loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
64     // clear pending GnssConfig
65     memset(&mPendingConfig, 0, sizeof(GnssConfig));
66 
67     mGnssDeathRecipient = new GnssDeathRecipient(this);
68 }
69 
~Gnss()70 Gnss::~Gnss() {
71     ENTRY_LOG_CALLFLOW();
72     if (mApi != nullptr) {
73         delete mApi;
74         mApi = nullptr;
75     }
76     sGnss = nullptr;
77 }
78 
getApi()79 GnssAPIClient* Gnss::getApi() {
80     if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
81         mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
82         if (mApi == nullptr) {
83             LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
84             return mApi;
85         }
86 
87         if (mPendingConfig.size == sizeof(GnssConfig)) {
88             // we have pending GnssConfig
89             mApi->gnssConfigurationUpdate(mPendingConfig);
90             // clear size to invalid mPendingConfig
91             mPendingConfig.size = 0;
92             if (mPendingConfig.assistanceServer.hostName != nullptr) {
93                 free((void*)mPendingConfig.assistanceServer.hostName);
94             }
95         }
96     }
97     if (mApi == nullptr) {
98         LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
99     }
100     return mApi;
101 }
102 
getGnssInterface()103 const GnssInterface* Gnss::getGnssInterface() {
104     static bool getGnssInterfaceFailed = false;
105     if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
106         void * libHandle = nullptr;
107         getLocationInterface* getter = (getLocationInterface*)
108                 dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
109 
110         if (nullptr == getter) {
111             getGnssInterfaceFailed = true;
112         } else {
113             mGnssInterface = (GnssInterface*)(*getter)();
114         }
115     }
116     return mGnssInterface;
117 }
118 
setCallback(const sp<V1_0::IGnssCallback> & callback)119 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback)  {
120     ENTRY_LOG_CALLFLOW();
121     if (mGnssCbIface != nullptr) {
122         mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
123     }
124     mGnssCbIface = callback;
125     if (mGnssCbIface != nullptr) {
126         mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
127     }
128 
129     GnssAPIClient* api = getApi();
130     if (api != nullptr) {
131         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
132         api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
133         api->requestCapabilities();
134     }
135     return true;
136 }
137 
setGnssNiCb(const sp<IGnssNiCallback> & callback)138 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
139     ENTRY_LOG_CALLFLOW();
140     mGnssNiCbIface = callback;
141     GnssAPIClient* api = getApi();
142     if (api != nullptr) {
143         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
144     }
145     return true;
146 }
147 
updateConfiguration(GnssConfig & gnssConfig)148 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
149     ENTRY_LOG_CALLFLOW();
150     GnssAPIClient* api = getApi();
151     if (api) {
152         api->gnssConfigurationUpdate(gnssConfig);
153     } else if (gnssConfig.flags != 0) {
154         // api is not ready yet, update mPendingConfig with gnssConfig
155         mPendingConfig.size = sizeof(GnssConfig);
156 
157         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
158             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
159             mPendingConfig.gpsLock = gnssConfig.gpsLock;
160         }
161         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
162             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
163             mPendingConfig.suplVersion = gnssConfig.suplVersion;
164         }
165         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
166             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
167             mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
168             mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
169             if (mPendingConfig.assistanceServer.hostName != nullptr) {
170                 free((void*)mPendingConfig.assistanceServer.hostName);
171                 mPendingConfig.assistanceServer.hostName =
172                     strdup(gnssConfig.assistanceServer.hostName);
173             }
174             mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
175         }
176         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
177             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
178             mPendingConfig.lppProfile = gnssConfig.lppProfile;
179         }
180         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
181             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
182             mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
183         }
184         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
185             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
186             mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
187         }
188         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
189             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
190             mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
191         }
192         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
193             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
194             mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
195         }
196         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
197             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
198             mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
199         }
200         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
201             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
202             mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
203         }
204         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
205             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
206             mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
207         }
208     }
209     return true;
210 }
211 
start()212 Return<bool> Gnss::start()  {
213     ENTRY_LOG_CALLFLOW();
214     bool retVal = false;
215     GnssAPIClient* api = getApi();
216     if (api) {
217         retVal = api->gnssStart();
218     }
219     return retVal;
220 }
221 
stop()222 Return<bool> Gnss::stop()  {
223     ENTRY_LOG_CALLFLOW();
224     bool retVal = false;
225     GnssAPIClient* api = getApi();
226     if (api) {
227         retVal = api->gnssStop();
228     }
229     return retVal;
230 }
231 
cleanup()232 Return<void> Gnss::cleanup()  {
233     ENTRY_LOG_CALLFLOW();
234 
235     if (mApi != nullptr) {
236         mApi->gnssDisable();
237     }
238 
239     return Void();
240 }
241 
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)242 Return<bool> Gnss::injectLocation(double latitudeDegrees,
243                                   double longitudeDegrees,
244                                   float accuracyMeters)  {
245     ENTRY_LOG_CALLFLOW();
246     const GnssInterface* gnssInterface = getGnssInterface();
247     if (nullptr != gnssInterface) {
248         gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
249         return true;
250     } else {
251         return false;
252     }
253 }
254 
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)255 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
256                               int32_t uncertaintyMs) {
257     return true;
258 }
259 
deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)260 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)  {
261     ENTRY_LOG_CALLFLOW();
262     GnssAPIClient* api = getApi();
263     if (api) {
264         api->gnssDeleteAidingData(aidingDataFlags);
265     }
266     return Void();
267 }
268 
setPositionMode(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)269 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
270                                    V1_0::IGnss::GnssPositionRecurrence recurrence,
271                                    uint32_t minIntervalMs,
272                                    uint32_t preferredAccuracyMeters,
273                                    uint32_t preferredTimeMs)  {
274     ENTRY_LOG_CALLFLOW();
275     bool retVal = false;
276     GnssAPIClient* api = getApi();
277     if (api) {
278         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
279                 preferredAccuracyMeters, preferredTimeMs);
280     }
281     return retVal;
282 }
283 
getExtensionAGnss()284 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss()  {
285     ENTRY_LOG_CALLFLOW();
286     mAGnssIface = new AGnss(this);
287     return mAGnssIface;
288 }
289 
getExtensionGnssNi()290 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
291     ENTRY_LOG_CALLFLOW();
292     mGnssNi = new GnssNi(this);
293     return mGnssNi;
294 }
295 
getExtensionGnssMeasurement()296 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
297     ENTRY_LOG_CALLFLOW();
298     if (mGnssMeasurement == nullptr)
299         mGnssMeasurement = new GnssMeasurement();
300     return mGnssMeasurement;
301 }
302 
getExtensionGnssConfiguration()303 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
304     ENTRY_LOG_CALLFLOW();
305     mGnssConfig = new GnssConfiguration(this);
306     return mGnssConfig;
307 }
308 
getExtensionGnssGeofencing()309 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
310     ENTRY_LOG_CALLFLOW();
311     mGnssGeofencingIface = new GnssGeofencing();
312     return mGnssGeofencingIface;
313 }
314 
getExtensionGnssBatching()315 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching()  {
316     mGnssBatching = new GnssBatching();
317     return mGnssBatching;
318 }
319 
getExtensionGnssDebug()320 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
321     ENTRY_LOG_CALLFLOW();
322     mGnssDebug = new GnssDebug(this);
323     return mGnssDebug;
324 }
325 
getExtensionAGnssRil()326 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
327     mGnssRil = new AGnssRil(this);
328     return mGnssRil;
329 }
330 
HIDL_FETCH_IGnss(const char * hal)331 IGnss* HIDL_FETCH_IGnss(const char* hal) {
332     ENTRY_LOG_CALLFLOW();
333     IGnss* iface = nullptr;
334     iface = new Gnss();
335     if (iface == nullptr) {
336         LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
337     }
338     return iface;
339 }
340 
341 }  // namespace implementation
342 }  // namespace V1_0
343 }  // namespace gnss
344 }  // namespace hardware
345 }  // namespace android
346