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