blob: ef28bce1513735e2f456e1caba14a884b277840f [file] [log] [blame]
Saurabh Srivastavabc3c18a2020-05-14 18:18:14 +05301/* Copyright (c) 2017, 2020 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
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +053029#define LOG_NDEBUG 0
Dante Russoc85c8ff2017-02-28 16:45:47 -080030#define LOG_TAG "LocSvc_APIClientBase"
31
Kevin Tang61de97e2016-09-12 17:20:55 -070032#include <loc_pla.h>
33#include <log_util.h>
Baili Feng4c9c7832017-07-03 21:00:31 +080034#include <inttypes.h>
Dante Russoc85c8ff2017-02-28 16:45:47 -080035#include <loc_cfg.h>
36#include "LocationAPIClientBase.h"
37
Baili Fengc0a300c2017-06-13 15:26:57 +080038#define GEOFENCE_SESSION_ID 0xFFFFFFFF
39#define CONFIG_SESSION_ID 0xFFFFFFFF
Dante Russoc85c8ff2017-02-28 16:45:47 -080040
Baili Feng1a128bd2017-06-21 17:46:23 +080041// LocationAPIControlClient
42LocationAPIControlClient::LocationAPIControlClient() :
43 mEnabled(false)
44{
45 pthread_mutex_init(&mMutex, nullptr);
46
47 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +053048 mRequestQueues[i].reset((uint32_t)0);
Baili Feng1a128bd2017-06-21 17:46:23 +080049 }
50
51 memset(&mConfig, 0, sizeof(GnssConfig));
52
53 LocationControlCallbacks locationControlCallbacks;
54 locationControlCallbacks.size = sizeof(LocationControlCallbacks);
55
56 locationControlCallbacks.responseCb =
57 [this](LocationError error, uint32_t id) {
58 onCtrlResponseCb(error, id);
59 };
60 locationControlCallbacks.collectiveResponseCb =
61 [this](size_t count, LocationError* errors, uint32_t* ids) {
62 onCtrlCollectiveResponseCb(count, errors, ids);
63 };
64
65 mLocationControlAPI = LocationControlAPI::createInstance(locationControlCallbacks);
66}
67
68LocationAPIControlClient::~LocationAPIControlClient()
69{
70 pthread_mutex_lock(&mMutex);
71
72 if (mLocationControlAPI) {
73 mLocationControlAPI->destroy();
74 mLocationControlAPI = nullptr;
75 }
76
77 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +053078 mRequestQueues[i].reset((uint32_t)0);
Baili Feng1a128bd2017-06-21 17:46:23 +080079 }
80
81 pthread_mutex_unlock(&mMutex);
82
83 pthread_mutex_destroy(&mMutex);
84}
85
86uint32_t LocationAPIControlClient::locAPIGnssDeleteAidingData(GnssAidingData& data)
87{
88 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
89 pthread_mutex_lock(&mMutex);
90 if (mLocationControlAPI) {
91 uint32_t session = mLocationControlAPI->gnssDeleteAidingData(data);
92 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
93 mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].reset(session);
94 mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].push(new GnssDeleteAidingDataRequest(*this));
95
96 retVal = LOCATION_ERROR_SUCCESS;
97 }
98 pthread_mutex_unlock(&mMutex);
99
100 return retVal;
101}
102
103uint32_t LocationAPIControlClient::locAPIEnable(LocationTechnologyType techType)
104{
105 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
106 pthread_mutex_lock(&mMutex);
107 if (mEnabled) {
108 // just return success if already enabled
109 retVal = LOCATION_ERROR_SUCCESS;
110 } else if (mLocationControlAPI) {
111 uint32_t session = mLocationControlAPI->enable(techType);
112 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
113 mRequestQueues[CTRL_REQUEST_CONTROL].reset(session);
114 mRequestQueues[CTRL_REQUEST_CONTROL].push(new EnableRequest(*this));
115 retVal = LOCATION_ERROR_SUCCESS;
116 mEnabled = true;
117 } else {
118 LOC_LOGE("%s:%d] failed.", __FUNCTION__, __LINE__);
119 }
120 pthread_mutex_unlock(&mMutex);
121
122 return retVal;
123}
124
125void LocationAPIControlClient::locAPIDisable()
126{
127 pthread_mutex_lock(&mMutex);
128 if (mEnabled && mLocationControlAPI) {
129 uint32_t session = 0;
130 session = mRequestQueues[CTRL_REQUEST_CONTROL].getSession();
131 if (session > 0) {
132 mRequestQueues[CTRL_REQUEST_CONTROL].push(new DisableRequest(*this));
133 mLocationControlAPI->disable(session);
134 mEnabled = false;
135 } else {
136 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
137 }
138 }
139 pthread_mutex_unlock(&mMutex);
140}
141
142uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
143{
144 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530145
146 pthread_mutex_lock(&mMutex);
147 if (mLocationControlAPI) {
148 if (mConfig.equals(config)) {
149 LOC_LOGv("GnssConfig is identical to previous call");
150 retVal = LOCATION_ERROR_SUCCESS;
151 } else {
152 mConfig = config;
153 uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
154 LOC_LOGv("gnssUpdateConfig return array: %p", idArray);
155 if (nullptr != idArray) {
156 if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr()) {
157 mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].reset(idArray);
158 }
159 mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this));
160 retVal = LOCATION_ERROR_SUCCESS;
161 }
162 }
Baili Feng1a128bd2017-06-21 17:46:23 +0800163 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530164 pthread_mutex_unlock(&mMutex);
165 return retVal;
166}
167
168uint32_t LocationAPIControlClient::locAPIGnssGetConfig(GnssConfigFlagsMask mask)
169{
170 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Feng1a128bd2017-06-21 17:46:23 +0800171
172 pthread_mutex_lock(&mMutex);
173 if (mLocationControlAPI) {
174
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530175 uint32_t* idArray = mLocationControlAPI->gnssGetConfig(mask);
176 LOC_LOGv("gnssGetConfig return array: %p", idArray);
177 if (nullptr != idArray) {
178 if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr()) {
179 mRequestQueues[CTRL_REQUEST_CONFIG_GET].reset(idArray);
Baili Feng1a128bd2017-06-21 17:46:23 +0800180 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530181 mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this));
Baili Feng1a128bd2017-06-21 17:46:23 +0800182 retVal = LOCATION_ERROR_SUCCESS;
183 }
184 }
185 pthread_mutex_unlock(&mMutex);
186 return retVal;
187}
188
189void LocationAPIControlClient::onCtrlResponseCb(LocationError error, uint32_t id)
190{
191 if (error != LOCATION_ERROR_SUCCESS) {
192 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
193 } else {
194 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
195 }
196 LocationAPIRequest* request = getRequestBySession(id);
197 if (request) {
Baili Feng2df685d2017-07-20 17:02:26 +0800198 request->onResponse(error, id);
Baili Feng1a128bd2017-06-21 17:46:23 +0800199 delete request;
200 }
201}
202
203void LocationAPIControlClient::onCtrlCollectiveResponseCb(
204 size_t count, LocationError* errors, uint32_t* ids)
205{
206 for (size_t i = 0; i < count; i++) {
207 if (errors[i] != LOCATION_ERROR_SUCCESS) {
208 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
209 } else {
210 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
211 }
212 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530213 LocationAPIRequest* request = getRequestBySessionArrayPtr(ids);
Baili Feng1a128bd2017-06-21 17:46:23 +0800214 if (request) {
215 request->onCollectiveResponse(count, errors, ids);
216 delete request;
217 }
218}
219
220LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t session)
221{
222 pthread_mutex_lock(&mMutex);
223 LocationAPIRequest* request = nullptr;
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530224
225 if (mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].getSession() == session) {
226 request = mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].pop();
227 } else if (mRequestQueues[CTRL_REQUEST_CONTROL].getSession() == session) {
228 request = mRequestQueues[CTRL_REQUEST_CONTROL].pop();
Baili Feng1a128bd2017-06-21 17:46:23 +0800229 }
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530230
231 pthread_mutex_unlock(&mMutex);
232 return request;
233}
234
235LocationAPIRequest*
236LocationAPIControlClient::getRequestBySessionArrayPtr(
237 uint32_t* sessionArrayPtr)
238{
239 pthread_mutex_lock(&mMutex);
240 LocationAPIRequest* request = nullptr;
241
242 if (mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr() == sessionArrayPtr) {
243 request = mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].pop();
244 } else if (mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr() == sessionArrayPtr) {
245 request = mRequestQueues[CTRL_REQUEST_CONFIG_GET].pop();
246 }
247
Baili Feng1a128bd2017-06-21 17:46:23 +0800248 pthread_mutex_unlock(&mMutex);
249 return request;
250}
251
252// LocationAPIClientBase
Dante Russoc85c8ff2017-02-28 16:45:47 -0800253LocationAPIClientBase::LocationAPIClientBase() :
Dante Russoc85c8ff2017-02-28 16:45:47 -0800254 mGeofenceBreachCallback(nullptr),
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700255 mBatchingStatusCallback(nullptr),
Dante Russoc85c8ff2017-02-28 16:45:47 -0800256 mLocationAPI(nullptr),
Dante Russoc1da12a2017-07-27 10:44:54 -0700257 mBatchSize(-1),
258 mTracking(false)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800259{
260
261 // use recursive mutex, in case callback come from the same thread
262 pthread_mutexattr_t attr;
263 pthread_mutexattr_init(&attr);
264 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
265 pthread_mutex_init(&mMutex, &attr);
266
267 for (int i = 0; i < REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530268 mRequestQueues[i].reset((uint32_t)0);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800269 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800270}
271
272void LocationAPIClientBase::locAPISetCallbacks(LocationCallbacks& locationCallbacks)
273{
Baili Fengb29778e2017-05-23 14:32:22 +0800274 pthread_mutex_lock(&mMutex);
275
Dante Russoc85c8ff2017-02-28 16:45:47 -0800276 if (locationCallbacks.geofenceBreachCb != nullptr) {
277 mGeofenceBreachCallback = locationCallbacks.geofenceBreachCb;
278 locationCallbacks.geofenceBreachCb =
279 [this](GeofenceBreachNotification geofenceBreachNotification) {
280 beforeGeofenceBreachCb(geofenceBreachNotification);
281 };
282 }
283
284 locationCallbacks.capabilitiesCb =
285 [this](LocationCapabilitiesMask capabilitiesMask) {
286 onCapabilitiesCb(capabilitiesMask);
287 };
288 locationCallbacks.responseCb = [this](LocationError error, uint32_t id) {
289 onResponseCb(error, id);
290 };
291 locationCallbacks.collectiveResponseCb =
292 [this](size_t count, LocationError* errors, uint32_t* ids) {
293 onCollectiveResponseCb(count, errors, ids);
294 };
295
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700296 if (locationCallbacks.batchingStatusCb != nullptr) {
297 mBatchingStatusCallback = locationCallbacks.batchingStatusCb;
298 locationCallbacks.batchingStatusCb =
299 [this](BatchingStatusInfo batchStatus, std::list<uint32_t> & tripCompletedList) {
300 beforeBatchingStatusCb(batchStatus, tripCompletedList);
301 };
302 }
303
Dante Russoc85c8ff2017-02-28 16:45:47 -0800304 if (mLocationAPI == nullptr ) {
305 mLocationAPI = LocationAPI::createInstance(locationCallbacks);
306 } else {
307 mLocationAPI->updateCallbacks(locationCallbacks);
308 }
309
Baili Fengb29778e2017-05-23 14:32:22 +0800310 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800311}
312
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530313void LocationAPIClientBase::destroy()
Dante Russoc85c8ff2017-02-28 16:45:47 -0800314{
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530315 LOC_LOGD("LocationAPIClientBase::destroy()");
316
Baili Fengb29778e2017-05-23 14:32:22 +0800317 pthread_mutex_lock(&mMutex);
318
Baili Fengc0a300c2017-06-13 15:26:57 +0800319 mGeofenceBreachCallback = nullptr;
320
Dante Russoc85c8ff2017-02-28 16:45:47 -0800321 for (int i = 0; i < REQUEST_MAX; i++) {
Saurabh Srivastavaeaf7e542018-05-20 19:29:46 +0530322 mRequestQueues[i].reset((uint32_t)0);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800323 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800324
Saurabh Srivastava624c2722020-08-24 15:58:41 +0530325 LocationAPI* localHandle = nullptr;
326 if (nullptr != mLocationAPI) {
327 localHandle = mLocationAPI;
328 mLocationAPI = nullptr;
329 }
330
Dante Russoc85c8ff2017-02-28 16:45:47 -0800331 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava624c2722020-08-24 15:58:41 +0530332
333 // Invoking destroy has the possibility of destroy complete callback
334 // being invoked right away in the same context, hence no instance
335 // member must be accessed after the destroy call.
336 if (nullptr != localHandle) {
337 localHandle->destroy([this]() {onLocationApiDestroyCompleteCb();});
338 }
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530339}
Dante Russoc85c8ff2017-02-28 16:45:47 -0800340
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530341LocationAPIClientBase::~LocationAPIClientBase()
342{
Dante Russoc85c8ff2017-02-28 16:45:47 -0800343 pthread_mutex_destroy(&mMutex);
344}
345
Saurabh Srivastavaa2f2fdc2020-07-10 16:46:16 +0530346void LocationAPIClientBase::onLocationApiDestroyCompleteCb()
347{
348 LOC_LOGD("LocationAPIClientBase::onLocationApiDestroyCompleteCb()");
349 delete this;
350}
351
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530352uint32_t LocationAPIClientBase::locAPIStartTracking(TrackingOptions& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800353{
354 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800355 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800356 if (mLocationAPI) {
Dante Russoc1da12a2017-07-27 10:44:54 -0700357 if (mTracking) {
358 LOC_LOGW("%s:%d] Existing tracking session present", __FUNCTION__, __LINE__);
359 } else {
360 uint32_t session = mLocationAPI->startTracking(options);
361 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
362 // onResponseCb might be called from other thread immediately after
363 // startTracking returns, so we are not going to unlock mutex
364 // until StartTrackingRequest is pushed into mRequestQueues[REQUEST_TRACKING]
365 mRequestQueues[REQUEST_TRACKING].reset(session);
366 mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this));
367 mTracking = true;
368 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800369
370 retVal = LOCATION_ERROR_SUCCESS;
371 }
Baili Fengb29778e2017-05-23 14:32:22 +0800372 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800373
374 return retVal;
375}
376
377void LocationAPIClientBase::locAPIStopTracking()
378{
Baili Fengb29778e2017-05-23 14:32:22 +0800379 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800380 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800381 uint32_t session = 0;
Baili Fengc0a300c2017-06-13 15:26:57 +0800382 session = mRequestQueues[REQUEST_TRACKING].getSession();
383 if (session > 0) {
384 mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this));
385 mLocationAPI->stopTracking(session);
Dante Russoc1da12a2017-07-27 10:44:54 -0700386 mTracking = false;
Baili Fengc0a300c2017-06-13 15:26:57 +0800387 } else {
Dante Russo04db4be2019-05-29 17:59:00 -0700388 LOC_LOGD("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800389 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800390 }
Baili Fengb29778e2017-05-23 14:32:22 +0800391 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800392}
393
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530394void LocationAPIClientBase::locAPIUpdateTrackingOptions(TrackingOptions& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800395{
Baili Fengb29778e2017-05-23 14:32:22 +0800396 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800397 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800398 uint32_t session = 0;
Baili Fengc0a300c2017-06-13 15:26:57 +0800399 session = mRequestQueues[REQUEST_TRACKING].getSession();
400 if (session > 0) {
401 mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this));
402 mLocationAPI->updateTrackingOptions(session, options);
403 } else {
404 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800405 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800406 }
Baili Fengb29778e2017-05-23 14:32:22 +0800407 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800408}
409
410int32_t LocationAPIClientBase::locAPIGetBatchSize()
411{
412 if (mBatchSize == -1) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800413 const loc_param_s_type flp_conf_param_table[] =
Dante Russoc85c8ff2017-02-28 16:45:47 -0800414 {
415 {"BATCH_SIZE", &mBatchSize, nullptr, 'n'},
416 };
Dante Russo47d2e812018-03-16 11:50:05 -0700417 UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800418 if (mBatchSize < 0) {
419 // set mBatchSize to 0 if we got an illegal value from config file
420 mBatchSize = 0;
421 }
422 }
423 return mBatchSize;
424}
425
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530426uint32_t LocationAPIClientBase::locAPIStartSession(
427 uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800428{
429 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800430 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800431 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800432
Baili Feng2df685d2017-07-20 17:02:26 +0800433 if (mSessionBiDict.hasId(id)) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800434 LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id);
435 retVal = LOCATION_ERROR_ALREADY_STARTED;
436 } else {
437 uint32_t trackingSession = 0;
438 uint32_t batchingSession = 0;
439
440 if (sessionMode == SESSION_MODE_ON_FIX) {
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530441 trackingSession = mLocationAPI->startTracking(options);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800442 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800443 mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
Dante Russo34ce2a62017-10-03 14:38:42 -0700444 } else {
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700445 // Fill in the batch mode
446 BatchingOptions batchOptions = {};
447 batchOptions.size = sizeof(BatchingOptions);
Dante Russo34ce2a62017-10-03 14:38:42 -0700448 switch (sessionMode) {
449 case SESSION_MODE_ON_FULL:
450 batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
451 break;
452 case SESSION_MODE_ON_TRIP_COMPLETED:
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700453 batchOptions.batchingMode = BATCHING_MODE_TRIP;
Dante Russo34ce2a62017-10-03 14:38:42 -0700454 break;
455 default:
456 batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
457 break;
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700458 }
459
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530460 // Populate location option values
461 batchOptions.minDistance = options.minDistance;
462 batchOptions.minInterval = options.minInterval;
463 batchOptions.mode = options.mode;
464
465 batchingSession = mLocationAPI->startBatching(batchOptions);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800466 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800467 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
468 mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800469 }
470
Dante Russo34ce2a62017-10-03 14:38:42 -0700471 uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700472 batchingSession : trackingSession);
473
Dante Russoc85c8ff2017-02-28 16:45:47 -0800474 SessionEntity entity;
475 entity.id = id;
476 entity.trackingSession = trackingSession;
477 entity.batchingSession = batchingSession;
478 entity.sessionMode = sessionMode;
Baili Feng2df685d2017-07-20 17:02:26 +0800479 mSessionBiDict.set(id, session, entity);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800480
481 retVal = LOCATION_ERROR_SUCCESS;
482 }
483
Dante Russoc85c8ff2017-02-28 16:45:47 -0800484 }
Baili Fengb29778e2017-05-23 14:32:22 +0800485 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800486
487 return retVal;
488}
489
490uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
491{
492 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800493 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800494 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800495
Baili Feng2df685d2017-07-20 17:02:26 +0800496 if (mSessionBiDict.hasId(id)) {
497 SessionEntity entity = mSessionBiDict.getExtById(id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800498
499 uint32_t trackingSession = entity.trackingSession;
500 uint32_t batchingSession = entity.batchingSession;
501 uint32_t sMode = entity.sessionMode;
502
Dante Russoc85c8ff2017-02-28 16:45:47 -0800503 if (sMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800504 mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this));
505 mLocationAPI->stopTracking(trackingSession);
Dante Russo34ce2a62017-10-03 14:38:42 -0700506 } else {
Baili Feng2df685d2017-07-20 17:02:26 +0800507 mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this));
508 mLocationAPI->stopBatching(batchingSession);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800509 }
510
511 retVal = LOCATION_ERROR_SUCCESS;
512 } else {
513 retVal = LOCATION_ERROR_ID_UNKNOWN;
514 LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
515 }
516
Dante Russoc85c8ff2017-02-28 16:45:47 -0800517 }
Baili Fengb29778e2017-05-23 14:32:22 +0800518 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800519 return retVal;
520}
521
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530522uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(
523 uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800524{
525 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800526 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800527 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800528
Baili Feng2df685d2017-07-20 17:02:26 +0800529 if (mSessionBiDict.hasId(id)) {
530 SessionEntity entity = mSessionBiDict.getExtById(id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800531
532 uint32_t trackingSession = entity.trackingSession;
533 uint32_t batchingSession = entity.batchingSession;
534 uint32_t sMode = entity.sessionMode;
535
536 if (sessionMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800537 // we only add an UpdateTrackingOptionsRequest to mRequestQueues[REQUEST_SESSION],
538 // even if this update request will stop batching and then start tracking.
539 mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800540 if (sMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800541 mLocationAPI->updateTrackingOptions(trackingSession, options);
Dante Russo34ce2a62017-10-03 14:38:42 -0700542 } else {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800543 // stop batching
Baili Feng2df685d2017-07-20 17:02:26 +0800544 // batchingSession will be removed from mSessionBiDict soon,
545 // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
546 mLocationAPI->stopBatching(batchingSession);
547 batchingSession = 0;
548 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
549
Dante Russoc85c8ff2017-02-28 16:45:47 -0800550 // start tracking
Baili Feng2df685d2017-07-20 17:02:26 +0800551 trackingSession = mLocationAPI->startTracking(options);
552 LOC_LOGI("%s:%d] start new session: %d",
553 __FUNCTION__, __LINE__, trackingSession);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800554 }
Dante Russo34ce2a62017-10-03 14:38:42 -0700555 } else {
Baili Feng2df685d2017-07-20 17:02:26 +0800556 // we only add an UpdateBatchingOptionsRequest to mRequestQueues[REQUEST_SESSION],
557 // even if this update request will stop tracking and then start batching.
558 mRequestQueues[REQUEST_SESSION].push(new UpdateBatchingOptionsRequest(*this));
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700559 BatchingOptions batchOptions = {};
560 batchOptions.size = sizeof(BatchingOptions);
Dante Russo34ce2a62017-10-03 14:38:42 -0700561 switch (sessionMode) {
562 case SESSION_MODE_ON_FULL:
563 batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
564 break;
565 case SESSION_MODE_ON_TRIP_COMPLETED:
566 batchOptions.batchingMode = BATCHING_MODE_TRIP;
567 break;
568 default:
569 batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
570 break;
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700571 }
572
Dante Russoc85c8ff2017-02-28 16:45:47 -0800573 if (sMode == SESSION_MODE_ON_FIX) {
574 // stop tracking
Baili Feng2df685d2017-07-20 17:02:26 +0800575 // trackingSession will be removed from mSessionBiDict soon,
576 // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
577 mLocationAPI->stopTracking(trackingSession);
578 trackingSession = 0;
579
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530580 // Populate location option values
581 batchOptions.minDistance = options.minDistance;
582 batchOptions.minInterval = options.minInterval;
583 batchOptions.mode = options.mode;
584
Dante Russoc85c8ff2017-02-28 16:45:47 -0800585 // start batching
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530586 batchingSession = mLocationAPI->startBatching(batchOptions);
Baili Feng2df685d2017-07-20 17:02:26 +0800587 LOC_LOGI("%s:%d] start new session: %d",
588 __FUNCTION__, __LINE__, batchingSession);
589 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800590 } else {
Saurabh Srivastava66c682f2018-05-20 23:06:12 +0530591 mLocationAPI->updateBatchingOptions(batchingSession, batchOptions);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800592 }
Baili Feng2df685d2017-07-20 17:02:26 +0800593
Dante Russoc85c8ff2017-02-28 16:45:47 -0800594 }
595
Dante Russo34ce2a62017-10-03 14:38:42 -0700596 uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700597 batchingSession : trackingSession);
598
Dante Russoc85c8ff2017-02-28 16:45:47 -0800599 entity.trackingSession = trackingSession;
600 entity.batchingSession = batchingSession;
601 entity.sessionMode = sessionMode;
Baili Feng2df685d2017-07-20 17:02:26 +0800602 // remove the old values from mSessionBiDict before we add a new one.
603 mSessionBiDict.rmById(id);
604 mSessionBiDict.set(id, session, entity);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800605
606 retVal = LOCATION_ERROR_SUCCESS;
607 } else {
608 retVal = LOCATION_ERROR_ID_UNKNOWN;
609 LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
610 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800611 }
Baili Fengb29778e2017-05-23 14:32:22 +0800612 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800613 return retVal;
614}
615
Dante Russo34ce2a62017-10-03 14:38:42 -0700616uint32_t LocationAPIClientBase::locAPIGetBatchedLocations(uint32_t id, size_t count)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800617{
Dante Russo34ce2a62017-10-03 14:38:42 -0700618 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800619 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800620 if (mLocationAPI) {
Dante Russo34ce2a62017-10-03 14:38:42 -0700621 if (mSessionBiDict.hasId(id)) {
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700622 SessionEntity entity = mSessionBiDict.getExtById(id);
Harikrishnan Hariharan6ccaa832017-11-03 10:30:01 +0530623 if (entity.sessionMode != SESSION_MODE_ON_FIX) {
624 uint32_t batchingSession = entity.batchingSession;
625 mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this));
626 mLocationAPI->getBatchedLocations(batchingSession, count);
627 retVal = LOCATION_ERROR_SUCCESS;
628 } else {
629 LOC_LOGE("%s:%d] Unsupported for session id: %d, mode is SESSION_MODE_ON_FIX",
630 __FUNCTION__, __LINE__, id);
631 retVal = LOCATION_ERROR_NOT_SUPPORTED;
632 }
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700633 } else {
Dante Russo34ce2a62017-10-03 14:38:42 -0700634 retVal = LOCATION_ERROR_ID_UNKNOWN;
635 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800636 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800637 }
Baili Fengb29778e2017-05-23 14:32:22 +0800638 pthread_mutex_unlock(&mMutex);
Dante Russo34ce2a62017-10-03 14:38:42 -0700639
640 return retVal;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800641}
642
643uint32_t LocationAPIClientBase::locAPIAddGeofences(
644 size_t count, uint32_t* ids, GeofenceOption* options, GeofenceInfo* data)
645{
646 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800647 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800648 if (mLocationAPI) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800649 if (mRequestQueues[REQUEST_GEOFENCE].getSession() != GEOFENCE_SESSION_ID) {
650 mRequestQueues[REQUEST_GEOFENCE].reset(GEOFENCE_SESSION_ID);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800651 }
652 uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
Dante Russo2e87b202017-03-20 15:04:36 -0700653 if (sessions) {
654 LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
Baili Fengc0a300c2017-06-13 15:26:57 +0800655 mRequestQueues[REQUEST_GEOFENCE].push(new AddGeofencesRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800656
Dante Russo2e87b202017-03-20 15:04:36 -0700657 for (size_t i = 0; i < count; i++) {
658 mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
659 }
660 retVal = LOCATION_ERROR_SUCCESS;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800661 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800662 }
Baili Fengb29778e2017-05-23 14:32:22 +0800663 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800664
665 return retVal;
666}
667
668void LocationAPIClientBase::locAPIRemoveGeofences(size_t count, uint32_t* ids)
669{
Baili Fengb29778e2017-05-23 14:32:22 +0800670 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800671 if (mLocationAPI) {
672 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530673 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800674 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530675 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530676 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530677 return;
678 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800679
Baili Fengc0a300c2017-06-13 15:26:57 +0800680 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700681 BiDict<GeofenceBreachTypeMask>* removedGeofenceBiDict =
682 new BiDict<GeofenceBreachTypeMask>();
Baili Fengb29778e2017-05-23 14:32:22 +0800683 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800684 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800685 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
686 if (sessions[j] > 0) {
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700687 GeofenceBreachTypeMask type = mGeofenceBiDict.getExtBySession(sessions[j]);
Kevin Tangc7642dc2017-09-22 17:28:58 -0700688 mGeofenceBiDict.rmBySession(sessions[j]);
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700689 removedGeofenceBiDict->set(ids[i], sessions[j], type);
Baili Fengb29778e2017-05-23 14:32:22 +0800690 j++;
691 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800692 }
Baili Fengb29778e2017-05-23 14:32:22 +0800693 if (j > 0) {
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700694 mRequestQueues[REQUEST_GEOFENCE].push(new RemoveGeofencesRequest(*this,
695 removedGeofenceBiDict));
Baili Fengb29778e2017-05-23 14:32:22 +0800696 mLocationAPI->removeGeofences(j, sessions);
Kevin Tang63c4d2f2017-10-20 13:26:11 -0700697 } else {
698 delete(removedGeofenceBiDict);
Baili Fengb29778e2017-05-23 14:32:22 +0800699 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800700 } else {
701 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
702 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800703 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800704
705 free(sessions);
706 }
Baili Fengb29778e2017-05-23 14:32:22 +0800707 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800708}
709
710void LocationAPIClientBase::locAPIModifyGeofences(
711 size_t count, uint32_t* ids, GeofenceOption* options)
712{
Baili Fengb29778e2017-05-23 14:32:22 +0800713 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800714 if (mLocationAPI) {
715 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530716 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800717 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530718 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530719 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530720 return;
721 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800722
Baili Fengc0a300c2017-06-13 15:26:57 +0800723 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800724 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800725 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800726 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
727 if (sessions[j] > 0) {
728 mGeofenceBiDict.set(ids[i], sessions[j], options[i].breachTypeMask);
729 j++;
730 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800731 }
Baili Fengb29778e2017-05-23 14:32:22 +0800732 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800733 mRequestQueues[REQUEST_GEOFENCE].push(new ModifyGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800734 mLocationAPI->modifyGeofences(j, sessions, options);
735 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800736 } else {
737 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
738 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800739 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800740
741 free(sessions);
742 }
Baili Fengb29778e2017-05-23 14:32:22 +0800743 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800744}
745
746void LocationAPIClientBase::locAPIPauseGeofences(size_t count, uint32_t* ids)
747{
Baili Fengb29778e2017-05-23 14:32:22 +0800748 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800749 if (mLocationAPI) {
750 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530751 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800752 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530753 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530754 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530755 return;
756 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800757
Baili Fengc0a300c2017-06-13 15:26:57 +0800758 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800759 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800760 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800761 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
762 if (sessions[j] > 0) {
763 j++;
764 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800765 }
Baili Fengb29778e2017-05-23 14:32:22 +0800766 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800767 mRequestQueues[REQUEST_GEOFENCE].push(new PauseGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800768 mLocationAPI->pauseGeofences(j, sessions);
769 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800770 } else {
771 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
772 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800773 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800774
775 free(sessions);
776 }
Baili Fengb29778e2017-05-23 14:32:22 +0800777 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800778}
779
780void LocationAPIClientBase::locAPIResumeGeofences(
781 size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask)
782{
Baili Fengb29778e2017-05-23 14:32:22 +0800783 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800784 if (mLocationAPI) {
785 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530786 if (sessions == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800787 LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530788 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530789 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530790 return;
791 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800792
Baili Fengc0a300c2017-06-13 15:26:57 +0800793 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800794 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800795 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800796 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
797 if (sessions[j] > 0) {
798 if (mask) {
799 mGeofenceBiDict.set(ids[i], sessions[j], mask[i]);
800 }
801 j++;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800802 }
803 }
Baili Fengb29778e2017-05-23 14:32:22 +0800804 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800805 mRequestQueues[REQUEST_GEOFENCE].push(new ResumeGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800806 mLocationAPI->resumeGeofences(j, sessions);
807 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800808 } else {
809 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
810 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800811 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800812
813 free(sessions);
814 }
Baili Fengb29778e2017-05-23 14:32:22 +0800815 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800816}
817
818void LocationAPIClientBase::locAPIRemoveAllGeofences()
819{
Kevin Tangc7642dc2017-09-22 17:28:58 -0700820 std::vector<uint32_t> sessionsVec = mGeofenceBiDict.getAllSessions();
Saurabh Srivastavabc3c18a2020-05-14 18:18:14 +0530821 if (sessionsVec.size() > 0) {
822 locAPIRemoveGeofences(sessionsVec.size(), &sessionsVec[0]);
823 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800824}
825
826void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
827{
Baili Fengb29778e2017-05-23 14:32:22 +0800828 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800829 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800830 uint32_t session = id;
831 mLocationAPI->gnssNiResponse(id, response);
832 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
Baili Fengc0a300c2017-06-13 15:26:57 +0800833 mRequestQueues[REQUEST_NIRESPONSE].reset(session);
834 mRequestQueues[REQUEST_NIRESPONSE].push(new GnssNiResponseRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800835 }
Baili Fengb29778e2017-05-23 14:32:22 +0800836 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800837}
838
Dante Russoc85c8ff2017-02-28 16:45:47 -0800839void LocationAPIClientBase::beforeGeofenceBreachCb(
840 GeofenceBreachNotification geofenceBreachNotification)
841{
Dante Russoc85c8ff2017-02-28 16:45:47 -0800842 uint32_t* ids = (uint32_t*)malloc(sizeof(uint32_t) * geofenceBreachNotification.count);
843 uint32_t* backup = geofenceBreachNotification.ids;
844 size_t n = geofenceBreachNotification.count;
Baili Fengc0a300c2017-06-13 15:26:57 +0800845 geofenceBreachCallback genfenceCallback = nullptr;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800846
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530847 if (ids == NULL) {
Baili Feng4c9c7832017-07-03 21:00:31 +0800848 LOC_LOGE("%s:%d] Failed to alloc %zu bytes",
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530849 __FUNCTION__, __LINE__,
850 sizeof(uint32_t) * geofenceBreachNotification.count);
851 return;
852 }
853
Baili Fengc0a300c2017-06-13 15:26:57 +0800854 pthread_mutex_lock(&mMutex);
855 if (mGeofenceBreachCallback != nullptr) {
856 size_t count = 0;
857 for (size_t i = 0; i < n; i++) {
858 uint32_t id = mGeofenceBiDict.getId(geofenceBreachNotification.ids[i]);
859 GeofenceBreachTypeMask type =
Baili Feng2df685d2017-07-20 17:02:26 +0800860 mGeofenceBiDict.getExtBySession(geofenceBreachNotification.ids[i]);
Baili Fengc0a300c2017-06-13 15:26:57 +0800861 // if type == 0, we will not head into the fllowing block anyway.
862 // so we don't need to check id and type
863 if ((geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER &&
864 (type & GEOFENCE_BREACH_ENTER_BIT)) ||
865 (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT &&
866 (type & GEOFENCE_BREACH_EXIT_BIT))
867 ) {
868 ids[count] = id;
869 count++;
870 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800871 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800872 geofenceBreachNotification.count = count;
873 geofenceBreachNotification.ids = ids;
874
875 genfenceCallback = mGeofenceBreachCallback;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800876 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800877 pthread_mutex_unlock(&mMutex);
878
879 if (genfenceCallback != nullptr) {
880 genfenceCallback(geofenceBreachNotification);
881 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800882
883 // restore ids
884 geofenceBreachNotification.ids = backup;
885 geofenceBreachNotification.count = n;
886 free(ids);
887}
888
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700889void LocationAPIClientBase::beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
890 std::list<uint32_t> & tripCompletedList) {
891
892 // map the trip ids to the client ids
893 std::list<uint32_t> tripCompletedClientIdList;
894 tripCompletedClientIdList.clear();
895
896 if (batchStatus.batchingStatus == BATCHING_STATUS_TRIP_COMPLETED) {
897 for (auto itt = tripCompletedList.begin(); itt != tripCompletedList.end(); itt++) {
898 if (mSessionBiDict.hasSession(*itt)) {
899 SessionEntity sessEntity = mSessionBiDict.getExtBySession(*itt);
900
901 if (sessEntity.sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
902 tripCompletedClientIdList.push_back(sessEntity.id);
903 mSessionBiDict.rmBySession(*itt);
904 }
905 }
906 }
907 }
908
909 mBatchingStatusCallback(batchStatus, tripCompletedClientIdList);
910}
911
Dante Russoc85c8ff2017-02-28 16:45:47 -0800912void LocationAPIClientBase::onResponseCb(LocationError error, uint32_t id)
913{
914 if (error != LOCATION_ERROR_SUCCESS) {
915 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
916 } else {
Baili Feng1a128bd2017-06-21 17:46:23 +0800917 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800918 }
919 LocationAPIRequest* request = getRequestBySession(id);
920 if (request) {
Baili Feng2df685d2017-07-20 17:02:26 +0800921 request->onResponse(error, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800922 delete request;
923 }
924}
925
926void LocationAPIClientBase::onCollectiveResponseCb(
927 size_t count, LocationError* errors, uint32_t* ids)
928{
929 for (size_t i = 0; i < count; i++) {
930 if (errors[i] != LOCATION_ERROR_SUCCESS) {
931 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
932 } else {
Baili Feng1a128bd2017-06-21 17:46:23 +0800933 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800934 }
935 }
936 LocationAPIRequest* request = nullptr;
Baili Feng1f3ac892017-05-31 16:22:16 +0800937 pthread_mutex_lock(&mMutex);
Baili Fengc0a300c2017-06-13 15:26:57 +0800938 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
939 request = mRequestQueues[REQUEST_GEOFENCE].pop();
Baili Feng1f3ac892017-05-31 16:22:16 +0800940 }
941 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800942 if (request) {
943 request->onCollectiveResponse(count, errors, ids);
944 delete request;
945 }
946}
947
Baili Feng2df685d2017-07-20 17:02:26 +0800948void LocationAPIClientBase::removeSession(uint32_t session) {
949 if (mSessionBiDict.hasSession(session)) {
950 mSessionBiDict.rmBySession(session);
951 }
952}
953
Baili Feng1a128bd2017-06-21 17:46:23 +0800954LocationAPIRequest* LocationAPIClientBase::getRequestBySession(uint32_t session)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800955{
956 pthread_mutex_lock(&mMutex);
957 LocationAPIRequest* request = nullptr;
958 for (int i = 0; i < REQUEST_MAX; i++) {
959 if (i != REQUEST_GEOFENCE &&
Baili Feng2df685d2017-07-20 17:02:26 +0800960 i != REQUEST_SESSION &&
Baili Fengc0a300c2017-06-13 15:26:57 +0800961 mRequestQueues[i].getSession() == session) {
962 request = mRequestQueues[i].pop();
Dante Russoc85c8ff2017-02-28 16:45:47 -0800963 break;
964 }
965 }
Baili Feng2df685d2017-07-20 17:02:26 +0800966 if (request == nullptr) {
967 // Can't find a request with correct session,
968 // try to find it from mSessionBiDict
969 if (mSessionBiDict.hasSession(session)) {
970 request = mRequestQueues[REQUEST_SESSION].pop();
971 }
972 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800973 pthread_mutex_unlock(&mMutex);
974 return request;
975}