blob: d4a86c2d85bdc37418bc49d06758a12ff42550e6 [file] [log] [blame]
Joe Huangbeff69e2021-02-24 18:05:40 +08001/* Copyright (c) 2017, 2020-2021 The Linux Foundation. All rights reserved.
Dante Russoc85c8ff2017-02-28 16:45:47 -08002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
Joe Huang4f6e3c62023-05-29 21:29:58 +080029/* ​​​​​Changes from Qualcomm Innovation Center are provided under the following license:
30 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
31 * SPDX-License-Identifier: BSD-3-Clause-Clear
32 */
33
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +053034#define LOG_NDEBUG 0
Dante Russoc85c8ff2017-02-28 16:45:47 -080035#define LOG_TAG "LocSvc_APIClientBase"
36
Kevin Tang61de97e2016-09-12 17:20:55 -070037#include <loc_pla.h>
38#include <log_util.h>
Baili Feng4c9c7832017-07-03 21:00:31 +080039#include <inttypes.h>
Dante Russoc85c8ff2017-02-28 16:45:47 -080040#include <loc_cfg.h>
41#include "LocationAPIClientBase.h"
42
Baili Fengc0a300c2017-06-13 15:26:57 +080043#define GEOFENCE_SESSION_ID 0xFFFFFFFF
44#define CONFIG_SESSION_ID 0xFFFFFFFF
Dante Russoc85c8ff2017-02-28 16:45:47 -080045
Baili Feng1a128bd2017-06-21 17:46:23 +080046// LocationAPIControlClient
47LocationAPIControlClient::LocationAPIControlClient() :
48 mEnabled(false)
49{
50 pthread_mutex_init(&mMutex, nullptr);
51
52 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +053053 mRequestQueues[i].reset((uint32_t)0);
Baili Feng1a128bd2017-06-21 17:46:23 +080054 }
55
56 memset(&mConfig, 0, sizeof(GnssConfig));
57
58 LocationControlCallbacks locationControlCallbacks;
59 locationControlCallbacks.size = sizeof(LocationControlCallbacks);
60
61 locationControlCallbacks.responseCb =
62 [this](LocationError error, uint32_t id) {
63 onCtrlResponseCb(error, id);
64 };
65 locationControlCallbacks.collectiveResponseCb =
66 [this](size_t count, LocationError* errors, uint32_t* ids) {
67 onCtrlCollectiveResponseCb(count, errors, ids);
68 };
69
70 mLocationControlAPI = LocationControlAPI::createInstance(locationControlCallbacks);
71}
72
73LocationAPIControlClient::~LocationAPIControlClient()
74{
75 pthread_mutex_lock(&mMutex);
76
77 if (mLocationControlAPI) {
78 mLocationControlAPI->destroy();
79 mLocationControlAPI = nullptr;
80 }
81
82 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +053083 mRequestQueues[i].reset((uint32_t)0);
Baili Feng1a128bd2017-06-21 17:46:23 +080084 }
85
86 pthread_mutex_unlock(&mMutex);
87
88 pthread_mutex_destroy(&mMutex);
89}
90
91uint32_t LocationAPIControlClient::locAPIGnssDeleteAidingData(GnssAidingData& data)
92{
93 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
94 pthread_mutex_lock(&mMutex);
95 if (mLocationControlAPI) {
96 uint32_t session = mLocationControlAPI->gnssDeleteAidingData(data);
97 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
98 mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].reset(session);
99 mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].push(new GnssDeleteAidingDataRequest(*this));
100
101 retVal = LOCATION_ERROR_SUCCESS;
102 }
103 pthread_mutex_unlock(&mMutex);
104
105 return retVal;
106}
107
108uint32_t LocationAPIControlClient::locAPIEnable(LocationTechnologyType techType)
109{
110 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
111 pthread_mutex_lock(&mMutex);
112 if (mEnabled) {
113 // just return success if already enabled
114 retVal = LOCATION_ERROR_SUCCESS;
115 } else if (mLocationControlAPI) {
116 uint32_t session = mLocationControlAPI->enable(techType);
117 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
118 mRequestQueues[CTRL_REQUEST_CONTROL].reset(session);
119 mRequestQueues[CTRL_REQUEST_CONTROL].push(new EnableRequest(*this));
120 retVal = LOCATION_ERROR_SUCCESS;
121 mEnabled = true;
122 } else {
123 LOC_LOGE("%s:%d] failed.", __FUNCTION__, __LINE__);
124 }
125 pthread_mutex_unlock(&mMutex);
126
127 return retVal;
128}
129
130void LocationAPIControlClient::locAPIDisable()
131{
132 pthread_mutex_lock(&mMutex);
133 if (mEnabled && mLocationControlAPI) {
134 uint32_t session = 0;
135 session = mRequestQueues[CTRL_REQUEST_CONTROL].getSession();
136 if (session > 0) {
137 mRequestQueues[CTRL_REQUEST_CONTROL].push(new DisableRequest(*this));
138 mLocationControlAPI->disable(session);
139 mEnabled = false;
140 } else {
141 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
142 }
143 }
144 pthread_mutex_unlock(&mMutex);
145}
146
147uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
148{
149 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530150
151 pthread_mutex_lock(&mMutex);
152 if (mLocationControlAPI) {
153 if (mConfig.equals(config)) {
154 LOC_LOGv("GnssConfig is identical to previous call");
155 retVal = LOCATION_ERROR_SUCCESS;
156 } else {
157 mConfig = config;
158 uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
159 LOC_LOGv("gnssUpdateConfig return array: %p", idArray);
160 if (nullptr != idArray) {
161 if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr()) {
162 mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].reset(idArray);
163 }
164 mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this));
165 retVal = LOCATION_ERROR_SUCCESS;
Wei (GPS SD) Chen993aed92020-09-22 14:31:22 -0700166 delete [] idArray;
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530167 }
168 }
Baili Feng1a128bd2017-06-21 17:46:23 +0800169 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530170 pthread_mutex_unlock(&mMutex);
171 return retVal;
172}
173
174uint32_t LocationAPIControlClient::locAPIGnssGetConfig(GnssConfigFlagsMask mask)
175{
176 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Feng1a128bd2017-06-21 17:46:23 +0800177
178 pthread_mutex_lock(&mMutex);
179 if (mLocationControlAPI) {
180
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530181 uint32_t* idArray = mLocationControlAPI->gnssGetConfig(mask);
182 LOC_LOGv("gnssGetConfig return array: %p", idArray);
183 if (nullptr != idArray) {
184 if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr()) {
185 mRequestQueues[CTRL_REQUEST_CONFIG_GET].reset(idArray);
Baili Feng1a128bd2017-06-21 17:46:23 +0800186 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530187 mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this));
Baili Feng1a128bd2017-06-21 17:46:23 +0800188 retVal = LOCATION_ERROR_SUCCESS;
Wei (GPS SD) Chen993aed92020-09-22 14:31:22 -0700189 delete [] idArray;
Baili Feng1a128bd2017-06-21 17:46:23 +0800190 }
191 }
192 pthread_mutex_unlock(&mMutex);
193 return retVal;
194}
195
196void LocationAPIControlClient::onCtrlResponseCb(LocationError error, uint32_t id)
197{
198 if (error != LOCATION_ERROR_SUCCESS) {
199 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
200 } else {
201 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
202 }
203 LocationAPIRequest* request = getRequestBySession(id);
204 if (request) {
Baili Feng2df685d2017-07-20 17:02:26 +0800205 request->onResponse(error, id);
Baili Feng1a128bd2017-06-21 17:46:23 +0800206 delete request;
207 }
208}
209
210void LocationAPIControlClient::onCtrlCollectiveResponseCb(
211 size_t count, LocationError* errors, uint32_t* ids)
212{
213 for (size_t i = 0; i < count; i++) {
214 if (errors[i] != LOCATION_ERROR_SUCCESS) {
215 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
216 } else {
217 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
218 }
219 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530220 LocationAPIRequest* request = getRequestBySessionArrayPtr(ids);
Baili Feng1a128bd2017-06-21 17:46:23 +0800221 if (request) {
222 request->onCollectiveResponse(count, errors, ids);
223 delete request;
224 }
225}
226
227LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t session)
228{
229 pthread_mutex_lock(&mMutex);
230 LocationAPIRequest* request = nullptr;
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530231
232 if (mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].getSession() == session) {
233 request = mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].pop();
234 } else if (mRequestQueues[CTRL_REQUEST_CONTROL].getSession() == session) {
235 request = mRequestQueues[CTRL_REQUEST_CONTROL].pop();
Baili Feng1a128bd2017-06-21 17:46:23 +0800236 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530237
238 pthread_mutex_unlock(&mMutex);
239 return request;
240}
241
242LocationAPIRequest*
243LocationAPIControlClient::getRequestBySessionArrayPtr(
244 uint32_t* sessionArrayPtr)
245{
246 pthread_mutex_lock(&mMutex);
247 LocationAPIRequest* request = nullptr;
248
249 if (mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr() == sessionArrayPtr) {
250 request = mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].pop();
251 } else if (mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr() == sessionArrayPtr) {
252 request = mRequestQueues[CTRL_REQUEST_CONFIG_GET].pop();
253 }
254
Baili Feng1a128bd2017-06-21 17:46:23 +0800255 pthread_mutex_unlock(&mMutex);
256 return request;
257}
258
259// LocationAPIClientBase
Dante Russoc85c8ff2017-02-28 16:45:47 -0800260LocationAPIClientBase::LocationAPIClientBase() :
Dante Russoc85c8ff2017-02-28 16:45:47 -0800261 mGeofenceBreachCallback(nullptr),
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700262 mBatchingStatusCallback(nullptr),
Dante Russoc85c8ff2017-02-28 16:45:47 -0800263 mLocationAPI(nullptr),
Dante Russoc1da12a2017-07-27 10:44:54 -0700264 mBatchSize(-1),
265 mTracking(false)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800266{
267
268 // use recursive mutex, in case callback come from the same thread
269 pthread_mutexattr_t attr;
270 pthread_mutexattr_init(&attr);
271 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
272 pthread_mutex_init(&mMutex, &attr);
273
274 for (int i = 0; i < REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530275 mRequestQueues[i].reset((uint32_t)0);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800276 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800277}
278
279void LocationAPIClientBase::locAPISetCallbacks(LocationCallbacks& locationCallbacks)
280{
Baili Fengb29778e2017-05-23 14:32:22 +0800281 pthread_mutex_lock(&mMutex);
282
Dante Russoc85c8ff2017-02-28 16:45:47 -0800283 if (locationCallbacks.geofenceBreachCb != nullptr) {
284 mGeofenceBreachCallback = locationCallbacks.geofenceBreachCb;
285 locationCallbacks.geofenceBreachCb =
286 [this](GeofenceBreachNotification geofenceBreachNotification) {
287 beforeGeofenceBreachCb(geofenceBreachNotification);
288 };
289 }
290
291 locationCallbacks.capabilitiesCb =
292 [this](LocationCapabilitiesMask capabilitiesMask) {
293 onCapabilitiesCb(capabilitiesMask);
294 };
295 locationCallbacks.responseCb = [this](LocationError error, uint32_t id) {
296 onResponseCb(error, id);
297 };
298 locationCallbacks.collectiveResponseCb =
299 [this](size_t count, LocationError* errors, uint32_t* ids) {
300 onCollectiveResponseCb(count, errors, ids);
301 };
302
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700303 if (locationCallbacks.batchingStatusCb != nullptr) {
304 mBatchingStatusCallback = locationCallbacks.batchingStatusCb;
305 locationCallbacks.batchingStatusCb =
306 [this](BatchingStatusInfo batchStatus, std::list<uint32_t> & tripCompletedList) {
307 beforeBatchingStatusCb(batchStatus, tripCompletedList);
308 };
309 }
310
Dante Russoc85c8ff2017-02-28 16:45:47 -0800311 if (mLocationAPI == nullptr ) {
312 mLocationAPI = LocationAPI::createInstance(locationCallbacks);
313 } else {
314 mLocationAPI->updateCallbacks(locationCallbacks);
315 }
316
Baili Fengb29778e2017-05-23 14:32:22 +0800317 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800318}
319
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530320void LocationAPIClientBase::destroy()
Dante Russoc85c8ff2017-02-28 16:45:47 -0800321{
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530322 LOC_LOGD("LocationAPIClientBase::destroy()");
323
Baili Fengb29778e2017-05-23 14:32:22 +0800324 pthread_mutex_lock(&mMutex);
325
Baili Fengc0a300c2017-06-13 15:26:57 +0800326 mGeofenceBreachCallback = nullptr;
327
Dante Russoc85c8ff2017-02-28 16:45:47 -0800328 for (int i = 0; i < REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530329 mRequestQueues[i].reset((uint32_t)0);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800330 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800331
Saurabh Srivastava624c2722020-08-24 15:58:41 +0530332 LocationAPI* localHandle = nullptr;
333 if (nullptr != mLocationAPI) {
334 localHandle = mLocationAPI;
335 mLocationAPI = nullptr;
336 }
337
Dante Russoc85c8ff2017-02-28 16:45:47 -0800338 pthread_mutex_unlock(&mMutex);
339
Saurabh Srivastava624c2722020-08-24 15:58:41 +0530340 // Invoking destroy has the possibility of destroy complete callback
341 // being invoked right away in the same context, hence no instance
342 // member must be accessed after the destroy call.
343 if (nullptr != localHandle) {
344 localHandle->destroy([this]() {onLocationApiDestroyCompleteCb();});
345 }
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530346}
Dante Russoc85c8ff2017-02-28 16:45:47 -0800347
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530348LocationAPIClientBase::~LocationAPIClientBase()
349{
Dante Russoc85c8ff2017-02-28 16:45:47 -0800350 pthread_mutex_destroy(&mMutex);
351}
352
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530353void LocationAPIClientBase::onLocationApiDestroyCompleteCb()
354{
355 LOC_LOGD("LocationAPIClientBase::onLocationApiDestroyCompleteCb()");
356 delete this;
357}
358
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530359uint32_t LocationAPIClientBase::locAPIStartTracking(TrackingOptions& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800360{
361 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800362 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800363 if (mLocationAPI) {
Dante Russoc1da12a2017-07-27 10:44:54 -0700364 if (mTracking) {
Joe Huang4f6e3c62023-05-29 21:29:58 +0800365 pthread_mutex_unlock(&mMutex);
366 locAPIUpdateTrackingOptions(options);
Dante Russoc1da12a2017-07-27 10:44:54 -0700367 } else {
368 uint32_t session = mLocationAPI->startTracking(options);
369 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
370 // onResponseCb might be called from other thread immediately after
371 // startTracking returns, so we are not going to unlock mutex
372 // until StartTrackingRequest is pushed into mRequestQueues[REQUEST_TRACKING]
373 mRequestQueues[REQUEST_TRACKING].reset(session);
374 mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this));
375 mTracking = true;
Joe Huang4f6e3c62023-05-29 21:29:58 +0800376 pthread_mutex_unlock(&mMutex);
Dante Russoc1da12a2017-07-27 10:44:54 -0700377 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800378
379 retVal = LOCATION_ERROR_SUCCESS;
Joe Huang4f6e3c62023-05-29 21:29:58 +0800380 } else {
381 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800382 }
383
384 return retVal;
385}
386
387void LocationAPIClientBase::locAPIStopTracking()
388{
Baili Fengb29778e2017-05-23 14:32:22 +0800389 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800390 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800391 uint32_t session = 0;
Baili Fengc0a300c2017-06-13 15:26:57 +0800392 session = mRequestQueues[REQUEST_TRACKING].getSession();
393 if (session > 0) {
394 mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this));
395 mLocationAPI->stopTracking(session);
Dante Russoc1da12a2017-07-27 10:44:54 -0700396 mTracking = false;
Baili Fengc0a300c2017-06-13 15:26:57 +0800397 } else {
Dante Russo04db4be2019-05-29 17:59:00 -0700398 LOC_LOGD("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800399 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800400 }
Baili Fengb29778e2017-05-23 14:32:22 +0800401 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800402}
403
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530404void LocationAPIClientBase::locAPIUpdateTrackingOptions(TrackingOptions& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800405{
Baili Fengb29778e2017-05-23 14:32:22 +0800406 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800407 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800408 uint32_t session = 0;
Baili Fengc0a300c2017-06-13 15:26:57 +0800409 session = mRequestQueues[REQUEST_TRACKING].getSession();
410 if (session > 0) {
411 mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this));
412 mLocationAPI->updateTrackingOptions(session, options);
413 } else {
414 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800415 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800416 }
Baili Fengb29778e2017-05-23 14:32:22 +0800417 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800418}
419
420int32_t LocationAPIClientBase::locAPIGetBatchSize()
421{
422 if (mBatchSize == -1) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800423 const loc_param_s_type flp_conf_param_table[] =
Dante Russoc85c8ff2017-02-28 16:45:47 -0800424 {
425 {"BATCH_SIZE", &mBatchSize, nullptr, 'n'},
426 };
Dante Russo47d2e812018-03-16 11:50:05 -0700427 UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800428 if (mBatchSize < 0) {
429 // set mBatchSize to 0 if we got an illegal value from config file
430 mBatchSize = 0;
431 }
432 }
433 return mBatchSize;
434}
435
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530436uint32_t LocationAPIClientBase::locAPIStartSession(
437 uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800438{
439 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800440 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800441 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800442
Baili Feng2df685d2017-07-20 17:02:26 +0800443 if (mSessionBiDict.hasId(id)) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800444 LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id);
445 retVal = LOCATION_ERROR_ALREADY_STARTED;
446 } else {
447 uint32_t trackingSession = 0;
448 uint32_t batchingSession = 0;
449
450 if (sessionMode == SESSION_MODE_ON_FIX) {
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530451 trackingSession = mLocationAPI->startTracking(options);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800452 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800453 mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
Dante Russo34ce2a62017-10-03 14:38:42 -0700454 } else {
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700455 // Fill in the batch mode
456 BatchingOptions batchOptions = {};
457 batchOptions.size = sizeof(BatchingOptions);
Dante Russo34ce2a62017-10-03 14:38:42 -0700458 switch (sessionMode) {
459 case SESSION_MODE_ON_FULL:
460 batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
461 break;
462 case SESSION_MODE_ON_TRIP_COMPLETED:
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700463 batchOptions.batchingMode = BATCHING_MODE_TRIP;
Dante Russo34ce2a62017-10-03 14:38:42 -0700464 break;
465 default:
466 batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
467 break;
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700468 }
469
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530470 // Populate location option values
471 batchOptions.minDistance = options.minDistance;
472 batchOptions.minInterval = options.minInterval;
473 batchOptions.mode = options.mode;
474
475 batchingSession = mLocationAPI->startBatching(batchOptions);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800476 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800477 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
478 mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800479 }
480
Dante Russo34ce2a62017-10-03 14:38:42 -0700481 uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700482 batchingSession : trackingSession);
483
Dante Russoc85c8ff2017-02-28 16:45:47 -0800484 SessionEntity entity;
485 entity.id = id;
486 entity.trackingSession = trackingSession;
487 entity.batchingSession = batchingSession;
488 entity.sessionMode = sessionMode;
Baili Feng2df685d2017-07-20 17:02:26 +0800489 mSessionBiDict.set(id, session, entity);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800490
491 retVal = LOCATION_ERROR_SUCCESS;
492 }
493
Dante Russoc85c8ff2017-02-28 16:45:47 -0800494 }
Baili Fengb29778e2017-05-23 14:32:22 +0800495 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800496
497 return retVal;
498}
499
500uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
501{
502 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800503 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800504 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800505
Baili Feng2df685d2017-07-20 17:02:26 +0800506 if (mSessionBiDict.hasId(id)) {
507 SessionEntity entity = mSessionBiDict.getExtById(id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800508
509 uint32_t trackingSession = entity.trackingSession;
510 uint32_t batchingSession = entity.batchingSession;
511 uint32_t sMode = entity.sessionMode;
512
Dante Russoc85c8ff2017-02-28 16:45:47 -0800513 if (sMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800514 mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this));
515 mLocationAPI->stopTracking(trackingSession);
Dante Russo34ce2a62017-10-03 14:38:42 -0700516 } else {
Baili Feng2df685d2017-07-20 17:02:26 +0800517 mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this));
518 mLocationAPI->stopBatching(batchingSession);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800519 }
520
521 retVal = LOCATION_ERROR_SUCCESS;
522 } else {
523 retVal = LOCATION_ERROR_ID_UNKNOWN;
524 LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
525 }
526
Dante Russoc85c8ff2017-02-28 16:45:47 -0800527 }
Baili Fengb29778e2017-05-23 14:32:22 +0800528 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800529 return retVal;
530}
531
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530532uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(
533 uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800534{
535 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800536 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800537 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800538
Baili Feng2df685d2017-07-20 17:02:26 +0800539 if (mSessionBiDict.hasId(id)) {
540 SessionEntity entity = mSessionBiDict.getExtById(id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800541
542 uint32_t trackingSession = entity.trackingSession;
543 uint32_t batchingSession = entity.batchingSession;
544 uint32_t sMode = entity.sessionMode;
545
546 if (sessionMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800547 // we only add an UpdateTrackingOptionsRequest to mRequestQueues[REQUEST_SESSION],
548 // even if this update request will stop batching and then start tracking.
549 mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800550 if (sMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800551 mLocationAPI->updateTrackingOptions(trackingSession, options);
Dante Russo34ce2a62017-10-03 14:38:42 -0700552 } else {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800553 // stop batching
Baili Feng2df685d2017-07-20 17:02:26 +0800554 // batchingSession will be removed from mSessionBiDict soon,
555 // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
556 mLocationAPI->stopBatching(batchingSession);
557 batchingSession = 0;
558 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
559
Dante Russoc85c8ff2017-02-28 16:45:47 -0800560 // start tracking
Baili Feng2df685d2017-07-20 17:02:26 +0800561 trackingSession = mLocationAPI->startTracking(options);
562 LOC_LOGI("%s:%d] start new session: %d",
563 __FUNCTION__, __LINE__, trackingSession);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800564 }
Dante Russo34ce2a62017-10-03 14:38:42 -0700565 } else {
Baili Feng2df685d2017-07-20 17:02:26 +0800566 // we only add an UpdateBatchingOptionsRequest to mRequestQueues[REQUEST_SESSION],
567 // even if this update request will stop tracking and then start batching.
568 mRequestQueues[REQUEST_SESSION].push(new UpdateBatchingOptionsRequest(*this));
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700569 BatchingOptions batchOptions = {};
570 batchOptions.size = sizeof(BatchingOptions);
Dante Russo34ce2a62017-10-03 14:38:42 -0700571 switch (sessionMode) {
572 case SESSION_MODE_ON_FULL:
573 batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
574 break;
575 case SESSION_MODE_ON_TRIP_COMPLETED:
576 batchOptions.batchingMode = BATCHING_MODE_TRIP;
577 break;
578 default:
579 batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
580 break;
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700581 }
582
Dante Russoc85c8ff2017-02-28 16:45:47 -0800583 if (sMode == SESSION_MODE_ON_FIX) {
584 // stop tracking
Baili Feng2df685d2017-07-20 17:02:26 +0800585 // trackingSession will be removed from mSessionBiDict soon,
586 // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
587 mLocationAPI->stopTracking(trackingSession);
588 trackingSession = 0;
589
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530590 // Populate location option values
591 batchOptions.minDistance = options.minDistance;
592 batchOptions.minInterval = options.minInterval;
593 batchOptions.mode = options.mode;
594
Dante Russoc85c8ff2017-02-28 16:45:47 -0800595 // start batching
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530596 batchingSession = mLocationAPI->startBatching(batchOptions);
Baili Feng2df685d2017-07-20 17:02:26 +0800597 LOC_LOGI("%s:%d] start new session: %d",
598 __FUNCTION__, __LINE__, batchingSession);
599 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800600 } else {
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530601 mLocationAPI->updateBatchingOptions(batchingSession, batchOptions);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800602 }
Baili Feng2df685d2017-07-20 17:02:26 +0800603
Dante Russoc85c8ff2017-02-28 16:45:47 -0800604 }
605
Dante Russo34ce2a62017-10-03 14:38:42 -0700606 uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700607 batchingSession : trackingSession);
608
Dante Russoc85c8ff2017-02-28 16:45:47 -0800609 entity.trackingSession = trackingSession;
610 entity.batchingSession = batchingSession;
611 entity.sessionMode = sessionMode;
Baili Feng2df685d2017-07-20 17:02:26 +0800612 // remove the old values from mSessionBiDict before we add a new one.
613 mSessionBiDict.rmById(id);
614 mSessionBiDict.set(id, session, entity);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800615
616 retVal = LOCATION_ERROR_SUCCESS;
617 } else {
618 retVal = LOCATION_ERROR_ID_UNKNOWN;
619 LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
620 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800621 }
Baili Fengb29778e2017-05-23 14:32:22 +0800622 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800623 return retVal;
624}
625
Dante Russo34ce2a62017-10-03 14:38:42 -0700626uint32_t LocationAPIClientBase::locAPIGetBatchedLocations(uint32_t id, size_t count)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800627{
Dante Russo34ce2a62017-10-03 14:38:42 -0700628 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800629 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800630 if (mLocationAPI) {
Dante Russo34ce2a62017-10-03 14:38:42 -0700631 if (mSessionBiDict.hasId(id)) {
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700632 SessionEntity entity = mSessionBiDict.getExtById(id);
Harikrishnan Hariharan6ccaa832017-11-03 10:30:01 +0530633 if (entity.sessionMode != SESSION_MODE_ON_FIX) {
634 uint32_t batchingSession = entity.batchingSession;
635 mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this));
636 mLocationAPI->getBatchedLocations(batchingSession, count);
637 retVal = LOCATION_ERROR_SUCCESS;
638 } else {
639 LOC_LOGE("%s:%d] Unsupported for session id: %d, mode is SESSION_MODE_ON_FIX",
640 __FUNCTION__, __LINE__, id);
641 retVal = LOCATION_ERROR_NOT_SUPPORTED;
642 }
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700643 } else {
Dante Russo34ce2a62017-10-03 14:38:42 -0700644 retVal = LOCATION_ERROR_ID_UNKNOWN;
Joe Huangbeff69e2021-02-24 18:05:40 +0800645 LOC_LOGd("unknown session id: %d, might flush() a stopped session", id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800646 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800647 }
Baili Fengb29778e2017-05-23 14:32:22 +0800648 pthread_mutex_unlock(&mMutex);
Dante Russo34ce2a62017-10-03 14:38:42 -0700649
650 return retVal;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800651}
652
653uint32_t LocationAPIClientBase::locAPIAddGeofences(
654 size_t count, uint32_t* ids, GeofenceOption* options, GeofenceInfo* data)
655{
656 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800657 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800658 if (mLocationAPI) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800659 if (mRequestQueues[REQUEST_GEOFENCE].getSession() != GEOFENCE_SESSION_ID) {
660 mRequestQueues[REQUEST_GEOFENCE].reset(GEOFENCE_SESSION_ID);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800661 }
662 uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
Dante Russo2e87b202017-03-20 15:04:36 -0700663 if (sessions) {
664 LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
Baili Fengc0a300c2017-06-13 15:26:57 +0800665 mRequestQueues[REQUEST_GEOFENCE].push(new AddGeofencesRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800666
Dante Russo2e87b202017-03-20 15:04:36 -0700667 for (size_t i = 0; i < count; i++) {
668 mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
669 }
670 retVal = LOCATION_ERROR_SUCCESS;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800671 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800672 }
Baili Fengb29778e2017-05-23 14:32:22 +0800673 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800674
675 return retVal;
676}
677
678void LocationAPIClientBase::locAPIRemoveGeofences(size_t count, uint32_t* ids)
679{
Baili Fengb29778e2017-05-23 14:32:22 +0800680 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800681 if (mLocationAPI) {
682 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530683 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800684 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530685 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530686 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530687 return;
688 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800689
Baili Fengc0a300c2017-06-13 15:26:57 +0800690 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700691 BiDict<GeofenceBreachTypeMask>* removedGeofenceBiDict =
692 new BiDict<GeofenceBreachTypeMask>();
Baili Fengb29778e2017-05-23 14:32:22 +0800693 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800694 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800695 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
696 if (sessions[j] > 0) {
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700697 GeofenceBreachTypeMask type = mGeofenceBiDict.getExtBySession(sessions[j]);
Kevin Tangc7642dc2017-09-22 17:28:58 -0700698 mGeofenceBiDict.rmBySession(sessions[j]);
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700699 removedGeofenceBiDict->set(ids[i], sessions[j], type);
Baili Fengb29778e2017-05-23 14:32:22 +0800700 j++;
701 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800702 }
Baili Fengb29778e2017-05-23 14:32:22 +0800703 if (j > 0) {
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700704 mRequestQueues[REQUEST_GEOFENCE].push(new RemoveGeofencesRequest(*this,
705 removedGeofenceBiDict));
Baili Fengb29778e2017-05-23 14:32:22 +0800706 mLocationAPI->removeGeofences(j, sessions);
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700707 } else {
708 delete(removedGeofenceBiDict);
Baili Fengb29778e2017-05-23 14:32:22 +0800709 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800710 } else {
711 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
712 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800713 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800714
715 free(sessions);
716 }
Baili Fengb29778e2017-05-23 14:32:22 +0800717 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800718}
719
720void LocationAPIClientBase::locAPIModifyGeofences(
721 size_t count, uint32_t* ids, GeofenceOption* options)
722{
Baili Fengb29778e2017-05-23 14:32:22 +0800723 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800724 if (mLocationAPI) {
725 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530726 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800727 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530728 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530729 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530730 return;
731 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800732
Baili Fengc0a300c2017-06-13 15:26:57 +0800733 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800734 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800735 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800736 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
737 if (sessions[j] > 0) {
738 mGeofenceBiDict.set(ids[i], sessions[j], options[i].breachTypeMask);
739 j++;
740 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800741 }
Baili Fengb29778e2017-05-23 14:32:22 +0800742 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800743 mRequestQueues[REQUEST_GEOFENCE].push(new ModifyGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800744 mLocationAPI->modifyGeofences(j, sessions, options);
745 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800746 } else {
747 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
748 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800749 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800750
751 free(sessions);
752 }
Baili Fengb29778e2017-05-23 14:32:22 +0800753 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800754}
755
756void LocationAPIClientBase::locAPIPauseGeofences(size_t count, uint32_t* ids)
757{
Baili Fengb29778e2017-05-23 14:32:22 +0800758 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800759 if (mLocationAPI) {
760 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530761 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800762 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530763 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530764 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530765 return;
766 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800767
Baili Fengc0a300c2017-06-13 15:26:57 +0800768 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800769 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800770 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800771 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
772 if (sessions[j] > 0) {
773 j++;
774 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800775 }
Baili Fengb29778e2017-05-23 14:32:22 +0800776 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800777 mRequestQueues[REQUEST_GEOFENCE].push(new PauseGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800778 mLocationAPI->pauseGeofences(j, sessions);
779 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800780 } else {
781 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
782 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800783 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800784
785 free(sessions);
786 }
Baili Fengb29778e2017-05-23 14:32:22 +0800787 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800788}
789
790void LocationAPIClientBase::locAPIResumeGeofences(
791 size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask)
792{
Baili Fengb29778e2017-05-23 14:32:22 +0800793 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800794 if (mLocationAPI) {
795 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530796 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800797 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530798 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530799 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530800 return;
801 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800802
Baili Fengc0a300c2017-06-13 15:26:57 +0800803 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800804 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800805 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800806 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
807 if (sessions[j] > 0) {
808 if (mask) {
809 mGeofenceBiDict.set(ids[i], sessions[j], mask[i]);
810 }
811 j++;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800812 }
813 }
Baili Fengb29778e2017-05-23 14:32:22 +0800814 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800815 mRequestQueues[REQUEST_GEOFENCE].push(new ResumeGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800816 mLocationAPI->resumeGeofences(j, sessions);
817 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800818 } else {
819 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
820 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800821 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800822
823 free(sessions);
824 }
Baili Fengb29778e2017-05-23 14:32:22 +0800825 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800826}
827
828void LocationAPIClientBase::locAPIRemoveAllGeofences()
829{
Kevin Tangc7642dc2017-09-22 17:28:58 -0700830 std::vector<uint32_t> sessionsVec = mGeofenceBiDict.getAllSessions();
Saurabh Srivastavabc3c18a2020-05-14 18:18:14 +0530831 if (sessionsVec.size() > 0) {
832 locAPIRemoveGeofences(sessionsVec.size(), &sessionsVec[0]);
833 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800834}
835
836void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
837{
Baili Fengb29778e2017-05-23 14:32:22 +0800838 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800839 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800840 uint32_t session = id;
841 mLocationAPI->gnssNiResponse(id, response);
842 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
Baili Fengc0a300c2017-06-13 15:26:57 +0800843 mRequestQueues[REQUEST_NIRESPONSE].reset(session);
844 mRequestQueues[REQUEST_NIRESPONSE].push(new GnssNiResponseRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800845 }
Baili Fengb29778e2017-05-23 14:32:22 +0800846 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800847}
848
Dante Russoc85c8ff2017-02-28 16:45:47 -0800849void LocationAPIClientBase::beforeGeofenceBreachCb(
850 GeofenceBreachNotification geofenceBreachNotification)
851{
Dante Russoc85c8ff2017-02-28 16:45:47 -0800852 uint32_t* ids = (uint32_t*)malloc(sizeof(uint32_t) * geofenceBreachNotification.count);
853 uint32_t* backup = geofenceBreachNotification.ids;
854 size_t n = geofenceBreachNotification.count;
Baili Fengc0a300c2017-06-13 15:26:57 +0800855 geofenceBreachCallback genfenceCallback = nullptr;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800856
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530857 if (ids == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800858 LOC_LOGE("%s:%d] Failed to alloc %zu bytes",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530859 __FUNCTION__, __LINE__,
860 sizeof(uint32_t) * geofenceBreachNotification.count);
861 return;
862 }
863
Baili Fengc0a300c2017-06-13 15:26:57 +0800864 pthread_mutex_lock(&mMutex);
865 if (mGeofenceBreachCallback != nullptr) {
866 size_t count = 0;
867 for (size_t i = 0; i < n; i++) {
868 uint32_t id = mGeofenceBiDict.getId(geofenceBreachNotification.ids[i]);
869 GeofenceBreachTypeMask type =
Baili Feng2df685d2017-07-20 17:02:26 +0800870 mGeofenceBiDict.getExtBySession(geofenceBreachNotification.ids[i]);
Baili Fengc0a300c2017-06-13 15:26:57 +0800871 // if type == 0, we will not head into the fllowing block anyway.
872 // so we don't need to check id and type
873 if ((geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER &&
874 (type & GEOFENCE_BREACH_ENTER_BIT)) ||
875 (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT &&
876 (type & GEOFENCE_BREACH_EXIT_BIT))
877 ) {
878 ids[count] = id;
879 count++;
880 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800881 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800882 geofenceBreachNotification.count = count;
883 geofenceBreachNotification.ids = ids;
884
885 genfenceCallback = mGeofenceBreachCallback;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800886 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800887 pthread_mutex_unlock(&mMutex);
888
889 if (genfenceCallback != nullptr) {
890 genfenceCallback(geofenceBreachNotification);
891 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800892
893 // restore ids
894 geofenceBreachNotification.ids = backup;
895 geofenceBreachNotification.count = n;
896 free(ids);
897}
898
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700899void LocationAPIClientBase::beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
900 std::list<uint32_t> & tripCompletedList) {
901
902 // map the trip ids to the client ids
903 std::list<uint32_t> tripCompletedClientIdList;
904 tripCompletedClientIdList.clear();
905
906 if (batchStatus.batchingStatus == BATCHING_STATUS_TRIP_COMPLETED) {
907 for (auto itt = tripCompletedList.begin(); itt != tripCompletedList.end(); itt++) {
908 if (mSessionBiDict.hasSession(*itt)) {
909 SessionEntity sessEntity = mSessionBiDict.getExtBySession(*itt);
910
911 if (sessEntity.sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
912 tripCompletedClientIdList.push_back(sessEntity.id);
913 mSessionBiDict.rmBySession(*itt);
914 }
915 }
916 }
917 }
918
919 mBatchingStatusCallback(batchStatus, tripCompletedClientIdList);
920}
921
Dante Russoc85c8ff2017-02-28 16:45:47 -0800922void LocationAPIClientBase::onResponseCb(LocationError error, uint32_t id)
923{
924 if (error != LOCATION_ERROR_SUCCESS) {
925 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
926 } else {
Baili Feng1a128bd2017-06-21 17:46:23 +0800927 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800928 }
929 LocationAPIRequest* request = getRequestBySession(id);
930 if (request) {
Baili Feng2df685d2017-07-20 17:02:26 +0800931 request->onResponse(error, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800932 delete request;
933 }
934}
935
936void LocationAPIClientBase::onCollectiveResponseCb(
937 size_t count, LocationError* errors, uint32_t* ids)
938{
939 for (size_t i = 0; i < count; i++) {
940 if (errors[i] != LOCATION_ERROR_SUCCESS) {
941 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
942 } else {
Baili Feng1a128bd2017-06-21 17:46:23 +0800943 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800944 }
945 }
946 LocationAPIRequest* request = nullptr;
Baili Feng1f3ac892017-05-31 16:22:16 +0800947 pthread_mutex_lock(&mMutex);
Baili Fengc0a300c2017-06-13 15:26:57 +0800948 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
949 request = mRequestQueues[REQUEST_GEOFENCE].pop();
Baili Feng1f3ac892017-05-31 16:22:16 +0800950 }
951 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800952 if (request) {
953 request->onCollectiveResponse(count, errors, ids);
954 delete request;
955 }
956}
957
Baili Feng2df685d2017-07-20 17:02:26 +0800958void LocationAPIClientBase::removeSession(uint32_t session) {
959 if (mSessionBiDict.hasSession(session)) {
960 mSessionBiDict.rmBySession(session);
961 }
962}
963
Baili Feng1a128bd2017-06-21 17:46:23 +0800964LocationAPIRequest* LocationAPIClientBase::getRequestBySession(uint32_t session)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800965{
966 pthread_mutex_lock(&mMutex);
967 LocationAPIRequest* request = nullptr;
968 for (int i = 0; i < REQUEST_MAX; i++) {
969 if (i != REQUEST_GEOFENCE &&
Baili Feng2df685d2017-07-20 17:02:26 +0800970 i != REQUEST_SESSION &&
Baili Fengc0a300c2017-06-13 15:26:57 +0800971 mRequestQueues[i].getSession() == session) {
972 request = mRequestQueues[i].pop();
Dante Russoc85c8ff2017-02-28 16:45:47 -0800973 break;
974 }
975 }
Baili Feng2df685d2017-07-20 17:02:26 +0800976 if (request == nullptr) {
977 // Can't find a request with correct session,
978 // try to find it from mSessionBiDict
979 if (mSessionBiDict.hasSession(session)) {
980 request = mRequestQueues[REQUEST_SESSION].pop();
981 }
982 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800983 pthread_mutex_unlock(&mMutex);
984 return request;
985}