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