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