diff options
author | Nandan SR <nandan.sr@samsung.com> | 2013-06-07 12:34:17 +0900 |
---|---|---|
committer | Nandan SR <nandan.sr@samsung.com> | 2013-06-07 12:34:17 +0900 |
commit | d0af1bf8139af86c51cb7ab84b18e1448e8d0bf8 (patch) | |
tree | 9f956b4d39ebffd002ab80e4a5c936920c7c27d9 /src/FLoc_LocationManager.cpp | |
parent | e2edf7ea7d25ec12d306f2d5362a7af6f1da743e (diff) | |
download | locations-d0af1bf8139af86c51cb7ab84b18e1448e8d0bf8.tar.gz locations-d0af1bf8139af86c51cb7ab84b18e1448e8d0bf8.tar.bz2 locations-d0af1bf8139af86c51cb7ab84b18e1448e8d0bf8.zip |
Implementation of new location manager.
Change-Id: I98a81dc40192362b688ea8b5e400c37feb50e5d7
Signed-off-by: Nandan SR <nandan.sr@samsung.com>
Diffstat (limited to 'src/FLoc_LocationManager.cpp')
-rw-r--r-- | src/FLoc_LocationManager.cpp | 1353 |
1 files changed, 989 insertions, 364 deletions
diff --git a/src/FLoc_LocationManager.cpp b/src/FLoc_LocationManager.cpp index cf95366..c85d4d1 100644 --- a/src/FLoc_LocationManager.cpp +++ b/src/FLoc_LocationManager.cpp @@ -34,9 +34,11 @@ #include <FBaseRtTimer.h> #include <FBaseRtMonitor.h> #include <FBaseSysLog.h> +#include <FBaseUtilMath.h> #include <FLocCoordinates.h> -#include <FSysSystemTime.h> +#include <FSysSettingInfo.h> #include <FSys_PowerManagerImpl.h> +#include <FSys_SettingInfoImpl.h> #include "FLoc_AlarmRequestInfo.h" #include "FLoc_Config.h" #include "FLoc_LocationImpl.h" @@ -45,27 +47,30 @@ #include "FLoc_LocationRequestInfo.h" #include "FLoc_SyncLocationRequestInfo.h" +using namespace std; using namespace Tizen::Base; using namespace Tizen::Base::Collection; using namespace Tizen::Base::Runtime; using namespace Tizen::Base::Utility; using namespace Tizen::System; -using namespace std; namespace Tizen { namespace Locations { + _LocationManager* _LocationManager::__pUniqueInstance = null; _LocationManager::_LocationManager(void) : Tizen::Base::Runtime::EventDrivenThread() - , __locMethodRequested(LOC_METHOD_REQUESTED_NONE) - , __locationMgrState(LOC_MGR_STATE_IDLE) + , __gpsEnabled(false) + , __wpsEnabled(false) , __minRequestedAccuracy(LOC_ACCURACY_INVALID) , __timerInterval(0) , __timerTicks(0) , __pLocRequestInfoList(null) , __pSyncLocRequestInfoList(null) - , __pLocUpdateTimer(null) + , __pAlarmRequestInfoList(null) + , __pLocCallbackTimer(null) + , __pLocCheckTimer(null) , __pInitMonitor(null) { } @@ -81,9 +86,8 @@ _LocationManager::StartLocationUpdates(LocationAccuracy accuracy, int interval, static RequestId nextLocRequestId = 1; const int ARRAY_LIST_CAPACITY = 1; - std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - std::unique_ptr< _LocationRequestInfo > pLocRequestInfo(new (std::nothrow) _LocationRequestInfo(accuracy, interval, pListener, nextLocRequestId)); SysTryReturn(NID_LOC, pLocRequestInfo, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); @@ -91,18 +95,16 @@ _LocationManager::StartLocationUpdates(LocationAccuracy accuracy, int interval, SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pLocRequestInfo); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating", GetErrorMessage(r)); - pLocRequestInfo.release(); r = SendUserEvent(REQ_ID_START_LOC_UPDATES, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); + pArgList.release(); reqId = nextLocRequestId; nextLocRequestId++; - - pArgList.release(); - SysLog(NID_LOC, "Request ID (%ld) is assigned for the location request with accuracy (%d) and interval (%d).", reqId, accuracy, interval); + return E_SUCCESS; } @@ -112,9 +114,8 @@ _LocationManager::StopLocationUpdates(RequestId reqId) SysLog(NID_LOC, "Location update stop requested for request ID (%d).", reqId); const int ARRAY_LIST_CAPACITY = 1; - std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - std::unique_ptr< Integer > pReqId(new (std::nothrow) Integer(static_cast< int >(reqId))); SysTryReturn(NID_LOC, pReqId, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); @@ -122,13 +123,12 @@ _LocationManager::StopLocationUpdates(RequestId reqId) SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pReqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); - pReqId.release(); r = SendUserEvent(REQ_ID_STOP_LOC_UPDATES, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); - pArgList.release(); + return E_SUCCESS; } @@ -138,7 +138,7 @@ _LocationManager::ChangeUpdateInterval(RequestId reqId, int interval) SysLog(NID_LOC, "Interval update requested for request ID (%d).", reqId); const int ARRAY_LIST_CAPACITY = 2; - std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); @@ -148,7 +148,6 @@ _LocationManager::ChangeUpdateInterval(RequestId reqId, int interval) r = pArgList->Add(*pReqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); - pReqId.release(); std::unique_ptr< Integer > pInterval(new (std::nothrow) Integer(interval)); @@ -156,13 +155,12 @@ _LocationManager::ChangeUpdateInterval(RequestId reqId, int interval) r = pArgList->Add(*pInterval); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); - pInterval.release(); r = SendUserEvent(REQ_ID_UPDATE_INTERVAL, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); - pArgList.release(); + return E_SUCCESS; } @@ -173,13 +171,13 @@ _LocationManager::RegisterLocationMonitor(_LocationMonitor* pLocationMonitor) const int ARRAY_LIST_CAPACITY = 1; Location location = GetLastKnownLocation(); - Tizen::Base::DateTime lastLocTime = location.GetTimestamp(); + DateTime lastLocTime = location.GetTimestamp(); result r = StartLocationUpdates(pLocationMonitor->GetAccuracy(), 1, null, reqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Error to request location updates.", GetErrorMessage(r)); std::unique_ptr< _SyncLocationRequestInfo > pSyncLocationRequestInfo(new (std::nothrow) _SyncLocationRequestInfo(pLocationMonitor, reqId, lastLocTime)); - std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryCatch(NID_LOC, pSyncLocationRequestInfo != null && pArgList != null, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); @@ -192,8 +190,8 @@ _LocationManager::RegisterLocationMonitor(_LocationMonitor* pLocationMonitor) r = SendUserEvent(REQ_ID_SYNC_LOC_RETRIEVAL, pArgList.get()); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); - pArgList.release(); + return E_SUCCESS; CATCH: @@ -206,9 +204,8 @@ _LocationManager::RequestStartAlarm(int interval, _ILocationManagerListener* pLi { const int ARRAY_LIST_CAPACITY = 1; - std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - std::unique_ptr< _AlarmRequestInfo > pAlarmRequestInfo(new (std::nothrow) _AlarmRequestInfo(interval, pListener, reqId)); SysTryReturn(NID_LOC, pAlarmRequestInfo, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); @@ -216,15 +213,13 @@ _LocationManager::RequestStartAlarm(int interval, _ILocationManagerListener* pLi SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pAlarmRequestInfo.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating", GetErrorMessage(r)); - pAlarmRequestInfo.release(); r = SendUserEvent(REQ_ID_START_ALARM, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); - pArgList.release(); + SysLog(NID_LOC, "Successfully requested for alarm addition."); - SysLog(NID_LOC, "Success to add the alarm."); return E_SUCCESS; } @@ -234,9 +229,8 @@ _LocationManager::RequestStopAlarm(RequestId reqId) SysLog(NID_LOC, "Alarm stop requested for request ID (%d).", reqId); const int ARRAY_LIST_CAPACITY = 1; - std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - std::unique_ptr< Integer > pReqId(new (std::nothrow) Integer(static_cast< int >(reqId))); SysTryReturn(NID_LOC, pReqId, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); @@ -244,13 +238,12 @@ _LocationManager::RequestStopAlarm(RequestId reqId) SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pReqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); - pReqId.release(); r = SendUserEvent(REQ_ID_STOP_ALARM, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); - pArgList.release(); + return E_SUCCESS; } @@ -262,7 +255,7 @@ _LocationManager::GetLastKnownLocation(void) result r = synchronizer.Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, location, r, "[%s] Propogating.", GetErrorMessage(r)); - std::unique_ptr< Tizen::Base::Collection::ArrayList > pArgList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, location, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pArgList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, location, r, "[%s] Propogating.", GetErrorMessage(r)); @@ -357,9 +350,15 @@ _LocationManager::AddToLocRequestInfoList(const _LocationRequestInfo* pLocReques result r = _PowerManagerImpl::PowerControl(1, 1); SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to keep the CPU in awake state.", GetErrorMessage(r)); } - SysLog(NID_LOC, "Total count of request info is (%d).", __pLocRequestInfoList->GetCount()); - RestartLocationUpdates(); - RestartUpdateTimer(); + const int FIRST_REQUEST = 1; + int count = __pLocRequestInfoList->GetCount(); + SysLog(NID_LOC, "Total count of request info is (%d).", count); + if (count == FIRST_REQUEST) + { + InitiateLocationRequest(); + } + UpdateMinimunAccuracy(); + RestartCallbackTimer(); } void @@ -382,15 +381,14 @@ _LocationManager::RemoveFromLocRequestInfoList(RequestId reqId) { _PowerManagerImpl::PowerControl(1, 0); - __pLocUpdateTimer->Cancel(); - location_manager_stop(__gpsHandler.handle); - location_manager_stop(__wpsHandler.handle); Reset(); + location_manager_stop(__locMgrStatus.gpsHandler.handle); + location_manager_stop(__locMgrStatus.wpsHandler.handle); } else { - RestartLocationUpdates(); - RestartUpdateTimer(); + UpdateMinimunAccuracy(); + RestartCallbackTimer(); } } @@ -402,7 +400,6 @@ _LocationManager::AddToSyncLocationRequestInfoList(_SyncLocationRequestInfo& syn r = __pSyncLocRequestInfoList->Add(syncLocRequestInfo); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to add the sync request into the list.", GetErrorMessage(r)); - return; CATCH: @@ -422,16 +419,16 @@ void _LocationManager::AddToAlarmRequestInfoList(_AlarmRequestInfo& alarmRequestInfo) { alarm_id_t alarmId; + int res = alarmmgr_add_alarm_withcb(ALARM_TYPE_DEFAULT, alarmRequestInfo.GetInterval(), 0, AlarmExpiryCallback, this, &alarmId); SysTryReturnVoidResult(NID_LOC, res == ALARMMGR_RESULT_SUCCESS, E_SYSTEM, "Failed to add the alarm for next cycle."); - - SysLog(NID_LOC, "The alarm ID (%d) will be set to the request.", alarmId); alarmRequestInfo.SetAlarmId(alarmId); + SysLog(NID_LOC, "The alarm ID (%d) is set to the alarm request.", alarmId); std::unique_ptr< _AlarmRequestInfo > pNewAlarmRequestInfo(new (std::nothrow) _AlarmRequestInfo(alarmRequestInfo)); SysTryReturnVoidResult(NID_LOC, pNewAlarmRequestInfo, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = __pAlarmRequestInfoList->Add(*pNewAlarmRequestInfo.get()); - SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, E_SYSTEM, "Failed to add the alarm request into list."); + SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to add the alarm request into list."); pNewAlarmRequestInfo.release(); return; @@ -442,7 +439,6 @@ _LocationManager::RemoveFromAlarmRequestInfoList(RequestId reqId) { int count = __pAlarmRequestInfoList->GetCount(); SysLog(NID_LOC, "Total count of Alarm Request pending is (%d).", count); - for (int i = 0; i < count; i++) { const _AlarmRequestInfo* pAlarmRequestInfo = static_cast< const _AlarmRequestInfo* >(__pAlarmRequestInfoList->GetAt(i)); @@ -455,82 +451,84 @@ _LocationManager::RemoveFromAlarmRequestInfoList(RequestId reqId) break; } } - return; } void -_LocationManager::RestartLocationUpdates(void) +_LocationManager::UpdateMinimunAccuracy(void) { int count = __pLocRequestInfoList->GetCount(); - int result = 0; - bool isAccuracyChanged = false; - for (int i = 0; i < count; i++) { const _LocationRequestInfo* pLocRequestInfo = static_cast< const _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i)); if (__minRequestedAccuracy > pLocRequestInfo->GetAccuracy() || __minRequestedAccuracy == LOC_ACCURACY_INVALID) { __minRequestedAccuracy = pLocRequestInfo->GetAccuracy(); - isAccuracyChanged = true; } } - if (!isAccuracyChanged) +} + +void +_LocationManager::InitiateLocationRequest(void) +{ + if (__locMgrStatus.locMgrState != LOC_MGR_STATE_IDLE) { + SysLog(NID_LOC, "Location manager already running."); return; } - SysLog(NID_LOC, "Location updates are restarted and new minimum requested Accuracy is (%d).", __minRequestedAccuracy); - switch (__locMethodRequested) - { - case LOC_METHOD_REQUESTED_NONE: - { - SysLog(NID_LOC, "None of the methods running. Start all"); + SysLog(NID_LOC, "None of the methods running. Start all"); + bool gpsEnabled = false; + bool wpsEnabled = false; + int resultGps = -1; + int resultWps = -1; + const int LOC_CHECK_TIMER_VALUE = 1000; - result = location_manager_start(__gpsHandler.handle); - SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS."); + result gps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.gps", gpsEnabled); + result wps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.wps", wpsEnabled); + __gpsEnabled = gpsEnabled; + __wpsEnabled = wpsEnabled; - result = location_manager_start(__wpsHandler.handle); - SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS."); + if (gps == E_SUCCESS && __gpsEnabled) + { + resultGps = location_manager_start(__locMgrStatus.gpsHandler.handle); + SysTryLog(NID_LOC, resultGps == 0, "Failed to start the core GPS location provider with result (%d).", resultGps); } - break; - - case LOC_METHOD_REQUESTED_GPS: + if (wps == E_SUCCESS && __wpsEnabled) { - SysLog(NID_LOC, "GPS Running. Start WPS."); - - result = location_manager_start(__wpsHandler.handle); - SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS."); + resultWps = location_manager_start(__locMgrStatus.wpsHandler.handle); + SysTryLog(NID_LOC, resultWps == 0, "Failed to start the core WPS location provider with result (%d).", resultWps); } - break; - case LOC_METHOD_REQUESTED_WPS: + if (resultGps == 0 && resultWps == 0) { - SysLog(NID_LOC, "WPS Running. Start GPS."); - - result = location_manager_start(__gpsHandler.handle); - SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS."); + __locMgrStatus.locMgrState = LOC_MGR_STATE_BOTH_GPS_WPS; } - break; - - case LOC_METHOD_REQUESTED_ALL: + else if (resultGps == 0 && resultWps != 0) { - SysLog(NID_LOC, "All the providers are already started."); + __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY; } - break; + else if (resultGps != 0 && resultWps == 0) + { + __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY; } - - __locationMgrState = LOC_MGR_STATE_FAST_SENSING; - __locMethodRequested = LOC_METHOD_REQUESTED_ALL; + else + { + SysLog(NID_LOC, "Failed to start both the location providers."); + __locMgrStatus.locMgrState = LOC_MGR_STATE_PASSIVE_IDLE; + return; + } + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE); } void -_LocationManager::RestartUpdateTimer(void) +_LocationManager::RestartCallbackTimer(void) { int gcd = 1; int count = __pLocRequestInfoList->GetCount(); - __pLocUpdateTimer->Cancel(); + __pLocCallbackTimer->Cancel(); if (count > 0) { @@ -554,12 +552,9 @@ _LocationManager::RestartUpdateTimer(void) __timerInterval = gcd; __timerTicks = 0; - SysLog(NID_LOC, "Updated Timer interval is (%d).", __timerInterval); - result r = __pLocUpdateTimer->Start(__timerInterval * 1000); - if (IsFailed(r)) - { - SysLog(NID_LOC, "Failed to start the Location update timer."); - } + result r = __pLocCallbackTimer->Start(__timerInterval * 1000); + SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the location callback timer.", GetErrorMessage(r)); + SysLog(NID_LOC, "The callback timer interval successfully updated to (%d).", __timerInterval); } void @@ -569,6 +564,7 @@ _LocationManager::HandleSyncRetrievalTimerExpiry(_SyncLocationRequestInfo& syncL DateTime timestamp = DateTime::GetMinValue(); const Location* pBestLoc = FindBestLocation(); + SysTryReturnVoidResult(NID_LOC, pBestLoc != null, E_INVALID_DATA, "[E_INVALID_DATA] Location not available."); SysLog(NID_LOC, "Location(timestamp: %ls, validity: %x, accuracy: %f) is retrieved.", pBestLoc->GetTimestamp().ToString().GetPointer(), pBestLoc->IsValid(), pBestLoc->GetHorizontalAccuracy()); if (pBestLoc->IsValid()) @@ -617,128 +613,11 @@ NOTIFY: RemoveSyncLocRetrievalRequest(syncLocRequestInfo); } -result -_LocationManager::SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod, Location* pLocation) -{ - SysSecureLog(NID_LOC, "Location Information is: Latitude (%lf), Longitude (%lf), Altitude (%lf), TimeStamp (%ld), Location method (%d)", latitude, longitude, altitude, timestamp, locMethod); - - int res = -1; - LocationAccuracy requiredAcc; - int rangeValue = 0; - - //Accuracy details. - location_accuracy_level_e accLevel = LOCATIONS_ACCURACY_NONE; - double horAcc = Tizen::Locations::NaN; - double verAcc = Tizen::Locations::NaN; - - //Velocity details. - double climb = Tizen::Locations::NaN; - double direction = Tizen::Locations::NaN; - double speed = Tizen::Locations::NaN; - time_t time_stamp = 0; - - RequestId requestId; - Location locationData = _LocationImpl::GetLocationInstance(); - _LocationImpl* pLocDataImpl = _LocationImpl::GetInstance(locationData); - - switch (locMethod) - { - case LOCATIONS_METHOD_GPS: - { - res = location_manager_get_accuracy(__gpsHandler.handle, &accLevel, &horAcc, &verAcc); - SysLog(NID_LOC, "Get Accuracy: Result (%d), Horizontal Acc (%lf), Vertical Acc (%lf)", res, horAcc, verAcc); - SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Invalid accuracy values from Native Location Provider."); - - res = location_manager_get_velocity(__gpsHandler.handle, &climb, &direction, &speed, &time_stamp); - SysLog(NID_LOC, "Get Velocity: Result (%d), Climb (%lf), Direction (%lf), Speed (%lf), Time stamp (%ld)", res, climb, direction, speed, time_stamp); - SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Invalid accuracy values from Native Location Provider."); - - pLocDataImpl->SetExtraInfo(L"location_method", L"gps"); - requestId = REQ_ID_SUSTAIN_GPS; - } - break; - - case LOCATIONS_METHOD_WPS: - { - res = location_manager_get_accuracy(__wpsHandler.handle, &accLevel, &horAcc, &verAcc); - SysLog(NID_LOC, "Get Accuracy: Result (%d), Horizontal Acc (%lf), Vertical Acc (%lf)", res, horAcc, verAcc); - SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Invalid accuracy values from Native Location Provider."); - - res = location_manager_get_velocity(__wpsHandler.handle, &climb, &direction, &speed, &time_stamp); - SysTryLog(NID_LOC, res == 0, "Get Velocity: Result (%d), Climb (%lf), Direction (%lf), Speed (%lf), Time stamp (%ld)", res, climb, direction, speed, time_stamp); - - pLocDataImpl->SetExtraInfo(L"location_method", L"network"); - requestId = REQ_ID_SUSTAIN_WPS; - } - break; - - default: - SysTryReturn(NID_LOC, false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The location method is not valid"); - } - - Coordinates coordinates; - coordinates.Set(latitude, longitude, altitude); - pLocDataImpl->SetCoordinates(coordinates); - - horAcc = ConvertToNativeFormat(horAcc); - pLocDataImpl->SetHorizontalAccuracy(horAcc); - verAcc = ConvertToNativeFormat(verAcc); - pLocDataImpl->SetVerticalAccuracy(verAcc); - pLocDataImpl->SetTimestamp((long long) timestamp * 1000); - direction = ConvertToNativeFormat(direction); - pLocDataImpl->SetCourse(direction); - speed = ConvertToNativeFormat(speed); - pLocDataImpl->SetSpeed(speed); - pLocDataImpl->SetValidity(true); - *pLocation = locationData; - - requiredAcc = __minRequestedAccuracy; - switch (requiredAcc) - { - case LOC_ACCURACY_FINEST: - rangeValue = ACCURACY_FINEST; - break; - - case LOC_ACCURACY_TEN_METERS: - rangeValue = ACCURACY_TEN_MTRS; - break; - - case LOC_ACCURACY_HUNDRED_METERS: - rangeValue = ACCURACY_HUNDRED_MTRS; - break; - - case LOC_ACCURACY_ONE_KILOMETER: - rangeValue = ACCURACY_ONE_KILOMETER; - break; - - case LOC_ACCURACY_ANY: - rangeValue = ACCURACY_ANY; - break; - - case LOC_ACCURACY_INVALID: - // follow through - default: - SysAssertf(false, "The Accuracy value is not defined."); - } - - if (__locationMgrState == LOC_MGR_STATE_FAST_SENSING && (!Double::IsNaN(horAcc) && horAcc <= rangeValue)) - { - SysLog(NID_LOC, "State is LOC_MGR_STATE_FAST_SENSING and accuracy is within range. RequestId is (%d)", requestId); - __locationMgrState = LOC_MGR_STATE_FAST_SENSING_SETTLED; - SendUserEvent(requestId, null); - } - else - { - SysLog(NID_LOC, "State is LOC_MGR_STATE_FAST_SENSING_SETTLED and accuracy is out of range. Restart location updates."); - SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null); - } - return E_SUCCESS; -} - void _LocationManager::SendLocationCallbacks(void) { const Location* pBestLocation = FindBestLocation(); + SysTryReturnVoidResult(NID_LOC, pBestLocation != null, E_INVALID_DATA, "[E_INVALID_DATA] Location not available."); SysLog(NID_LOC, "Send location(validity: %x) through the callback.", pBestLocation->IsValid()); unique_ptr< Location > pLocation(new (std::nothrow) Location(*pBestLocation)); @@ -758,8 +637,11 @@ _LocationManager::SendLocationCallbacks(void) void _LocationManager::Reset(void) { - __locMethodRequested = LOC_METHOD_REQUESTED_NONE; - __locationMgrState = LOC_MGR_STATE_IDLE; + StopSubStateTimer(); + __pLocCallbackTimer->Cancel(); + __pLocCheckTimer->Cancel(); + __locMgrStatus.locMgrSubState = LM_SS_IDLE; + __locMgrStatus.locMgrState = LOC_MGR_STATE_IDLE; __minRequestedAccuracy = LOC_ACCURACY_INVALID; __timerInterval = 0; __timerTicks = 0; @@ -790,14 +672,14 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod) { case LOCATIONS_METHOD_GPS: { - nativeHandle = __gpsHandler.handle; + nativeHandle = __locMgrStatus.gpsHandler.handle; locationMethod = L"gps"; } break; case LOCATIONS_METHOD_WPS: { - nativeHandle = __wpsHandler.handle; + nativeHandle = __locMgrStatus.wpsHandler.handle; locationMethod = L"network"; } break; @@ -822,8 +704,6 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod) SysSecureLog(NID_LOC, "Last position(latitude: %lf, longitude: %lf, altitude: %lf, timestamp: %ld", latitude, longitude, altitude, timestampPosition); - altitude = ConvertToNativeFormatAltitude(altitude); - Coordinates coord; coord.Set(latitude, longitude, altitude); pLocationImpl->SetCoordinates(coord); @@ -836,8 +716,8 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod) { SysLog(NID_LOC, "Last accuracy(horAcc: %lf, vAcc: %lf, level: %x)", horAcc, verAcc, level); horAcc = ConvertToNativeFormat(horAcc); - pLocationImpl->SetHorizontalAccuracy(horAcc); verAcc = ConvertToNativeFormat(verAcc); + pLocationImpl->SetHorizontalAccuracy(horAcc); pLocationImpl->SetVerticalAccuracy(verAcc); } @@ -848,12 +728,10 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod) res = location_manager_get_last_velocity(nativeHandle, &climb, &direction, &speed, ×tampVelocity); if (res == 0) { - SysLog(NID_LOC, "Last velocity(climb: %lf, direction: %lf, speed: %lf, timestamp: %ld)", - climb, direction, speed, timestampVelocity); - + SysLog(NID_LOC, "Last velocity(climb: %lf, direction: %lf, speed: %lf, timestamp: %ld)", climb, direction, speed, timestampVelocity); direction = ConvertToNativeFormat(direction); - pLocationImpl->SetCourse(direction); speed = ConvertToNativeFormat(speed); + pLocationImpl->SetCourse(direction); pLocationImpl->SetSpeed(speed); } @@ -866,7 +744,7 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod) res = gps_status_get_last_satellite(nativeHandle, &satUsedCount, &satViewCount, ×tampSatellite); if (res == 0) { - long timeDiff = abs(timestampPosition - timestampSatellite); + long timeDiff = Math::Abs(timestampPosition - timestampSatellite); res = gps_status_foreach_last_satellites_in_view(nativeHandle, SatelliteInfoUpdated, &satInfo); SysLog(NID_LOC, "Last satellite(foreachResult: %d, inUse: %d, inView: %d, timestamp: %ld, timeDiff: %ld)", res, satUsedCount, satViewCount, timestampSatellite, timeDiff); @@ -918,7 +796,7 @@ _LocationManager::GetRecentLocationAvailable(void) } void -_LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval) +_LocationManager::UpdateLocRequestInterval(RequestId reqId, int interval) { int count = __pLocRequestInfoList->GetCount(); @@ -928,7 +806,7 @@ _LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval) if (reqId == pLocRequestInfo->GetRequestId()) { pLocRequestInfo->SetInterval(interval); - RestartUpdateTimer(); + RestartCallbackTimer(); break; } } @@ -937,89 +815,94 @@ _LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval) const Location* _LocationManager::FindBestLocation(void) { - switch (__locMethodRequested) + switch (__locMgrStatus.locMgrState) { - case LOC_METHOD_REQUESTED_GPS: + case LOC_MGR_STATE_GPS_ONLY: { SysLog(NID_LOC, "GPS location provider running."); - return __gpsHandler.pLocation.get(); + return __locMgrStatus.gpsHandler.pLocation.get(); } break; - case LOC_METHOD_REQUESTED_WPS: + case LOC_MGR_STATE_WPS_ONLY: { SysLog(NID_LOC, "WPS location provider running."); - return __wpsHandler.pLocation.get(); + return __locMgrStatus.wpsHandler.pLocation.get(); } break; - case LOC_METHOD_REQUESTED_ALL: + case LOC_MGR_STATE_PASSIVE_IDLE: //Give back the available location in case of Passive location because the location provider takes care of the location and send Denied. + // follow through + case LOC_MGR_STATE_BOTH_GPS_WPS: { SysLog(NID_LOC, "All the methods are running. Get the best location among all the providers."); long long gpsTimestamp = 0; long long wpsTimestamp = 0; - if (__gpsHandler.pLocation->IsValid()) + if (__locMgrStatus.gpsHandler.pLocation->IsValid()) { - gpsTimestamp = _LocationImpl::GetInstance(*__gpsHandler.pLocation)->GetTimestampInMs(); + gpsTimestamp = _LocationImpl::GetInstance(*__locMgrStatus.gpsHandler.pLocation)->GetTimestampInMs(); } - if (__wpsHandler.pLocation->IsValid()) + if (__locMgrStatus.wpsHandler.pLocation->IsValid()) { - wpsTimestamp = _LocationImpl::GetInstance(*__wpsHandler.pLocation)->GetTimestampInMs(); + wpsTimestamp = _LocationImpl::GetInstance(*__locMgrStatus.wpsHandler.pLocation)->GetTimestampInMs(); } SysLog(NID_LOC, "Compare timestamp(gps: %lld, wps: %lld) of different locations.", gpsTimestamp, wpsTimestamp); if (gpsTimestamp > wpsTimestamp) { SysLog(NID_LOC, "GPS time stamp is greater than WPS."); - return __gpsHandler.pLocation.get(); + return __locMgrStatus.gpsHandler.pLocation.get(); } else if (wpsTimestamp > gpsTimestamp) { SysLog(NID_LOC, "WPS time stamp is greater than GPS."); - return __wpsHandler.pLocation.get(); + return __locMgrStatus.wpsHandler.pLocation.get(); } else if (gpsTimestamp == wpsTimestamp) { - if (__gpsHandler.pLocation->GetHorizontalAccuracy() <= __wpsHandler.pLocation->GetHorizontalAccuracy()) + double gpsAccuracy = __locMgrStatus.gpsHandler.pLocation->GetHorizontalAccuracy(); + double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy(); + if ((gpsAccuracy <= wpsAccuracy) || Double::IsNaN(wpsAccuracy)) { SysLog(NID_LOC, "GPS time stamp is equal to WPS and GPS accuracy is better than WPS."); - return __gpsHandler.pLocation.get(); + return __locMgrStatus.gpsHandler.pLocation.get(); } else { - SysLog(NID_LOC, "WPS time stamp is equal to GPS but WPS accuracy is better than GPS."); - return __wpsHandler.pLocation.get(); + SysLog(NID_LOC, "WPS time stamp is equal to GPS and WPS accuracy is better than GPS."); + return __locMgrStatus.wpsHandler.pLocation.get(); } } } break; - case LOC_METHOD_REQUESTED_NONE: + case LOC_MGR_STATE_IDLE: // follow through default: SysLog(NID_LOC, "Location updates not running."); return null; } - SysLog(NID_LOC, "Returning null as none of the conditions are satsfied."); + SysLog(NID_LOC, "Returning null as none of the conditions are satisfied."); return null; } result _LocationManager::GetLocation(location_method_e nativeLocMethod) { - const int MAX_VALID_TIME_DIFFERENCE = 2000; - double altitude = Tizen::Locations::NaN; - double latitude = Tizen::Locations::NaN; - double longitude = Tizen::Locations::NaN; - time_t timestamp; + location_accuracy_level_e accuracy_level; int res = -1; - int satellitesInViewCount = 0; - int satellitesInUseCount = 0; - time_t timestampSatellite = 0; - String satInfo = L""; + time_t timestamp = 0; long long timeDiff = 0; + double altitude = NaN; + double latitude = NaN; + double longitude = NaN; + double climb = NaN; + double direction = NaN; + double speed = NaN; + double horizontal_acc = NaN; + double vertical_acc = NaN; location_manager_h nativeHandle = null; Location* pLocation = null; @@ -1027,15 +910,15 @@ _LocationManager::GetLocation(location_method_e nativeLocMethod) { case LOCATIONS_METHOD_GPS: { - nativeHandle = __gpsHandler.handle; - pLocation = __gpsHandler.pLocation.get(); + nativeHandle = __locMgrStatus.gpsHandler.handle; + pLocation = __locMgrStatus.gpsHandler.pLocation.get(); } break; case LOCATIONS_METHOD_WPS: { - nativeHandle = __wpsHandler.handle; - pLocation = __wpsHandler.pLocation.get(); + nativeHandle = __locMgrStatus.wpsHandler.handle; + pLocation = __locMgrStatus.wpsHandler.pLocation.get(); } break; @@ -1043,39 +926,698 @@ _LocationManager::GetLocation(location_method_e nativeLocMethod) break; } - res = location_manager_get_position(nativeHandle, &altitude, &latitude, &longitude, ×tamp); + res = location_manager_get_location(nativeHandle, &altitude, &latitude, &longitude, &climb, &direction, &speed, &accuracy_level, &horizontal_acc, &vertical_acc, ×tamp); SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Failed to obtain the natvie location information for the method (%x)", nativeLocMethod); + SysSecureLog(NID_LOC, "Location details: Lat(%lf), Long(%lf), Alt(%lf), Climb (%lf), Direction (%lf), Speed (%lf), Accuracy Level(%d), HAcc (%lf), VAcc (%lf), timestamp (%ld).", + latitude, longitude, altitude, climb, direction, speed, accuracy_level, horizontal_acc, vertical_acc, timestamp); if (res == 0) { - altitude = ConvertToNativeFormatAltitude(altitude); - result r = SetLocationInformation(latitude, longitude, altitude, timestamp, nativeLocMethod, pLocation); - if (r != E_SUCCESS) - { - SysLog(NID_LOC, "Failed to set the location information"); - } + Location locationData = _LocationImpl::GetLocationInstance(); + _LocationImpl* pLocDataImpl = _LocationImpl::GetInstance(locationData); + + horizontal_acc = ConvertToNativeFormat(horizontal_acc); + vertical_acc = ConvertToNativeFormat(vertical_acc); + Coordinates coordinates; + coordinates.Set(latitude, longitude, altitude); + pLocDataImpl->SetCoordinates(coordinates); + pLocDataImpl->SetHorizontalAccuracy(horizontal_acc); + pLocDataImpl->SetVerticalAccuracy(vertical_acc); + pLocDataImpl->SetTimestamp((long long) timestamp * 1000); + pLocDataImpl->SetCourse(direction); + pLocDataImpl->SetSpeed(speed); + pLocDataImpl->SetValidity(true); if (nativeLocMethod == LOCATIONS_METHOD_GPS) { - res = gps_status_get_satellite(__gpsHandler.handle, &satellitesInUseCount, &satellitesInViewCount, ×tampSatellite); + const int MAX_VALID_TIME_DIFFERENCE = 2000; + int satellitesInViewCount = 0; + int satellitesInUseCount = 0; + time_t timestampSatellite = 0; + String satInfo = L""; - timeDiff = abs(timestamp - timestampSatellite); + __locMgrStatus.gpsFailCount = 0; + pLocDataImpl->SetExtraInfo(L"location_method", L"gps"); + res = gps_status_get_satellite(nativeHandle, &satellitesInUseCount, &satellitesInViewCount, ×tampSatellite); + + timeDiff = Math::Abs(timestamp - timestampSatellite); timeDiff = timeDiff * 1000; SysLog(NID_LOC, "Result (%d), Satellites in Use (%d), Satellites in View (%d), Time stamp (%ld), Time Difference (Loc and Sat) (%ld)", res, satellitesInUseCount, satellitesInViewCount, timestampSatellite, timeDiff); if (res == 0 && timeDiff <= MAX_VALID_TIME_DIFFERENCE) { - res = gps_status_foreach_satellites_in_view(__gpsHandler.handle, SatelliteInfoUpdated, &satInfo); + res = gps_status_foreach_satellites_in_view(__locMgrStatus.gpsHandler.handle, SatelliteInfoUpdated, &satInfo); } satInfo.Trim(); SysLog(NID_LOC, "Result of get satellite is (%d) and satelliteInfo string representation is (%ls)", res, satInfo.GetPointer()); - _LocationImpl::GetInstance(*__gpsHandler.pLocation.get())->SetExtraInfo(L"satellite", satInfo); + pLocDataImpl->SetExtraInfo(L"satellite", satInfo); + } + else if (nativeLocMethod == LOCATIONS_METHOD_WPS) + { + pLocDataImpl->SetExtraInfo(L"location_method", L"network"); + } + *pLocation = locationData; + } + + return E_SUCCESS; +} + +void +_LocationManager::HandleBothGpsWpsState(void) +{ + bool isGpsAccMet = false; + bool isWpsAccMet = false; + bool isGpsTimeUpdated = false; + bool isWpsTimeUpdated = false; + + IsGpsLocationUpdated(isGpsTimeUpdated, isGpsAccMet); + IsWpsLocationUpdated(isWpsTimeUpdated, isWpsAccMet); + + if (isWpsAccMet) + { + StopSubStateTimer(); + SysLog(NID_LOC, "WPS accuracy is met during LOC_MGR_STATE_BOTH_GPS_WPS state."); + location_manager_stop(__locMgrStatus.gpsHandler.handle); + __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY; + __locMgrStatus.locMgrSubState = LM_SS_SETTLED; + } + else if (isGpsAccMet) + { + SysLog(NID_LOC, "GPS accuracy is met during LOC_MGR_STATE_BOTH_GPS_WPS state. Wait for 10 more seconds to give WPS a chance."); + + if (__locMgrStatus.locMgrSubState != LM_SS_BOTH_SETTLED_WAITING) + { + const int SUB_STATE_TIMER_VALUE = 10; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started a timer for 10 seconds to give WPS a chance in the state LOC_MGR_STATE_BOTH_GPS_WPS."); + __locMgrStatus.locMgrSubState = LM_SS_BOTH_SETTLED_WAITING; + } } } + else if (isWpsTimeUpdated || isGpsTimeUpdated) + { + SysLog(NID_LOC, "GPS accuracy and WPS accuracy not met during LOC_MGR_STATE_BOTH_GPS_WPS state. Wait for 20 seconds."); + + if (__locMgrStatus.locMgrSubState != LM_SS_BOTH_SENSING) + { + const int SUB_STATE_TIMER_VALUE = 20; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started a timer for 20 seconds as the accuracy is not met in state LOC_MGR_STATE_BOTH_GPS_WPS."); + __locMgrStatus.locMgrSubState = LM_SS_BOTH_SENSING; + } + } + } + else + { + SysLog(NID_LOC, "Position not obtained by either GPS or WPS."); + StopSubStateTimer(); + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } +} + +void +_LocationManager::HandleGpsOnlyState(void) +{ + bool isGpsAccMet = false; + bool isTimeUpdated = false; + double minAccRequested = ConvertLocationAccuracyToDouble(__minRequestedAccuracy); + + IsGpsLocationUpdated(isTimeUpdated, isGpsAccMet); + + if (!__wpsEnabled && isGpsAccMet) + { + StopSubStateTimer(); + __locMgrStatus.locMgrSubState = LM_SS_SETTLED; + return; + } + if (__wpsEnabled) + { + SysLog(NID_LOC, "WPS setting is enabled."); + if (isGpsAccMet) //Location available with requested accuracy. + { + if (minAccRequested > ConvertLocationAccuracyToDouble(LOC_ACCURACY_TEN_METERS)) + { + if (__locMgrStatus.locMgrSubState != LM_SS_GPS_ONLY_SETTLED) + { + const int SUB_STATE_TIMER_VALUE = 120; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer of 120 seconds in LOC_MGR_STATE_GPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_GPS_ONLY_SETTLED; + } + } + } + else + { + __locMgrStatus.locMgrSubState = LM_SS_SETTLED; + } + } + else if (isTimeUpdated) //GPS Location available with less accuracy. + { + if (__locMgrStatus.locMgrSubState != LM_SS_GPS_ONLY_SENSING) + { + const int SUB_STATE_TIMER_VALUE = 40; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer of 40 seconds in LOC_MGR_STATE_GPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_GPS_ONLY_SENSING; + } + } + } + else //Location not available + { + if (__locMgrStatus.locMgrSubState != LM_SS_GPS_ONLY_NO_FIX) + { + const int SUB_STATE_TIMER_VALUE = 10; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer of 10 seconds in LOC_MGR_STATE_GPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_GPS_ONLY_NO_FIX; + } + } + } + } + else + { + StopSubStateTimer(); + + if (isTimeUpdated) + { + SysLog(NID_LOC, "GPS position available with less accuracy in LOC_MGR_STATE_GPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_SENSING; + } + else + { + SysLog(NID_LOC, "GPS position not available in LOC_MGR_STATE_GPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } + } +} + +void +_LocationManager::HandleWpsOnlyState(void) +{ + bool isWpsAccMet = false; + bool isTimeUpdated = false; + double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy(); + + IsWpsLocationUpdated(isTimeUpdated, isWpsAccMet); + + if (isWpsAccMet) + { + StopSubStateTimer(); + __locMgrStatus.locMgrSubState = LM_SS_SETTLED; + return; + } + + if (__gpsEnabled) + { + SysLog(NID_LOC, "GPS is enabled."); + if (isTimeUpdated) // WPS location available with less accuracy + { + SysLog(NID_LOC, "WPS position available with less accuracy in LOC_MGR_STATE_WPS_ONLY state."); + if (__locMgrStatus.gpsFailCount == 0) + { + if (__minRequestedAccuracy > LOC_ACCURACY_TEN_METERS) + { + if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_LESS_ACC_SENSING) + { + double currAccDiff = wpsAccuracy - ConvertLocationAccuracyToDouble(__minRequestedAccuracy); + int subStateTimerValue = 0; + + if (currAccDiff < 100) + { + subStateTimerValue = 15; + } + else + { + subStateTimerValue = 10; + } + result r = RestartSubStateTimer(subStateTimerValue * 1000); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer for (%d) seconds in LOC_MGR_STATE_WPS_ONLY as WPS accuracy not met.", subStateTimerValue); + __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_LESS_ACC_SENSING; + } + } + } + else if (__minRequestedAccuracy == LOC_ACCURACY_FINEST || __minRequestedAccuracy == LOC_ACCURACY_TEN_METERS) + { + if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_FINE_ACC_SENSING) + { + const int SUB_STATE_TIMER_VALUE = 5; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer for 5 seconds in LOC_MGR_STATE_WPS_ONLY as WPS accuracy not met."); + __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_FINE_ACC_SENSING; + } + } + } + } + else + { + if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_SENSING) + { + SysLog(NID_LOC, "The number of GPS failures is (%d)", __locMgrStatus.gpsFailCount); + double timerVal = Math::Pow(2, (__locMgrStatus.gpsFailCount - 1)) * 10; + if (timerVal > MAX_TIMER_VALUE_DURING_WPS_POSITIONING) + { + timerVal = MAX_TIMER_VALUE_DURING_WPS_POSITIONING; + } + const int SUB_STATE_TIMER_VALUE = (int) timerVal; + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer for (%d) seconds in LOC_MGR_STATE_WPS_ONLY mode when last GPS session has failed."); + __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_SENSING; + } + } + } + } + else + { + if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_NO_FIX) + { + const int SUB_STATE_TIMER_VALUE = 10; + SysLog(NID_LOC, "WPS position not available in LOC_MGR_STATE_WPS_ONLY state."); + result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE); + if (!IsFailed(r)) + { + SysLog(NID_LOC, "Started the sub state timer for 10 seconds in LOC_MGR_STATE_WPS_ONLY state when GPS is enabled and WPS no fix."); + __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_NO_FIX; + } + } + } + } + else + { + StopSubStateTimer(); + if (isTimeUpdated) + { + SysLog(NID_LOC, "WPS position available with less accuracy in LOC_MGR_STATE_WPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_SENSING; + } + else + { + SysLog(NID_LOC, "WPS position not available in LOC_MGR_STATE_WPS_ONLY state."); + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } + } +} + +void +_LocationManager::IsGpsLocationUpdated(bool& isTimeUpdated, bool& isAccMet) +{ + double minAccRequested = ConvertLocationAccuracyToDouble(__minRequestedAccuracy); + + if (__locMgrStatus.gpsHandler.pLocation->GetTimestamp() > __locMgrStatus.gpsHandler.oldTimeStamp) + { + double gpsAccuracy = __locMgrStatus.gpsHandler.pLocation->GetHorizontalAccuracy(); + isTimeUpdated = true; + if (!Double::IsNaN(gpsAccuracy) && gpsAccuracy <= minAccRequested) + { + isAccMet = true; + } + __locMgrStatus.gpsHandler.oldTimeStamp = __locMgrStatus.gpsHandler.pLocation->GetTimestamp(); + } +} + +void +_LocationManager::IsWpsLocationUpdated(bool& isTimeUpdated, bool& isAccMet) +{ + double minAccRequested = ConvertLocationAccuracyToDouble(__minRequestedAccuracy); + + if (__locMgrStatus.wpsHandler.pLocation->GetTimestamp() > __locMgrStatus.wpsHandler.oldTimeStamp) + { + double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy(); + isTimeUpdated = true; + if (!Double::IsNaN(wpsAccuracy) && wpsAccuracy <= minAccRequested) + { + isAccMet = true; + } + __locMgrStatus.wpsHandler.oldTimeStamp = __locMgrStatus.wpsHandler.pLocation->GetTimestamp(); + } +} + +double +_LocationManager::ConvertLocationAccuracyToDouble(LocationAccuracy locAcc) +{ + SysAssertf((locAcc > LOC_ACCURACY_INVALID && locAcc <= LOC_ACCURACY_ANY), "The accuracy value is not valid."); + + static int accArray[] = {NaN, ACCURACY_FINEST, ACCURACY_TEN_MTRS, ACCURACY_HUNDRED_MTRS, ACCURACY_ONE_KILOMETER, ACCURACY_ANY}; + + return accArray[locAcc]; +} + +result +_LocationManager::RestartSubStateTimer(int timeout) +{ + result r = E_SUCCESS; + + StopSubStateTimer(); + r = __locMgrStatus.pLocMgrSubStateTimer->Start(timeout * 1000); + SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the sub state timer with timer value (%d) seconds.", GetErrorMessage(r), timeout); + __locMgrStatus.isSubStateTimerStarted = true; + // Make a note of the GPS time stamp when sub state timer started. This is used to identify GPS fail case. + __locMgrStatus.gpsTimeAtSubstateTimerStart = __locMgrStatus.gpsHandler.pLocation->GetTimestamp(); return E_SUCCESS; } +void +_LocationManager::StopSubStateTimer(void) +{ + if (__locMgrStatus.isSubStateTimerStarted) + { + result r = __locMgrStatus.pLocMgrSubStateTimer->Cancel(); + SysTryLog(NID_LOC, r == E_SUCCESS, "[%s] Failed to stop the sub state timer.", GetErrorMessage(r)); + __locMgrStatus.isSubStateTimerStarted = false; + } +} + +void +_LocationManager::HandleSubStateTimerExpiry(void) +{ + SysLog(NID_LOC, "The substate timer expired for the State (%d) with sub state (%d).", __locMgrStatus.locMgrState, __locMgrStatus.locMgrSubState); + + switch (__locMgrStatus.locMgrState) + { + case LOC_MGR_STATE_BOTH_GPS_WPS: + { + switch (__locMgrStatus.locMgrSubState) + { + case LM_SS_BOTH_SENSING: + // follow through + case LM_SS_BOTH_SETTLED_WAITING: + { + enum nextState + { + SWITCH_STATE_NONE, + SWITCH_STATE_WPS_ONLY, + SWITCH_STATE_GPS_ONLY + }; + + nextState nxtState = SWITCH_STATE_NONE; + double gpsAccuracy = __locMgrStatus.gpsHandler.pLocation->GetHorizontalAccuracy(); + double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy(); + + long long wpsTimestamp = __locMgrStatus.wpsHandler.pLocation->GetTimestamp().GetTicks(); + long long gpsTimestamp = __locMgrStatus.gpsHandler.pLocation->GetTimestamp().GetTicks(); + + long long timeDiff = Math::Abs(wpsTimestamp - gpsTimestamp); + SysLog(NID_LOC, "Accuracy values are, GPS (%lf) and WPS (%lf). Time difference is (%lld).", gpsAccuracy, wpsAccuracy, timeDiff); + + if (timeDiff <= 1) + { + SysLog(NID_LOC, "Both GPS and WPS position available."); + if (!Double::IsNaN(wpsAccuracy) && wpsAccuracy <= gpsAccuracy) + { + SysLog(NID_LOC, "WPS accuracy is better than or equal to GPS."); + nxtState = SWITCH_STATE_WPS_ONLY; + } + else + { + SysLog(NID_LOC, "GPS accuracy is better than WPS."); + nxtState = SWITCH_STATE_GPS_ONLY; + } + } + else + { + SysLog(NID_LOC, "WPS and GPS timestamp is not similar."); + if (wpsTimestamp > gpsTimestamp) + { + SysLog(NID_LOC, "WPS timestamp is better than GPS."); + nxtState = SWITCH_STATE_WPS_ONLY; + } + else + { + SysLog(NID_LOC, "GPS timestamp is better than WPS."); + nxtState = SWITCH_STATE_GPS_ONLY; + } + } + + switch(nxtState) + { + case SWITCH_STATE_WPS_ONLY: + { + location_manager_stop(__locMgrStatus.gpsHandler.handle); + __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY; + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } + break; + + case SWITCH_STATE_GPS_ONLY: + { + location_manager_stop(__locMgrStatus.wpsHandler.handle); + __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY; + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } + break; + + case SWITCH_STATE_NONE: + // follow through + default: + SysAssertf(false, "This state cannot happen."); + break; + } + + if (__locMgrStatus.locMgrSubState == LM_SS_BOTH_SENSING) + { + long long diff = gpsTimestamp - __locMgrStatus.gpsTimeAtSubstateTimerStart.GetTicks(); + if (diff < 0) // Considered to be GPS fail. + { + __locMgrStatus.gpsFailCount++; + } + } + } + break; + + case LM_SS_IDLE: + // follow through + case LM_SS_SETTLED: + // follow through + case LM_SS_SENSING: + // follow through + case LM_SS_NO_FIX: + // follow through + case LM_SS_GPS_ONLY_SETTLED: + // follow through + case LM_SS_GPS_ONLY_SENSING: + // follow through + case LM_SS_GPS_ONLY_NO_FIX: + // follow through + case LM_SS_WPS_ONLY_LESS_ACC_SENSING: + // follow through + case LM_SS_WPS_ONLY_FINE_ACC_SENSING: + // follow through + case LM_SS_WPS_ONLY_SENSING: + // follow through + case LM_SS_WPS_ONLY_NO_FIX: + // follow through + default: + SysLog(NID_LOC, "The sub state timer expired in wrong location manager sub state."); + break; + } + } + break; + + case LOC_MGR_STATE_GPS_ONLY: + { + switch (__locMgrStatus.locMgrSubState) + { + case LM_SS_GPS_ONLY_SETTLED: + // follow through + case LM_SS_GPS_ONLY_SENSING: + // follow through + case LM_SS_GPS_ONLY_NO_FIX: + { + if (__wpsEnabled) + { + SysLog(NID_LOC, "WPS setting is enabled. Start WPS now."); + int res = location_manager_start(__locMgrStatus.wpsHandler.handle); + SysTryLog(NID_LOC, res == 0, "Failed to start the core WPS location manager. So continue with GPS only."); + if (res == 0) + { + __locMgrStatus.locMgrState = LOC_MGR_STATE_BOTH_GPS_WPS; + } + } + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } + break; + + case LM_SS_IDLE: + // follow through + case LM_SS_SETTLED: + // follow through + case LM_SS_SENSING: + // follow through + case LM_SS_NO_FIX: + // follow through + case LM_SS_BOTH_SENSING: + // follow through + case LM_SS_BOTH_SETTLED_WAITING: + // follow through + case LM_SS_WPS_ONLY_LESS_ACC_SENSING: + // follow through + case LM_SS_WPS_ONLY_FINE_ACC_SENSING: + // follow through + case LM_SS_WPS_ONLY_SENSING: + // follow through + case LM_SS_WPS_ONLY_NO_FIX: + // follow through + default: + SysLog(NID_LOC, "The sub state timer expired in wrong location manager sub state."); + break; + } + } + break; + + case LOC_MGR_STATE_WPS_ONLY: + { + switch (__locMgrStatus.locMgrSubState) + { + case LM_SS_WPS_ONLY_LESS_ACC_SENSING: + // follow through + case LM_SS_WPS_ONLY_FINE_ACC_SENSING: + // follow through + case LM_SS_WPS_ONLY_SENSING: + // follow through + case LM_SS_WPS_ONLY_NO_FIX: + { + if (__gpsEnabled) + { + SysLog(NID_LOC, "GPS setting is enabled and WPS could not fix the location with requested accuracy. Start GPS now."); + int res = location_manager_start(__locMgrStatus.gpsHandler.handle); + SysTryLog(NID_LOC, res == 0, "Failed to start the core GPS location provider. So continue with WPS only."); + if (res == 0) + { + __locMgrStatus.locMgrState = LOC_MGR_STATE_BOTH_GPS_WPS; + } + } + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + } + break; + + case LM_SS_IDLE: + // follow through + case LM_SS_SETTLED: + // follow through + case LM_SS_SENSING: + // follow through + case LM_SS_NO_FIX: + // follow through + case LM_SS_BOTH_SENSING: + // follow through + case LM_SS_BOTH_SETTLED_WAITING: + // follow through + case LM_SS_GPS_ONLY_SETTLED: + // follow through + case LM_SS_GPS_ONLY_SENSING: + // follow through + case LM_SS_GPS_ONLY_NO_FIX: + // follow through + default: + SysLog(NID_LOC, "The sub state timer expired in wrong location manager sub state."); + break; + } + } + break; + + case LOC_MGR_STATE_IDLE: + // follow through + case LOC_MGR_STATE_PASSIVE_IDLE: + // follow through + default: + SysLog(NID_LOC, "The sub state timer expired in wrong location manager state."); + break; + } + + __locMgrStatus.isSubStateTimerStarted = false; +} + +void +_LocationManager::HandleLocationCheckTimerExpiry(void) +{ + SysLog(NID_LOC, "Location check timer expired."); + const int LOC_CHECK_TIMER_VALUE = 1000; + + switch (__locMgrStatus.locMgrState) + { + case LOC_MGR_STATE_BOTH_GPS_WPS: + { + if (__locMgrStatus.wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) + { + result gpsRes = GetLocation(LOCATIONS_METHOD_WPS); + SysTryLog(NID_LOC, gpsRes == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information."); + } + else + { + SysLog(NID_LOC, "WPS Location not available at the Native side."); + } + + if (__locMgrStatus.gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) + { + result wpsRes = GetLocation(LOCATIONS_METHOD_GPS); + SysTryLog(NID_LOC, wpsRes == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information."); + } + else + { + SysLog(NID_LOC, "GPS Location not available at the Native side."); + } + HandleBothGpsWpsState(); + } + break; + + case LOC_MGR_STATE_GPS_ONLY: + { + if (__locMgrStatus.gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) + { + result res = GetLocation(LOCATIONS_METHOD_GPS); + SysTryLog(NID_LOC, res == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information."); + } + else + { + SysLog(NID_LOC, "GPS Location not available at the Native side."); + } + HandleGpsOnlyState(); + } + break; + + case LOC_MGR_STATE_WPS_ONLY: + { + if (__locMgrStatus.wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) + { + result res = GetLocation(LOCATIONS_METHOD_WPS); + SysTryLog(NID_LOC, res == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information."); + } + else + { + SysLog(NID_LOC, "WPS Location not available at the Native side."); + } + HandleWpsOnlyState(); + } + break; + + case LOC_MGR_STATE_IDLE: + //follow through + case LOC_MGR_STATE_PASSIVE_IDLE: + //follow through + default: + SysLog(NID_LOC, "The timer expiry called in wrong location manager state."); + return; + } + + __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE); +} + bool _LocationManager::OnStart(void) { @@ -1083,17 +1625,17 @@ _LocationManager::OnStart(void) int res = -1; - std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pLocInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); + std::unique_ptr< ArrayList, AllElementsDeleter > pLocInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pLocInfoRequestList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Location Request list."); - std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pSyncLocInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); + std::unique_ptr< ArrayList, AllElementsDeleter > pSyncLocInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pSyncLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pSyncLocInfoRequestList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Sync Location Request list."); - std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pAlarmInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); + std::unique_ptr< ArrayList, AllElementsDeleter > pAlarmInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pAlarmInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pAlarmInfoRequestList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Sync Location Request list."); @@ -1103,26 +1645,37 @@ _LocationManager::OnStart(void) unique_ptr< Tizen::Locations::Location > pWpsLocation(_LocationImpl::GetLocationInstanceN()); SysTryReturn(NID_LOC, pWpsLocation != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - std::unique_ptr< Tizen::Base::Runtime::Timer > pLocUpdateTimer(new (std::nothrow) Timer()); + std::unique_ptr< Timer > pLocUpdateTimer(new (std::nothrow) Timer()); r = pLocUpdateTimer->Construct(*this); - SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location timer."); - - res = location_manager_create(LOCATIONS_METHOD_GPS, &__gpsHandler.handle); - SysTryReturn(NID_LOC, res == 0, false, E_SYSTEM, "[E_SYSTEM] Failed to create Native GPS Location provider."); - res = location_manager_set_service_state_changed_cb(__gpsHandler.handle, GpsServiceUpdateCallback, this); + SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location update timer."); + std::unique_ptr< Timer > pLocCheckTimer(new (std::nothrow) Timer()); + r = pLocCheckTimer->Construct(*this); + SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location chek timer."); + std::unique_ptr< Timer > pLocMgrSubstateTimer(new (std::nothrow) Timer()); + r = pLocMgrSubstateTimer->Construct(*this); + SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location manager sub state timer."); + + r = SettingInfo::AddSettingEventListener(*this); + SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to set the setting event listener."); + + res = location_manager_create(LOCATIONS_METHOD_GPS, &__locMgrStatus.gpsHandler.handle); + SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native GPS Location provider."); + res = location_manager_set_service_state_changed_cb(__locMgrStatus.gpsHandler.handle, GpsServiceUpdateCallback, this); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native GPS Location provider."); - res = location_manager_create(LOCATIONS_METHOD_WPS, &__wpsHandler.handle); + res = location_manager_create(LOCATIONS_METHOD_WPS, &__locMgrStatus.wpsHandler.handle); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native WPS Location provider."); - res = location_manager_set_service_state_changed_cb(__wpsHandler.handle, WpsServiceUpdateCallback, this); + res = location_manager_set_service_state_changed_cb(__locMgrStatus.wpsHandler.handle, WpsServiceUpdateCallback, this); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native WPS Location provider."); __pLocRequestInfoList = std::move(pLocInfoRequestList); __pSyncLocRequestInfoList = std::move(pSyncLocInfoRequestList); __pAlarmRequestInfoList = std::move(pAlarmInfoRequestList); - __pLocUpdateTimer = std::move(pLocUpdateTimer); - __gpsHandler.pLocation = std::move(pGpsLocation); - __wpsHandler.pLocation = std::move(pWpsLocation); + __pLocCallbackTimer = std::move(pLocUpdateTimer); + __pLocCheckTimer = std::move(pLocCheckTimer); + __locMgrStatus.pLocMgrSubStateTimer = std::move(pLocMgrSubstateTimer); + __locMgrStatus.gpsHandler.pLocation = std::move(pGpsLocation); + __locMgrStatus.wpsHandler.pLocation = std::move(pWpsLocation); r = __pInitMonitor->Enter(); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to Enter Monitor. Propagating.", GetErrorMessage(r)); @@ -1135,15 +1688,17 @@ _LocationManager::OnStart(void) return true; CATCH: - if (__gpsHandler.handle) + if (__locMgrStatus.gpsHandler.handle) { - location_manager_destroy(__gpsHandler.handle); + location_manager_destroy(__locMgrStatus.gpsHandler.handle); } - if (__wpsHandler.handle) + if (__locMgrStatus.wpsHandler.handle) { - location_manager_destroy(__wpsHandler.handle); + location_manager_destroy(__locMgrStatus.wpsHandler.handle); } + SettingInfo::RemoveSettingEventListener(*this); + return false; } @@ -1153,14 +1708,15 @@ _LocationManager::OnStop(void) delete __pInitMonitor; __pInitMonitor = null; - if (__gpsHandler.handle) + if (__locMgrStatus.gpsHandler.handle) { - location_manager_destroy(__gpsHandler.handle); + location_manager_destroy(__locMgrStatus.gpsHandler.handle); } - if (__wpsHandler.handle) + if (__locMgrStatus.wpsHandler.handle) { - location_manager_destroy(__wpsHandler.handle); + location_manager_destroy(__locMgrStatus.wpsHandler.handle); } + SettingInfo::RemoveSettingEventListener(*this); } void @@ -1196,29 +1752,6 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs) } break; - case REQ_ID_RESTART_LOC_UPDATES: - { - SysLog(NID_LOC, "REQ_ID_RESTART_LOC_UPDATES."); - RestartLocationUpdates(); - } - break; - - case REQ_ID_SUSTAIN_GPS: - { - SysLog(NID_LOC, "REQ_ID_SUSTAIN_GPS."); - location_manager_stop(__wpsHandler.handle); - __locMethodRequested = LOC_METHOD_REQUESTED_GPS; - } - break; - - case REQ_ID_SUSTAIN_WPS: - { - SysLog(NID_LOC, "REQ_ID_SUSTAIN_WPS."); - location_manager_stop(__gpsHandler.handle); - __locMethodRequested = LOC_METHOD_REQUESTED_WPS; - } - break; - case REQ_ID_SYNC_LOC_RETRIEVAL: { SysLog(NID_LOC, "REQ_ID_SYNC_LOC_RETRIEVAL."); @@ -1272,7 +1805,7 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs) pInterval = static_cast< Integer* >(pArgs->GetAt(1)); SysTryCatch(NID_LOC, pInterval, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); - UpdateLocRequestInfoList(static_cast< long >(pReqId->ToInt()), pInterval->ToInt()); + UpdateLocRequestInterval(static_cast< long >(pReqId->ToInt()), pInterval->ToInt()); } break; @@ -1320,87 +1853,180 @@ CATCH: void _LocationManager::OnTimerExpired(Tizen::Base::Runtime::Timer& timer) { - if (__pLocUpdateTimer->Equals(timer)) + if (__pLocCheckTimer->Equals(timer)) + { + HandleLocationCheckTimerExpiry(); + } + else if (__pLocCallbackTimer->Equals(timer)) { __timerTicks++; SysLog(NID_LOC, "LocationManager update timer expired. Timer Tick value is (%d).", __timerTicks); - result r = E_SUCCESS; - switch (__locMethodRequested) - { - case LOC_METHOD_REQUESTED_GPS: + __pLocCallbackTimer->Start(__timerInterval * 1000); + SendLocationCallbacks(); + } + else if (__locMgrStatus.pLocMgrSubStateTimer.get()->Equals(timer)) + { + SysLog(NID_LOC, "Substate timer expired."); + HandleSubStateTimerExpiry(); + } + else + { + int count = __pSyncLocRequestInfoList->GetCount(); + for (int i = 0; i < count; i++) { - r = GetLocation(LOCATIONS_METHOD_GPS); - SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information"); - if (IsFailed(r)) + _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i)); + if (pSyncLocRequestInfo != null && pSyncLocRequestInfo->Equals(timer)) { - SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null); + SysLog(NID_LOC, "Timer expired for the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId()); + + HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo); + break; } } - break; + } + return; +} - case LOC_METHOD_REQUESTED_WPS: +void +_LocationManager::OnSettingChanged(Tizen::Base::String& key) +{ + const String GPS_STRING(L"http://tizen.org/setting/location.gps"); + const String WPS_STRING(L"http://tizen.org/setting/location.wps"); + + SysLog(NID_LOC, "The setting value is changed for (%ls) setting.", key.GetPointer()); + + if (!((key.Equals(GPS_STRING, false)) || (key.Equals(WPS_STRING, false)))) + { + return; + } + + bool gpsEnabled = false; + bool wpsEnabled = false; + result gps = _SettingInfoImpl::GetValue(GPS_STRING, gpsEnabled); + SysTryReturnVoidResult(NID_LOC, gps == E_SUCCESS, gps, "[%s] Failed to get the setting value for GPS.", GetErrorMessage(gps)); + result wps = _SettingInfoImpl::GetValue(WPS_STRING, wpsEnabled); + SysTryReturnVoidResult(NID_LOC, wps == E_SUCCESS, wps, "[%s] Failed to get the setting value for WPS.", GetErrorMessage(wps)); + + SysLog(NID_LOC, "The current GPS setting value is (%d) and WPS setting value is (%d).", __gpsEnabled, __wpsEnabled); + SysLog(NID_LOC, "The changed GPS setting value is (%d) and WPS setting value is (%d).", gpsEnabled, wpsEnabled); + + switch (__locMgrStatus.locMgrState) + { + case LOC_MGR_STATE_PASSIVE_IDLE: + { + if (gpsEnabled && !wpsEnabled) { - r = GetLocation(LOCATIONS_METHOD_WPS); - SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information"); - if (IsFailed(r)) + SysLog(NID_LOC, "GPS setting enabled during the LOC_MGR_STATE_PASSIVE_IDLE."); + int res = location_manager_start(__locMgrStatus.gpsHandler.handle); + SysTryLog(NID_LOC, res == 0, "Failed to start the GPS location updates in Passive Idle mode."); + if (res == 0) { - SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null); + const int LOC_CHECK_TIMER_VALUE = 1; + __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY; + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE * 1000); } } - break; - - case LOC_METHOD_REQUESTED_ALL: + else if (!gpsEnabled && wpsEnabled) { - if (__wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) - { - r = GetLocation(LOCATIONS_METHOD_WPS); - SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information"); - } - else + SysLog(NID_LOC, "WPS setting enabled during the LOC_MGR_STATE_PASSIVE_IDLE."); + int res = location_manager_start(__locMgrStatus.wpsHandler.handle); + SysTryLog(NID_LOC, res == 0, "Failed to start the WPS location updates in Passive Idle mode."); + if (res == 0) { - SysLog(NID_LOC, "WPS Location not available at the Native side."); + const int LOC_CHECK_TIMER_VALUE = 1; + __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY; + __locMgrStatus.locMgrSubState = LM_SS_NO_FIX; + __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE * 1000); } + } + } + break; + + case LOC_MGR_STATE_BOTH_GPS_WPS: + { + if (!gpsEnabled) + { + SysLog(NID_LOC, "GPS setting turned off during LOC_MGR_STATE_BOTH_GPS_WPS."); + location_manager_stop(__locMgrStatus.gpsHandler.handle); + __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY; + } + + if (!wpsEnabled) + { + SysLog(NID_LOC, "WPS setting turned off during LOC_MGR_STATE_BOTH_GPS_WPS."); + location_manager_stop(__locMgrStatus.wpsHandler.handle); + __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY; + } + } + break; - if (__gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) + case LOC_MGR_STATE_GPS_ONLY: + { + if (!gpsEnabled) + { + int res = -1; + if (wpsEnabled) { - r = GetLocation(LOCATIONS_METHOD_GPS); - SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information"); + SysLog(NID_LOC, "The WPS setting is enabled. So starting WPS now."); + res = location_manager_start(__locMgrStatus.wpsHandler.handle); + SysTryLog(NID_LOC, res == 0, "Failed to start the location updates for WPS. Return value is (%d).", res); + if (res == 0) + { + __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY; + } } - else + if (!wpsEnabled || res != 0) { - SysLog(NID_LOC, "GPS Location not available at the Native side."); + __locMgrStatus.locMgrState = LOC_MGR_STATE_PASSIVE_IDLE; + StopSubStateTimer(); + __pLocCheckTimer->Cancel(); } - } - break; - case LOC_METHOD_REQUESTED_NONE: - // follow through - default: - SysLog(NID_LOC, "Timer expired when no location update is called."); - return; + SysLog(NID_LOC, "GPS setting turned off during LOC_MGR_STATE_GPS_ONLY."); + location_manager_stop(__locMgrStatus.gpsHandler.handle); } - - __pLocUpdateTimer->Start(__timerInterval * 1000); - SendLocationCallbacks(); } - else + break; + + case LOC_MGR_STATE_WPS_ONLY: { - int count = __pSyncLocRequestInfoList->GetCount(); - for (int i = 0; i < count; i++) + if (!wpsEnabled) { - _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i)); - if (pSyncLocRequestInfo != null && pSyncLocRequestInfo->Equals(timer)) + int res = -1; + if (gpsEnabled) { - SysLog(NID_LOC, "Timer expired for the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId()); - - HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo); - break; + SysLog(NID_LOC, "The GPS setting is enabled. So starting GPS now."); + res = location_manager_start(__locMgrStatus.gpsHandler.handle); + SysTryLog(NID_LOC, res == 0, "Failed to start the location updates for GPS. Return value is (%d).", res); + if (res == 0) + { + __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY; + } + } + if (!gpsEnabled || res != 0) + { + __locMgrStatus.locMgrState = LOC_MGR_STATE_PASSIVE_IDLE; + StopSubStateTimer(); + __pLocCheckTimer->Cancel(); } + + SysLog(NID_LOC, "WPS setting turned off during LOC_MGR_STATE_WPS_ONLY."); + location_manager_stop(__locMgrStatus.wpsHandler.handle); } } + break; - return; + case LOC_MGR_STATE_IDLE: + // follow through + default: + SysLog(NID_LOC, "GPS setting changed when there is no active location request. (%d),", __locMgrStatus.locMgrState); + break; + } + + __gpsEnabled = gpsEnabled; + __wpsEnabled = wpsEnabled; } bool @@ -1441,7 +2067,7 @@ _LocationManager::GpsServiceUpdateCallback(location_service_state_e state, void* } _LocationManager* pThis = static_cast< _LocationManager* >(user_data); - pThis->__gpsHandler.serviceState = state; + pThis->__locMgrStatus.gpsHandler.serviceState = state; } void @@ -1455,7 +2081,7 @@ _LocationManager::WpsServiceUpdateCallback(location_service_state_e state, void* } _LocationManager* pThis = static_cast< _LocationManager* >(user_data); - pThis->__wpsHandler.serviceState = state; + pThis->__locMgrStatus.wpsHandler.serviceState = state; } int @@ -1467,7 +2093,6 @@ _LocationManager::AlarmExpiryCallback(alarm_id_t alarm_id, void* user_param) SysLog(NID_LOC, "The user parameter is null. So cannot handle the callback."); return -1; } - _LocationManager* pThis = static_cast< _LocationManager* >(user_param); int count = pThis->__pAlarmRequestInfoList->GetCount(); |