blob: d8eae3f7ab776866b923bcd14386360af79905db [file] [log] [blame]
Dante Russoc85c8ff2017-02-28 16:45:47 -08001/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
2 *
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
Baili Fengc0a300c2017-06-13 15:26:57 +080029#define LOG_NDDEBUG 0
Dante Russoc85c8ff2017-02-28 16:45:47 -080030#define LOG_TAG "LocSvc_APIClientBase"
31
Naresh Munagalaea051702017-06-20 22:18:19 +053032#include <platform_lib_log_util.h>
Dante Russoc85c8ff2017-02-28 16:45:47 -080033#include <loc_cfg.h>
34#include "LocationAPIClientBase.h"
35
Baili Fengc0a300c2017-06-13 15:26:57 +080036#define FLP_CONF_FILE "/etc/flp.conf"
37#define GEOFENCE_SESSION_ID 0xFFFFFFFF
38#define CONFIG_SESSION_ID 0xFFFFFFFF
Dante Russoc85c8ff2017-02-28 16:45:47 -080039
Baili Feng1a128bd2017-06-21 17:46:23 +080040// LocationAPIControlClient
41LocationAPIControlClient::LocationAPIControlClient() :
42 mEnabled(false)
43{
44 pthread_mutex_init(&mMutex, nullptr);
45
46 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
47 mRequestQueues[i].reset(0);
48 }
49
50 memset(&mConfig, 0, sizeof(GnssConfig));
51
52 LocationControlCallbacks locationControlCallbacks;
53 locationControlCallbacks.size = sizeof(LocationControlCallbacks);
54
55 locationControlCallbacks.responseCb =
56 [this](LocationError error, uint32_t id) {
57 onCtrlResponseCb(error, id);
58 };
59 locationControlCallbacks.collectiveResponseCb =
60 [this](size_t count, LocationError* errors, uint32_t* ids) {
61 onCtrlCollectiveResponseCb(count, errors, ids);
62 };
63
64 mLocationControlAPI = LocationControlAPI::createInstance(locationControlCallbacks);
65}
66
67LocationAPIControlClient::~LocationAPIControlClient()
68{
69 pthread_mutex_lock(&mMutex);
70
71 if (mLocationControlAPI) {
72 mLocationControlAPI->destroy();
73 mLocationControlAPI = nullptr;
74 }
75
76 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
77 mRequestQueues[i].reset(0);
78 }
79
80 pthread_mutex_unlock(&mMutex);
81
82 pthread_mutex_destroy(&mMutex);
83}
84
85uint32_t LocationAPIControlClient::locAPIGnssDeleteAidingData(GnssAidingData& data)
86{
87 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
88 pthread_mutex_lock(&mMutex);
89 if (mLocationControlAPI) {
90 uint32_t session = mLocationControlAPI->gnssDeleteAidingData(data);
91 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
92 mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].reset(session);
93 mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].push(new GnssDeleteAidingDataRequest(*this));
94
95 retVal = LOCATION_ERROR_SUCCESS;
96 }
97 pthread_mutex_unlock(&mMutex);
98
99 return retVal;
100}
101
102uint32_t LocationAPIControlClient::locAPIEnable(LocationTechnologyType techType)
103{
104 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
105 pthread_mutex_lock(&mMutex);
106 if (mEnabled) {
107 // just return success if already enabled
108 retVal = LOCATION_ERROR_SUCCESS;
109 } else if (mLocationControlAPI) {
110 uint32_t session = mLocationControlAPI->enable(techType);
111 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
112 mRequestQueues[CTRL_REQUEST_CONTROL].reset(session);
113 mRequestQueues[CTRL_REQUEST_CONTROL].push(new EnableRequest(*this));
114 retVal = LOCATION_ERROR_SUCCESS;
115 mEnabled = true;
116 } else {
117 LOC_LOGE("%s:%d] failed.", __FUNCTION__, __LINE__);
118 }
119 pthread_mutex_unlock(&mMutex);
120
121 return retVal;
122}
123
124void LocationAPIControlClient::locAPIDisable()
125{
126 pthread_mutex_lock(&mMutex);
127 if (mEnabled && mLocationControlAPI) {
128 uint32_t session = 0;
129 session = mRequestQueues[CTRL_REQUEST_CONTROL].getSession();
130 if (session > 0) {
131 mRequestQueues[CTRL_REQUEST_CONTROL].push(new DisableRequest(*this));
132 mLocationControlAPI->disable(session);
133 mEnabled = false;
134 } else {
135 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
136 }
137 }
138 pthread_mutex_unlock(&mMutex);
139}
140
141uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
142{
143 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
144 if (memcmp(&mConfig, &config, sizeof(GnssConfig)) == 0) {
145 LOC_LOGV("%s:%d] GnssConfig is identical to previous call", __FUNCTION__, __LINE__);
146 retVal = LOCATION_ERROR_SUCCESS;
147 return retVal;
148 }
149
150 pthread_mutex_lock(&mMutex);
151 if (mLocationControlAPI) {
152
153 memcpy(&mConfig, &config, sizeof(GnssConfig));
154
155 uint32_t session = 0;
156 uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
157 LOC_LOGV("%s:%d] gnssUpdateConfig return array: %p", __FUNCTION__, __LINE__, idArray);
158 if (idArray != nullptr) {
159 if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() != CONFIG_SESSION_ID) {
160 mRequestQueues[CTRL_REQUEST_CONFIG].reset(CONFIG_SESSION_ID);
161 }
162 mRequestQueues[CTRL_REQUEST_CONFIG].push(new GnssUpdateConfigRequest(*this));
163 retVal = LOCATION_ERROR_SUCCESS;
164 }
165 }
166 pthread_mutex_unlock(&mMutex);
167 return retVal;
168}
169
170void LocationAPIControlClient::onCtrlResponseCb(LocationError error, uint32_t id)
171{
172 if (error != LOCATION_ERROR_SUCCESS) {
173 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
174 } else {
175 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
176 }
177 LocationAPIRequest* request = getRequestBySession(id);
178 if (request) {
Baili Feng2df685d2017-07-20 17:02:26 +0800179 request->onResponse(error, id);
Baili Feng1a128bd2017-06-21 17:46:23 +0800180 delete request;
181 }
182}
183
184void LocationAPIControlClient::onCtrlCollectiveResponseCb(
185 size_t count, LocationError* errors, uint32_t* ids)
186{
187 for (size_t i = 0; i < count; i++) {
188 if (errors[i] != LOCATION_ERROR_SUCCESS) {
189 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
190 } else {
191 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
192 }
193 }
194 LocationAPIRequest* request = nullptr;
195 pthread_mutex_lock(&mMutex);
196 if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() == CONFIG_SESSION_ID) {
197 request = mRequestQueues[CTRL_REQUEST_CONFIG].pop();
198 }
199 pthread_mutex_unlock(&mMutex);
200 if (request) {
201 request->onCollectiveResponse(count, errors, ids);
202 delete request;
203 }
204}
205
206LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t session)
207{
208 pthread_mutex_lock(&mMutex);
209 LocationAPIRequest* request = nullptr;
210 for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
211 if (i != CTRL_REQUEST_CONFIG &&
212 mRequestQueues[i].getSession() == session) {
213 request = mRequestQueues[i].pop();
214 break;
215 }
216 }
217 pthread_mutex_unlock(&mMutex);
218 return request;
219}
220
221// LocationAPIClientBase
Dante Russoc85c8ff2017-02-28 16:45:47 -0800222LocationAPIClientBase::LocationAPIClientBase() :
Dante Russoc85c8ff2017-02-28 16:45:47 -0800223 mGeofenceBreachCallback(nullptr),
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700224 mBatchingStatusCallback(nullptr),
Dante Russoc85c8ff2017-02-28 16:45:47 -0800225 mLocationAPI(nullptr),
Baili Feng1a128bd2017-06-21 17:46:23 +0800226 mBatchSize(-1)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800227{
228
229 // use recursive mutex, in case callback come from the same thread
230 pthread_mutexattr_t attr;
231 pthread_mutexattr_init(&attr);
232 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
233 pthread_mutex_init(&mMutex, &attr);
234
235 for (int i = 0; i < REQUEST_MAX; i++) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800236 mRequestQueues[i].reset(0);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800237 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800238}
239
240void LocationAPIClientBase::locAPISetCallbacks(LocationCallbacks& locationCallbacks)
241{
Baili Fengb29778e2017-05-23 14:32:22 +0800242 pthread_mutex_lock(&mMutex);
243
Dante Russoc85c8ff2017-02-28 16:45:47 -0800244 if (locationCallbacks.geofenceBreachCb != nullptr) {
245 mGeofenceBreachCallback = locationCallbacks.geofenceBreachCb;
246 locationCallbacks.geofenceBreachCb =
247 [this](GeofenceBreachNotification geofenceBreachNotification) {
248 beforeGeofenceBreachCb(geofenceBreachNotification);
249 };
250 }
251
252 locationCallbacks.capabilitiesCb =
253 [this](LocationCapabilitiesMask capabilitiesMask) {
254 onCapabilitiesCb(capabilitiesMask);
255 };
256 locationCallbacks.responseCb = [this](LocationError error, uint32_t id) {
257 onResponseCb(error, id);
258 };
259 locationCallbacks.collectiveResponseCb =
260 [this](size_t count, LocationError* errors, uint32_t* ids) {
261 onCollectiveResponseCb(count, errors, ids);
262 };
263
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700264 if (locationCallbacks.batchingStatusCb != nullptr) {
265 mBatchingStatusCallback = locationCallbacks.batchingStatusCb;
266 locationCallbacks.batchingStatusCb =
267 [this](BatchingStatusInfo batchStatus, std::list<uint32_t> & tripCompletedList) {
268 beforeBatchingStatusCb(batchStatus, tripCompletedList);
269 };
270 }
271
Dante Russoc85c8ff2017-02-28 16:45:47 -0800272 if (mLocationAPI == nullptr ) {
273 mLocationAPI = LocationAPI::createInstance(locationCallbacks);
274 } else {
275 mLocationAPI->updateCallbacks(locationCallbacks);
276 }
277
Baili Fengb29778e2017-05-23 14:32:22 +0800278 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800279}
280
281LocationAPIClientBase::~LocationAPIClientBase()
282{
Baili Fengb29778e2017-05-23 14:32:22 +0800283 pthread_mutex_lock(&mMutex);
284
Baili Fengc0a300c2017-06-13 15:26:57 +0800285 mGeofenceBreachCallback = nullptr;
286
Dante Russoc85c8ff2017-02-28 16:45:47 -0800287 if (mLocationAPI) {
288 mLocationAPI->destroy();
289 mLocationAPI = nullptr;
290 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800291
Dante Russoc85c8ff2017-02-28 16:45:47 -0800292 for (int i = 0; i < REQUEST_MAX; i++) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800293 mRequestQueues[i].reset(0);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800294 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800295
Dante Russoc85c8ff2017-02-28 16:45:47 -0800296 pthread_mutex_unlock(&mMutex);
297
298 pthread_mutex_destroy(&mMutex);
299}
300
301uint32_t LocationAPIClientBase::locAPIStartTracking(LocationOptions& options)
302{
303 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800304 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800305 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800306 uint32_t session = mLocationAPI->startTracking(options);
307 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
308 // onResponseCb might be called from other thread immediately after
309 // startTracking returns, so we are not going to unlock mutex
310 // until StartTrackingRequest is pushed into mRequestQueues[REQUEST_TRACKING]
Baili Fengc0a300c2017-06-13 15:26:57 +0800311 mRequestQueues[REQUEST_TRACKING].reset(session);
312 mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this));
313
Dante Russoc85c8ff2017-02-28 16:45:47 -0800314
315 retVal = LOCATION_ERROR_SUCCESS;
316 }
Baili Fengb29778e2017-05-23 14:32:22 +0800317 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800318
319 return retVal;
320}
321
322void LocationAPIClientBase::locAPIStopTracking()
323{
Baili Fengb29778e2017-05-23 14:32:22 +0800324 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800325 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800326 uint32_t session = 0;
Baili Fengc0a300c2017-06-13 15:26:57 +0800327 session = mRequestQueues[REQUEST_TRACKING].getSession();
328 if (session > 0) {
329 mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this));
330 mLocationAPI->stopTracking(session);
331 } else {
332 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800333 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800334 }
Baili Fengb29778e2017-05-23 14:32:22 +0800335 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800336}
337
338void LocationAPIClientBase::locAPIUpdateTrackingOptions(LocationOptions& options)
339{
Baili Fengb29778e2017-05-23 14:32:22 +0800340 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800341 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800342 uint32_t session = 0;
Baili Fengc0a300c2017-06-13 15:26:57 +0800343 session = mRequestQueues[REQUEST_TRACKING].getSession();
344 if (session > 0) {
345 mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this));
346 mLocationAPI->updateTrackingOptions(session, options);
347 } else {
348 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800349 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800350 }
Baili Fengb29778e2017-05-23 14:32:22 +0800351 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800352}
353
354int32_t LocationAPIClientBase::locAPIGetBatchSize()
355{
356 if (mBatchSize == -1) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800357 const loc_param_s_type flp_conf_param_table[] =
Dante Russoc85c8ff2017-02-28 16:45:47 -0800358 {
359 {"BATCH_SIZE", &mBatchSize, nullptr, 'n'},
360 };
Baili Fengc0a300c2017-06-13 15:26:57 +0800361 UTIL_READ_CONF(FLP_CONF_FILE, flp_conf_param_table);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800362 if (mBatchSize < 0) {
363 // set mBatchSize to 0 if we got an illegal value from config file
364 mBatchSize = 0;
365 }
366 }
367 return mBatchSize;
368}
369
370
371uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t sessionMode,
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700372 LocationOptions& locationOptions)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800373{
374 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800375 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800376 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800377
Baili Feng2df685d2017-07-20 17:02:26 +0800378 if (mSessionBiDict.hasId(id)) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800379 LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id);
380 retVal = LOCATION_ERROR_ALREADY_STARTED;
381 } else {
382 uint32_t trackingSession = 0;
383 uint32_t batchingSession = 0;
384
385 if (sessionMode == SESSION_MODE_ON_FIX) {
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700386 trackingSession = mLocationAPI->startTracking(locationOptions);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800387 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800388 mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700389 } else if ((sessionMode == SESSION_MODE_ON_FULL) ||
390 (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
391 // Fill in the batch mode
392 BatchingOptions batchOptions = {};
393 batchOptions.size = sizeof(BatchingOptions);
394 batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
395 if (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
396 batchOptions.batchingMode = BATCHING_MODE_TRIP;
397 }
398
399 batchingSession = mLocationAPI->startBatching(locationOptions, batchOptions);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800400 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
Baili Feng2df685d2017-07-20 17:02:26 +0800401 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
402 mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800403 }
404
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700405 uint32_t session = ((sessionMode == SESSION_MODE_ON_FULL ||
406 (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED)) ?
407 batchingSession : trackingSession);
408
Dante Russoc85c8ff2017-02-28 16:45:47 -0800409 SessionEntity entity;
410 entity.id = id;
411 entity.trackingSession = trackingSession;
412 entity.batchingSession = batchingSession;
413 entity.sessionMode = sessionMode;
Baili Feng2df685d2017-07-20 17:02:26 +0800414 mSessionBiDict.set(id, session, entity);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800415
416 retVal = LOCATION_ERROR_SUCCESS;
417 }
418
Dante Russoc85c8ff2017-02-28 16:45:47 -0800419 }
Baili Fengb29778e2017-05-23 14:32:22 +0800420 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800421
422 return retVal;
423}
424
425uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
426{
427 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800428 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800429 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800430
Baili Feng2df685d2017-07-20 17:02:26 +0800431 if (mSessionBiDict.hasId(id)) {
432 SessionEntity entity = mSessionBiDict.getExtById(id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800433
434 uint32_t trackingSession = entity.trackingSession;
435 uint32_t batchingSession = entity.batchingSession;
436 uint32_t sMode = entity.sessionMode;
437
Dante Russoc85c8ff2017-02-28 16:45:47 -0800438 if (sMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800439 mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this));
440 mLocationAPI->stopTracking(trackingSession);
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700441 } else if ((sMode == SESSION_MODE_ON_FULL) ||
442 (sMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
Baili Feng2df685d2017-07-20 17:02:26 +0800443 mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this));
444 mLocationAPI->stopBatching(batchingSession);
445 } else {
446 LOC_LOGE("%s:%d] unknown mode %d.", __FUNCTION__, __LINE__, sMode);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800447 }
448
449 retVal = LOCATION_ERROR_SUCCESS;
450 } else {
451 retVal = LOCATION_ERROR_ID_UNKNOWN;
452 LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
453 }
454
Dante Russoc85c8ff2017-02-28 16:45:47 -0800455 }
Baili Fengb29778e2017-05-23 14:32:22 +0800456 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800457 return retVal;
458}
459
460uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
461 LocationOptions& options)
462{
463 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800464 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800465 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800466
Baili Feng2df685d2017-07-20 17:02:26 +0800467 if (mSessionBiDict.hasId(id)) {
468 SessionEntity entity = mSessionBiDict.getExtById(id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800469
470 uint32_t trackingSession = entity.trackingSession;
471 uint32_t batchingSession = entity.batchingSession;
472 uint32_t sMode = entity.sessionMode;
473
474 if (sessionMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800475 // we only add an UpdateTrackingOptionsRequest to mRequestQueues[REQUEST_SESSION],
476 // even if this update request will stop batching and then start tracking.
477 mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800478 if (sMode == SESSION_MODE_ON_FIX) {
Baili Feng2df685d2017-07-20 17:02:26 +0800479 mLocationAPI->updateTrackingOptions(trackingSession, options);
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700480 } else if ((sMode == SESSION_MODE_ON_FULL) ||
481 (sMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800482 // stop batching
Baili Feng2df685d2017-07-20 17:02:26 +0800483 // batchingSession will be removed from mSessionBiDict soon,
484 // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
485 mLocationAPI->stopBatching(batchingSession);
486 batchingSession = 0;
487 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
488
Dante Russoc85c8ff2017-02-28 16:45:47 -0800489 // start tracking
Baili Feng2df685d2017-07-20 17:02:26 +0800490 trackingSession = mLocationAPI->startTracking(options);
491 LOC_LOGI("%s:%d] start new session: %d",
492 __FUNCTION__, __LINE__, trackingSession);
493 } else {
494 LOC_LOGE("%s:%d] unknown mode %d", __FUNCTION__, __LINE__, sMode);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800495 }
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700496 } else if ((sessionMode == SESSION_MODE_ON_FULL) ||
497 (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
Baili Feng2df685d2017-07-20 17:02:26 +0800498 // we only add an UpdateBatchingOptionsRequest to mRequestQueues[REQUEST_SESSION],
499 // even if this update request will stop tracking and then start batching.
500 mRequestQueues[REQUEST_SESSION].push(new UpdateBatchingOptionsRequest(*this));
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700501 BatchingOptions batchOptions = {};
502 batchOptions.size = sizeof(BatchingOptions);
503 batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
504 if (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
505 batchOptions.batchingMode = BATCHING_MODE_TRIP;
506 }
507
Dante Russoc85c8ff2017-02-28 16:45:47 -0800508 if (sMode == SESSION_MODE_ON_FIX) {
509 // stop tracking
Baili Feng2df685d2017-07-20 17:02:26 +0800510 // trackingSession will be removed from mSessionBiDict soon,
511 // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
512 mLocationAPI->stopTracking(trackingSession);
513 trackingSession = 0;
514
Dante Russoc85c8ff2017-02-28 16:45:47 -0800515 // start batching
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700516 batchingSession = mLocationAPI->startBatching(options, batchOptions);
Baili Feng2df685d2017-07-20 17:02:26 +0800517 LOC_LOGI("%s:%d] start new session: %d",
518 __FUNCTION__, __LINE__, batchingSession);
519 mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700520 } else if ((sMode == SESSION_MODE_ON_FULL) ||
521 (sMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
522 mLocationAPI->updateBatchingOptions(batchingSession, options, batchOptions);
Baili Feng2df685d2017-07-20 17:02:26 +0800523 } else {
524 LOC_LOGE("%s:%d] unknown mode %d", __FUNCTION__, __LINE__, sMode);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800525 }
Baili Feng2df685d2017-07-20 17:02:26 +0800526
527 } else {
528 LOC_LOGE("%s:%d] unknown mode %d.", __FUNCTION__, __LINE__, sessionMode);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800529 }
530
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700531 uint32_t session = ((sessionMode == SESSION_MODE_ON_FULL) ||
532 (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) ?
533 batchingSession : trackingSession);
534
Dante Russoc85c8ff2017-02-28 16:45:47 -0800535 entity.trackingSession = trackingSession;
536 entity.batchingSession = batchingSession;
537 entity.sessionMode = sessionMode;
Baili Feng2df685d2017-07-20 17:02:26 +0800538 // remove the old values from mSessionBiDict before we add a new one.
539 mSessionBiDict.rmById(id);
540 mSessionBiDict.set(id, session, entity);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800541
542 retVal = LOCATION_ERROR_SUCCESS;
543 } else {
544 retVal = LOCATION_ERROR_ID_UNKNOWN;
545 LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
546 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800547 }
Baili Fengb29778e2017-05-23 14:32:22 +0800548 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800549 return retVal;
550}
551
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700552void LocationAPIClientBase::locAPIGetBatchedLocations(uint32_t id, size_t count)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800553{
Baili Fengb29778e2017-05-23 14:32:22 +0800554 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800555 if (mLocationAPI) {
Baili Fengb29778e2017-05-23 14:32:22 +0800556 uint32_t session = 0;
Baili Feng2df685d2017-07-20 17:02:26 +0800557 session = mRequestQueues[REQUEST_SESSION].getSession();
Baili Fengc0a300c2017-06-13 15:26:57 +0800558 if (session > 0) {
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700559 SessionEntity entity = mSessionBiDict.getExtById(id);
560 uint32_t batchingSession = entity.batchingSession;
Baili Feng2df685d2017-07-20 17:02:26 +0800561 mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this));
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700562 mLocationAPI->getBatchedLocations(batchingSession, count);
563 } else {
Baili Fengc0a300c2017-06-13 15:26:57 +0800564 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800565 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800566 }
Baili Fengb29778e2017-05-23 14:32:22 +0800567 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800568}
569
570uint32_t LocationAPIClientBase::locAPIAddGeofences(
571 size_t count, uint32_t* ids, GeofenceOption* options, GeofenceInfo* data)
572{
573 uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
Baili Fengb29778e2017-05-23 14:32:22 +0800574 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800575 if (mLocationAPI) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800576 if (mRequestQueues[REQUEST_GEOFENCE].getSession() != GEOFENCE_SESSION_ID) {
577 mRequestQueues[REQUEST_GEOFENCE].reset(GEOFENCE_SESSION_ID);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800578 }
579 uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
Dante Russo2e87b202017-03-20 15:04:36 -0700580 if (sessions) {
581 LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
Baili Fengc0a300c2017-06-13 15:26:57 +0800582 mRequestQueues[REQUEST_GEOFENCE].push(new AddGeofencesRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800583
Dante Russo2e87b202017-03-20 15:04:36 -0700584 for (size_t i = 0; i < count; i++) {
585 mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
586 }
587 retVal = LOCATION_ERROR_SUCCESS;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800588 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800589 }
Baili Fengb29778e2017-05-23 14:32:22 +0800590 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800591
592 return retVal;
593}
594
595void LocationAPIClientBase::locAPIRemoveGeofences(size_t count, uint32_t* ids)
596{
Baili Fengb29778e2017-05-23 14:32:22 +0800597 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800598 if (mLocationAPI) {
599 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530600 if (sessions == NULL) {
601 LOC_LOGE("%s:%d] Failed to allocate %d bytes !",
602 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530603 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530604 return;
605 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800606
Baili Fengc0a300c2017-06-13 15:26:57 +0800607 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800608 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800609 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800610 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
611 if (sessions[j] > 0) {
612 j++;
613 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800614 }
Baili Fengb29778e2017-05-23 14:32:22 +0800615 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800616 mRequestQueues[REQUEST_GEOFENCE].push(new RemoveGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800617 mLocationAPI->removeGeofences(j, sessions);
618 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800619 } else {
620 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
621 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800622 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800623
624 free(sessions);
625 }
Baili Fengb29778e2017-05-23 14:32:22 +0800626 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800627}
628
629void LocationAPIClientBase::locAPIModifyGeofences(
630 size_t count, uint32_t* ids, GeofenceOption* options)
631{
Baili Fengb29778e2017-05-23 14:32:22 +0800632 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800633 if (mLocationAPI) {
634 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530635 if (sessions == NULL) {
636 LOC_LOGE("%s:%d] Failed to allocate %d bytes !",
637 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530638 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530639 return;
640 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800641
Baili Fengc0a300c2017-06-13 15:26:57 +0800642 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800643 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800644 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800645 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
646 if (sessions[j] > 0) {
647 mGeofenceBiDict.set(ids[i], sessions[j], options[i].breachTypeMask);
648 j++;
649 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800650 }
Baili Fengb29778e2017-05-23 14:32:22 +0800651 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800652 mRequestQueues[REQUEST_GEOFENCE].push(new ModifyGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800653 mLocationAPI->modifyGeofences(j, sessions, options);
654 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800655 } else {
656 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
657 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800658 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800659
660 free(sessions);
661 }
Baili Fengb29778e2017-05-23 14:32:22 +0800662 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800663}
664
665void LocationAPIClientBase::locAPIPauseGeofences(size_t count, uint32_t* ids)
666{
Baili Fengb29778e2017-05-23 14:32:22 +0800667 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800668 if (mLocationAPI) {
669 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530670 if (sessions == NULL) {
671 LOC_LOGE("%s:%d] Failed to allocate %d bytes !",
672 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530673 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530674 return;
675 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800676
Baili Fengc0a300c2017-06-13 15:26:57 +0800677 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800678 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800679 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800680 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
681 if (sessions[j] > 0) {
682 j++;
683 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800684 }
Baili Fengb29778e2017-05-23 14:32:22 +0800685 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800686 mRequestQueues[REQUEST_GEOFENCE].push(new PauseGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800687 mLocationAPI->pauseGeofences(j, sessions);
688 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800689 } else {
690 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
691 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800692 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800693
694 free(sessions);
695 }
Baili Fengb29778e2017-05-23 14:32:22 +0800696 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800697}
698
699void LocationAPIClientBase::locAPIResumeGeofences(
700 size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask)
701{
Baili Fengb29778e2017-05-23 14:32:22 +0800702 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800703 if (mLocationAPI) {
704 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530705 if (sessions == NULL) {
706 LOC_LOGE("%s:%d] Failed to allocate %d bytes !",
707 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530708 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530709 return;
710 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800711
Baili Fengc0a300c2017-06-13 15:26:57 +0800712 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800713 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800714 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800715 sessions[j] = mGeofenceBiDict.getSession(ids[i]);
716 if (sessions[j] > 0) {
717 if (mask) {
718 mGeofenceBiDict.set(ids[i], sessions[j], mask[i]);
719 }
720 j++;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800721 }
722 }
Baili Fengb29778e2017-05-23 14:32:22 +0800723 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800724 mRequestQueues[REQUEST_GEOFENCE].push(new ResumeGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800725 mLocationAPI->resumeGeofences(j, sessions);
726 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800727 } else {
728 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
729 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800730 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800731
732 free(sessions);
733 }
Baili Fengb29778e2017-05-23 14:32:22 +0800734 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800735}
736
737void LocationAPIClientBase::locAPIRemoveAllGeofences()
738{
Baili Fengb29778e2017-05-23 14:32:22 +0800739 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800740 if (mLocationAPI) {
741 std::vector<uint32_t> sessionsVec = mGeofenceBiDict.getAllSessions();
742 size_t count = sessionsVec.size();
743 uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530744 if (sessions == NULL) {
745 LOC_LOGE("%s:%d] Failed to allocate %d bytes !",
746 __FUNCTION__, __LINE__, sizeof(uint32_t) * count);
Saurabh Srivastava2481cf32017-07-27 17:20:24 +0530747 pthread_mutex_unlock(&mMutex);
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530748 return;
749 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800750
Baili Fengc0a300c2017-06-13 15:26:57 +0800751 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
Baili Fengb29778e2017-05-23 14:32:22 +0800752 size_t j = 0;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800753 for (size_t i = 0; i < count; i++) {
Baili Fengb29778e2017-05-23 14:32:22 +0800754 sessions[j] = sessionsVec[i];
755 if (sessions[j] > 0) {
756 j++;
757 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800758 }
Baili Fengb29778e2017-05-23 14:32:22 +0800759 if (j > 0) {
Baili Fengc0a300c2017-06-13 15:26:57 +0800760 mRequestQueues[REQUEST_GEOFENCE].push(new RemoveGeofencesRequest(*this));
Baili Fengb29778e2017-05-23 14:32:22 +0800761 mLocationAPI->removeGeofences(j, sessions);
762 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800763 } else {
764 LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
765 mRequestQueues[REQUEST_GEOFENCE].getSession());
Dante Russoc85c8ff2017-02-28 16:45:47 -0800766 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800767
768 free(sessions);
769 }
Baili Fengb29778e2017-05-23 14:32:22 +0800770 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800771}
772
773void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
774{
Baili Fengb29778e2017-05-23 14:32:22 +0800775 pthread_mutex_lock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800776 if (mLocationAPI) {
Dante Russoc85c8ff2017-02-28 16:45:47 -0800777 uint32_t session = id;
778 mLocationAPI->gnssNiResponse(id, response);
779 LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
Baili Fengc0a300c2017-06-13 15:26:57 +0800780 mRequestQueues[REQUEST_NIRESPONSE].reset(session);
781 mRequestQueues[REQUEST_NIRESPONSE].push(new GnssNiResponseRequest(*this));
Dante Russoc85c8ff2017-02-28 16:45:47 -0800782 }
Baili Fengb29778e2017-05-23 14:32:22 +0800783 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800784}
785
Dante Russoc85c8ff2017-02-28 16:45:47 -0800786void LocationAPIClientBase::beforeGeofenceBreachCb(
787 GeofenceBreachNotification geofenceBreachNotification)
788{
Dante Russoc85c8ff2017-02-28 16:45:47 -0800789 uint32_t* ids = (uint32_t*)malloc(sizeof(uint32_t) * geofenceBreachNotification.count);
790 uint32_t* backup = geofenceBreachNotification.ids;
791 size_t n = geofenceBreachNotification.count;
Baili Fengc0a300c2017-06-13 15:26:57 +0800792 geofenceBreachCallback genfenceCallback = nullptr;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800793
Saurabh Srivastava8cf201a2017-07-03 17:07:37 +0530794 if (ids == NULL) {
795 LOC_LOGE("%s:%d] Failed to alloc %d bytes",
796 __FUNCTION__, __LINE__,
797 sizeof(uint32_t) * geofenceBreachNotification.count);
798 return;
799 }
800
Baili Fengc0a300c2017-06-13 15:26:57 +0800801 pthread_mutex_lock(&mMutex);
802 if (mGeofenceBreachCallback != nullptr) {
803 size_t count = 0;
804 for (size_t i = 0; i < n; i++) {
805 uint32_t id = mGeofenceBiDict.getId(geofenceBreachNotification.ids[i]);
806 GeofenceBreachTypeMask type =
Baili Feng2df685d2017-07-20 17:02:26 +0800807 mGeofenceBiDict.getExtBySession(geofenceBreachNotification.ids[i]);
Baili Fengc0a300c2017-06-13 15:26:57 +0800808 // if type == 0, we will not head into the fllowing block anyway.
809 // so we don't need to check id and type
810 if ((geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER &&
811 (type & GEOFENCE_BREACH_ENTER_BIT)) ||
812 (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT &&
813 (type & GEOFENCE_BREACH_EXIT_BIT))
814 ) {
815 ids[count] = id;
816 count++;
817 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800818 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800819 geofenceBreachNotification.count = count;
820 geofenceBreachNotification.ids = ids;
821
822 genfenceCallback = mGeofenceBreachCallback;
Dante Russoc85c8ff2017-02-28 16:45:47 -0800823 }
Baili Fengc0a300c2017-06-13 15:26:57 +0800824 pthread_mutex_unlock(&mMutex);
825
826 if (genfenceCallback != nullptr) {
827 genfenceCallback(geofenceBreachNotification);
828 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800829
830 // restore ids
831 geofenceBreachNotification.ids = backup;
832 geofenceBreachNotification.count = n;
833 free(ids);
834}
835
Bhavna Sharma686a5c52017-05-02 14:29:46 -0700836void LocationAPIClientBase::beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
837 std::list<uint32_t> & tripCompletedList) {
838
839 // map the trip ids to the client ids
840 std::list<uint32_t> tripCompletedClientIdList;
841 tripCompletedClientIdList.clear();
842
843 if (batchStatus.batchingStatus == BATCHING_STATUS_TRIP_COMPLETED) {
844 for (auto itt = tripCompletedList.begin(); itt != tripCompletedList.end(); itt++) {
845 if (mSessionBiDict.hasSession(*itt)) {
846 SessionEntity sessEntity = mSessionBiDict.getExtBySession(*itt);
847
848 if (sessEntity.sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
849 tripCompletedClientIdList.push_back(sessEntity.id);
850 mSessionBiDict.rmBySession(*itt);
851 }
852 }
853 }
854 }
855
856 mBatchingStatusCallback(batchStatus, tripCompletedClientIdList);
857}
858
Dante Russoc85c8ff2017-02-28 16:45:47 -0800859void LocationAPIClientBase::onResponseCb(LocationError error, uint32_t id)
860{
861 if (error != LOCATION_ERROR_SUCCESS) {
862 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
863 } else {
Baili Feng1a128bd2017-06-21 17:46:23 +0800864 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800865 }
866 LocationAPIRequest* request = getRequestBySession(id);
867 if (request) {
Baili Feng2df685d2017-07-20 17:02:26 +0800868 request->onResponse(error, id);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800869 delete request;
870 }
871}
872
873void LocationAPIClientBase::onCollectiveResponseCb(
874 size_t count, LocationError* errors, uint32_t* ids)
875{
876 for (size_t i = 0; i < count; i++) {
877 if (errors[i] != LOCATION_ERROR_SUCCESS) {
878 LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
879 } else {
Baili Feng1a128bd2017-06-21 17:46:23 +0800880 LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800881 }
882 }
883 LocationAPIRequest* request = nullptr;
Baili Feng1f3ac892017-05-31 16:22:16 +0800884 pthread_mutex_lock(&mMutex);
Baili Fengc0a300c2017-06-13 15:26:57 +0800885 if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
886 request = mRequestQueues[REQUEST_GEOFENCE].pop();
Baili Feng1f3ac892017-05-31 16:22:16 +0800887 }
888 pthread_mutex_unlock(&mMutex);
Dante Russoc85c8ff2017-02-28 16:45:47 -0800889 if (request) {
890 request->onCollectiveResponse(count, errors, ids);
891 delete request;
892 }
893}
894
Baili Feng2df685d2017-07-20 17:02:26 +0800895void LocationAPIClientBase::removeSession(uint32_t session) {
896 if (mSessionBiDict.hasSession(session)) {
897 mSessionBiDict.rmBySession(session);
898 }
899}
900
Baili Feng1a128bd2017-06-21 17:46:23 +0800901LocationAPIRequest* LocationAPIClientBase::getRequestBySession(uint32_t session)
Dante Russoc85c8ff2017-02-28 16:45:47 -0800902{
903 pthread_mutex_lock(&mMutex);
904 LocationAPIRequest* request = nullptr;
905 for (int i = 0; i < REQUEST_MAX; i++) {
906 if (i != REQUEST_GEOFENCE &&
Baili Feng2df685d2017-07-20 17:02:26 +0800907 i != REQUEST_SESSION &&
Baili Fengc0a300c2017-06-13 15:26:57 +0800908 mRequestQueues[i].getSession() == session) {
909 request = mRequestQueues[i].pop();
Dante Russoc85c8ff2017-02-28 16:45:47 -0800910 break;
911 }
912 }
Baili Feng2df685d2017-07-20 17:02:26 +0800913 if (request == nullptr) {
914 // Can't find a request with correct session,
915 // try to find it from mSessionBiDict
916 if (mSessionBiDict.hasSession(session)) {
917 request = mRequestQueues[REQUEST_SESSION].pop();
918 }
919 }
Dante Russoc85c8ff2017-02-28 16:45:47 -0800920 pthread_mutex_unlock(&mMutex);
921 return request;
922}