[my-place] Change debug flag from TIZEN_ENGINEER_MODE to DEBUG_MODE.
[platform/core/context/context-provider.git] / src / my-place / visit-detector / LocationLogger.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sstream>
18 #include <Types.h>
19 #include <Json.h>
20 #include <DatabaseManager.h>
21 #include <UserPlacesTypes.h>
22 #include <UserPlacesParams.h>
23 #include <DebugUtils.h>
24 #include "LocationLogger.h"
25
26 #ifdef DEBUG_MODE
27 #define __LOCATION_CREATE_TABLE_COLUMNS \
28         LOCATION_COLUMN_LATITUDE " REAL NOT NULL, "\
29         LOCATION_COLUMN_LONGITUDE " REAL NOT NULL, "\
30         LOCATION_COLUMN_ACCURACY " REAL, "\
31         LOCATION_COLUMN_TIMESTAMP " timestamp NOT NULL, "\
32         LOCATION_COLUMN_TIMESTAMP_HUMAN " TEXT, "\
33         LOCATION_COLUMN_METHOD " INTEGER "
34 #else /* DEBUG_MODE */
35 #define __LOCATION_CREATE_TABLE_COLUMNS \
36         LOCATION_COLUMN_LATITUDE " REAL NOT NULL, "\
37         LOCATION_COLUMN_LONGITUDE " REAL NOT NULL, "\
38         LOCATION_COLUMN_ACCURACY " REAL, "\
39         LOCATION_COLUMN_TIMESTAMP " timestamp NOT NULL "
40 #endif /* DEBUG_MODE */
41
42 #define __LOCATION_ERROR_LOG(error) { \
43         if (error != LOCATIONS_ERROR_NONE) { \
44                 _E("ERROR == %s", __locationError2Str(error)); \
45         } else { \
46                 _D("SUCCESS"); \
47         } \
48 }
49
50 void ctx::LocationLogger::__locationServiceStateChangedCb(location_service_state_e state, void *userData)
51 {
52         ctx::LocationLogger* locationLogger = (ctx::LocationLogger *)userData;
53         locationLogger->__locationServiceState = state;
54         if (state == LOCATIONS_SERVICE_ENABLED) {
55                 _D("LOCATIONS_SERVICE_ENABLED");
56                 switch (locationLogger->__timerPurpose) {
57                 case LOCATION_LOGGER_WAITING_FOR_SERVICE_START:
58                         _D("Waiting for location service start FINISHED");
59                         locationLogger->__timerStop();
60                         locationLogger->__locationRequest();
61                         break;
62                 case LOCATION_LOGGER_WAITING_FOR_ACTIVE_REQUEST:
63                 case LOCATION_LOGGER_WAITING_FOR_LOCATION_METHOD_SETTING_ON:
64                 case LOCATION_LOGGER_WAITING_FOR_ACTIVE_INTERVAL:
65                 case LOCATION_LOGGER_WAITING_FOR_PASSIVE_INTERVAL:
66                 default:
67                         // Do nothing
68                         break;
69                 }
70         } else {
71                 _D("LOCATIONS_SERVICE_DISABLED");
72 //              locationLogger->__timerStop();
73         }
74 }
75
76 void ctx::LocationLogger::__locationSettingChangedCb(location_method_e method, bool enable, void *userData)
77 {
78         ctx::LocationLogger* locationLogger = (ctx::LocationLogger *)userData;
79         locationLogger->__locationMethodState = enable;
80         if (method == locationLogger->__locationMethod) {
81                 if (enable) {
82                         _D("Location method settings ON");
83                         switch (locationLogger->__timerPurpose) {
84                         case LOCATION_LOGGER_WAITING_FOR_LOCATION_METHOD_SETTING_ON:
85                                 _D("Waiting for location method settings on FINISHED");
86                                 if (locationLogger->__locationServiceState == LOCATIONS_SERVICE_ENABLED) {
87                                         locationLogger->__timerStop();
88                                         locationLogger->__locationRequest();
89                                 } else {
90                                         locationLogger->__locationManagerStart();
91                                 }
92                                 break;
93                         case LOCATION_LOGGER_WAITING_FOR_SERVICE_START:
94                         case LOCATION_LOGGER_WAITING_FOR_ACTIVE_REQUEST:
95                         case LOCATION_LOGGER_WAITING_FOR_ACTIVE_INTERVAL:
96                         case LOCATION_LOGGER_WAITING_FOR_PASSIVE_INTERVAL:
97                         default:
98                                 // Do nothing
99                                 break;
100                         }
101                 } else {
102                         _D("Location method settings OFF");
103 //                      locationLogger->__timerStop();
104                 }
105         }
106 }
107
108 void ctx::LocationLogger::__positionUpdatedCb(double latitude, double longitude,
109                 double altitude, time_t timestamp, void *userData)
110 {
111         _D("");
112         ctx::LocationLogger* locationLogger = (ctx::LocationLogger *)userData;
113         double horizontal = locationLogger->__locationManagerGetHorizontalAccuracy();
114 #ifdef DEBUG_MODE
115         ctx::LocationEvent location(latitude, longitude, horizontal, timestamp, LOCATION_METHOD_REQUEST);
116 #else /* DEBUG_MODE */
117         ctx::LocationEvent location(latitude, longitude, horizontal, timestamp);
118 #endif /* DEBUG_MODE */
119         locationLogger->__broadcast(location);
120         locationLogger->__onActiveRequestSucceeded();
121 }
122
123 void ctx::LocationLogger::__locationUpdatedCb(location_error_e error, double latitude, double longitude,
124                 double altitude, time_t timestamp, double speed, double direction, double climb, void *userData)
125 {
126         _D("");
127         __positionUpdatedCb(latitude, longitude, altitude, timestamp, userData);
128 }
129
130 const char* ctx::LocationLogger::__locationError2Str(int error)
131 {
132         switch (error) {
133         case LOCATIONS_ERROR_NONE:
134                 return "LOCATIONS_ERROR_NONE";
135         case LOCATIONS_ERROR_OUT_OF_MEMORY:
136                 return "LOCATIONS_ERROR_OUT_OF_MEMORY";
137         case LOCATIONS_ERROR_INVALID_PARAMETER:
138                 return "LOCATIONS_ERROR_INVALID_PARAMETER";
139         case LOCATIONS_ERROR_ACCESSIBILITY_NOT_ALLOWED:
140                 return "LOCATIONS_ERROR_ACCESSIBILITY_NOT_ALLOWED";
141         case LOCATIONS_ERROR_NOT_SUPPORTED:
142                 return "LOCATIONS_ERROR_NOT_SUPPORTED";
143         case LOCATIONS_ERROR_INCORRECT_METHOD:
144                 return "LOCATIONS_ERROR_INCORRECT_METHOD";
145         case LOCATIONS_ERROR_NETWORK_FAILED:
146                 return "LOCATIONS_ERROR_NETWORK_FAILED";
147         case LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE:
148                 return "LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE";
149         case LOCATIONS_ERROR_GPS_SETTING_OFF:
150                 return "LOCATIONS_ERROR_GPS_SETTING_OFF";
151         case LOCATIONS_ERROR_SECURITY_RESTRICTED:
152                 return "LOCATIONS_ERROR_SECURITY_RESTRICTED";
153         default:
154                 return "unknown location error code";
155         }
156 }
157
158
159 void ctx::LocationLogger::__log(location_accessibility_state_e state)
160 {
161         switch (state) {
162         case LOCATIONS_ACCESS_STATE_NONE : // Access state is not determined
163                 _D("LOCATIONS_ACCESS_STATE_NONE ");
164                 break;
165         case LOCATIONS_ACCESS_STATE_DENIED: // Access denied
166                 _D("LOCATIONS_ACCESS_STATE_DENIED");
167                 break;
168         case LOCATIONS_ACCESS_STATE_ALLOWED: // Access authorized
169                 _D("LOCATIONS_ACCESS_STATE_ALLOWED");
170                 break;
171         default:
172                 break;
173         }
174 }
175
176 int ctx::LocationLogger::__dbCreateTable()
177 {
178         DatabaseManager dbManager;
179         bool ret = dbManager.createTableSync(LOCATION_TABLE, __LOCATION_CREATE_TABLE_COLUMNS);
180         _D("%s -> Table Creation Request", ret ? "SUCCESS" : "FAIL");
181         return 0;
182 }
183
184 int ctx::LocationLogger::__dbInsertLog(LocationEvent locationEvent)
185 {
186         Json data;
187         data.set(NULL, LOCATION_COLUMN_LATITUDE, locationEvent.coordinates.latitude);
188         data.set(NULL, LOCATION_COLUMN_LONGITUDE, locationEvent.coordinates.longitude);
189         data.set(NULL, LOCATION_COLUMN_ACCURACY, locationEvent.coordinates.accuracy);
190         data.set(NULL, LOCATION_COLUMN_TIMESTAMP, static_cast<int>(locationEvent.timestamp));
191 #ifdef DEBUG_MODE
192         std::string timeHuman = DebugUtils::humanReadableDateTime(locationEvent.timestamp, "%F %T", 80);
193         data.set(NULL, LOCATION_COLUMN_TIMESTAMP_HUMAN, timeHuman);
194         data.set(NULL, LOCATION_COLUMN_METHOD, static_cast<int>(locationEvent.method));
195 #endif /* DEBUG_MODE */
196
197         DatabaseManager dbManager;
198         int64_t rowId;
199         bool ret = dbManager.insertSync(LOCATION_TABLE, data, &rowId);
200         _D("%s -> DB: location table insert result", ret ? "SUCCESS" : "FAIL");
201         return ret;
202 }
203
204 ctx::LocationLogger::LocationLogger(ILocationListener *listener) :
205         __listener(listener),
206         __activeRequestAttempts(0),
207         __activeAttempts(0),
208         __allAttempts(0),
209         __locationCount(0),
210         __activeRequestSucceeded(false),
211         __activeLocationSucceeded(false),
212         __timerId(-1),
213         __timerTimestamp(0),
214         __timerPurpose(LOCATION_LOGGER_WAITING_FOR_PASSIVE_INTERVAL),
215         __locationServiceState(LOCATIONS_SERVICE_DISABLED),
216         __locationMethod(LOCATION_LOGGER_METHOD),
217         __locationMethodState(false)
218 {
219         _D("CONSTRUCTOR");
220
221         __locationManagerCreate();
222
223         if (LOCATION_LOGGER_DATABASE)
224                 __dbCreateTable();
225
226         __locationManagerSetServiceStateChangedCb();
227         __locationManagerSetSettingChangedCb();
228         __locationMethodState = __locationManagerIsEnabledMethod(__locationMethod);
229 }
230
231 ctx::LocationLogger::~LocationLogger()
232 {
233         _D("DESTRUCTOR");
234         __stopLogging();
235         __locationManagerUnsetServiceStateChangedCb();
236         __locationManagerUnsetSettingChangedCb();
237         __locationManagerDestroy();
238 }
239
240 void ctx::LocationLogger::__locationManagerCreate()
241 {
242         int ret = location_manager_create(__locationMethod, &__locationManager);
243         __LOCATION_ERROR_LOG(ret);
244 }
245
246 void ctx::LocationLogger::__locationManagerDestroy()
247 {
248         int ret = location_manager_destroy(__locationManager);
249         __LOCATION_ERROR_LOG(ret);
250 }
251
252 void ctx::LocationLogger::__locationManagerSetServiceStateChangedCb()
253 {
254         int ret = location_manager_set_service_state_changed_cb(__locationManager, __locationServiceStateChangedCb, this);
255         __LOCATION_ERROR_LOG(ret);
256 }
257
258 void ctx::LocationLogger::__locationManagerUnsetServiceStateChangedCb()
259 {
260         int ret = location_manager_unset_service_state_changed_cb(__locationManager);
261         __LOCATION_ERROR_LOG(ret);
262 }
263
264 void ctx::LocationLogger::__locationManagerStart()
265 {
266         int ret = location_manager_start(__locationManager);
267         __LOCATION_ERROR_LOG(ret);
268         __startServiceTimerStart();
269 }
270
271 void ctx::LocationLogger::__locationManagerStop()
272 {
273         int ret = location_manager_stop(__locationManager);
274         __LOCATION_ERROR_LOG(ret);
275 }
276
277 double ctx::LocationLogger::__locationManagerGetHorizontalAccuracy()
278 {
279         location_accuracy_level_e accuracyLevel;
280         double horizontal, vertical;
281         int ret = location_manager_get_accuracy(__locationManager, &accuracyLevel, &horizontal, &vertical);
282         __LOCATION_ERROR_LOG(ret);
283         return horizontal;
284 }
285
286 location_accessibility_state_e ctx::LocationLogger::__locationManagerGetAccessibilityState()
287 {
288         location_accessibility_state_e state;
289         int ret = location_manager_get_accessibility_state(&state);
290         __LOCATION_ERROR_LOG(ret);
291         return state;
292 }
293
294 void ctx::LocationLogger::__locationManagerSetSettingChangedCb()
295 {
296         int ret = location_manager_set_setting_changed_cb(__locationMethod, __locationSettingChangedCb, this);
297         __LOCATION_ERROR_LOG(ret);
298 }
299
300 void ctx::LocationLogger::__locationManagerUnsetSettingChangedCb()
301 {
302         int ret = location_manager_unset_setting_changed_cb(__locationMethod);
303         __LOCATION_ERROR_LOG(ret);
304 }
305
306 bool ctx::LocationLogger::__locationManagerRequestSingleLocation()
307 {
308         int ret = location_manager_request_single_location(__locationManager,
309                         LOCATION_LOGGER_ACTIVE_REQUEST_TIMEOUT_SECONDS, __locationUpdatedCb, this);
310         _D("%s (seconds=%d) ----- ATTEMPTS: REQ[%d/%d], ACT[%d/%d], ALL[%d/%d]; ----- LOCATIONS:[%d/%d]",
311                         ret == LOCATIONS_ERROR_NONE ? "SUCCESS" : "ERROR",
312                         LOCATION_LOGGER_ACTIVE_REQUEST_TIMEOUT_SECONDS,
313                         __activeRequestAttempts,
314                         LOCATION_LOGGER_MAX_ACTIVE_REQUEST_ATTEMPTS,
315                         __activeAttempts,
316                         LOCATION_LOGGER_MAX_ACTIVE_LOCATION_ATTEMPTS,
317                         __allAttempts,
318                         LOCATION_LOGGER_MAX_LOCATION_ATTEMPTS,
319                         __locationCount,
320                         LOCATION_LOGGER_MAX_LOCATION_COUNT);
321         __LOCATION_ERROR_LOG(ret);
322         __activeRequestAttempts++;
323         __activeAttempts++;
324         __allAttempts++;
325         if (ret == LOCATIONS_ERROR_NONE) {
326                 __activeRequestTimerStart();
327                 return true;
328         } else {
329                 return false;
330         }
331 }
332
333 bool ctx::LocationLogger::__locationManagerGetLocation()
334 {
335         double altitude, latitude, longitude, climb, direction, speed, horizontal, vertical;
336         location_accuracy_level_e level;
337         time_t timestamp;
338         int ret = location_manager_get_location(__locationManager, &altitude, &latitude, &longitude,
339                         &climb, &direction, &speed, &level, &horizontal, &vertical, &timestamp);
340         _D("%s ----- ATTEMPTS: REQ[%d/%d], ACT[%d/%d], ALL[%d/%d]; ----- LOCATIONS:[%d/%d]",
341                         ret == LOCATIONS_ERROR_NONE ? "SUCCESS" : "ERROR",
342                         __activeRequestAttempts,
343                         LOCATION_LOGGER_MAX_ACTIVE_REQUEST_ATTEMPTS,
344                         __activeAttempts,
345                         LOCATION_LOGGER_MAX_ACTIVE_LOCATION_ATTEMPTS,
346                         __allAttempts,
347                         LOCATION_LOGGER_MAX_LOCATION_ATTEMPTS,
348                         __locationCount,
349                         LOCATION_LOGGER_MAX_LOCATION_COUNT);
350         __LOCATION_ERROR_LOG(ret);
351         __activeAttempts++;
352         __allAttempts++;
353         if (ret == LOCATIONS_ERROR_NONE) {
354 #ifdef DEBUG_MODE
355                 ctx::LocationEvent location(latitude, longitude, horizontal, timestamp, LOCATION_METHOD_GET_LOCATION);
356 #else /* DEBUG_MODE */
357                 ctx::LocationEvent location(latitude, longitude, horizontal, timestamp);
358 #endif /* DEBUG_MODE */
359                 __broadcast(location);
360                 __onActiveLocationSucceeded();
361                 return true;
362         } else {
363                 return false;
364         }
365 }
366
367 void ctx::LocationLogger::__locationManagerGetLastLocation()
368 {
369         double altitude, latitude, longitude, climb, direction, speed, horizontal, vertical;
370         location_accuracy_level_e level;
371         time_t timestamp;
372         int ret = location_manager_get_last_location(__locationManager, &altitude, &latitude, &longitude,
373                         &climb, &direction, &speed, &level, &horizontal, &vertical, &timestamp);
374         _D("%s ----- ATTEMPTS: REQ[%d/%d], ACT[%d/%d], ALL[%d/%d]; ----- LOCATIONS:[%d/%d]",
375                         ret == LOCATIONS_ERROR_NONE ? "SUCCESS" : "ERROR",
376                         __activeRequestAttempts,
377                         LOCATION_LOGGER_MAX_ACTIVE_REQUEST_ATTEMPTS,
378                         __activeAttempts,
379                         LOCATION_LOGGER_MAX_ACTIVE_LOCATION_ATTEMPTS,
380                         __allAttempts,
381                         LOCATION_LOGGER_MAX_LOCATION_ATTEMPTS,
382                         __locationCount,
383                         LOCATION_LOGGER_MAX_LOCATION_COUNT);
384         __LOCATION_ERROR_LOG(ret);
385         __allAttempts++;
386         if (ret == LOCATIONS_ERROR_NONE) {
387 #ifdef DEBUG_MODE
388                 ctx::LocationEvent location(latitude, longitude, horizontal, timestamp, LOCATION_METHOD_GET_LAST_LOCATION);
389 #else /* DEBUG_MODE */
390                 ctx::LocationEvent location(latitude, longitude, horizontal, timestamp);
391 #endif /* DEBUG_MODE */
392                 __broadcast(location);
393         }
394 }
395
396 bool ctx::LocationLogger::__locationManagerIsEnabledMethod(location_method_e method)
397 {
398         bool enable;
399         int ret = location_manager_is_enabled_method(method, &enable);
400         __LOCATION_ERROR_LOG(ret);
401         return enable;
402 }
403
404 bool ctx::LocationLogger::__checkGeneralLimits()
405 {
406         return (__locationCount < LOCATION_LOGGER_MAX_LOCATION_COUNT
407                         && __allAttempts < LOCATION_LOGGER_MAX_LOCATION_ATTEMPTS);
408 }
409
410 bool ctx::LocationLogger::__checkActiveLimits()
411 {
412         return (!__activeLocationSucceeded
413                         && __activeAttempts < LOCATION_LOGGER_MAX_ACTIVE_LOCATION_ATTEMPTS);
414 }
415
416 bool ctx::LocationLogger::__checkActiveRequestLimits()
417 {
418         return (!__activeRequestSucceeded
419                         && __activeRequestAttempts < LOCATION_LOGGER_MAX_ACTIVE_REQUEST_ATTEMPTS);
420 }
421
422 void ctx::LocationLogger::__locationRequest()
423 {
424         _D("");
425         bool requestSingleLocationRet = false;
426         bool getLocationRet = false;
427         if (__checkGeneralLimits() && __checkActiveLimits() && __checkActiveRequestLimits()) {
428                 requestSingleLocationRet = __locationManagerRequestSingleLocation();
429         }
430         if (__checkGeneralLimits() && __checkActiveLimits() && !requestSingleLocationRet) {
431                 getLocationRet = __locationManagerGetLocation();
432         }
433         if (__checkGeneralLimits() && !requestSingleLocationRet && !getLocationRet
434                         && __activeAttempts >= LOCATION_LOGGER_MAX_ACTIVE_LOCATION_ATTEMPTS) {
435                 __locationManagerGetLastLocation();
436         }
437         if (!requestSingleLocationRet) {
438                 __locationManagerStop();
439                 __setNextTimer();
440         }
441 }
442
443 void ctx::LocationLogger::__setNextTimer()
444 {
445         _D("ATTEMPTS: REQ[%d/%d], ACT[%d/%d], ALL[%d/%d]; ----- LOCATIONS:[%d/%d])",
446                         __activeRequestAttempts,
447                         LOCATION_LOGGER_MAX_ACTIVE_REQUEST_ATTEMPTS,
448                         __activeAttempts,
449                         LOCATION_LOGGER_MAX_ACTIVE_LOCATION_ATTEMPTS,
450                         __allAttempts,
451                         LOCATION_LOGGER_MAX_LOCATION_ATTEMPTS,
452                         __locationCount,
453                         LOCATION_LOGGER_MAX_LOCATION_COUNT);
454         if (__checkGeneralLimits()) {
455                 if (__checkActiveLimits()) {
456                         __activeIntervalTimerStart();
457                 } else {
458                         __passiveIntervalTimerStart();
459                 }
460         }
461 }
462
463 void ctx::LocationLogger::__onActiveRequestSucceeded()
464 {
465         _D("");
466         __locationManagerStop();
467         __activeRequestSucceeded = true;
468         __onActiveLocationSucceeded();
469 }
470
471 void ctx::LocationLogger::__onActiveLocationSucceeded()
472 {
473         _D("");
474         __activeLocationSucceeded = true;
475 }
476
477 void ctx::LocationLogger::__broadcast(ctx::LocationEvent locationEvent)
478 {
479         _D("");
480         __locationCount++;
481         if (__listener)
482                 __listener->onNewLocation(locationEvent);
483         if (LOCATION_LOGGER_DATABASE)
484                 __dbInsertLog(locationEvent);
485 }
486
487 bool ctx::LocationLogger::onTimerExpired(int id)
488 {
489         time_t now = time(nullptr);
490         double seconds = difftime(now, __timerTimestamp);
491
492         switch (__timerPurpose) {
493         case LOCATION_LOGGER_WAITING_FOR_ACTIVE_REQUEST:
494                 _D("Active request FAILED, timerId = %d[%d], from start = %.1fs", id, __timerId, seconds);
495                 __locationManagerStop();
496                 __setNextTimer();
497                 return false;
498         case LOCATION_LOGGER_WAITING_FOR_SERVICE_START:
499                 _D("Service start in timeout time FAILED, timerId = %d[%d], from start = %.1fs", id, __timerId, seconds);
500                 // Waiting for service start FAILURE is also some kind of active request attempt
501                 __activeRequestAttempts++;
502                 __activeAttempts++;
503                 __allAttempts++;
504                 __locationManagerStop();
505                 __setNextTimer();
506                 return false;
507         case LOCATION_LOGGER_WAITING_FOR_LOCATION_METHOD_SETTING_ON:
508                 _D("Still waiting for Location method settings on, timerId = %d[%d], from start = %.1fs", id, __timerId, seconds);
509                 // Do nothing
510                 return false;
511         case LOCATION_LOGGER_WAITING_FOR_ACTIVE_INTERVAL:
512                 _D("Active interval time expired, timerId = %d[%d], from start = %.1fs", id, __timerId, seconds);
513                 break;
514         case LOCATION_LOGGER_WAITING_FOR_PASSIVE_INTERVAL:
515                 _D("Passive interval time expired, timerId = %d[%d], from start = %.1fs", id, __timerId, seconds);
516                 break;
517         default:
518                 _D("Do nothing, timerId = %d[%d], from start = %.1fs", id, __timerId, seconds);
519                 return false;
520         }
521         if (__locationMethodState) {
522                 __locationManagerStart();
523         } else {
524                 __timerPurpose = LOCATION_LOGGER_WAITING_FOR_LOCATION_METHOD_SETTING_ON;
525                 _D("LOCATION_LOGGER_WAITING_FOR_LOCATION_METHOD_SETTING_ON");
526         }
527         return false;
528 }
529
530 void ctx::LocationLogger::__activeRequestTimerStart()
531 {
532         int minutes = LOCATION_LOGGER_ACTIVE_REQUEST_TIMEOUT_SECONDS / 60;
533         if (LOCATION_LOGGER_ACTIVE_REQUEST_TIMEOUT_SECONDS % 60)
534                 minutes++;
535         __timerPurpose = LOCATION_LOGGER_WAITING_FOR_ACTIVE_REQUEST;
536         _D("LOCATION_LOGGER_WAITING_FOR_ACTIVE_REQUEST (minutes=%d)", minutes);
537         __timerStart(minutes);
538 }
539
540 void ctx::LocationLogger::__startServiceTimerStart()
541 {
542         __timerPurpose = LOCATION_LOGGER_WAITING_FOR_SERVICE_START;
543         _D("LOCATION_LOGGER_WAITING_FOR_SERVICE_START");
544         __timerStart(LOCATION_LOGGER_SERVICE_START_TIMEOUT_MINUTES);
545 }
546
547 void ctx::LocationLogger::__activeIntervalTimerStart()
548 {
549         __timerPurpose = LOCATION_LOGGER_WAITING_FOR_ACTIVE_INTERVAL;
550         _D("LOCATION_LOGGER_WAITING_FOR_ACTIVE_INTERVAL");
551         __timerStart(LOCATION_LOGGER_ACTIVE_INTERVAL_MINUTES);
552 }
553
554 void ctx::LocationLogger::__passiveIntervalTimerStart()
555 {
556         __timerPurpose = LOCATION_LOGGER_WAITING_FOR_PASSIVE_INTERVAL;
557         _D("LOCATION_LOGGER_WAITING_FOR_PASSIVE_INTERVAL");
558         __timerStart(LOCATION_LOGGER_PASSIVE_INTERVAL_MINUTES);
559 }
560
561 void ctx::LocationLogger::__timerStart(time_t minutes)
562 {
563         __timerTimestamp = time(nullptr);
564         __timerId = __timerManager.setFor(minutes, this);
565         _D("%s (minutes=%d) timerId = %d", __timerId >= 0 ? "SUCCESS" : "ERROR", minutes, __timerId);
566 }
567
568 void ctx::LocationLogger::__timerStop()
569 {
570         _D("");
571         __timerManager.remove(__timerId);
572 }
573
574 void ctx::LocationLogger::__startLogging()
575 {
576         _D("");
577         __activeRequestAttempts = 0;
578         __activeAttempts = 0;
579         __allAttempts = 0;
580         __locationCount = 0;
581         __activeRequestSucceeded = false;;
582         __activeLocationSucceeded = false;
583         __locationManagerStart();
584 }
585
586 void ctx::LocationLogger::__stopLogging()
587 {
588         _D("");
589         __timerStop();
590         __locationManagerStop();
591 }
592
593 void ctx::LocationLogger::onVisitStart()
594 {
595         _D("");
596         __startLogging();
597 }
598
599 void ctx::LocationLogger::onVisitEnd()
600 {
601         _D("");
602         __stopLogging();
603 }
604
605 #undef __LOCATION_ERROR_LOG