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