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