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